if src_rel.startswith("../"): msg = "Source path: %s doesn't share common root directory: %s" logger.error(msg, src, args.common_root) sys.exit(1) dest = os.path.join(output_dir, src_rel) deps.extend( copy_with_deps.copy_with_deps(src, dest, search_path, [kconfig])) deps = sorted(set(deps)) # Add a dependency on copy_with_deps.py, which won't have been set by Bob deps.append(os.path.join(os.path.dirname(sys.argv[0]), "copy_with_deps.py")) copy_with_deps.write_depfile(args.depfile, args.output, deps) make_args = args.make_args make_args.extend(args.kbuild_options) make_args.append("ARCH=" + arch) # CROSS_COMPILE is still required with CC=clang if cross_compile: make_args.append("CROSS_COMPILE=" + cross_compile) if target_cc: make_args.append("CC=" + target_cc) if host_cc: make_args.append("HOSTCC=" + host_cc) if args.clang_triple: make_args.append("CLANG_TRIPLE=" + args.clang_triple) if args.extra_symbols is not None:
def main(): args = parse_args() # The build is run in $KDIR, rather than the usual build workdir, so # parameters need to be absolute so they are accessible with a different CWD. output_dir = os.path.dirname(args.output) abs_output_dir = os.path.abspath(output_dir) abs_kdir = os.path.abspath(args.kernel) search_path = [os.path.abspath(d) for d in args.include_dir] cross_compile = get_tool_abspath(args.cross_compile) target_cc = get_tool_abspath(args.cc) host_cc = get_tool_abspath(args.hostcc) make_command = get_tool_abspath(args.make_command) # Check the kernel ARCH arch = kernel_config_parser.get_arch(abs_kdir) if not arch: sys.exit(1) kbuild_cflags = [] kbuild_conflicts = 0 # Parse kbuild_options and make them cflags style for option, value in parse_kbuild_options(args.kbuild_options).items(): kbuild_conflicts += check_kbuild_option_conflicts( abs_kdir, option, value) kbuild_cflags.append(kbuild_to_cflag(option, value)) if kbuild_conflicts > 0: sys.exit(1) # Prepend EXTRA_CFLAGS with modified include paths includes = ["-I" + s for s in search_path] extra_cflags = " ".join(includes) + " " + args.extra_cflags + " " + \ " ".join(kbuild_cflags) # If autoconf.h is older than kernel config, the kernel needs to be rebuilt # to update this file. autoconf_file = os.path.join(abs_kdir, "include", "generated", "autoconf.h") kernel_config_file = kernel_config_parser.get_config_file_path(abs_kdir) if os.path.exists(autoconf_file): if os.path.getmtime(autoconf_file) < os.path.getmtime( kernel_config_file): msg = "%s is older than %s. make modules_prepare needs to be run." logger.warning(msg, autoconf_file, kernel_config_file) else: msg = "%s not found. make modules_prepare needs to be run" logger.warning(msg, autoconf_file) deps = [] # Add commonly needed search paths for copy_with_deps search_path.extend( [str.format(d, kdir=abs_kdir, arch=arch) for d in kernel_search_paths]) kconfig = os.path.join("linux", "kconfig.h") root = os.path.abspath(args.common_root) for src in args.module_sources: src_rel = os.path.relpath(os.path.abspath(src), root) if src_rel.startswith("../"): msg = "Source path: %s doesn't share common root directory: %s" logger.error(msg, src, args.common_root) sys.exit(1) dest = os.path.join(output_dir, src_rel) deps.extend( copy_with_deps.copy_with_deps(src, dest, search_path, [kconfig])) deps = sorted(set(deps)) # Add a dependency on copy_with_deps.py, which won't have been set by Bob deps.append(os.path.join(os.path.dirname(sys.argv[0]), "copy_with_deps.py")) # Add a dependency on the test kernel Makefile. We do not attempt to add # dependencies on every part of the kernel's build system - this is just # enough to ensure that incremental builds of the Bob tests work OK. deps.append(os.path.join(abs_kdir, "Makefile")) # Add a dependency to kernel config because we are parsing it to # populate CFLAGS. deps.append(kernel_config_file) copy_with_deps.write_depfile(args.depfile, args.output, deps) make_args = args.make_args make_args.extend(args.kbuild_options) make_args.append("ARCH=" + arch) # CROSS_COMPILE is still required with CC=clang if cross_compile: make_args.append("CROSS_COMPILE=" + cross_compile) if target_cc: make_args.append("CC=" + target_cc) if host_cc: make_args.append("HOSTCC=" + host_cc) if args.clang_triple: make_args.append("CLANG_TRIPLE=" + args.clang_triple) if args.ld: make_args.append("LD=" + args.ld) elif kernel_config_parser.option_enabled(abs_kdir, "CONFIG_LD_IS_LLD"): # Auto-set LD to `ld.lld` if LTO has been enabled make_args.append("LD=ld.lld") if args.extra_symbols: extra_symbols = [os.path.abspath(d) for d in args.extra_symbols] make_args.append("KBUILD_EXTRA_SYMBOLS=" + " ".join(extra_symbols)) if args.jobs: make_args.append("-j" + str(args.jobs)) else: # If the following env var is set, we are running in a build # farm where we should avoid increasing thread # count. Therefore leave make to run with a single core. # If not, build kernel modules with the number of CPUs we have. if os.getenv("MPDTI_BUILD_PARALLELISM") is None: make_args.append("-j" + str(multiprocessing.cpu_count())) module_ko = os.path.basename(args.output) abs_module_dir = os.path.abspath(args.module_dir) build_module(output_dir, module_ko, abs_kdir, abs_module_dir, make_command, make_args, extra_cflags)