def UsePrivateLibraries(libs): """ Place libnacl_sys_private.a before libnacl.a Replace libpthread.a with libpthread_private.a Replace libnacl_dyncode.a with libnacl_dyncode_private.a This assumes that the private libs can be found at the same directory as the public libs. """ result_libs = [] for l in libs: base = pathtools.basename(l) dname = pathtools.dirname(l) if base == 'libnacl.a': Log.Info( 'Not using IRT -- injecting libnacl_sys_private.a to link line' ) result_libs.append(pathtools.join(dname, 'libnacl_sys_private.a')) result_libs.append(l) elif base == 'libpthread.a': Log.Info('Not using IRT -- swapping private lib for libpthread') result_libs.append(pathtools.join(dname, 'libpthread_private.a')) elif base == 'libnacl_dyncode.a': Log.Info( 'Not using IRT -- swapping private lib for libnacl_dyncode') result_libs.append( pathtools.join(dname, 'libnacl_dyncode_private.a')) else: result_libs.append(l) return result_libs
def Run(args, errexit=True, redirect_stdout=None, redirect_stderr=None): """ Run: Run a command. Returns: return_code, stdout, stderr Run() is used to invoke "other" tools, e.g. those NOT prefixed with "pnacl-" stdout and stderr only contain meaningful data if redirect_{stdout,stderr} == subprocess.PIPE Run will terminate the program upon failure unless errexit == False TODO(robertm): errexit == True has not been tested and needs more work redirect_stdout and redirect_stderr are passed straight to subprocess.Popen """ result_stdout = None result_stderr = None if isinstance(args, str): args = shell.split(env.eval(args)) args = [pathtools.tosys(args[0])] + args[1:] Log.Info('Running: ' + StringifyCommand(args)) if env.getbool('DRY_RUN'): if redirect_stderr or redirect_stdout: # TODO(pdox): Prevent this from happening, so that # dry-run is more useful. Log.Fatal("Unhandled dry-run case.") return 0, None, None try: # If we have too long of a cmdline on windows, running it would fail. # Attempt to use a file with the command line options instead in that case. if ArgsTooLongForWindows(args): actual_args = ConvertArgsToFile(args) Log.Info('Wrote long commandline to file for Windows: ' + StringifyCommand(actual_args)) else: actual_args = args p = subprocess.Popen(actual_args, stdout=redirect_stdout, stderr=redirect_stderr) result_stdout, result_stderr = p.communicate() except Exception, e: msg = '%s\nCommand was: %s' % (str(e), StringifyCommand(args)) print(msg) DriverExit(1)
def RunDriver(invocation, args, suppress_inherited_arch_args=False): """ RunDriver() is used to invoke "driver" tools, e.g. those prefixed with "pnacl-" It automatically appends some additional flags to the invocation which were inherited from the current invocation. Those flags were preserved by ParseArgs """ if isinstance(args, str): args = shell.split(env.eval(args)) module_name = 'pnacl-%s' % invocation script = env.eval('${DRIVER_BIN}/%s' % module_name) script = shell.unescape(script) inherited_driver_args = env.get('INHERITED_DRIVER_ARGS') if suppress_inherited_arch_args: inherited_driver_args = FilterOutArchArgs(inherited_driver_args) script = pathtools.tosys(script) cmd = [script] + args + inherited_driver_args Log.Info('Driver invocation: %s', repr(cmd)) module = __import__(module_name) # Save the environment, reset the environment, run # the driver module, and then restore the environment. env.push() env.reset() DriverMain(module, cmd) env.pop()
def UseDefaultCommandlineLLC(): if not env.getbool('USE_DEFAULT_CMD_LINE'): return False else: reason, non_standard = RequiresNonStandardLLCCommandline() if non_standard: Log.Info(reason + ' -- not using default SRPC commandline for LLC!') return False return True
redirect_stdin = None if stdin_contents: redirect_stdin = subprocess.PIPE p = subprocess.Popen(actual_args, stdin=redirect_stdin, stdout=redirect_stdout, stderr=redirect_stderr) result_stdout, result_stderr = p.communicate(input=stdin_contents) except Exception, e: msg = '%s\nCommand was: %s' % (str(e), StringifyCommand(args, stdin_contents)) print msg DriverExit(1) Log.Info('Return Code: ' + str(p.returncode)) if errexit and p.returncode != 0: if redirect_stdout == subprocess.PIPE: Log.Error('--------------stdout: begin') Log.Error(result_stdout) Log.Error('--------------stdout: end') if redirect_stderr == subprocess.PIPE: Log.Error('--------------stderr: begin') Log.Error(result_stderr) Log.Error('--------------stderr: end') DriverExit(p.returncode) return p.returncode, result_stdout, result_stderr
def ToggleDefaultCommandlineLD(inputs, infile): if env.getbool('USE_DEFAULT_CMD_LINE'): reason, non_standard = RequiresNonStandardLDCommandline(inputs, infile) if non_standard: Log.Info(reason + ' -- not using default SRPC commandline for LD!') inputs.append('--pnacl-driver-set-USE_DEFAULT_CMD_LINE=0')
def main(argv): argv = [env.getone('DRIVER_PATH')] + argv Log.Info('IGNORING: ' + StringifyCommand(argv)) return 0
def main(argv): env.update(EXTRA_ENV) driver_tools.ParseArgs(argv, TranslatorPatterns) if env.getbool('SHARED'): env.set('PIC', '1') if env.getbool('SHARED') and env.getbool('STATIC'): Log.Fatal('Cannot mix -static and -shared') driver_tools.GetArch(required=True) inputs = env.get('INPUTS') output = env.getone('OUTPUT') if len(inputs) == 0: Log.Fatal("No input files") if output == '': Log.Fatal("Please specify output file with -o") # Find the bitcode file on the command line. bcfiles = [ f for f in inputs if driver_tools.IsPNaClBitcode(f) or driver_tools.IsLLVMBitcode(f) or driver_tools.FileType(f) == 'll' ] if len(bcfiles) > 1: Log.Fatal('Expecting at most 1 bitcode file') elif len(bcfiles) == 1: bcfile = bcfiles[0] else: bcfile = None # If there's a bitcode file, translate it now. tng = driver_tools.TempNameGen(inputs + bcfiles, output) output_type = env.getone('OUTPUT_TYPE') metadata = None if bcfile: sfile = None if output_type == 's': sfile = output elif env.getbool('FORCE_INTERMEDIATE_S'): sfile = tng.TempNameForInput(bcfile, 's') ofile = None if output_type == 'o': ofile = output elif output_type != 's': ofile = tng.TempNameForInput(bcfile, 'o') if sfile: RunLLC(bcfile, sfile, filetype='asm') if ofile: RunAS(sfile, ofile) else: RunLLC(bcfile, ofile, filetype='obj') else: ofile = None # If we've been told to stop after translation, stop now. if output_type in ('o', 's'): return 0 # Replace the bitcode file with __BITCODE__ in the input list if bcfile: inputs = ListReplace(inputs, bcfile, '__BITCODE__') env.set('INPUTS', *inputs) # Get bitcode type and metadata if bcfile: # Until we stabilize the ABI for shared libraries, # assume that pnacl-translate only handles pexes # to avoid a dependency on bitcode metadata. assert not env.getbool('SHARED') bctype = driver_tools.GetBitcodeType(bcfile, True) metadata = driver_tools.GetBitcodeMetadata(bcfile, True) # Determine the output type, in this order of precedence: # 1) Output type can be specified on command-line (-S, -c, -shared, -static) # 2) If bitcode file given, use its output type. (pso->so, pexe->nexe, po->o) # 3) Otherwise, assume nexe output. if env.getbool('SHARED'): output_type = 'so' elif env.getbool('STATIC'): output_type = 'nexe' elif bcfile: DefaultOutputTypes = { 'pso': 'so', 'pexe': 'nexe', 'po': 'o', } output_type = DefaultOutputTypes[bctype] else: output_type = 'nexe' # If the bitcode is of type "object", no linking is required. if output_type == 'o': # Copy ofile to output Log.Info('Copying %s to %s' % (ofile, output)) shutil.copy(pathtools.tosys(ofile), pathtools.tosys(output)) return 0 if bcfile: ApplyBitcodeConfig(metadata, bctype) # NOTE: we intentionally delay setting STATIC here to give user choices # preference but we should think about dropping the support for # the -static, -shared flags in the translator and have everything # be determined by bctype if metadata is None: env.set('STATIC', '1') elif len(metadata['NeedsLibrary']) == 0 and not env.getbool('SHARED'): env.set('STATIC', '1') assert output_type in ('so', 'nexe') RunLD(ofile, output) return 0