1 /*
2  * Copyright 2013, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <memory>
18 #include <unistd.h>
19 #include "Abcc_host.h"
20 using namespace abcc;
21 
parseArguments(char ** argv,std::string & abi,std::string & ndk_dir,std::string & sysroot,std::string & input,std::string & output,std::string & platform,bool & savetemps)22 static int parseArguments(char **argv,
23                            std::string &abi, std::string &ndk_dir, std::string &sysroot,
24                            std::string &input, std::string &output, std::string &platform, bool &savetemps) {
25   unsigned idx = 1;
26   savetemps = false;
27   while (argv[idx] != 0) {
28     std::string arg = argv[idx++];
29     if (arg.find("--abi=") != std::string::npos) {
30       abi = arg.substr(arg.rfind('=')+1);
31       continue;
32     }
33     if (arg.find("--ndk-dir=") != std::string::npos) {
34       ndk_dir = arg.substr(arg.rfind('=')+1);
35       continue;
36     }
37     if (arg.find("--sysroot=") != std::string::npos) {
38       sysroot = arg.substr(arg.rfind('=')+1);
39       continue;
40     }
41     if (arg.find("--platform=") != std::string::npos) {
42       platform = arg.substr(arg.rfind('=')+1);
43       continue;
44     }
45     if (arg.find("--file") != std::string::npos) {
46       input = argv[idx++];
47       output = argv[idx++];
48       continue;
49     }
50     if (arg == "--verbose" || arg == "-v") {
51       kVerbose = true;
52       continue;
53     }
54 
55     if (arg == "-save-temps") {
56       savetemps = true;
57       continue;
58     }
59 
60     LOGE("Unsupport argument: %s", arg.c_str());
61     return -1;
62   }
63   return 0;
64 }
65 
main(int argc,char ** argv)66 int main(int argc, char **argv) {
67   char buf[256] = {'\0'};
68   std::string this_bin = argv[0];
69   std::string cwd;
70   if (getcwd(buf, 256))
71     cwd = buf;
72   else {
73     LOGE("getcwd failed");
74     return -1;
75   }
76   std::string abi;
77   std::string ndk_dir;
78   std::string sysroot;
79   std::string input;
80   std::string output;
81   std::string platform;
82   std::string working_dir;
83   std::string toolchain_bin;
84   bool savetemps;
85 
86   if (parseArguments(argv,
87                      abi, ndk_dir, sysroot, input, output, platform, savetemps) != 0)
88     return -1;
89 
90   // Make sure they are absolute path
91   if (this_bin[0] != '/')
92     this_bin = cwd + "/" + this_bin;
93   if (input[0] != '/')
94     input = cwd + "/" + input;
95   if (output[0] != '/')
96     output = cwd + "/" + output;
97 
98   toolchain_bin = this_bin.substr(0, this_bin.rfind('/'));
99   working_dir = input.substr(0, input.rfind('/'));
100   if (platform.empty()) // Folow ndk-bc2native.py usage
101     platform = "android-9";
102 
103   if (abi.empty() || input.empty() || output.empty() || toolchain_bin.empty() || platform.empty()) {
104     LOGE("Argument out-of-expect.");
105     return -1;
106   }
107 
108   if (sysroot.empty() && ndk_dir.empty()) {
109     LOGE("Must be either standalone or ndk mode");
110     return -1;
111   }
112 
113   if (sysroot.empty()) {
114     // NDK mode
115     sysroot = ndk_dir + "/platforms/" + platform + "/arch-" + TargetAbi(abi).getArch();
116   }
117 
118 
119   std::auto_ptr<BitcodeCompiler> compiler;
120   if (ndk_dir.empty())
121     compiler.reset(new HostBitcodeCompiler(abi, sysroot, toolchain_bin,
122                                            input, output,
123                                            working_dir, platform, savetemps));
124   else
125     compiler.reset(new HostBitcodeCompiler(abi, sysroot, ndk_dir, toolchain_bin,
126                                            input, output,
127                                            working_dir, platform, savetemps));
128 
129   compiler->prepare();
130   if (compiler->returnCode() != RET_OK) {
131     LOGE("prepare failed");
132     return -1;
133   }
134 
135   compiler->cleanupPre();
136   if (compiler->returnCode() != RET_OK) {
137     LOGE("cleanupPre failed");
138     return -1;
139   }
140 
141   compiler->execute();
142   compiler->cleanupPost();
143 
144   if (compiler->returnCode() != RET_OK) {
145     LOGE("execution failed");
146     return -1;
147   }
148 
149   return 0;
150 }
151