| OLD | NEW |
| (Empty) |
| 1 #!/usr/bin/python | |
| 2 # Copyright (c) 2011 The Native Client Authors. All rights reserved. | |
| 3 # Use of this source code is governed by a BSD-style license that can be | |
| 4 # found in the LICENSE file. | |
| 5 # | |
| 6 # IMPORTANT NOTE: If you make local mods to this file, you must run: | |
| 7 # % tools/llvm/utman.sh driver | |
| 8 # in order for them to take effect in the scons build. This command | |
| 9 # updates the copy in the toolchain/ tree. | |
| 10 # | |
| 11 | |
| 12 from driver_tools import * | |
| 13 | |
| 14 EXTRA_ENV = { | |
| 15 'ALLOW_TRANSLATE': '0', # Allow bitcode translation before linking. | |
| 16 # It doesn't normally make sense to do this. | |
| 17 | |
| 18 'ALLOW_NATIVE' : '0', # Allow native objects (.S,.s,.o) to be in the | |
| 19 # linker line for .pexe or .pso generation. | |
| 20 # It doesn't normally make sense to do this. | |
| 21 'EMIT_LL' : '1', # Produce an intermediate .ll file | |
| 22 # Currently enabled for debugging. | |
| 23 'BIAS' : 'NONE', # This can be 'NONE', 'ARM', 'X8632', or 'X8664'. | |
| 24 # When not set to none, this causes the front-end to | |
| 25 # act like a target-specific compiler. This bias is | |
| 26 # currently needed while compiling llvm-gcc, newlib, | |
| 27 # and some scons tests. | |
| 28 # TODO(pdox): Can this be removed? | |
| 29 'MC_DIRECT' : '1', # Use MC direct object emission instead of | |
| 30 # producing an intermediate .s file | |
| 31 'LANGUAGE' : 'C', # C or CXX | |
| 32 'FRONTEND' : '', # CLANG, LLVMGCC, or DRAGONEGG | |
| 33 | |
| 34 # Command-line options | |
| 35 'GCC_MODE' : '', # '' (default), '-E', '-c', or '-S' | |
| 36 'SHARED' : '0', # Produce a shared library | |
| 37 'STDINC' : '1', # Include standard headers (-nostdinc sets to 0) | |
| 38 'STDLIB' : '1', # Include standard libraries (-nostdlib sets to 0) | |
| 39 'DIAGNOSTIC' : '0', # Diagnostic flag detected | |
| 40 'STATIC' : '${LIBMODE_NEWLIB ? 1 : 0}', # -static (on for newlib) | |
| 41 'PIC' : '0', # Generate PIC | |
| 42 | |
| 43 'INPUTS' : '', # Input files | |
| 44 'OUTPUT' : '', # Output file | |
| 45 'UNMATCHED' : '', # Unrecognized parameters | |
| 46 | |
| 47 # We need to remove the pre-existing ARM defines which appear | |
| 48 # because we are using the ARM llvm-gcc frontend. | |
| 49 # TODO(pdox): Prevent these from being defined by llvm-gcc in | |
| 50 # the first place by creating a custom target for PNaCl. | |
| 51 'REMOVE_BIAS' : '-U__arm__ -U__APCS_32__ -U__thumb__ -U__thumb2__ ' + | |
| 52 '-U__ARMEB__ -U__THUMBEB__ -U__ARMWEL__ ' + | |
| 53 '-U__ARMEL__ -U__THUMBEL__ -U__SOFTFP__ ' + | |
| 54 '-U__VFP_FP__ -U__ARM_NEON__ -U__ARM_FP16 ' + | |
| 55 '-U__ARM_FP16__ -U__MAVERICK__ -U__XSCALE__ -U__IWMMXT__ ' + | |
| 56 '-U__ARM_EABI__ -U__ARM_ARCH_7A__', | |
| 57 | |
| 58 'BIAS_NONE' : '${FRONTEND==LLVMGCC ? ${REMOVE_BIAS}}', | |
| 59 'BIAS_ARM' : '-D__arm__ -D__ARM_ARCH_7A__ -D__ARMEL__', | |
| 60 'BIAS_X8632' : '${REMOVE_BIAS} ' + | |
| 61 '-D__i386__ -D__i386 -D__i686 -D__i686__ -D__pentium4__', | |
| 62 'BIAS_X8664' : '${REMOVE_BIAS} ' + | |
| 63 '-D__amd64__ -D__amd64 -D__x86_64__ -D__x86_64 -D__core2__', | |
| 64 | |
| 65 'OPT_LEVEL' : '0', | |
| 66 'CC_FLAGS' : '-O${OPT_LEVEL} ' + | |
| 67 '-nostdinc -DNACL_LINUX=1 ${BIAS_%BIAS%} ' + | |
| 68 '${CC_FLAGS_%FRONTEND%}', | |
| 69 'CC_FLAGS_LLVMGCC': '-D__native_client__=1 -D__pnacl__=1 ' + | |
| 70 '-fuse-llvm-va-arg -Werror-portable-llvm', | |
| 71 'CC_FLAGS_CLANG': '-ccc-host-triple le32-unknown-nacl', | |
| 72 'CC_FLAGS_DRAGONEGG': '-D__native_client__=1 -D__pnacl__=1 ' + | |
| 73 '-flto -fplugin=${DRAGONEGG_PLUGIN}', | |
| 74 | |
| 75 'ISYSTEM' : '${ISYSTEM_USER} ${ISYSTEM_BUILTIN}', | |
| 76 'ISYSTEM_BUILTIN': '${STDINC ? ${ISYSTEM_%LIBMODE%}}', | |
| 77 'ISYSTEM_USER' : '', # System include directories specified by | |
| 78 # using the -isystem flag. | |
| 79 | |
| 80 | |
| 81 'ISYSTEM_CLANG': | |
| 82 '${BASE_LLVM}/lib/clang/3.0/include ' + | |
| 83 # Fall back to gcc include, for unwind.h | |
| 84 '${BASE_LLVM_GCC}/lib/gcc/arm-none-linux-gnueabi/4.2.1/include', | |
| 85 | |
| 86 'ISYSTEM_LLVMGCC': | |
| 87 '${BASE_LLVM_GCC}/lib/gcc/arm-none-linux-gnueabi/4.2.1/include ' + | |
| 88 '${BASE_LLVM_GCC}/' + | |
| 89 'lib/gcc/arm-none-linux-gnueabi/4.2.1/install-tools/include', | |
| 90 | |
| 91 'ISYSTEM_DRAGONEGG': | |
| 92 '${BASE_LLVM_GCC}/lib/gcc/arm-none-linux-gnueabi/4.2.1/include ' + | |
| 93 '${BASE_LLVM_GCC}/' + | |
| 94 'lib/gcc/arm-none-linux-gnueabi/4.2.1/install-tools/include', | |
| 95 | |
| 96 'ISYSTEM_newlib' : | |
| 97 '${BASE_SDK}/include ' + | |
| 98 '${ISYSTEM_%FRONTEND%} ' + | |
| 99 '${BASE_LIBSTDCPP}/include/c++/4.2.1 ' + | |
| 100 '${BASE_LIBSTDCPP}/include/c++/4.2.1/arm-none-linux-gnueabi ' + | |
| 101 '${BASE_INCLUDE} ' + | |
| 102 '${BASE_NEWLIB}/arm-none-linux-gnueabi/include', | |
| 103 | |
| 104 'ISYSTEM_glibc' : | |
| 105 '${BASE_SDK}/include ' + | |
| 106 '${BASE_GLIBC}/include ' + | |
| 107 '${ISYSTEM_%FRONTEND%} ' + | |
| 108 '${BASE_GLIBC}/include/c++/4.4.3 ' + | |
| 109 '${BASE_GLIBC}/include/c++/4.4.3/x86_64-nacl', | |
| 110 | |
| 111 'LD_FLAGS' : '-O${OPT_LEVEL} ${STATIC ? -static} ${SHARED ? -shared} ' + | |
| 112 '${PIC ? -fPIC} ${@AddPrefix:-L:SEARCH_DIRS}', | |
| 113 | |
| 114 'SEARCH_DIRS' : '${SEARCH_DIRS_USER} ${PREFIXES}', | |
| 115 'SEARCH_DIRS_USER' : '', # Directories specified using -L | |
| 116 'PREFIXES' : '', # Prefixes specified by using the -B flag. | |
| 117 | |
| 118 # Library Strings | |
| 119 'EMITMODE' : '${STATIC ? static : ${SHARED ? shared : dynamic}}', | |
| 120 | |
| 121 'LD_ARGS' : '${STDLIB ? ${LD_ARGS_%LIBMODE%_%EMITMODE%}' + | |
| 122 ' : ${LD_ARGS_nostdlib}}', | |
| 123 | |
| 124 # ${ld_inputs} signifies where to place the objects and libraries | |
| 125 # provided on the command-line. | |
| 126 'LD_ARGS_nostdlib': '-barebones-link -nostdlib ${ld_inputs}', | |
| 127 | |
| 128 'LD_ARGS_newlib_static': | |
| 129 '-l:crt1.o -l:nacl_startup.bc ${ld_inputs} ' + | |
| 130 '--start-group -lgcc_eh -lgcc -lc -lnacl ' + | |
| 131 '${LIBSTDCPP} -l:libcrt_platform.a --end-group', | |
| 132 | |
| 133 # The next three are copied verbatim from nacl-gcc | |
| 134 'LD_ARGS_glibc_static': | |
| 135 '-l:crt1.o -l:crti.o -l:crtbeginT.o ' + | |
| 136 '${ld_inputs} ${LIBSTDCPP} ' + | |
| 137 '--start-group -lgcc -lgcc_eh -lc ' + | |
| 138 '--end-group -l:crtend.o -l:crtn.o', | |
| 139 | |
| 140 'LD_ARGS_glibc_shared': | |
| 141 '--eh-frame-hdr -shared -l:crti.o -l:crtbeginS.o ' + | |
| 142 '${ld_inputs} ${LIBSTDCPP} ' + | |
| 143 '-lgcc --as-needed -lgcc_s --no-as-needed ' + | |
| 144 '-lc -lgcc --as-needed -lgcc_s --no-as-needed ' + | |
| 145 '-l:crtendS.o -l:crtn.o', | |
| 146 | |
| 147 'LD_ARGS_glibc_dynamic': | |
| 148 '--eh-frame-hdr -l:crt1.o -l:crti.o ' + | |
| 149 '-l:crtbegin.o ${ld_inputs} ${LIBSTDCPP} ' + | |
| 150 '-lgcc --as-needed -lgcc_s --no-as-needed ' + | |
| 151 '-lc -lgcc --as-needed -lgcc_s --no-as-needed ' + | |
| 152 '-l:crtend.o -l:crtn.o', | |
| 153 | |
| 154 'LIBSTDCPP' : '${LANGUAGE==CXX ? -lstdc++ -lm }', | |
| 155 | |
| 156 'CC' : '${CC_%FRONTEND%_%LANGUAGE%}', | |
| 157 'CC_LLVMGCC_C' : '${LLVM_GCC}', | |
| 158 'CC_LLVMGCC_CXX' : '${LLVM_GXX}', | |
| 159 'CC_CLANG_C' : '${CLANG}', | |
| 160 'CC_CLANG_CXX' : '${CLANGXX}', | |
| 161 'CC_DRAGONEGG_C' : '${DRAGONEGG_GCC}', | |
| 162 'CC_DRAGONEGG_CXX': '${DRAGONEGG_GXX}', | |
| 163 | |
| 164 'RUN_CC': '${CC} -emit-llvm ${mode} ${CC_FLAGS} ' + | |
| 165 '${@AddPrefix:-isystem :ISYSTEM} ' + | |
| 166 '${input} -o ${output}', | |
| 167 | |
| 168 'RUN_PP' : '${CC} -E ${CC_FLAGS} ${@AddPrefix:-isystem :ISYSTEM} ' + | |
| 169 '"${input}" -o "${output}"' | |
| 170 } | |
| 171 env.update(EXTRA_ENV) | |
| 172 | |
| 173 def AddLDFlag(*args): | |
| 174 env.append('LD_FLAGS', *args) | |
| 175 | |
| 176 def AddCCFlag(*args): | |
| 177 env.append('CC_FLAGS', *args) | |
| 178 | |
| 179 def AddBPrefix(prefix): | |
| 180 prefix = pathtools.normalize(prefix) | |
| 181 if pathtools.isdir(prefix) and not prefix.endswith('/'): | |
| 182 prefix += '/' | |
| 183 | |
| 184 env.append('PREFIXES', prefix) | |
| 185 | |
| 186 # Add prefix/include to isystem if it exists | |
| 187 include_dir = prefix + 'include' | |
| 188 if pathtools.isdir(include_dir): | |
| 189 env.append('ISYSTEM_USER', include_dir) | |
| 190 | |
| 191 CustomPatterns = [ | |
| 192 ( '--driver=(.+)', "env.set('CC', pathtools.normalize($0))\n"), | |
| 193 ( '--pnacl-skip-ll', "env.set('EMIT_LL', '0')"), | |
| 194 | |
| 195 ( '--pnacl-gcc', "env.set('LANGUAGE', 'C')\n" | |
| 196 "env.set('FRONTEND', 'LLVMGCC')"), | |
| 197 ( '--pnacl-gxx', "env.set('LANGUAGE', 'CXX')\n" | |
| 198 "env.set('FRONTEND', 'LLVMGCC')"), | |
| 199 | |
| 200 ( '--pnacl-clang', "env.set('LANGUAGE', 'C')\n" | |
| 201 "env.set('FRONTEND', 'CLANG')"), | |
| 202 ( '--pnacl-clangxx', "env.set('LANGUAGE', 'CXX')\n" | |
| 203 "env.set('FRONTEND', 'CLANG')"), | |
| 204 | |
| 205 ( '--pnacl-dgcc', "env.set('LANGUAGE', 'C')\n" | |
| 206 "env.set('FRONTEND', 'DRAGONEGG')"), | |
| 207 ( '--pnacl-dgxx', "env.set('LANGUAGE', 'CXX')\n" | |
| 208 "env.set('FRONTEND', 'DRAGONEGG')"), | |
| 209 | |
| 210 ( '--pnacl-allow-native', "env.set('ALLOW_NATIVE', '1')"), | |
| 211 ( '--pnacl-allow-translate', "env.set('ALLOW_TRANSLATE', '1')"), | |
| 212 ( '--pnacl-native-hack', "env.append('LD_FLAGS', '--pnacl-native-hack')\n" | |
| 213 "env.set('ALLOW_NATIVE', '1')"), | |
| 214 ] | |
| 215 | |
| 216 GCCPatterns = [ | |
| 217 ( '-o(.+)', "env.set('OUTPUT', pathtools.normalize($0))"), | |
| 218 ( ('-o', '(.+)'), "env.set('OUTPUT', pathtools.normalize($0))"), | |
| 219 | |
| 220 ( '-E', "env.set('GCC_MODE', '-E')"), | |
| 221 ( '-S', "env.set('GCC_MODE', '-S')"), | |
| 222 ( '-c', "env.set('GCC_MODE', '-c')"), | |
| 223 | |
| 224 ( '-nostdinc', "env.set('STDINC', '0')"), | |
| 225 ( '-nostdlib', "env.set('STDLIB', '0')"), | |
| 226 | |
| 227 # We don't care about -fPIC, but pnacl-ld and pnacl-translate do. | |
| 228 ( '-fPIC', "env.set('PIC', '1')"), | |
| 229 | |
| 230 # We must include -l, -Xlinker, and -Wl options into the INPUTS | |
| 231 # in the order they appeared. This is the exactly behavior of gcc. | |
| 232 # For example: gcc foo.c -Wl,--start-group -lx -ly -Wl,--end-group | |
| 233 # | |
| 234 ( '(-l.+)', "env.append('INPUTS', $0)"), | |
| 235 ( ('(-l)','(.+)'), "env.append('INPUTS', $0+$1)"), | |
| 236 ( ('-Xlinker','(.*)'), "env.append('INPUTS', '-Xlinker=' + $0)"), | |
| 237 ( '(-Wl,.*)', "env.append('INPUTS', $0)"), | |
| 238 ( '(-Bstatic)', "env.append('INPUTS', $0)"), | |
| 239 ( '(-Bdynamic)', "env.append('INPUTS', $0)"), | |
| 240 | |
| 241 ( '-O([0-4s])', "env.set('OPT_LEVEL', $0)\n"), | |
| 242 ( '-O', "env.set('OPT_LEVEL', '1')\n"), | |
| 243 | |
| 244 ( ('-isystem', '(.*)'), | |
| 245 "env.append('ISYSTEM_USER', pathtools.normalize($0))"), | |
| 246 ( ('-I', '(.+)'), "env.append('CC_FLAGS', '-I'+pathtools.normalize($0))"), | |
| 247 ( '-I(.+)', "env.append('CC_FLAGS', '-I'+pathtools.normalize($0))"), | |
| 248 | |
| 249 ( '(-g)', AddCCFlag), | |
| 250 ( '(-W.*)', AddCCFlag), | |
| 251 ( '(-std=.*)', AddCCFlag), | |
| 252 ( ('(-D)','(.*)'), AddCCFlag), | |
| 253 ( '(-D.+)', AddCCFlag), | |
| 254 ( ('(-U)','(.*)'), AddCCFlag), | |
| 255 ( '(-U.+)', AddCCFlag), | |
| 256 ( '(-f.*)', AddCCFlag), | |
| 257 ( '(-pedantic)', AddCCFlag), | |
| 258 ( '(-pedantic-errors)', AddCCFlag), | |
| 259 ( '(-g.*)', AddCCFlag), | |
| 260 ( '(-xassembler-with-cpp)', AddCCFlag), | |
| 261 | |
| 262 ( '-shared', "env.set('SHARED', '1')"), | |
| 263 ( '-static', "env.set('STATIC', '1')"), | |
| 264 | |
| 265 ( ('-B','(.*)'), AddBPrefix), | |
| 266 ( ('-B(.+)'), AddBPrefix), | |
| 267 | |
| 268 ( ('-L','(.+)'), "env.append('SEARCH_DIRS_USER', pathtools.normalize($0))"), | |
| 269 ( '-L(.+)', "env.append('SEARCH_DIRS_USER', pathtools.normalize($0))"), | |
| 270 | |
| 271 ( '(-Wp,.*)', AddCCFlag), | |
| 272 ( '(-MMD)', AddCCFlag), | |
| 273 ( '(-MP)', AddCCFlag), | |
| 274 ( '(-MD)', AddCCFlag), | |
| 275 ( ('(-MT)','(.*)'), AddCCFlag), | |
| 276 ( ('(-MF)','(.*)'), "env.append('CC_FLAGS', $0, pathtools.normalize($1))"), | |
| 277 | |
| 278 # With -xc, GCC considers future inputs to be an input source file. | |
| 279 # The following is not the correct handling of -x, | |
| 280 # but it works in the limited case used by llvm/configure. | |
| 281 # TODO(pdox): Make this -x really work in the general case. | |
| 282 ( '-xc', "env.append('CC_FLAGS', '-xc')\n" | |
| 283 "SetForcedFileType('src')"), | |
| 284 | |
| 285 # Ignore these gcc flags | |
| 286 ( '(-msse)', ""), | |
| 287 ( '(-march=armv7-a)', ""), | |
| 288 | |
| 289 ( '(-s)', AddLDFlag), | |
| 290 ( '(--strip-all)', AddLDFlag), | |
| 291 ( '(--strip-debug)', AddLDFlag), | |
| 292 | |
| 293 # Ignore these assembler flags | |
| 294 ( '(-Qy)', ""), | |
| 295 ( ('(--traditional-format)', '.*'), ""), | |
| 296 ( '(-gstabs)', ""), | |
| 297 ( '(--gstabs)', ""), | |
| 298 ( '(-gdwarf2)', ""), | |
| 299 ( '(--gdwarf2)', ""), | |
| 300 ( '(--fatal-warnings)', ""), | |
| 301 ( '(-meabi=.*)', ""), | |
| 302 ( '(-mfpu=.*)', ""), | |
| 303 | |
| 304 # GCC diagnostic mode triggers | |
| 305 ( '(-print-.*)', "env.set('DIAGNOSTIC', '1')"), | |
| 306 ( '(--print.*)', "env.set('DIAGNOSTIC', '1')"), | |
| 307 ( '(-dumpspecs)', "env.set('DIAGNOSTIC', '1')"), | |
| 308 ( '(-v|--v|--version)', "env.set('DIAGNOSTIC', '1')"), | |
| 309 ( '(-V)', "env.set('DIAGNOSTIC', '1')\n" | |
| 310 "env.clear('CC_FLAGS')"), | |
| 311 ( '(-d.*)', "env.set('DIAGNOSTIC', '1')"), | |
| 312 | |
| 313 # Catch all other command-line arguments | |
| 314 ( '(-.*)', "env.append('UNMATCHED', $0)"), | |
| 315 | |
| 316 # Input Files | |
| 317 # Call ForceFileType for all input files at the time they are | |
| 318 # parsed on the command-line. This ensures that the gcc "-x" | |
| 319 # setting is correctly applied. | |
| 320 | |
| 321 ( '(.*)', "env.append('INPUTS', pathtools.normalize($0))\n" | |
| 322 "ForceFileType(pathtools.normalize($0))"), | |
| 323 ] | |
| 324 | |
| 325 | |
| 326 def main(argv): | |
| 327 _, real_argv = ParseArgs(argv, CustomPatterns, must_match = False) | |
| 328 ParseArgs(real_argv, GCCPatterns) | |
| 329 | |
| 330 # "configure", especially when run as part of a toolchain bootstrap | |
| 331 # process, will invoke gcc with various diagnostic options and | |
| 332 # parse the output. In these cases we do not alter the incoming | |
| 333 # commandline. It is also important to not emit spurious messages. | |
| 334 if env.getbool('DIAGNOSTIC'): | |
| 335 RunWithLog(env.get('CC') + env.get('CC_FLAGS') + real_argv) | |
| 336 return 0 | |
| 337 | |
| 338 unmatched = env.get('UNMATCHED') | |
| 339 if len(unmatched) > 0: | |
| 340 UnrecognizedOption(*unmatched) | |
| 341 | |
| 342 libmode_newlib = env.getbool('LIBMODE_NEWLIB') | |
| 343 is_static = env.getbool('STATIC') | |
| 344 is_shared = env.getbool('SHARED') | |
| 345 | |
| 346 if libmode_newlib and (is_shared or not is_static): | |
| 347 Log.Fatal("Can't produce dynamic objects with newlib.") | |
| 348 | |
| 349 if env.getbool('STATIC') and env.getbool('SHARED'): | |
| 350 Log.Fatal("Can't handle both -static and -shared") | |
| 351 | |
| 352 inputs = env.get('INPUTS') | |
| 353 output = env.getone('OUTPUT') | |
| 354 | |
| 355 if len(inputs) == 0: | |
| 356 Log.Fatal('No input files') | |
| 357 | |
| 358 # If -arch was given, we are compiling directly to native code | |
| 359 compiling_to_native = GetArch() is not None | |
| 360 | |
| 361 gcc_mode = env.getone('GCC_MODE') | |
| 362 | |
| 363 if env.getbool('SHARED'): | |
| 364 bclink_output = 'pso' | |
| 365 link_output = 'so' | |
| 366 else: | |
| 367 bclink_output = 'pexe' | |
| 368 link_output = 'nexe' | |
| 369 | |
| 370 output_type_map = { | |
| 371 ('-E', False) : 'pp', | |
| 372 ('-E', True) : 'pp', | |
| 373 ('-c', False) : 'po', | |
| 374 ('-c', True) : 'o', | |
| 375 ('-S', False) : 'll', | |
| 376 ('-S', True) : 's', | |
| 377 ('', False) : bclink_output, | |
| 378 ('', True) : link_output | |
| 379 } | |
| 380 | |
| 381 output_type = output_type_map[(gcc_mode, compiling_to_native)] | |
| 382 needs_linking = (gcc_mode == '') | |
| 383 | |
| 384 # There are multiple input files and no linking is being done. | |
| 385 # There will be multiple outputs. Handle this case separately. | |
| 386 if not needs_linking: | |
| 387 if output != '' and len(inputs) > 1: | |
| 388 Log.Fatal('Cannot have -o with -c, -S, or -E and multiple inputs') | |
| 389 | |
| 390 for f in inputs: | |
| 391 if f.startswith('-'): | |
| 392 continue | |
| 393 intype = FileType(f) | |
| 394 if ((output_type == 'pp' and intype not in ('src','S')) or | |
| 395 (output_type == 'll' and intype not in 'src') or | |
| 396 (output_type == 'po' and intype not in ('src','ll')) or | |
| 397 (output_type == 's' and intype not in ('src','ll','po','S')) or | |
| 398 (output_type == 'o' and intype not in ('src','ll','po','S','s'))): | |
| 399 Log.Fatal("%s: Unexpected type of file for '%s'", | |
| 400 pathtools.touser(f), gcc_mode) | |
| 401 | |
| 402 if output == '': | |
| 403 f_output = DefaultOutputName(f, output_type) | |
| 404 else: | |
| 405 f_output = output | |
| 406 | |
| 407 namegen = TempNameGen([f], f_output) | |
| 408 CompileOne(f, output_type, namegen, f_output) | |
| 409 return 0 | |
| 410 | |
| 411 # Linking case | |
| 412 assert(needs_linking) | |
| 413 assert(output_type in ('pso','so','pexe','nexe')) | |
| 414 | |
| 415 if output == '': | |
| 416 output = pathtools.normalize('a.out') | |
| 417 namegen = TempNameGen(inputs, output) | |
| 418 | |
| 419 # Compile all source files (c/c++/ll) to .po | |
| 420 for i in xrange(0, len(inputs)): | |
| 421 if inputs[i].startswith('-'): | |
| 422 continue | |
| 423 intype = FileType(inputs[i]) | |
| 424 if intype in ('src','ll'): | |
| 425 inputs[i] = CompileOne(inputs[i], 'po', namegen) | |
| 426 | |
| 427 # Compile all .s/.S to .o | |
| 428 if env.getbool('ALLOW_NATIVE'): | |
| 429 for i in xrange(0, len(inputs)): | |
| 430 if inputs[i].startswith('-'): | |
| 431 continue | |
| 432 intype = FileType(inputs[i]) | |
| 433 if intype in ('s','S'): | |
| 434 inputs[i] = CompileOne(inputs[i], 'o', namegen) | |
| 435 | |
| 436 # We should only be left with .po and .o and libraries | |
| 437 for f in inputs: | |
| 438 if f.startswith('-'): | |
| 439 continue | |
| 440 intype = FileType(f) | |
| 441 if intype in ('o','s','S') or IsNativeArchive(f): | |
| 442 if not env.getbool('ALLOW_NATIVE'): | |
| 443 Log.Fatal('%s: Native object files not allowed in link. ' | |
| 444 'Use --pnacl-allow-native to override.', pathtools.touser(f)) | |
| 445 assert(intype in ('po','o','so','pso','ldscript') or IsArchive(f)) | |
| 446 | |
| 447 # Fix the user-specified linker arguments | |
| 448 ld_inputs = [] | |
| 449 for f in inputs: | |
| 450 if f.startswith('-Xlinker='): | |
| 451 ld_inputs.append(f[len('-Xlinker='):]) | |
| 452 elif f.startswith('-Wl,'): | |
| 453 ld_inputs += f[len('-Wl,'):].split(',') | |
| 454 else: | |
| 455 ld_inputs.append(f) | |
| 456 | |
| 457 # Invoke the linker | |
| 458 env.set('ld_inputs', *ld_inputs) | |
| 459 | |
| 460 ld_args = env.get('LD_ARGS') | |
| 461 ld_flags = env.get('LD_FLAGS') | |
| 462 | |
| 463 RunDriver('pnacl-ld', ld_flags + ld_args + ['-o', output]) | |
| 464 return 0 | |
| 465 | |
| 466 def CompileOne(input, output_type, namegen, output = None): | |
| 467 if output is None: | |
| 468 output = namegen.TempNameForInput(input, output_type) | |
| 469 | |
| 470 chain = DriverChain(input, output, namegen) | |
| 471 SetupChain(chain, FileType(input), output_type) | |
| 472 chain.run() | |
| 473 return output | |
| 474 | |
| 475 def RunPP(input, output): | |
| 476 RunWithEnv("${RUN_PP}", input=input, output=output) | |
| 477 | |
| 478 def RunCC(input, output, mode): | |
| 479 RunWithEnv("${RUN_CC}", input=input, output=output, mode=mode) | |
| 480 | |
| 481 def RunLLVMAS(input, output): | |
| 482 RunDriver('pnacl-as', [input, '-o', output], suppress_arch = True) | |
| 483 | |
| 484 def RunNativeAS(input, output): | |
| 485 RunDriver('pnacl-as', [input, '-o', output]) | |
| 486 | |
| 487 def RunTranslate(input, output, mode): | |
| 488 if not env.getbool('ALLOW_TRANSLATE'): | |
| 489 Log.Fatal('%s: Trying to convert bitcode to an object file before ' | |
| 490 'bitcode linking. This is supposed to wait until ' | |
| 491 'translation. Use --pnacl-allow-translate to override.', | |
| 492 pathtools.touser(input)) | |
| 493 args = [mode, input, '-o', output] | |
| 494 if env.getbool('PIC'): | |
| 495 args += ['-fPIC'] | |
| 496 RunDriver('pnacl-translate', args) | |
| 497 | |
| 498 def SetupChain(chain, input_type, output_type): | |
| 499 assert(output_type in ('pp','ll','po','s','o')) | |
| 500 cur_type = input_type | |
| 501 | |
| 502 # src -> pp | |
| 503 if cur_type == 'src' and output_type == 'pp': | |
| 504 chain.add(RunPP, 'cpp') | |
| 505 cur_type = 'pp' | |
| 506 if cur_type == output_type: | |
| 507 return | |
| 508 | |
| 509 # src -> ll | |
| 510 if cur_type == 'src' and (env.getbool('EMIT_LL') or output_type == 'll'): | |
| 511 chain.add(RunCC, 'll', mode='-S') | |
| 512 cur_type = 'll' | |
| 513 if cur_type == output_type: | |
| 514 return | |
| 515 | |
| 516 # ll -> po | |
| 517 if cur_type == 'll': | |
| 518 chain.add(RunLLVMAS, 'po') | |
| 519 cur_type = 'po' | |
| 520 if cur_type == output_type: | |
| 521 return | |
| 522 | |
| 523 # src -> po | |
| 524 if cur_type == 'src' and output_type == 'po': | |
| 525 chain.add(RunCC, 'po', mode='-c') | |
| 526 cur_type = 'po' | |
| 527 if cur_type == output_type: | |
| 528 return | |
| 529 | |
| 530 # po -> o | |
| 531 if env.getbool('MC_DIRECT') and cur_type == 'po' and output_type == 'o': | |
| 532 chain.add(RunTranslate, 'o', mode='-c') | |
| 533 cur_type = 'o' | |
| 534 if cur_type == output_type: | |
| 535 return | |
| 536 | |
| 537 # po -> s | |
| 538 if cur_type == 'po': | |
| 539 chain.add(RunTranslate, 's', mode='-S') | |
| 540 cur_type = 's' | |
| 541 if cur_type == output_type: | |
| 542 return | |
| 543 | |
| 544 # S -> s | |
| 545 if cur_type == 'S': | |
| 546 chain.add(RunPP, 's') | |
| 547 cur_type = 's' | |
| 548 if cur_type == output_type: | |
| 549 return | |
| 550 | |
| 551 # s -> o | |
| 552 if cur_type == 's' and output_type == 'o': | |
| 553 chain.add(RunNativeAS, 'o') | |
| 554 cur_type = 'o' | |
| 555 if cur_type == output_type: | |
| 556 return | |
| 557 | |
| 558 Log.Fatal("Unable to compile .%s to .%s", input_type, output_type) | |
| 559 | |
| 560 | |
| 561 if __name__ == "__main__": | |
| 562 DriverMain(main) | |
| OLD | NEW |