blob: f2ed42f8759532dae4e1f7c01944b4f1c98883c5 [file] [log] [blame]
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001#include "libslang.h"
zonr6315f762010-10-05 15:35:14 +08002#include "slang_rs_reflect_utils.h"
Shih-wei Liao462aefd2010-06-04 15:32:04 -07003
4#include <assert.h>
5#include <getopt.h>
6
7#include <cstring>
8#include <cstdlib>
Ying Wangb0037072010-09-08 15:06:34 -07009#include <cstdio>
Shih-wei Liao462aefd2010-06-04 15:32:04 -070010#include <iomanip>
11#include <iostream>
Ying Wange2e522f2010-09-01 13:24:01 -070012#include <vector>
Shih-wei Liao462aefd2010-06-04 15:32:04 -070013
Shih-wei Liao4c9f7422010-08-05 04:30:02 -070014#include <sys/stat.h>
15#include <fcntl.h>
16#include <sys/wait.h>
17
Shih-wei Liao462aefd2010-06-04 15:32:04 -070018using namespace std;
19
20#define ERR_NO_INPUT_FILE "no input file"
21
Shih-wei Liaof83d3c32010-07-30 22:22:49 -070022#define NOTE(x) cerr << "note: " NOTE_ ## x << endl
Shih-wei Liao462aefd2010-06-04 15:32:04 -070023#define WARN(x) cerr << "warning: " WARN_ ## x << endl
24#define WARN1(x, v1) cerr << "warning: " WARN_ ## x(v1) << endl
25#define WARN2(x, v1, v2) cerr << "warning: " WARN_ ## x(v1, v2) << endl
26
Shih-wei Liaof83d3c32010-07-30 22:22:49 -070027#define NOTE_MULTIPLE_INPUT_FILES "multiple input files detected: Will enforce ODR (One Definition Rule) during reflection."
Shih-wei Liao462aefd2010-06-04 15:32:04 -070028
29#define WARN_UNKNOWN_CPU(v1) "the given CPU " << (v1) << " cannot be recognized, but we'll force passing it to Slang compiler"
30
31#define WARN_MISMATCH_CPU_TARGET_ARCH(v1, v2) \
Shih-wei Liaof83d3c32010-07-30 22:22:49 -070032 "CPU (target: " << (v1) << ") you selected doesn't match the target of enable features you specified or the triple string you given (" << (v2) << ")"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070033
Shih-wei Liaof83d3c32010-07-30 22:22:49 -070034#define WARN_MISMATCH_FEATURE_TARGET_ARCH(v1, v2) \
35 "Feature (target: " << (v1) << ") you selected doesn't match the target of CPU you specified or the triple string you given (" << (v2) << ")"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070036
37/* List of all support target, will look like "ArchARM" */
38#define MK_TARGET_ARCH(target) Arch ## target
Shih-wei Liao462aefd2010-06-04 15:32:04 -070039
Shih-wei Liaof83d3c32010-07-30 22:22:49 -070040typedef enum {
41 ArchNone,
42#define DEF_SUPPORT_TARGET(target, name, default_triple) \
43 MK_TARGET_ARCH(target),
44# include "target.inc"
45
46 MaxTargetArch
Shih-wei Liao462aefd2010-06-04 15:32:04 -070047} TargetArchEnum;
48
49typedef struct {
Shih-wei Liaof83d3c32010-07-30 22:22:49 -070050 TargetArchEnum Arch;
51 const char* Name;
52 const char* DefaultTriple;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070053} TargetArch;
54
55static const TargetArch TargetArchTable[] = {
Shih-wei Liaof83d3c32010-07-30 22:22:49 -070056 { ArchNone, "none", "unknown-unknown-linux" },
Shih-wei Liao462aefd2010-06-04 15:32:04 -070057#define DEF_SUPPORT_TARGET(target, name, default_triple) \
Shih-wei Liaof83d3c32010-07-30 22:22:49 -070058 { MK_TARGET_ARCH(target), name, default_triple },
59# include "target.inc"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070060};
61
62#if defined(__arm__)
Shih-wei Liao6de89272010-07-15 15:26:20 -070063# define HOST_ARCH MK_TARGET_ARCH(X86)
Shih-wei Liao462aefd2010-06-04 15:32:04 -070064#elif defined(__i386__)
Shih-wei Liao6de89272010-07-15 15:26:20 -070065# define HOST_ARCH MK_TARGET_ARCH(ARM)
66#elif defined(__x86_64__)
67# define HOST_ARCH MK_TARGET_ARCH(X64)
Shih-wei Liao462aefd2010-06-04 15:32:04 -070068#else
69# error "We can not find default triple string for your host machine, please define it by yourself via option '--triple' or '-t'"
70#endif
71
72#define DEFAULT_TARGET_TRIPLE_STRING TargetArchTable[HOST_ARCH].DefaultTriple
73
74/* Lists of all target features, will look like "{Target}FeatureNEON" */
75#define MK_TARGET_FEATURE(target, id) target ## id
76typedef enum {
Shih-wei Liaof83d3c32010-07-30 22:22:49 -070077 FeatureNone = 0,
Shih-wei Liao462aefd2010-06-04 15:32:04 -070078#define DEF_TARGET_FEATURE(target, id, key, description) \
Shih-wei Liaof83d3c32010-07-30 22:22:49 -070079 MK_TARGET_FEATURE(target, id),
80
Shih-wei Liao462aefd2010-06-04 15:32:04 -070081#define HOOK_TARGET_FIRST_FEATURE(target, id, key, description) \
Shih-wei Liaof83d3c32010-07-30 22:22:49 -070082 target ## FeatureStart, \
83 MK_TARGET_FEATURE(target, id) = target ## FeatureStart,
84
Shih-wei Liao462aefd2010-06-04 15:32:04 -070085# include "target.inc"
86
Shih-wei Liaof83d3c32010-07-30 22:22:49 -070087 MaxTargetFeature
Shih-wei Liao462aefd2010-06-04 15:32:04 -070088} TargetFeatureEnum;
89
90/* Feature as bits using in {Target}TargetCPU, will look like "X{Target}FeatureNEON" */
91#define MK_TARGET_FEATURE_BIT(target, id) X ## target ## id
92typedef enum {
Shih-wei Liaof83d3c32010-07-30 22:22:49 -070093 XFeatureNone = 0,
Shih-wei Liao462aefd2010-06-04 15:32:04 -070094#define DEF_TARGET_FEATURE(target, id, key, description) \
Shih-wei Liaof83d3c32010-07-30 22:22:49 -070095 MK_TARGET_FEATURE_BIT(target, id) = 1 << (MK_TARGET_FEATURE(target, id) - target ## FeatureStart),
96# include "target.inc"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070097
Shih-wei Liaof83d3c32010-07-30 22:22:49 -070098 XMaxTargetFeature
Shih-wei Liao462aefd2010-06-04 15:32:04 -070099} TargetFeatureBit;
100
101typedef struct {
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700102 TargetArchEnum Arch;
103 TargetFeatureEnum Key;
104 TargetFeatureBit Bit;
105 const char* Name;
106 const char* Desc;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700107} TargetFeature;
108
109/* Should be 1-1 mapping with TargetFeatureEnum */
110static const TargetFeature TargetFeatureTable[] = {
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700111 { ArchNone, FeatureNone, XFeatureNone, "none", "Empty feature" }, /* FeatureNone */
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700112#define DEF_TARGET_FEATURE(target, id, key, description) \
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700113 { MK_TARGET_ARCH(target), MK_TARGET_FEATURE(target, id), MK_TARGET_FEATURE_BIT(target, id), key, description },
114# include "target.inc"
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700115};
116
117typedef struct {
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700118 TargetArchEnum Arch;
119 const char* Name;
120 const char* Desc;
121 unsigned int FeatureEnabled;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700122} TargetCPU;
123
124/* Sorted by CPU name such that we can call bsearch() to quickly retain the CPU entry corresponding to the name */
125#define E(feature) MK_TARGET_FEATURE_BIT(ARM, feature)
126static const TargetCPU TargetCPUTable[] = {
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700127 { MK_TARGET_ARCH(ARM), "arm1020e", "Select the arm1020e processor", E(ArchV5TE) },
128 { MK_TARGET_ARCH(ARM), "arm1020t", "Select the arm1020t processor", E(ArchV5T) },
129 { MK_TARGET_ARCH(ARM), "arm1022e", "Select the arm1022e processor", E(ArchV5TE) },
130 { MK_TARGET_ARCH(ARM), "arm10e", "Select the arm10e processor", E(ArchV5TE) },
131 { MK_TARGET_ARCH(ARM), "arm10tdmi", "Select the arm10tdmi processor", E(ArchV5T) },
132 { MK_TARGET_ARCH(ARM), "arm1136j-s", "Select the arm1136j-s processor", E(ArchV6) },
133 { MK_TARGET_ARCH(ARM), "arm1136jf-s", "Select the arm1136jf-s processor", E(ArchV6) | E(FeatureVFP2) },
134 { MK_TARGET_ARCH(ARM), "arm1156t2-s", "Select the arm1156t2-s processor", E(ArchV6T2) | E(FeatureThumb2) },
135 { MK_TARGET_ARCH(ARM), "arm1156t2f-s", "Select the arm1156t2f-s processor", E(ArchV6T2) | E(FeatureThumb2) | E(FeatureVFP2) },
136 { MK_TARGET_ARCH(ARM), "arm1176jz-s", "Select the arm1176jz-s processor", E(ArchV6) },
137 { MK_TARGET_ARCH(ARM), "arm1176jzf-s", "Select the arm1176jzf-s processor", E(ArchV6) | E(FeatureVFP2) },
138 { MK_TARGET_ARCH(ARM), "arm710t", "Select the arm710t processor", E(ArchV4T) },
139 { MK_TARGET_ARCH(ARM), "arm720t", "Select the arm720t processor", E(ArchV4T) },
140 { MK_TARGET_ARCH(ARM), "arm7tdmi", "Select the arm7tdmi processor", E(ArchV4T) },
141 { MK_TARGET_ARCH(ARM), "arm7tdmi-s", "Select the arm7tdmi-s processor", E(ArchV4T) },
142 { MK_TARGET_ARCH(ARM), "arm8", "Select the arm8 processor", XFeatureNone },
143 { MK_TARGET_ARCH(ARM), "arm810", "Select the arm810 processor", XFeatureNone },
144 { MK_TARGET_ARCH(ARM), "arm9", "Select the arm9 processor", E(ArchV4T) },
145 { MK_TARGET_ARCH(ARM), "arm920", "Select the arm920 processor", E(ArchV4T) },
146 { MK_TARGET_ARCH(ARM), "arm920t", "Select the arm920t processor", E(ArchV4T) },
147 { MK_TARGET_ARCH(ARM), "arm922t", "Select the arm922t processor", E(ArchV4T) },
148 { MK_TARGET_ARCH(ARM), "arm926ej-s", "Select the arm926ej-s processor", E(ArchV5TE) },
149 { MK_TARGET_ARCH(ARM), "arm940t", "Select the arm940t processor", E(ArchV4T) },
150 { MK_TARGET_ARCH(ARM), "arm946e-s", "Select the arm946e-s processor", E(ArchV5TE) },
151 { MK_TARGET_ARCH(ARM), "arm966e-s", "Select the arm966e-s processor", E(ArchV5TE) },
152 { MK_TARGET_ARCH(ARM), "arm968e-s", "Select the arm968e-s processor", E(ArchV5TE) },
153 { MK_TARGET_ARCH(ARM), "arm9e", "Select the arm9e processor", E(ArchV5TE) },
154 { MK_TARGET_ARCH(ARM), "arm9tdmi", "Select the arm9tdmi processor", E(ArchV4T) },
155 { MK_TARGET_ARCH(ARM), "cortex-a8", "Select the cortex-a8 processor", E(ArchV7A) | E(FeatureThumb2) | E(FeatureNEON) },
156 { MK_TARGET_ARCH(ARM), "cortex-a9", "Select the cortex-a9 processor", E(ArchV7A) | E(FeatureThumb2) | E(FeatureNEON) },
157 { MK_TARGET_ARCH(ARM), "ep9312", "Select the ep9312 processor", E(ArchV4T) },
158 { MK_TARGET_ARCH(ARM), "generic", "Select the generic processor", XFeatureNone },
159 { MK_TARGET_ARCH(ARM), "iwmmxt", "Select the iwmmxt processor", E(ArchV5TE) },
160 { MK_TARGET_ARCH(ARM), "mpcore", "Select the mpcore processor", E(ArchV6) | E(FeatureVFP2) },
161 { MK_TARGET_ARCH(ARM), "mpcorenovfp", "Select the mpcorenovfp processor", E(ArchV6) },
162 { MK_TARGET_ARCH(ARM), "strongarm", "Select the strongarm processor", XFeatureNone },
163 { MK_TARGET_ARCH(ARM), "strongarm110", "Select the strongarm110 processor", XFeatureNone },
164 { MK_TARGET_ARCH(ARM), "strongarm1100", "Select the strongarm1100 processor", XFeatureNone },
165 { MK_TARGET_ARCH(ARM), "strongarm1110", "Select the strongarm1110 processor", XFeatureNone },
166 { MK_TARGET_ARCH(ARM), "xscale", "Select the xscale processor", MK_TARGET_FEATURE_BIT(ARM, ArchV5TE) }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700167};
168#undef E
169static int CompareCPUName(const void* a, const void* b) {
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700170 return strcasecmp(((TargetCPU*) a)->Name, ((TargetCPU*) b)->Name);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700171}
172#define NUM_TARGET_CPU (sizeof(TargetCPUTable) / sizeof(TargetCPU))
173
174static struct option* SlangOpts = NULL;
175
176static const char* CPUString;
177static const TargetCPU* CPU;
178static const char* TripleString;
179static TargetFeatureEnum EnableFeatureValue, DisableFeatureValue;
180static SlangCompilerOutputTy OutputFileType;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700181static const char* JavaReflectionPackageName;
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700182
Shih-wei Liao6de89272010-07-15 15:26:20 -0700183static const char* JavaReflectionPathName;
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700184static const char* OutputPathName;
185
Ying Wange2e522f2010-09-01 13:24:01 -0700186static std::vector<std::string> IncludePaths;
187
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700188static std::string* InputFileNames;
189static std::string* OutputFileNames;
190
Ying Wang3f8b44d2010-09-04 01:17:01 -0700191// Where to store the bc file.
192// possible values:
193// ar: packed as apk resource
194// jc: encoded in Java code.
Ying Wang0877f052010-09-09 17:19:33 -0700195static slang::BitCodeStorageType BitCodeStorage(slang::BCST_APK_RESOURCE);
Ying Wang3f8b44d2010-09-04 01:17:01 -0700196
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700197static bool Verbose;
198static const char* FeatureEnabledList[MaxTargetFeature + 1];
Kirk Stewart1fd85792010-07-07 09:51:23 -0700199static int AllowRSPrefix = 0;
Shih-wei Liao9c9bbc82010-08-18 03:08:44 -0700200static int Externalize = 0;
Shih-wei Liao24c20082010-09-21 10:04:05 -0700201static int NoLink = 1;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700202
203/* Construct the command options table used in ParseOption::getopt_long */
204static void ConstructCommandOptions() {
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700205 /* Basic slang command option */
206 static struct option BasicSlangOpts[] = {
207 { "allow-rs-prefix", no_argument, &AllowRSPrefix, 1 },
Shih-wei Liao9c9bbc82010-08-18 03:08:44 -0700208 { "externalize", no_argument, &Externalize, 1 },
Shih-wei Liao4c9f7422010-08-05 04:30:02 -0700209 { "no-link", no_argument, &NoLink, 1 },
Kirk Stewart1fd85792010-07-07 09:51:23 -0700210
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700211 { "emit-llvm", no_argument, (int*) &OutputFileType, SlangCompilerOutput_LL },
212 { "emit-bc", no_argument, (int*) &OutputFileType, SlangCompilerOutput_Bitcode },
213 { "emit-asm", no_argument, NULL, 'S' },
214 { "emit-obj", no_argument, NULL, 'c' },
215 { "emit-nothing", no_argument, (int*) &OutputFileType, SlangCompilerOutput_Nothing },
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700216
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700217 { "help", no_argument, NULL, 'h' }, /* -h */
218 { "verbose", no_argument, NULL, 'v' }, /* -v */
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700219
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700220 { "output-obj-path", required_argument, NULL, 'o' }, /* -o */
221 { "cpu", required_argument, NULL, 'u' }, /* -u */
222 { "triple", required_argument, NULL, 't' }, /* -t */
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700223
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700224 { "output-java-reflection-class", required_argument, NULL, 'j'}, /* -j */
225 { "output-java-reflection-path", required_argument, NULL, 'p'}, /* -p */
Ying Wange2e522f2010-09-01 13:24:01 -0700226
227 { "include-path", required_argument, NULL, 'I'}, /* -I */
Ying Wang3f8b44d2010-09-04 01:17:01 -0700228 { "bitcode-storage", required_argument, NULL, 's'}, /* -s */
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700229 };
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700230
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700231 const int NumberOfBasicOptions = sizeof(BasicSlangOpts) / sizeof(struct option);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700232
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700233 SlangOpts = new struct option [ NumberOfBasicOptions + MaxTargetFeature * 2 /* for --enable-feature and --disable-feature */ ];
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700234
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700235 /* Fill SlangOpts with basic options */
236 memcpy(SlangOpts, BasicSlangOpts, sizeof(BasicSlangOpts));
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700237
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700238 int i = NumberOfBasicOptions;
239 /* Add --enable-TARGET_FEATURE option into slang command option */
240#define DEF_TARGET_FEATURE(target, id, key, description) \
241 SlangOpts[i].name = "enable-" key; \
242 SlangOpts[i].has_arg = optional_argument; \
243 SlangOpts[i].flag = (int*) &EnableFeatureValue; \
244 SlangOpts[i].val = target ## id; \
245 i++;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700246# include "target.inc"
247
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700248 /* Add --disable-TARGET_FEATURE option into slang command option */
249#define DEF_TARGET_FEATURE(target, id, key, description) \
250 SlangOpts[i].name = "disable-" key; \
251 SlangOpts[i].has_arg = optional_argument; \
252 SlangOpts[i].flag = (int*) &DisableFeatureValue; \
253 SlangOpts[i].val = target ## id; \
254 i++;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700255# include "target.inc"
256
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700257 /* NULL-terminated the SlangOpts */
258 memset(&SlangOpts[i], 0, sizeof(struct option));
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700259
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700260 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700261}
262
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700263
264static void Usage(const char* CommandName);
265
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700266extern char *optarg;
267extern int optind;
268extern int optopt;
269extern int opterr;
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700270static int FileCount;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700271
Ying Wang3f8b44d2010-09-04 01:17:01 -0700272static int AddOutputFileSuffix(std::string &pathFile) {
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700273 switch (OutputFileType) {
274 case SlangCompilerOutput_Assembly:
Ying Wang3f8b44d2010-09-04 01:17:01 -0700275 pathFile += ".S";
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700276 break;
277 case SlangCompilerOutput_LL:
Ying Wang3f8b44d2010-09-04 01:17:01 -0700278 pathFile += ".ll";
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700279 break;
280 case SlangCompilerOutput_Obj:
Ying Wang3f8b44d2010-09-04 01:17:01 -0700281 pathFile += ".o";
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700282 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700283
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700284 case SlangCompilerOutput_Nothing:
285 return 0; //strcpy(OutputFileNames[count], "/dev/null");
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700286
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700287 case SlangCompilerOutput_Bitcode:
288 default:
Ying Wang3f8b44d2010-09-04 01:17:01 -0700289 pathFile += ".bc";
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700290 break;
291 }
292 return 1;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700293}
294
295static bool ParseOption(int Argc, char** Argv) {
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700296 assert(SlangOpts != NULL && "Slang command options table was not initialized!");
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700297
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700298 /* Set default value to option */
299 CPU = NULL;
300 TripleString = DEFAULT_TARGET_TRIPLE_STRING;
301 EnableFeatureValue = DisableFeatureValue = FeatureNone;
302 OutputFileType = SlangCompilerOutput_Default;
303 JavaReflectionPackageName = NULL;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700304
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700305 JavaReflectionPathName = NULL;
306 OutputPathName = NULL;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700307
Ying Wange2e522f2010-09-01 13:24:01 -0700308 IncludePaths.clear();
309
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700310 InputFileNames = NULL;
311 OutputFileNames = NULL;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700312
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700313 Verbose = false;
314 FeatureEnabledList[0] = NULL;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700315
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700316 int ch;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700317
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700318 unsigned int FeatureEnableBits = 0;
319 unsigned int FeatureDisableBits = 0;
320#define ENABLE_FEATURE(x) \
321 FeatureEnableBits |= (x)
322#define DISABLE_FEATURE(x) \
323 FeatureDisableBits |= (x)
324 TargetArchEnum ExpectedArch = ArchNone;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700325
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700326 /* Turn off the error message output by getopt_long */
327 opterr = 0;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700328
Ying Wang3f8b44d2010-09-04 01:17:01 -0700329 while((ch = getopt_long(Argc, Argv, "Schvo:u:t:j:p:I:s:", SlangOpts, NULL)) != -1) {
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700330 switch(ch) {
331 case 'S':
332 OutputFileType = SlangCompilerOutput_Assembly;
333 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700334
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700335 case 'c':
336 OutputFileType = SlangCompilerOutput_Obj;
337 break;
Shih-wei Liao6de89272010-07-15 15:26:20 -0700338
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700339 case 'o':
340 OutputPathName = optarg;
341 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700342
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700343 case 'j':
344 JavaReflectionPackageName = optarg;
345 break;
Shih-wei Liao6de89272010-07-15 15:26:20 -0700346
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700347 case 'p':
348 JavaReflectionPathName = optarg;
349 break;
350
Ying Wange2e522f2010-09-01 13:24:01 -0700351 case 'I':
352 IncludePaths.push_back(optarg);
353 break;
354
Ying Wang3f8b44d2010-09-04 01:17:01 -0700355 case 's':
Ying Wang0877f052010-09-09 17:19:33 -0700356 if (!std::strcmp(optarg, "ar")) {
357 BitCodeStorage = slang::BCST_APK_RESOURCE;
358 } else if (!std::strcmp(optarg, "jc")) {
359 BitCodeStorage = slang::BCST_JAVA_CODE;
360 } else {
361 cerr << "Error: bit code storage (-s) should be 'ar' or 'jc', saw "
362 << optarg << endl;
363 return false;
364 }
Ying Wang3f8b44d2010-09-04 01:17:01 -0700365 break;
366
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700367 case 'u':
368 {
369 CPUString = optarg;
370 const TargetCPU SearchCPU = { ArchNone, CPUString, NULL, XFeatureNone };
371 CPU = (TargetCPU*) bsearch(&SearchCPU, TargetCPUTable, sizeof(TargetCPUTable) / sizeof(TargetCPU), sizeof(TargetCPU), CompareCPUName);
372 if(CPU == NULL) {
373 WARN1(UNKNOWN_CPU, SearchCPU.Name);
374 } else {
375 CPUString = CPU->Name;
376
377 if(ExpectedArch == ArchNone)
378 ExpectedArch = CPU->Arch;
379 else if(ExpectedArch != CPU->Arch) {
380 WARN2(MISMATCH_CPU_TARGET_ARCH, TargetArchTable[CPU->Arch].Name, TargetArchTable[ExpectedArch].Name);
381 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700382 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700383
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700384 /* Get CPU Feature and enable its available feature */
385 FeatureEnableBits |= CPU->FeatureEnabled;
386 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700387 }
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700388 break;
389
390 case 't':
391 TripleString = optarg;
392 break;
393
394 case 'h':
395 Usage(Argv[0]);
396 return false;
397 break;
398
399 case 'v':
400 Verbose = true;
401 break;
402
403 case 0:
404 {
405 if(EnableFeatureValue != FeatureNone || DisableFeatureValue != FeatureNone) {
406 bool IsDisable = (DisableFeatureValue != FeatureNone);
407 const TargetFeature* FeatureSelected = &TargetFeatureTable[ ((IsDisable) ? DisableFeatureValue : EnableFeatureValue) ];
408 assert(FeatureSelected != NULL && "Unexpected target feature! (not presented in table but parsed!?)");
409
410 if(ExpectedArch == ArchNone)
411 ExpectedArch = FeatureSelected->Arch;
412 else if(FeatureSelected->Arch != ExpectedArch) {
413 WARN2(MISMATCH_FEATURE_TARGET_ARCH, TargetArchTable[FeatureSelected->Arch].Name, TargetArchTable[ExpectedArch].Name);
414 break;
415 }
416
417 if(optarg != NULL && atoi(optarg) == 0)
418 IsDisable = !IsDisable;
419
420 if(IsDisable)
421 DISABLE_FEATURE(FeatureSelected->Bit);
422 else
423 ENABLE_FEATURE(FeatureSelected->Bit);
424 }
425 }
426 break;
427
428 default:
429 cerr << "Unknown option: " << Argv[optind - 1] << endl;
430 return false;
431 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700432 }
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700433 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700434#undef ENABLE_FEATURE
435#undef DISABLE_FEATURE
436
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700437 int CurFeatureEnableListIdx = 0;
438 /* Add the enable/disable feature string to */
439 switch(ExpectedArch) {
440 case ArchNone:
441 ExpectedArch = HOST_ARCH;
442 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700443
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700444#define DEF_TARGET_FEATURE(target, id, key, description) \
445 if(FeatureDisableBits & MK_TARGET_FEATURE_BIT(target, id)) \
446 FeatureEnabledList[ CurFeatureEnableListIdx++ ] = "-" key; \
447 else if(FeatureEnableBits & MK_TARGET_FEATURE_BIT(target, id)) \
448 FeatureEnabledList[ CurFeatureEnableListIdx++ ] = "+" key;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700449#define HOOK_TARGET_FIRST_FEATURE(target, id, key, description) \
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700450 case Arch ## target: \
451 /* Fix target triple */ \
452 if(TripleString == DEFAULT_TARGET_TRIPLE_STRING) \
453 TripleString = TargetArchTable[MK_TARGET_ARCH(target)].DefaultTriple; \
454 DEF_TARGET_FEATURE(target, id, key, description)
455#define HOOK_TARGET_LAST_FEATURE(target, id, key, description) \
456 DEF_TARGET_FEATURE(target, id, key, description) \
457 FeatureEnabledList[ CurFeatureEnableListIdx++ ] = NULL; /* null-terminator */ \
458 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700459#include "target.inc"
460
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700461 default:
462 assert(false && "Unknown / Unsupported CPU architecture");
463 break;
464 }
465
466 Argc -= optind;
467 if(Argc <= 0) {
468 cerr << Argv[0] << ": "ERR_NO_INPUT_FILE << endl;
469 return false;
470 }
471
472 if(Argc > 1) {
473 NOTE(MULTIPLE_INPUT_FILES);
474 }
475
Ying Wang3f8b44d2010-09-04 01:17:01 -0700476
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700477 FileCount = Argc;
478 InputFileNames = new std::string[FileCount];
479 OutputFileNames = new std::string[FileCount];
480 int count;
481 for (count = 0; count < FileCount; count++) {
482 InputFileNames[count].assign(Argv[optind + count]);
483
484 if ( OutputPathName && !strcmp(OutputPathName, "-") ) {
485 OutputFileNames[count].assign("stdout");
486 continue;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700487 }
488
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700489 std::string _outF;
490 if (OutputPathName) {
491 _outF.assign(OutputPathName);
Ying Wang3f8b44d2010-09-04 01:17:01 -0700492 if (_outF[_outF.length()-1] != '/') {
493 _outF += "/";
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700494 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700495 }
Ying Wang3f8b44d2010-09-04 01:17:01 -0700496 _outF += slang::RSSlangReflectUtils::BCFileNameFromRSFileName(
497 InputFileNames[count].c_str());
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700498
Ying Wang3f8b44d2010-09-04 01:17:01 -0700499 int status = AddOutputFileSuffix(_outF);
500 if (status < 0) {
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700501 return false;
Ying Wang3f8b44d2010-09-04 01:17:01 -0700502 } else if (!status) {
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700503 OutputFileNames[count].assign("/dev/null");
504 } else {
505 OutputFileNames[count].assign(_outF);
506 }
507 }
508
509 if(Verbose) {
510 for (count = 0; count < FileCount; count++) {
511 cout << "Input: " << InputFileNames[count] << endl;
512 }
513
514 if(CPU != NULL)
515 cout << "Use CPU: " << CPU->Name << endl;
516 cout << "Use triple string: " << TripleString << endl;
517 cout << "Expected architecture: " << TargetArchTable[ExpectedArch].Name << endl;
518
519 cout << "Enable target feature: " << endl;
520 for(int i=0;FeatureEnabledList[i]!=NULL;i++)
521 if(*FeatureEnabledList[i] == '+')
522 cout << "\t" << &FeatureEnabledList[i][1] << endl;
523 cout << endl;
524
525 cout << "Disable target feature: " << endl;
526 for(int i=0;FeatureEnabledList[i]!=NULL;i++)
527 if(*FeatureEnabledList[i] == '-')
528 cout << "\t" << &FeatureEnabledList[i][1] << endl;
529 cout << endl;
530
531 cout << "Output to: " << ((strcmp(OutputPathName, "-")) ? OutputPathName : "(standard output)") << ", type: ";
532 switch(OutputFileType) {
533 case SlangCompilerOutput_Assembly: cout << "Target Assembly"; break;
534 case SlangCompilerOutput_LL: cout << "LLVM Assembly"; break;
535 case SlangCompilerOutput_Bitcode: cout << "Bitcode"; break;
536 case SlangCompilerOutput_Nothing: cout << "No output (test)"; break;
537 case SlangCompilerOutput_Obj: cout << "Object file"; break;
538 default: assert(false && "Unknown output type"); break;
539 }
540 cout << endl;
541 }
542
543 return true;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700544}
545
546static void DestroyCommandOptions() {
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700547 if(SlangOpts != NULL) {
548 delete [] SlangOpts;
549 SlangOpts = NULL;
550 }
551 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700552}
553
Shih-wei Liao4c9f7422010-08-05 04:30:02 -0700554/*
555 * E.g., replace out/host/linux-x86/bin/slang to out/host/linux-x86/bin/<fileName>
556 */
Shih-wei Liaoa7af2d72010-08-24 18:43:46 -0700557static std::string replaceLastPartWithFile(std::string& cmd, const char* fileName) {
Shih-wei Liao4c9f7422010-08-05 04:30:02 -0700558 size_t pos = cmd.rfind('/');
559 if (pos == std::string::npos) {
Shih-wei Liaoa7af2d72010-08-24 18:43:46 -0700560 return std::string(fileName);
Shih-wei Liao4c9f7422010-08-05 04:30:02 -0700561 }
562
563 cmd.resize(pos+1);
564 cmd.append(fileName);
Shih-wei Liaof8149d92010-08-22 05:32:02 -0700565 return cmd;
Shih-wei Liao4c9f7422010-08-05 04:30:02 -0700566 // std::string returnFile = cmd.substr(0, pos+1).append(fileName); // cmd.replace(pos+1, std::string::npos, fileName);
567}
568
Ying Wang01d86012010-09-07 18:14:46 -0700569#define LINK_FILE "/frameworks/compile/slang/rsScriptC_Lib.bc"
Shih-wei Liao4c9f7422010-08-05 04:30:02 -0700570
571static char* linkFile() {
572 char* dir = getenv("ANDROID_BUILD_TOP");
573 char* dirPath;
574 bool readyToLink = false;
575 if (dir) {
Shih-wei Liaoe14a2ea2010-09-20 09:41:51 -0700576 dirPath = new char[strlen(dir) + strlen(LINK_FILE) + 1];
Shih-wei Liao4c9f7422010-08-05 04:30:02 -0700577 strcpy(dirPath, dir);
578 strcpy(dirPath + strlen(dir), LINK_FILE);
579 if (open(dirPath, O_RDONLY) >= 0) {
580 readyToLink = true;
581 }
582 }
583
584 if (!readyToLink) {
585 /* try cwd */
586 int siz = 256;
587 dir = new char[siz];
588 while (!getcwd(dir, siz)) {
589 siz *= 2;
590 dir = new char[siz];
591 }
Shih-wei Liaoe14a2ea2010-09-20 09:41:51 -0700592 dirPath = new char[strlen(dir) + strlen(LINK_FILE) + 1];
Shih-wei Liao4c9f7422010-08-05 04:30:02 -0700593 strcpy(dirPath, dir);
594 strcpy(dirPath + strlen(dir), LINK_FILE);
Shih-wei Liaoe14a2ea2010-09-20 09:41:51 -0700595 //dirPath[strlen(dir) + LINK_FILE_LENGTH] = '\0';
Shih-wei Liao4c9f7422010-08-05 04:30:02 -0700596 if (open(dirPath, O_RDONLY) < 0) {
597 cerr << "Error: Couldn't load rs library bitcode file" << endl;
598 exit(1);
599 }
600 }
601 return dirPath;
602}
603
Ying Wang01d86012010-09-07 18:14:46 -0700604#define LINK_FILE1 "/frameworks/compile/slang/rslib.bc"
Shih-wei Liao4c9f7422010-08-05 04:30:02 -0700605#define LINK_FILE1_LENGTH 30
606
607static char* linkFile1() {
608 char* dir = getenv("ANDROID_BUILD_TOP");
609 char* dirPath;
610 bool readyToLink = false;
611 if (dir) {
612 dirPath = new char[strlen(dir) + LINK_FILE1_LENGTH];
613 strcpy(dirPath, dir);
614 strcpy(dirPath + strlen(dir), LINK_FILE1);
615 if (open(dirPath, O_RDONLY) >= 0) {
616 readyToLink = true;
617 }
618 }
619
620 if (!readyToLink) {
621 /* try cwd */
622 int siz = 256;
623 dir = new char[siz];
624 while (!getcwd(dir, siz)) {
625 siz *= 2;
626 dir = new char[siz];
627 }
628 dirPath = new char[strlen(dir) + LINK_FILE1_LENGTH];
629 strcpy(dirPath, dir);
630 strcpy(dirPath + strlen(dir), LINK_FILE1);
631 if (open(dirPath, O_RDONLY) < 0) {
632 cerr << "Error: Couldn't load rs library bitcode file" << endl;
633 exit(1);
634 }
635 }
636 return dirPath;
637}
638
Shih-wei Liao4c9f7422010-08-05 04:30:02 -0700639static int waitForChild(pid_t pid) {
640 pid_t w;
641 int childExitStatus;
642
643 do {
644 w = waitpid(pid, &childExitStatus, WUNTRACED | WCONTINUED);
645 if (w == -1) {
646 exit(1);
647 }
648 if (WIFEXITED(childExitStatus)) {
649 if (WEXITSTATUS(childExitStatus)) {
650 cerr << "Linking error" << endl;
651 exit(1);
652 }
653 return 0;
654 } else if (WIFSIGNALED(childExitStatus)) {
655 cerr << "Linking: Killed by signal " << WTERMSIG(childExitStatus) << endl;
656 exit(1);
657 } else if (WIFSTOPPED(childExitStatus)) {
658 cerr << "Linking: Stopped by signal " << WSTOPSIG(childExitStatus) << endl;
659 } else if (WIFCONTINUED(childExitStatus)) {
660 cerr << "LInking: Continued" << endl;
661 }
662 } while (!WIFEXITED(childExitStatus) && !WIFSIGNALED(childExitStatus));
663 return 0;
664}
665
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700666#define SLANG_CALL_AND_CHECK(expr) \
667 if(!(expr)) { \
668 if(slangGetInfoLog(slang)) \
669 cerr << slangGetInfoLog(slang); \
670 ret = 1; \
671 goto on_slang_error; \
672 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700673
674int main(int argc, char** argv) {
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700675 int ret = 0;
676 int count;
Shih-wei Liaoa7af2d72010-08-24 18:43:46 -0700677
678 std::string command(argv[0]);
679 // char* command = new char[strlen(argv[0])+16]; strcpy(command, argv[0]);
Shih-wei Liaoc552b7c2010-06-25 11:06:57 -0700680
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700681 if(argc < 2) {
682 cerr << argv[0] << ": "ERR_NO_INPUT_FILE << endl;
683 return 1;
684 }
685
686 ConstructCommandOptions();
687
688 if(ParseOption(argc, argv)) {
689 SlangCompiler* slang = slangCreateCompiler(TripleString, CPUString, FeatureEnabledList);
690 if(slang == NULL) {
691 goto on_slang_error;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700692 }
693
Shih-wei Liao4c9f7422010-08-05 04:30:02 -0700694 slangSetOutputType(slang, OutputFileType);
695
Ying Wangb0037072010-09-08 15:06:34 -0700696 for (size_t i = 0; i < IncludePaths.size(); ++i) {
Ying Wange2e522f2010-09-01 13:24:01 -0700697 slangAddIncludePath(slang, IncludePaths[i].c_str());
698 }
699
Shih-wei Liao4c9f7422010-08-05 04:30:02 -0700700 if (AllowRSPrefix)
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700701 slangAllowRSPrefix(slang);
Shih-wei Liao4c9f7422010-08-05 04:30:02 -0700702
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700703 for (count = 0; count < FileCount; count++) {
704 /* Start compilation */
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700705
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700706 SLANG_CALL_AND_CHECK( slangSetSourceFromFile(slang, InputFileNames[count].c_str()) );
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700707
Shih-wei Liao917c3c42010-08-24 03:38:08 -0700708 std::string beforeLink;
Shih-wei Liao4c9f7422010-08-05 04:30:02 -0700709 if (NoLink) {
710 SLANG_CALL_AND_CHECK( slangSetOutputToFile(slang, OutputFileNames[count].c_str()) );
711 } else {
Ying Wangb0037072010-09-08 15:06:34 -0700712 std::string stem = slang::RSSlangReflectUtils::BCFileNameFromRSFileName(
713 InputFileNames[count].c_str());
714 char tmpFileName[256];
715 snprintf(tmpFileName, sizeof(tmpFileName), "/tmp/%s.bc.XXXXXX", stem.c_str());
716 int f = mkstemp(tmpFileName);
717 if (f < 0) {
718 cerr << "Error: could not create temporary file " << tmpFileName << endl;
719 return 1;
720 }
721 // we don't need the file descriptor
722 close(f);
Shih-wei Liao917c3c42010-08-24 03:38:08 -0700723
Ying Wangb0037072010-09-08 15:06:34 -0700724 beforeLink.assign(tmpFileName);
Shih-wei Liao4c9f7422010-08-05 04:30:02 -0700725 SLANG_CALL_AND_CHECK( slangSetOutputToFile(slang, beforeLink.c_str()) );
Shih-wei Liao4c9f7422010-08-05 04:30:02 -0700726 }
727
728 SLANG_CALL_AND_CHECK( slangCompile(slang) <= 0 );
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700729
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700730 /* Output log anyway */
731 if(slangGetInfoLog(slang)) {
732 cout << slangGetInfoLog(slang);
733 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700734
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700735 SLANG_CALL_AND_CHECK( slangReflectToJavaPath(slang, JavaReflectionPathName) );
Shih-wei Liao6de89272010-07-15 15:26:20 -0700736
Ying Wang3f8b44d2010-09-04 01:17:01 -0700737 char realPackageName[0x100];
738 SLANG_CALL_AND_CHECK( slangReflectToJava(slang, JavaReflectionPackageName,
739 realPackageName, sizeof(realPackageName)));
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700740
Shih-wei Liao4c9f7422010-08-05 04:30:02 -0700741 if (NoLink) {
Ying Wang0877f052010-09-09 17:19:33 -0700742 goto generate_bitcode_accessor;
Shih-wei Liao4c9f7422010-08-05 04:30:02 -0700743 }
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700744
Shih-wei Liao835a7b72010-08-06 02:29:11 -0700745 // llvm-rs-link
Shih-wei Liao4c9f7422010-08-05 04:30:02 -0700746 pid_t pid;
747 if ((pid = fork()) < 0) {
Shih-wei Liao835a7b72010-08-06 02:29:11 -0700748 cerr << "Failed before llvm-rs-link" << endl;
Shih-wei Liao4c9f7422010-08-05 04:30:02 -0700749 exit(1);
750 } else if (pid == 0) {
Shih-wei Liaoa7af2d72010-08-24 18:43:46 -0700751 std::string cmd(command);
752 cmd = replaceLastPartWithFile(cmd, "llvm-rs-link");
Shih-wei Liao4c9f7422010-08-05 04:30:02 -0700753
754 char* link0 = linkFile();
755 char* link1 = linkFile1();
Shih-wei Liao9c9bbc82010-08-18 03:08:44 -0700756 if (Externalize) {
Shih-wei Liaof8149d92010-08-22 05:32:02 -0700757 char* cmdline[] = { (char*)cmd.c_str(), "-e", "-o", (char*)OutputFileNames[count].c_str(), (char*)beforeLink.c_str(), (char*)link0, /*link1,*/ NULL };
758 execvp(cmd.c_str(), cmdline);
Shih-wei Liao9c9bbc82010-08-18 03:08:44 -0700759 } else {
Shih-wei Liaof8149d92010-08-22 05:32:02 -0700760 //cerr << cmd << " -o " << OutputFileNames[count] << " " << beforeLink << " " << link0 << endl;
761 char* cmdline[] = { (char*)cmd.c_str(), "-o", (char*)OutputFileNames[count].c_str(), (char*)beforeLink.c_str(), (char*)link0, /*link1,*/ NULL };
762 execvp(cmd.c_str(), cmdline);
Shih-wei Liao9c9bbc82010-08-18 03:08:44 -0700763 }
Shih-wei Liao4c9f7422010-08-05 04:30:02 -0700764 }
765
766 waitForChild(pid);
767
768 /* // opt
769 if ((pid = fork()) < 0) {
770 cerr << "Failed before opt" << endl;
771 exit(1);
772 } else if (pid == 0) {
773 std::string cmd(command);
774 replaceLastPartWithFile(cmd, "opt");
775
776 const char* funcNames = slangExportFuncs(slang);
777 std::string internalize("-internalize-public-api-list=init,root");
778 if (funcNames) {
779 internalize.append(funcNames);
780 }
781
782 //cerr << cmd << " -std-link-opts " << internalize << " " << afterLink << " -o " << OutputFileNames[count] << endl;
Shih-wei Liao4c9f7422010-08-05 04:30:02 -0700783 execl(cmd.c_str(), cmd.c_str(), "-std-link-opts", internalize.c_str(), afterLink.c_str(), "-o", OutputFileNames[count].c_str(), NULL);
784 }
785
786 waitForChild(pid); */
Ying Wang3f8b44d2010-09-04 01:17:01 -0700787
Ying Wang0877f052010-09-09 17:19:33 -0700788 generate_bitcode_accessor:
Ying Wang3f8b44d2010-09-04 01:17:01 -0700789 if ((OutputFileType == SlangCompilerOutput_Bitcode)
Ying Wang0877f052010-09-09 17:19:33 -0700790 && (BitCodeStorage == slang::BCST_JAVA_CODE)
Ying Wang3f8b44d2010-09-04 01:17:01 -0700791 && (OutputFileNames[count] != "stdout")) {
Ying Wang0877f052010-09-09 17:19:33 -0700792 slang::RSSlangReflectUtils::BitCodeAccessorContext bc_context;
793 bc_context.rsFileName = InputFileNames[count].c_str();
794 bc_context.bcFileName = OutputFileNames[count].c_str();
795 bc_context.reflectPath = JavaReflectionPathName ? JavaReflectionPathName : "";
796 bc_context.packageName = realPackageName;
797 bc_context.bcStorage = BitCodeStorage;
798 if (!slang::RSSlangReflectUtils::GenerateBitCodeAccessor(
799 bc_context)) {
800 ret = 1;
Ying Wang3f8b44d2010-09-04 01:17:01 -0700801 }
802 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700803 }
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700804 on_slang_error:
805 delete slang;
806 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700807
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700808 DestroyCommandOptions();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700809
Shih-wei Liao4c9f7422010-08-05 04:30:02 -0700810 if (ret) exit(1);
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700811 return ret;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700812}
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700813
814/*
815 * OUTPUT_OPTION is only used inside Usage()
816 */
817#define OUTPUT_OPTION(short_name, long_name, desc) \
818 do { \
819 if(short_name) \
820 cout << setw(4) << right << (short_name) << ", "; \
821 else \
822 cout << " "; \
823 cout << setw(17) << left << (long_name); \
824 cout << " " << (desc) << endl; \
825 } while(false)
826
827static void Usage(const char* CommandName) {
828 cout << "Usage: " << CommandName << " [OPTION]... " << "[INPUT FILE]" << endl;
829
830 cout << endl;
831
832 cout << "Basic: " << endl;
833
834 OUTPUT_OPTION("-h", "--help", "Print this help");
835 OUTPUT_OPTION("-v", "--verbose", "Be verbose");
836 OUTPUT_OPTION(NULL, "--allow-rs-prefix", "Allow user-defined function names with the \"rs\" prefix");
Shih-wei Liao4c9f7422010-08-05 04:30:02 -0700837 OUTPUT_OPTION(NULL, "--no-link", "Do not link the system bitcode libraries");
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700838 OUTPUT_OPTION("-o", "--output-obj-path=<PATH>", "Write compilation output at this path ('-' means stdout)");
839 OUTPUT_OPTION("-j", "--output-java-reflection-class=<PACKAGE NAME>", "Output reflection of exportables in the native domain into Java");
840 OUTPUT_OPTION("-p", "--output-java-reflection-path=<PATH>", "Write reflection output at this path");
Ying Wang3f8b44d2010-09-04 01:17:01 -0700841 OUTPUT_OPTION("-I", "--include-path=<PATH>", "Add a hearder search path");
842 OUTPUT_OPTION("-s", "--bitcode-storage=<VALUE>", "Where to store the bc file. 'ar' means apk resource, 'jc' means Java code.");
Shih-wei Liaof83d3c32010-07-30 22:22:49 -0700843
844 cout << endl;
845
846 cout << "Output type:" << endl;
847
848 OUTPUT_OPTION(NULL, "--emit-llvm", "Set output type to LLVM assembly (.ll)");
849 OUTPUT_OPTION(NULL, "--emit-bc", "Set output type to Bitcode (.bc) (Default)");
850 OUTPUT_OPTION("-S", "--emit-asm", "Set output type to target assmbly code (.S)");
851 OUTPUT_OPTION("-c", "--emit-obj", "Set output type to target object file (.o)");
852 OUTPUT_OPTION(NULL, "--emit-nothing", "Output nothing");
853
854 cout << endl;
855
856 cout << "Code generation option: " << endl;
857
858 OUTPUT_OPTION("-u", "--cpu=CPU", "generate the assembly / object file for the CPU");
859 cout << endl;
860 cout << "\tAvailable CPU:" << endl;
861
862 for (unsigned i = 0; i < NUM_TARGET_CPU; i++)
863 cout << "\t" << setw(13) << right << TargetCPUTable[i].Name << left << ": (" << TargetArchTable[(TargetCPUTable[i].Arch)].Name << ") " << TargetCPUTable[i].Desc << endl;
864
865 cout << endl;
866
867 OUTPUT_OPTION("-t", "--triple=TRIPLE", "generate the assembly / object file for the Triple");
868 cout << "\tDefault triple: " << endl;
869#define DEF_SUPPORT_TARGET(target, name, default_triple) \
870 cout << "\t" << setw(5) << right << name << left << ": " << default_triple << endl;
871#include "target.inc"
872 cout << endl;
873
874 OUTPUT_OPTION(NULL, "--enable-FEATURE", "enable the FEATURE for the generation of the assembly / object file");
875 OUTPUT_OPTION(NULL, "--disable-FEATURE", "disable the FEATURE for the generation of the assembly / object file");
876 cout << endl;
877 cout << "\tAvailable features:" << endl;
878#define DEF_TARGET_FEATURE(target, id, key, description) \
879 cout << "\t" << setw(6) << right << key \
880 << left << ": (" << TargetArchTable[MK_TARGET_ARCH(target)].Name << ") " \
881 << description << endl;
882#include "target.inc"
883
884 cout << endl;
885
886 return;
887}
888
889#undef OUTPUT_OPTION