def ReadConfig(): # Mock out ReadConfig if running unittests. Settings are applied directly # by DriverTestEnv rather than reading this configuration file. if env.has('PNACL_RUNNING_UNITTESTS'): return driver_bin = env.getone('DRIVER_BIN') driver_conf = pathtools.join(driver_bin, 'driver.conf') fp = DriverOpen(driver_conf, 'r') linecount = 0 for line in fp: linecount += 1 line = line.strip() if line == '' or line.startswith('#'): continue sep = line.find('=') if sep < 0: Log.Fatal("%s: Parse error, missing '=' on line %d", pathtools.touser(driver_conf), linecount) keyname = line[:sep].strip() value = line[sep + 1:].strip() env.setraw(keyname, value) DriverClose(fp) if env.getone('LIBMODE') not in ('newlib', 'glibc'): Log.Fatal('Invalid LIBMODE in %s', pathtools.touser(driver_conf))
def main(argv): env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, StripPatterns) inputs = env.get('INPUTS') output = env.getone('OUTPUT') if len(inputs) > 1 and output != '': Log.Fatal('Cannot have -o with multiple inputs') if '--info' in env.get('STRIP_FLAGS'): code, _, _ = driver_tools.Run('${STRIP} ${STRIP_FLAGS}') return code for f in inputs: if output != '': f_output = output else: f_output = f if driver_tools.IsBitcode(f): driver_tools.RunWithEnv('${RUN_OPT}', input=f, output=f_output) if env.getbool('DO_WRAP'): driver_tools.WrapBitcode(f_output) elif driver_tools.IsELF(f) or driver_tools.IsNativeArchive(f): driver_tools.RunWithEnv('${RUN_STRIP}', input=f, output=f_output) elif driver_tools.IsBitcodeArchive(f): # The strip tool supports native archives, but it does not support the # LLVM gold plugin so cannot handle bitcode. There is also no bitcode # tool like opt that support archives. Log.Fatal('%s: strip does not support bitcode archives', pathtools.touser(f)) else: Log.Fatal('%s: File is neither ELF, nor bitcode', pathtools.touser(f)) return 0
def main(argv): env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, StripPatterns) inputs = env.get('INPUTS') output = env.getone('OUTPUT') if len(inputs) > 1 and output != '': Log.Fatal('Cannot have -o with multiple inputs') if '--info' in env.get('STRIP_FLAGS'): code, _, _ = driver_tools.Run('${STRIP} ${STRIP_FLAGS}') return code for f in inputs: if output != '': f_output = output else: f_output = f if driver_tools.IsLLVMBitcode(f): driver_tools.RunWithEnv('${RUN_OPT}', input=f, output=f_output) elif driver_tools.IsELF(f) or driver_tools.IsNativeArchive(f): driver_tools.RunWithEnv('${RUN_STRIP}', input=f, output=f_output) elif driver_tools.IsBitcodeArchive(f): # The strip tool supports native archives, but it does not support the # LLVM gold plugin so cannot handle bitcode. There is also no bitcode # tool like opt that support archives. Log.Fatal('%s: strip does not support bitcode archives', pathtools.touser(f)) else: Log.Fatal('%s: File is neither ELF, nor bitcode', pathtools.touser(f)) return 0
def ReadConfig(): # Mock out ReadConfig if running unittests. Settings are applied directly # by DriverTestEnv rather than reading this configuration file. if env.has('PNACL_RUNNING_UNITTESTS'): return driver_bin = env.getone('DRIVER_BIN') driver_conf = pathtools.join(driver_bin, 'driver.conf') fp = DriverOpen(driver_conf, 'r') linecount = 0 for line in fp: linecount += 1 line = line.strip() if line == '' or line.startswith('#'): continue sep = line.find('=') if sep < 0: Log.Fatal("%s: Parse error, missing '=' on line %d", pathtools.touser(driver_conf), linecount) keyname = line[:sep].strip() value = line[sep+1:].strip() env.setraw(keyname, value) DriverClose(fp) if env.getone('LIBMODE') not in ('newlib', 'glibc'): Log.Fatal('Invalid LIBMODE in %s', pathtools.touser(driver_conf))
def main(argv): env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, StripPatterns) inputs = env.get('INPUTS') output = env.getone('OUTPUT') if len(inputs) > 1 and output != '': Log.Fatal('Cannot have -o with multiple inputs') if '--info' in env.get('STRIP_FLAGS'): code, _, _ = driver_tools.Run('${STRIP} ${STRIP_FLAGS}') return code for f in inputs: if output != '': f_output = output else: f_output = f if driver_tools.IsBitcode(f): driver_tools.RunWithEnv('${RUN_OPT}', input=f, output=f_output) if env.getbool('DO_WRAP'): driver_tools.WrapBitcode(f_output) elif driver_tools.IsELF(f): driver_tools.RunWithEnv('${RUN_STRIP}', input=f, output=f_output) else: Log.Fatal('%s: File is neither ELF nor bitcode', pathtools.touser(f)) return 0
def DriverOpen(filename, mode, fail_ok=False): try: fp = open(pathtools.tosys(filename), mode) except Exception: if not fail_ok: Log.Fatal("%s: Unable to open file", pathtools.touser(filename)) DriverExit(1) else: return None return fp
def LinkerFiles(args): ret = [] for f in args: if IsFlag(f): continue else: if not pathtools.exists(f): Log.Fatal("Unable to open '%s'", pathtools.touser(f)) ret.append(f) return ret
def DriverOpen(filename, mode, fail_ok = False): try: fp = open(pathtools.tosys(filename), mode) except Exception: if not fail_ok: Log.Fatal("%s: Unable to open file", pathtools.touser(filename)) DriverExit(1) else: return None return fp
def wipe(self): for path in self.files: try: os.remove(pathtools.tosys(path)) except OSError as err: # If we're exiting early, the temp file # may have never been created. Log.Warning("TempFileHandler: Unable to wipe file %s w/ error %s", pathtools.touser(path), err.strerror) self.files = []
def RunTranslate(infile, output, mode): if not env.getbool('ALLOW_TRANSLATE'): Log.Fatal('%s: Trying to convert bitcode to an object file before ' 'bitcode linking. This is supposed to wait until ' 'translation. Use --pnacl-allow-translate to override.', pathtools.touser(infile)) args = env.get('TRANSLATE_FLAGS') + [mode, '--allow-llvm-bitcode-input', infile, '-o', output] if env.getbool('PIC'): args += ['-fPIC'] RunDriver('pnacl-translate', args)
def RunTranslate(infile, output, mode): if not env.getbool('ALLOW_TRANSLATE'): Log.Fatal('%s: Trying to convert bitcode to an object file before ' 'bitcode linking. This is supposed to wait until ' 'translation. Use --pnacl-allow-translate to override.', pathtools.touser(infile)) args = env.get('TRANSLATE_FLAGS') + [mode, '--allow-llvm-bitcode-input', infile, '-o', output] if env.getbool('PIC'): args += ['-fPIC'] RunDriver('translate', args)
def wipe(self): for path in self.files: try: sys_path = pathtools.tosys(path) # If exiting early, the file may not have been created yet. if os.path.exists(sys_path): os.remove(sys_path) except OSError as err: Log.Fatal("TempFileHandler: Unable to wipe file %s w/ error %s", pathtools.touser(path), err.strerror) self.files = []
def wipe(self): for path in self.files: try: sys_path = pathtools.tosys(path) # If exiting early, the file may not have been created yet. if os.path.exists(sys_path): os.remove(sys_path) except OSError as err: Log.Error( "TempFileHandler: Unable to wipe file %s w/ error %s", pathtools.touser(path), err.strerror) self.files = []
def ReadConfig(): driver_bin = env.getone('DRIVER_BIN') driver_conf = pathtools.join(driver_bin, 'driver.conf') fp = DriverOpen(driver_conf, 'r') linecount = 0 for line in fp: linecount += 1 line = line.strip() if line == '' or line.startswith('#'): continue sep = line.find('=') if sep < 0: Log.Fatal("%s: Parse error, missing '=' on line %d", pathtools.touser(driver_conf), linecount) keyname = line[:sep].strip() value = line[sep+1:].strip() env.setraw(keyname, value) DriverClose(fp) if env.getone('LIBMODE') not in ('newlib', 'glibc'): Log.Fatal('Invalid LIBMODE in %s', pathtools.touser(driver_conf))
def main(argv): env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, StripPatterns) inputs = env.get('INPUTS') output = env.getone('OUTPUT') for path in inputs + [output]: driver_tools.CheckPathLength(path) if len(inputs) > 1 and output != '': Log.Fatal('Cannot have -o with multiple inputs') if '--info' in env.get('STRIP_FLAGS'): code, _, _ = driver_tools.Run('${STRIP} ${STRIP_FLAGS}') return code for f in inputs: if output != '': f_output = output else: f_output = f if filetype.IsPNaClBitcode(f): # PNaCl-format bitcode has no symbols, i.e. it is already stripped. if f != f_output: shutil.copyfile(f, f_output) elif filetype.IsLLVMBitcode(f): driver_tools.RunWithEnv('${RUN_OPT}', input=f, output=f_output) elif filetype.IsELF(f) or filetype.IsNativeArchive(f): driver_tools.RunWithEnv('${RUN_STRIP}', input=f, output=f_output) elif filetype.IsBitcodeArchive(f): # The strip tool supports native archives, but it does not support the # LLVM gold plugin so cannot handle bitcode. There is also no bitcode # tool like opt that support archives. Log.Fatal('%s: strip does not support bitcode archives', pathtools.touser(f)) else: Log.Fatal('%s: File is neither ELF, nor bitcode', pathtools.touser(f)) return 0
def CheckInputsArch(inputs): count = 0 for f in inputs: if ldtools.IsFlag(f): continue elif filetype.IsLLVMBitcode(f) or filetype.IsBitcodeArchive(f): pass elif filetype.IsNative(f): ArchMerge(f, True) else: Log.Fatal("%s: Unexpected type of file for linking (%s)", pathtools.touser(f), filetype.FileType(f)) count += 1 if count == 0: Log.Fatal("no input files")
def GetNativeLibsDirname(other_inputs): """Check that native libs have a common directory and return the directory.""" dirname = None for f in other_inputs: if IsFlag(f): continue else: if not pathtools.exists(f): Log.Fatal("Unable to open '%s'", pathtools.touser(f)) if dirname is None: dirname = pathtools.dirname(f) else: if dirname != pathtools.dirname(f): Log.Fatal('Need a common directory for native libs: %s != %s', dirname, pathtools.dirname(f)) if not dirname: Log.Fatal('No native libraries found') return dirname + '/'
def GetNativeLibsDirname(other_inputs): """Check that native libs have a common directory and return the directory.""" dirname = None for f in other_inputs: if IsFlag(f): continue else: if not pathtools.exists(f): Log.Fatal("Unable to open '%s'", pathtools.touser(f)) if dirname is None: dirname = pathtools.dirname(f) else: if dirname != pathtools.dirname(f): Log.Fatal( 'Need a common directory for native libs: %s != %s', dirname, pathtools.dirname(f)) if not dirname: Log.Fatal('No native libraries found') return dirname + '/'
def main(argv): env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, META_PATTERNS) inputs = env.get('INPUTS') if not inputs: Usage() DriverExit(1) for f in inputs: if not driver_tools.IsBitcode(f): Log.Fatal("%s: File is not bitcode", pathtools.touser(f)) metadata = driver_tools.GetBitcodeMetadata(f) if env.getbool('RAW'): DumpRaw(metadata) else: DumpPretty(f, metadata) return 0
def DumpPretty(f, metadata): print pathtools.touser(f) + ":" for k, v in metadata.iteritems(): if isinstance(v, list): v = "[ " + ', '.join(v) + " ]" print " %-12s: %s" % (k, v)
def main(argv): env.update(EXTRA_ENV) CheckSetup() ParseArgs(argv, CustomPatterns + GCCPatterns) # "configure", especially when run as part of a toolchain bootstrap # process, will invoke gcc with various diagnostic options and # parse the output. In these cases we do not alter the incoming # commandline. It is also important to not emit spurious messages. if env.getbool('DIAGNOSTIC'): if env.getbool('SHOW_VERSION'): code, stdout, stderr = Run(env.get('CC') + env.get('CC_FLAGS'), redirect_stdout=subprocess.PIPE) out = stdout.split('\n') nacl_version = ReadDriverRevision() out[0] += ' nacl-version=%s' % nacl_version stdout = '\n'.join(out) print stdout, else: Run(env.get('CC') + env.get('CC_FLAGS')) return 0 unmatched = env.get('UNMATCHED') if len(unmatched) > 0: UnrecognizedOption(*unmatched) # If -arch was given, we are compiling directly to native code compiling_to_native = GetArch() is not None if env.getbool('ALLOW_NATIVE'): if not compiling_to_native: Log.Fatal("--pnacl-allow-native without -arch is not meaningful.") # For native/mixed links, also bring in the native libgcc and # libcrt_platform to avoid link failure if pre-translated native # code needs functions from it. env.append('LD_FLAGS', env.eval('-L${LIBS_NATIVE_ARCH}')) env.append('STDLIBS', '-lgcc') env.append('STDLIBS', '-lcrt_platform') flags_and_inputs = env.get('INPUTS') output = env.getone('OUTPUT') if len(flags_and_inputs) == 0: if env.getbool('VERBOSE'): # -v can be invoked without any inputs. Runs the original # command without modifying the commandline for this case. Run(env.get('CC') + env.get('CC_FLAGS')) return 0 else: Log.Fatal('No input files') gcc_mode = env.getone('GCC_MODE') output_type = DriverOutputTypes(gcc_mode, compiling_to_native) # INPUTS consists of actual input files and a subset of flags like -Wl,<foo>. # Create a version with just the files. inputs = [f for f in flags_and_inputs if not IsFlag(f)] header_inputs = [f for f in inputs if filetype.IsHeaderType(filetype.FileType(f))] # Handle PCH case specially (but only for a limited sense...) if header_inputs and gcc_mode != '-E': # We only handle doing pre-compiled headers for all inputs or not at # all at the moment. This is because DriverOutputTypes only assumes # one type of output, depending on the "gcc_mode" flag. When mixing # header inputs w/ non-header inputs, some of the outputs will be # pch while others will be output_type. We would also need to modify # the input->output chaining for the needs_linking case. if len(header_inputs) != len(inputs): Log.Fatal('mixed compiling of headers and source not supported') CompileHeaders(header_inputs, output) return 0 needs_linking = (gcc_mode == '') if env.getbool('NEED_DASH_E') and gcc_mode != '-E': Log.Fatal("-E or -x required when input is from stdin") # There are multiple input files and no linking is being done. # There will be multiple outputs. Handle this case separately. if not needs_linking: if output != '' and len(inputs) > 1: Log.Fatal('Cannot have -o with -c, -S, or -E and multiple inputs: %s', repr(inputs)) for f in inputs: intype = filetype.FileType(f) if not (filetype.IsSourceType(intype) or filetype.IsHeaderType(intype)): if ((output_type == 'pp' and intype != 'S') or (output_type == 'll') or (output_type == 'po' and intype != 'll') or (output_type == 's' and intype not in ('ll','po','S')) or (output_type == 'o' and intype not in ('ll','po','S','s'))): Log.Fatal("%s: Unexpected type of file for '%s'", pathtools.touser(f), gcc_mode) if output == '': f_output = DefaultOutputName(f, output_type) else: f_output = output namegen = TempNameGen([f], f_output) CompileOne(f, output_type, namegen, f_output) return 0 # Linking case assert(needs_linking) assert(output_type in ('pso','so','pexe','nexe')) if output == '': output = pathtools.normalize('a.out') namegen = TempNameGen(flags_and_inputs, output) # Compile all source files (c/c++/ll) to .po for i in xrange(0, len(flags_and_inputs)): if IsFlag(flags_and_inputs[i]): continue intype = filetype.FileType(flags_and_inputs[i]) if filetype.IsSourceType(intype) or intype == 'll': flags_and_inputs[i] = CompileOne(flags_and_inputs[i], 'po', namegen) # Compile all .s/.S to .o if env.getbool('ALLOW_NATIVE'): for i in xrange(0, len(flags_and_inputs)): if IsFlag(flags_and_inputs[i]): continue intype = filetype.FileType(flags_and_inputs[i]) if intype in ('s','S'): flags_and_inputs[i] = CompileOne(flags_and_inputs[i], 'o', namegen) # We should only be left with .po and .o and libraries for f in flags_and_inputs: if IsFlag(f): continue intype = filetype.FileType(f) if intype in ('o','s','S') or filetype.IsNativeArchive(f): if not env.getbool('ALLOW_NATIVE'): Log.Fatal('%s: Native object files not allowed in link. ' 'Use --pnacl-allow-native to override.', pathtools.touser(f)) assert(intype in ('po','o','so','ldscript') or filetype.IsArchive(f)) # Fix the user-specified linker arguments ld_inputs = [] for f in flags_and_inputs: if f.startswith('-Xlinker='): ld_inputs.append(f[len('-Xlinker='):]) elif f.startswith('-Wl,'): ld_inputs += f[len('-Wl,'):].split(',') else: ld_inputs.append(f) if env.getbool('ALLOW_NATIVE'): ld_inputs.append('--pnacl-allow-native') # Invoke the linker env.set('ld_inputs', *ld_inputs) ld_args = env.get('LD_ARGS') ld_flags = env.get('LD_FLAGS') RunDriver('pnacl-ld', ld_flags + ld_args + ['-o', output]) return 0
def main(argv): env.update(EXTRA_ENV) CheckSetup() ParseArgs(argv, CustomPatterns + GCCPatterns) # "configure", especially when run as part of a toolchain bootstrap # process, will invoke gcc with various diagnostic options and # parse the output. In these cases we do not alter the incoming # commandline. It is also important to not emit spurious messages. if env.getbool('DIAGNOSTIC'): if env.getbool('SHOW_VERSION'): code, stdout, stderr = Run(env.get('CC') + env.get('CC_FLAGS'), redirect_stdout=subprocess.PIPE) out = stdout.split('\n') nacl_version = ReadDriverRevision() out[0] += ' nacl-version=%s' % nacl_version stdout = '\n'.join(out) print stdout, else: Run(env.get('CC') + env.get('CC_FLAGS')) return 0 unmatched = env.get('UNMATCHED') if len(unmatched) > 0: UnrecognizedOption(*unmatched) # If -arch was given, we are compiling directly to native code compiling_to_native = GetArch() is not None if env.getbool('ALLOW_NATIVE'): if not compiling_to_native: Log.Fatal("--pnacl-allow-native without -arch is not meaningful.") # For native/mixed links, also bring in the native libgcc and # libcrt_platform to avoid link failure if pre-translated native # code needs functions from it. env.append('LD_FLAGS', env.eval('-L${LIBS_NATIVE_ARCH}')) env.append('STDLIBS', '-lgcc') env.append('STDLIBS', '-lcrt_platform') flags_and_inputs = env.get('INPUTS') output = env.getone('OUTPUT') if len(flags_and_inputs) == 0: if env.getbool('VERBOSE'): # -v can be invoked without any inputs. Runs the original # command without modifying the commandline for this case. Run(env.get('CC') + env.get('CC_FLAGS')) return 0 else: Log.Fatal('No input files') gcc_mode = env.getone('GCC_MODE') output_type = DriverOutputTypes(gcc_mode, compiling_to_native) # '-shared' modifies the output from the linker and should be considered when # determining the final output type. if env.getbool('SHARED'): if compiling_to_native: Log.Fatal('Building native shared libraries not supported') if gcc_mode != '': Log.Fatal('-c, -S, and -E are disallowed with -shared') output_type = 'pll' # INPUTS consists of actual input files and a subset of flags like -Wl,<foo>. # Create a version with just the files. inputs = [f for f in flags_and_inputs if not IsFlag(f)] header_inputs = [ f for f in inputs if filetype.IsHeaderType(filetype.FileType(f)) ] # Handle PCH case specially (but only for a limited sense...) if header_inputs and gcc_mode != '-E': # We only handle doing pre-compiled headers for all inputs or not at # all at the moment. This is because DriverOutputTypes only assumes # one type of output, depending on the "gcc_mode" flag. When mixing # header inputs w/ non-header inputs, some of the outputs will be # pch while others will be output_type. We would also need to modify # the input->output chaining for the needs_linking case. if len(header_inputs) != len(inputs): Log.Fatal('mixed compiling of headers and source not supported') CompileHeaders(header_inputs, output) return 0 needs_linking = (gcc_mode == '') if env.getbool('NEED_DASH_E') and gcc_mode != '-E': Log.Fatal("-E or -x required when input is from stdin") # There are multiple input files and no linking is being done. # There will be multiple outputs. Handle this case separately. if not needs_linking: if output != '' and len(inputs) > 1: Log.Fatal( 'Cannot have -o with -c, -S, or -E and multiple inputs: %s', repr(inputs)) for f in inputs: intype = filetype.FileType(f) if not (filetype.IsSourceType(intype) or filetype.IsHeaderType(intype)): if ((output_type == 'pp' and intype != 'S') or (output_type == 'll') or (output_type == 'po' and intype != 'll') or (output_type == 's' and intype not in ('ll', 'po', 'S')) or (output_type == 'o' and intype not in ('ll', 'po', 'S', 's'))): Log.Fatal("%s: Unexpected type of file for '%s'", pathtools.touser(f), gcc_mode) if output == '': f_output = DefaultOutputName(f, output_type) else: f_output = output namegen = TempNameGen([f], f_output) CompileOne(f, output_type, namegen, f_output) return 0 # Linking case assert (needs_linking) assert (output_type in ('pll', 'pexe', 'nexe')) if output == '': output = pathtools.normalize('a.out') namegen = TempNameGen(flags_and_inputs, output) # Compile all source files (c/c++/ll) to .po for i in xrange(0, len(flags_and_inputs)): if IsFlag(flags_and_inputs[i]): continue intype = filetype.FileType(flags_and_inputs[i]) if filetype.IsSourceType(intype) or intype == 'll': flags_and_inputs[i] = CompileOne(flags_and_inputs[i], 'po', namegen) # Compile all .s/.S to .o if env.getbool('ALLOW_NATIVE'): for i in xrange(0, len(flags_and_inputs)): if IsFlag(flags_and_inputs[i]): continue intype = filetype.FileType(flags_and_inputs[i]) if intype in ('s', 'S'): flags_and_inputs[i] = CompileOne(flags_and_inputs[i], 'o', namegen) # We should only be left with .po and .o and libraries for f in flags_and_inputs: if IsFlag(f): continue intype = filetype.FileType(f) if intype in ('o', 's', 'S') or filetype.IsNativeArchive(f): if not env.getbool('ALLOW_NATIVE'): Log.Fatal( '%s: Native object files not allowed in link. ' 'Use --pnacl-allow-native to override.', pathtools.touser(f)) assert (intype in ('po', 'o', 'so', 'ldscript') or filetype.IsArchive(f)) # Fix the user-specified linker arguments ld_inputs = [] for f in flags_and_inputs: if f.startswith('-Xlinker='): ld_inputs.append(f[len('-Xlinker='):]) elif f.startswith('-Wl,'): ld_inputs += f[len('-Wl,'):].split(',') else: ld_inputs.append(f) if env.getbool('ALLOW_NATIVE'): ld_inputs.append('--pnacl-allow-native') # Invoke the linker env.set('ld_inputs', *ld_inputs) ld_args = env.get('LD_ARGS') ld_flags = env.get('LD_FLAGS') RunDriver('pnacl-ld', ld_flags + ld_args + ['-o', output]) return 0
def main(argv): env.update(EXTRA_ENV) CheckSetup() ParseArgs(argv, CustomPatterns + GCCPatterns) # "configure", especially when run as part of a toolchain bootstrap # process, will invoke gcc with various diagnostic options and # parse the output. In these cases we do not alter the incoming # commandline. It is also important to not emit spurious messages. if env.getbool('DIAGNOSTIC'): if env.getbool('SHOW_VERSION'): code, stdout, stderr = Run(env.get('CC') + env.get('CC_FLAGS'), redirect_stdout=subprocess.PIPE) out = stdout.split('\n') nacl_version = ReadDriverRevision() out[0] += ' nacl-version=%s' % nacl_version stdout = '\n'.join(out) print stdout, else: Run(env.get('CC') + env.get('CC_FLAGS')) return 0 unmatched = env.get('UNMATCHED') if len(unmatched) > 0: UnrecognizedOption(*unmatched) # If -arch was given, we are compiling directly to native code compiling_to_native = GetArch() is not None if env.getbool('ALLOW_NATIVE') and not compiling_to_native: Log.Fatal("--pnacl-allow-native without -arch is not meaningful.") if not env.get('STDLIB'): # Default C++ Standard Library. SetStdLib('libc++') inputs = env.get('INPUTS') output = env.getone('OUTPUT') if len(inputs) == 0: if env.getbool('VERBOSE'): # -v can be invoked without any inputs. Runs the original # command without modifying the commandline for this case. Run(env.get('CC') + env.get('CC_FLAGS')) return 0 else: Log.Fatal('No input files') gcc_mode = env.getone('GCC_MODE') output_type = DriverOutputTypes(gcc_mode, compiling_to_native) needs_linking = (gcc_mode == '') if env.getbool('NEED_DASH_E') and gcc_mode != '-E': Log.Fatal("-E or -x required when input is from stdin") # There are multiple input files and no linking is being done. # There will be multiple outputs. Handle this case separately. if not needs_linking: # Filter out flags inputs = [f for f in inputs if not IsFlag(f)] if output != '' and len(inputs) > 1: Log.Fatal('Cannot have -o with -c, -S, or -E and multiple inputs: %s', repr(inputs)) for f in inputs: if IsFlag(f): continue intype = filetype.FileType(f) if not filetype.IsSourceType(intype): if ((output_type == 'pp' and intype != 'S') or (output_type == 'll') or (output_type == 'po' and intype != 'll') or (output_type == 's' and intype not in ('ll','po','S')) or (output_type == 'o' and intype not in ('ll','po','S','s'))): Log.Fatal("%s: Unexpected type of file for '%s'", pathtools.touser(f), gcc_mode) if output == '': f_output = DefaultOutputName(f, output_type) else: f_output = output namegen = TempNameGen([f], f_output) CompileOne(f, output_type, namegen, f_output) return 0 # Linking case assert(needs_linking) assert(output_type in ('pso','so','pexe','nexe')) if output == '': output = pathtools.normalize('a.out') namegen = TempNameGen(inputs, output) # Compile all source files (c/c++/ll) to .po for i in xrange(0, len(inputs)): if IsFlag(inputs[i]): continue intype = filetype.FileType(inputs[i]) if filetype.IsSourceType(intype) or intype == 'll': inputs[i] = CompileOne(inputs[i], 'po', namegen) # Compile all .s/.S to .o if env.getbool('ALLOW_NATIVE'): for i in xrange(0, len(inputs)): if IsFlag(inputs[i]): continue intype = filetype.FileType(inputs[i]) if intype in ('s','S'): inputs[i] = CompileOne(inputs[i], 'o', namegen) # We should only be left with .po and .o and libraries for f in inputs: if IsFlag(f): continue intype = filetype.FileType(f) if intype in ('o','s','S') or filetype.IsNativeArchive(f): if not env.getbool('ALLOW_NATIVE'): Log.Fatal('%s: Native object files not allowed in link. ' 'Use --pnacl-allow-native to override.', pathtools.touser(f)) assert(intype in ('po','o','so','ldscript') or filetype.IsArchive(f)) # Fix the user-specified linker arguments ld_inputs = [] for f in inputs: if f.startswith('-Xlinker='): ld_inputs.append(f[len('-Xlinker='):]) elif f.startswith('-Wl,'): ld_inputs += f[len('-Wl,'):].split(',') else: ld_inputs.append(f) if env.getbool('ALLOW_NATIVE'): ld_inputs.append('--pnacl-allow-native') # Invoke the linker env.set('ld_inputs', *ld_inputs) ld_args = env.get('LD_ARGS') ld_flags = env.get('LD_FLAGS') RunDriver('ld', ld_flags + ld_args + ['-o', output]) return 0
def main(argv): env.update(EXTRA_ENV) CheckSetup() ParseArgs(argv, CustomPatterns + GCCPatterns) # "configure", especially when run as part of a toolchain bootstrap # process, will invoke gcc with various diagnostic options and # parse the output. In these cases we do not alter the incoming # commandline. It is also important to not emit spurious messages. if env.getbool('DIAGNOSTIC'): if env.getbool('SHOW_VERSION'): code, stdout, stderr = Run(env.get('CC') + env.get('CC_FLAGS'), redirect_stdout=subprocess.PIPE) out = stdout.split('\n') nacl_version = ReadDriverRevision() out[0] += ' nacl-version=%s' % nacl_version stdout = '\n'.join(out) print stdout, else: Run(env.get('CC') + env.get('CC_FLAGS')) return 0 unmatched = env.get('UNMATCHED') if len(unmatched) > 0: UnrecognizedOption(*unmatched) # If -arch was given, we are compiling directly to native code compiling_to_native = GetArch() is not None if env.getbool('ALLOW_NATIVE') and not compiling_to_native: Log.Fatal("--pnacl-allow-native without -arch is not meaningful.") if not env.get('STDLIB'): # Default C++ Standard Library. SetStdLib('libc++') inputs = env.get('INPUTS') output = env.getone('OUTPUT') if len(inputs) == 0: if env.getbool('VERBOSE'): # -v can be invoked without any inputs. Runs the original # command without modifying the commandline for this case. Run(env.get('CC') + env.get('CC_FLAGS')) return 0 else: Log.Fatal('No input files') gcc_mode = env.getone('GCC_MODE') output_type = DriverOutputTypes(gcc_mode, compiling_to_native) needs_linking = (gcc_mode == '') if env.getbool('NEED_DASH_E') and gcc_mode != '-E': Log.Fatal("-E or -x required when input is from stdin") # There are multiple input files and no linking is being done. # There will be multiple outputs. Handle this case separately. if not needs_linking: # Filter out flags inputs = [f for f in inputs if not IsFlag(f)] if output != '' and len(inputs) > 1: Log.Fatal('Cannot have -o with -c, -S, or -E and multiple inputs: %s', repr(inputs)) for f in inputs: if IsFlag(f): continue intype = filetype.FileType(f) if not filetype.IsSourceType(intype): if ((output_type == 'pp' and intype != 'S') or (output_type == 'll') or (output_type == 'po' and intype != 'll') or (output_type == 's' and intype not in ('ll','po','S')) or (output_type == 'o' and intype not in ('ll','po','S','s'))): Log.Fatal("%s: Unexpected type of file for '%s'", pathtools.touser(f), gcc_mode) if output == '': f_output = DefaultOutputName(f, output_type) else: f_output = output namegen = TempNameGen([f], f_output) CompileOne(f, output_type, namegen, f_output) return 0 # Linking case assert(needs_linking) assert(output_type in ('pso','so','pexe','nexe')) if output == '': output = pathtools.normalize('a.out') namegen = TempNameGen(inputs, output) # Compile all source files (c/c++/ll) to .po for i in xrange(0, len(inputs)): if IsFlag(inputs[i]): continue intype = filetype.FileType(inputs[i]) if filetype.IsSourceType(intype) or intype == 'll': inputs[i] = CompileOne(inputs[i], 'po', namegen) # Compile all .s/.S to .o if env.getbool('ALLOW_NATIVE'): for i in xrange(0, len(inputs)): if IsFlag(inputs[i]): continue intype = filetype.FileType(inputs[i]) if intype in ('s','S'): inputs[i] = CompileOne(inputs[i], 'o', namegen) # We should only be left with .po and .o and libraries for f in inputs: if IsFlag(f): continue intype = filetype.FileType(f) if intype in ('o','s','S') or filetype.IsNativeArchive(f): if not env.getbool('ALLOW_NATIVE'): Log.Fatal('%s: Native object files not allowed in link. ' 'Use --pnacl-allow-native to override.', pathtools.touser(f)) assert(intype in ('po','o','so','ldscript') or filetype.IsArchive(f)) # Fix the user-specified linker arguments ld_inputs = [] for f in inputs: if f.startswith('-Xlinker='): ld_inputs.append(f[len('-Xlinker='):]) elif f.startswith('-Wl,'): ld_inputs += f[len('-Wl,'):].split(',') else: ld_inputs.append(f) if env.getbool('ALLOW_NATIVE'): ld_inputs.append('--pnacl-allow-native') # Invoke the linker env.set('ld_inputs', *ld_inputs) ld_args = env.get('LD_ARGS') ld_flags = env.get('LD_FLAGS') RunDriver('pnacl-ld', ld_flags + ld_args + ['-o', output]) return 0