#!/usr/bin/env python3 import errno import multiprocessing import os import subprocess import sys import build_configs CONFIGS = {config: params for config, params in build_configs.__dict__.items() if not config.startswith("_")} DEFAULT_CONFIG_NAME = CONFIGS.pop("DEFAULT") DEBUG_CONFIG_NAME = CONFIGS.pop("DEBUG") CMAKE = "cmake" DEFAULT_MAKE_PARAMETERS = [] if os.name == "posix": MAKE = "make" try: num_cpus = multiprocessing.cpu_count() except NotImplementedError: pass else: DEFAULT_MAKE_PARAMETERS.append('-j{}'.format(num_cpus)) CMAKE_GENERATOR = "Unix Makefiles" elif os.name == "nt": MAKE = "nmake" CMAKE_GENERATOR = "NMake Makefiles" else: print("Unsupported OS: " + os.name) sys.exit(1) def print_usage(): script_name = os.path.basename(__file__) configs = [] for name, args in sorted(CONFIGS.items()): if name == DEFAULT_CONFIG_NAME: name += " (default)" if name == DEBUG_CONFIG_NAME: name += " (default with --debug)" configs.append(name + "\n " + " ".join(args)) configs_string = "\n ".join(configs) cmake_name = os.path.basename(CMAKE) make_name = os.path.basename(MAKE) generator_name = CMAKE_GENERATOR.lower() default_config_name = DEFAULT_CONFIG_NAME debug_config_name = DEBUG_CONFIG_NAME print("""Usage: {script_name} [BUILD [BUILD ...]] [--all] [--debug] [MAKE_OPTIONS] Build one or more predefined build configurations of Fast Downward. Each build uses {cmake_name} to generate {generator_name} and then uses {make_name} to compile the code. Build configurations differ in the parameters they pass to {cmake_name}. By default, the build uses N threads on a machine with N cores if the number of cores can be determined. Use the "-j" option for {cmake_name} to override this default behaviour. Build configurations {configs_string} --all Alias to build all build configurations. --debug Alias to build the default debug build configuration. --help Print this message and exit. Make options All other parameters are forwarded to {make_name}. Example usage: ./{script_name} # build {default_config_name} in #cores threads ./{script_name} -j4 # build {default_config_name} in 4 threads ./{script_name} debug # build debug ./{script_name} --debug # build {debug_config_name} ./{script_name} release debug # build release and debug configs ./{script_name} --all VERBOSE=true # build all build configs with detailed logs """.format(**locals())) def get_project_root_path(): import __main__ return os.path.dirname(__main__.__file__) def get_builds_path(): return os.path.join(get_project_root_path(), "builds") def get_src_path(): return os.path.join(get_project_root_path(), "src") def get_build_path(config_name): return os.path.join(get_builds_path(), config_name) def try_run(cmd, cwd): print('Executing command "{}" in directory "{}".'.format(" ".join(cmd), cwd)) try: subprocess.check_call(cmd, cwd=cwd) except OSError as exc: if exc.errno == errno.ENOENT: print("Could not find '%s' on your PATH. For installation instructions, " "see https://www.fast-downward.org/ObtainingAndRunningFastDownward." % cmd[0]) sys.exit(1) else: raise def build(config_name, cmake_parameters, make_parameters): print("Building configuration {config_name}.".format(**locals())) build_path = get_build_path(config_name) rel_src_path = os.path.relpath(get_src_path(), build_path) try: os.makedirs(build_path) except OSError as exc: if exc.errno == errno.EEXIST and os.path.isdir(build_path): pass else: raise try_run([CMAKE, "-G", CMAKE_GENERATOR] + cmake_parameters + [rel_src_path], cwd=build_path) try_run([MAKE] + make_parameters, cwd=build_path) print("Built configuration {config_name} successfully.".format(**locals())) def main(): config_names = set() make_parameters = DEFAULT_MAKE_PARAMETERS for arg in sys.argv[1:]: if arg == "--help" or arg == "-h": print_usage() sys.exit(0) elif arg == "--debug": config_names.add(DEBUG_CONFIG_NAME) elif arg == "--all": config_names |= set(CONFIGS.keys()) elif arg in CONFIGS: config_names.add(arg) else: make_parameters.append(arg) if not config_names: config_names.add(DEFAULT_CONFIG_NAME) for config_name in config_names: build(config_name, CONFIGS[config_name], make_parameters) if __name__ == "__main__": main()