def run(self): """ Run the set of commands required by this driver """ # set output directory if not os.path.exists(self._output_directory): os.makedirs(self._output_directory) for c in self._commandsEnabled: # run the setup for the command self.preRun(c) # run the command cmd = self._commands[c] if cmd[0].find('/') != 0 and (util.find_bin(cmd[0]) == None): print >> sys.stderr, "{}: command not found".format(cmd[0]) sys.exit(1) rc = self.runCmd(c, cmd) # run the cleanup whether the command succeeded or failed postrc = self.postRun(c) # if the main command failed, exit with its error code if rc != 0: sys.exit(rc)
def run(self): """ Run the set of commands required by this driver """ # set output directory if not os.path.exists( self._output_directory) and not self._run_preprocessor_only: os.makedirs(self._output_directory) for c in self._commandsEnabled: # run the setup for the command self.preRun(c) # run the command cmd = self._commands[c] if cmd[0].find('/') != 0 and (util.find_bin(cmd[0]) == None): print("{}: command not found".format(cmd[0]), file=sys.stderr) sys.exit(1) rc = self.runCmd(c, cmd) # run the cleanup whether the command succeeded or failed postrc = self.postRun(c) # if the main command failed, stop and return its error code so that # backends that override run can chose what to do on error if rc != 0: return rc return 0
def main(): parser = argparse.ArgumentParser() parser.add_argument("-V", "--version", dest="show_version", help="show version and exit", action="store_true", default=False) parser.add_argument("-v", "--debug", dest="debug", help="verbose", action="store_true", default=False) parser.add_argument("-###", "--test-only", dest="dry_run", help="print (but do not run) the commands", action="store_true", default=False) parser.add_argument("-Xpreprocessor", dest="preprocessor_options", metavar="<arg>", help="Pass <arg> to the preprocessor", action="append", default=[]) parser.add_argument("-Xp4c", dest="compiler_options", metavar="<arg>", help="Pass <arg> to the compiler", action="append", default=[]) parser.add_argument("-Xassembler", dest="assembler_options", metavar="<arg>", help="Pass <arg> to the assembler", action="append", default=[]) parser.add_argument("-Xlinker", dest="linker_options", metavar="<arg>", help="Pass <arg> to the linker", action="append", default=[]) parser.add_argument("-b", "--target", dest="backend", help="specify target backend", action="store", default="bmv2-ss-p4org") parser.add_argument("-E", dest="run_preprocessor_only", help="Only run the preprocessor", action="store_true", default=False) parser.add_argument("-e", dest="skip_preprocessor", help="Skip the preprocessor", action="store_true", default=False) parser.add_argument("-S", dest="run_till_assembler", help="Only run the preprocess and compilation steps", action="store_true", default=False) parser.add_argument("-c", dest="run_all", help="Only run preprocess, compile, and assemble steps", action="store_true", default=True) parser.add_argument("-x", dest="language", choices = ["p4-14", "p4-16"], help="Treat subsequent input files as having type language.", action="store", default="p4-16") parser.add_argument("-I", dest="search_path", help="Add directory to include search path", action="append", default=[]) parser.add_argument("-o", dest="output_directory", help="Write output to the provided path", action="store", metavar="PATH", default=".") parser.add_argument("--target-help", dest="show_target_help", help="Display target specific command line options.", action="store_true", default=False) parser.add_argument("--p4runtime-file", help="Write a P4Runtime control plane API description " "to the specified file.", action="store", default=None) parser.add_argument("--p4runtime-format", choices=["binary", "json", "text"], help="Choose output format for the P4Runtime API " "description (default is binary).", action="store", default="binary") if (os.environ['P4C_BUILD_TYPE'] == "DEVELOPER"): add_developer_options(parser) parser.add_argument("source_file", nargs='?', help="Files to compile", default=None) # many more options opts = parser.parse_args() source = opts.source_file if opts.show_version: print("p4c %s" % (p4c_src.__version__)) sys.exit(0) # load supported configuration cfg_files = glob.glob("{}/*.cfg".format(os.environ['P4C_CFG_PATH'])) cfg = config.Config(config_prefix = "p4c") for cf in cfg_files: if opts.debug: print 'loading config {}'.format(cf) cfg.load_from_config(cf, opts.output_directory, opts.source_file) if opts.show_target_help: display_supported_targets(cfg) sys.exit(0) # target-arch-vendor, e.g. # bmv2-ss-p4org # ebpf-psa-p4org triplet = opts.backend.split('-') if (len(triplet) != 3): print "Invalid target-arch-vendor triplet." display_supported_targets(cfg) sys.exit(1) if not source: parser.error('No input specified.') backend = None for triplet, _ in cfg.steps.iteritems(): regex = triplet.replace('*', '[a-zA-Z0-9*]*') pattern = re.compile(regex) if (pattern.match(opts.backend)): backend = triplet break if backend == None: print "Unknown backend:", opts.backend sys.exit(1) commands['preprocessor'] = [] commands['compiler'] = [] commands['assembler'] = [] commands['linker'] = [] for option in opts.preprocessor_options: commands["preprocessor"] += shlex.split(option) for option in opts.compiler_options: commands["compiler"] += shlex.split(option) if (os.environ['P4C_BUILD_TYPE'] == "DEVELOPER"): for option in opts.log_levels: commands["compiler"].append("-T{}".format(option)) if opts.passes: commands["compiler"].append("--top4 {}".format(",".join(opts.passes))) if opts.debug: commands["compiler"].append("-vvv") if opts.dump_dir: commands["compiler"].append("--dump {}".format(opts.dump_dir)) if opts.json: commands["compiler"].append("--toJSON {}".format(opts.json)) if opts.pretty_print: commands["compiler"].append("--pp {}".format(opts.pretty_print)) for option in opts.assembler_options: commands["assembler"] += shlex.split(option) for option in opts.linker_options: commands["linker"] += shlex.split(option) # set output directory if not os.path.exists(opts.output_directory): os.makedirs(opts.output_directory) commands['preprocessor'].insert(0, cfg.get_preprocessor(backend)) commands['compiler'].insert(0, cfg.get_compiler(backend)) commands['assembler'].insert(0, cfg.get_assembler(backend)) commands['linker'].insert(0, cfg.get_linker(backend)) # handle mode flags step_enable = [False, False, False, False] if opts.run_preprocessor_only: step_enable = [True, False, False, False] elif opts.skip_preprocessor: step_enable = [False, True, True, True] elif opts.run_till_assembler: step_enable = [True, True, False, False] elif opts.run_all: step_enable = [True, True, True, True] # default search path if opts.language == 'p4-16': commands['preprocessor'].append("-I {}".format(os.environ['P4C_16_INCLUDE_PATH'])) commands['compiler'].append("-I {}".format(os.environ['P4C_16_INCLUDE_PATH'])) else: commands['preprocessor'].append("-I {}".format(os.environ['P4C_14_INCLUDE_PATH'])) commands['compiler'].append("-I {}".format(os.environ['P4C_14_INCLUDE_PATH'])) # append search path for path in opts.search_path: commands['preprocessor'].append("-I") commands['preprocessor'].append(path) commands['compiler'].append("-I") commands['compiler'].append(path) # set p4 version if opts.language == 'p4-16': commands['compiler'].append("--p4v=16") else: commands['compiler'].append("--p4v=14") # P4Runtime options if opts.p4runtime_file: commands['compiler'].append("--p4runtime-file {}".format(opts.p4runtime_file)) commands['compiler'].append("--p4runtime-format {}".format(opts.p4runtime_format)) for idx, step in enumerate(cfg.steps[backend]): cmd = [] for c in commands[step]: cmd = cmd + shlex.split(c) options = cfg.options[backend][step] for option in options: cmd = cmd + shlex.split(option) # check if cmd in PATH unless absolute path if cmd[0].find('/') != 0 and (util.find_bin(cmd[0]) == None): print "{}: command not found".format(cmd[0]) sys.exit(1) # only dry-run if opts.dry_run: print "{}: {}".format(step, " ".join(cmd)) continue # skip if not required if not step_enable[idx]: continue # run command try: p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) except: import traceback print "error invoking {}".format(" ".join(cmd)) print traceback.format_exc() sys.exit(1) if opts.debug: print 'running {}'.format(' '.join(cmd)) out, err = p.communicate() # now wait if len(out) > 0: print out if p.returncode != 0: sys.exit(p.returncode)