def print_info(parsed, deployment, build_dir): """ Builds and prints the informational output block """ build_types = BuildType if parsed.build_type is not None: build_types = [ build_type for build_type in BuildType if build_type.get_cmake_build_type() == parsed.build_type ] # Roll up targets for more concise display build_infos = {} local_generic_targets = set() global_generic_targets = set() # Loop through available builds and harvest targets for build_type in build_types: build = Build(build_type, deployment, verbose=parsed.verbose) build.load(parsed.platform, build_dir) build_info = build.get_build_info(parsed.path) # Target list local_targets = { "'{}'".format(target) for target in build_info.get("local_targets", []) } global_targets = { "'{}'".format(target) for target in build_info.get("global_targets", []) } build_artifacts = (build_info.get("auto_location") if build_info.get("auto_location") is not None else "N/A") local_generic_targets = local_generic_targets.union(local_targets) global_generic_targets = global_generic_targets.union(global_targets) build_infos[build_type] = build_artifacts # Print out directory and deployment target sections print("[INFO] Fprime build information:") print(" Available directory targets: {}".format( " ".join(local_generic_targets))) print() print(" Available deployment targets: {}".format( " ".join(global_generic_targets))) # Artifact locations come afterwards print(" ----------------------------------------------------------") for build_type, build_artifact_location in build_infos.items(): format_string = " Build artifact directory ({}): {}" print( format_string.format(build_type.get_cmake_build_type(), build_artifact_location)) print()
def get_build(parsed: argparse.Namespace, deployment: Path, verbose: bool, target: Target = None) -> Build: """Gets the build given the namespace Takes the parsed namespace and processes it to a known build configuration. This will refine down a supplied list of build types or loop through all of the build types if None is specified. Args: parsed: argparse namespace to read values from deployment: deployment directory the build will operate against verbose: have we enabled verbose output build_types: build types to search through Returns: build meeting the specifications on build type """ build_types = target.build_types if target is not None else BuildType build_type = [ build_type for build_type in build_types if parsed.build_type is None or build_type.get_cmake_build_type() == parsed.build_type ] # None found, explode if not build_type: raise NoValidBuildTypeException( "Could not execute '{}' with a build type '{}'".format( target, parsed.build_type)) # Grab first build when multiple are available return Build(build_type[0], deployment, verbose=verbose)
def utility_entry(args): """ Main interface to F prime utility """ parsed, cmake_args, make_args, parser = parse_args(args) build_dir_as_path = None if parsed.build_dir is None else Path( parsed.build_dir) try: deployment = Build.find_nearest_deployment(Path(parsed.path)) if parsed.command is None: print("[ERROR] Must supply subcommand for fprime-util. See below.") parser.print_help() print_info(parsed, deployment, build_dir_as_path) elif parsed.command == "info": print_info(parsed, deployment, build_dir_as_path) elif parsed.command == "hash-to-file": lines = get_build(parsed, deployment, verbose=parsed.verbose).find_hashed_file( parsed.hash) print_hash_info(lines, parsed.hash) elif parsed.command == "generate": # First check for existing builds and error-quick if one is found. Prevents divergent generations builds = [] for build_type in BuildType: build = Build(build_type, deployment, verbose=parsed.verbose) build.invent(parsed.platform, build_dir_as_path) builds.append(build) # Once we looked for errors, then generate for build in builds: toolchain = build.find_toolchain() print("[INFO] {} build directory at: {}".format( parsed.command.title(), build.build_dir)) print("[INFO] Using toolchain file {} for platform {}".format( toolchain, parsed.platform)) if toolchain is not None: cmake_args.update({"CMAKE_TOOLCHAIN_FILE": toolchain}) build.generate(cmake_args) elif parsed.command == "purge": for build_type in BuildType: build = Build(build_type, deployment, verbose=parsed.verbose) try: build.load(parsed.platform, build_dir_as_path) except InvalidBuildCacheException: continue print("[INFO] {} build directory at: {}".format( parsed.command.title(), build.build_dir)) if confirm() or parsed.force: build.purge() else: target = get_target(parsed) build = get_build(parsed, deployment, parsed.verbose, target) build.load(parsed.platform, build_dir_as_path) build.execute(target, context=Path(parsed.path), make_args=make_args) except GenerateException as genex: print( "[ERROR] {}. Partial build cache remains. Run purge to clean-up.". format(genex), file=sys.stderr, ) except UnableToDetectDeploymentException: print("[ERROR] Could not detect deployment directory for: {}".format( parsed.path)) except FprimeException as exc: print("[ERROR] {}".format(exc), file=sys.stderr) return 1 return 0