kleaf: support ddk_library in compile_commands.json Currently, ddk_library targets explicitly skip compdb generation, and kernel_module does not propagate CompileCommandsInfo from dependencies (which are represented as KernelModuleDepInfo structs in kernel_module_deps). This change: 1. Removes internal_compdb = "skip" from ddk_library. 2. Adds the compile_commands.json target to the generated Makefiles for libraries, allowing Kbuild to generate the commands. 3. Adds compile_commands_info field to KernelModuleDepInfo to propagate this information from libraries to modules that depend on them. 4. Updates kernel_module implementation to collect these transitive compile commands from both legacy targets and DDK dependency structs. This ensures that running kernel_compile_commands on a module will correctly include compile commands for its dependent libraries. Bug: 394411899 Test: tools/bazel run //build/kernel/kleaf/tests/ddk_examples/ddk_library:mymod_compile_commands Test: tools/bazel run //build/kernel/kleaf/tests/integration_test -- DdkWorkspaceSetupTest.test_compile_commands_reachable Assisted-by: Antigravity:Gemini Change-Id: I2c0f3c7ed88840c5616a2089e447760fe2006adf
diff --git a/kleaf/impl/common_providers.bzl b/kleaf/impl/common_providers.bzl index fe83f72..d8323dd 100644 --- a/kleaf/impl/common_providers.bzl +++ b/kleaf/impl/common_providers.bzl
@@ -451,6 +451,7 @@ "kernel_module_setup_info": "`KernelModuleSetupInfo`", "module_symvers_info": "`ModuleSymversInfo`", "kernel_module_info": "`KernelModuleInfo`", + "compile_commands_info": "`CompileCommandsInfo`", }, )
diff --git a/kleaf/impl/ddk/ddk_library.bzl b/kleaf/impl/ddk/ddk_library.bzl index 729c69a..7f5d932 100644 --- a/kleaf/impl/ddk/ddk_library.bzl +++ b/kleaf/impl/ddk/ddk_library.bzl
@@ -137,7 +137,6 @@ internal_ddk_config = name + "_config", internal_is_ddk_library = True, internal_extra_make_goals = ["kleaf-objects"], - internal_compdb = "skip", internal_modules_install = False, internal_mnemonic = "DDK library", # Don't ask Kbuild to stamp it
diff --git a/kleaf/impl/ddk/gen_makefiles.py b/kleaf/impl/ddk/gen_makefiles.py index 7abbb65..eeecbac 100755 --- a/kleaf/impl/ddk/gen_makefiles.py +++ b/kleaf/impl/ddk/gen_makefiles.py
@@ -142,6 +142,11 @@ \t$(MAKE) -C $(KERNEL_SRC) M=$(M) $(KBUILD_OPTIONS) \\ \t KBUILD_EXTRA_SYMBOLS="$(EXTRA_SYMBOLS)" \\ \t {objects} + + compile_commands.json: + \t$(MAKE) -C $(KERNEL_SRC) M=$(M) $(KBUILD_OPTIONS) \\ + \t KBUILD_EXTRA_SYMBOLS="$(EXTRA_SYMBOLS)" \\ + \t $(@) """) else: content += textwrap.dedent("""\
diff --git a/kleaf/impl/kernel_module.bzl b/kleaf/impl/kernel_module.bzl index 99e2dce..975e21c 100644 --- a/kleaf/impl/kernel_module.bzl +++ b/kleaf/impl/kernel_module.bzl
@@ -797,6 +797,8 @@ transitive = [dep.kernel_module_info.transitive_files for dep in kernel_module_deps], ) + transitive_compile_commands = [dep.compile_commands_info.infos for dep in kernel_module_deps] + return [ # Sync list of infos with kernel_module_group. DefaultInfo( @@ -840,10 +842,13 @@ directories = depset([grab_cmd_step.cmd_dir]), ), CompileCommandsInfo( - infos = depset([CompileCommandsSingleInfo( - compile_commands_with_vars = compile_commands_step.compile_commands_with_vars, - compile_commands_common_out_dir = compile_commands_step.compile_commands_common_out_dir, - )]), + infos = depset( + [CompileCommandsSingleInfo( + compile_commands_with_vars = compile_commands_step.compile_commands_with_vars, + compile_commands_common_out_dir = compile_commands_step.compile_commands_common_out_dir, + )] if compile_commands_step.compile_commands_with_vars else [], + transitive = transitive_compile_commands, + ), ), ModuleSymversFileInfo( module_symvers = depset([module_symvers]) if module_symvers else depset(),
diff --git a/kleaf/impl/utils.bzl b/kleaf/impl/utils.bzl index a150509..2bda23d 100644 --- a/kleaf/impl/utils.bzl +++ b/kleaf/impl/utils.bzl
@@ -22,6 +22,7 @@ load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo") load( ":common_providers.bzl", + "CompileCommandsInfo", "DdkConfigInfo", "DdkHeadersInfo", "DdkLibraryInfo", @@ -567,6 +568,7 @@ kernel_module_setup_info = kernel_module[KernelModuleSetupInfo], kernel_module_info = kernel_module[KernelModuleInfo], module_symvers_info = kernel_module[ModuleSymversInfo], + compile_commands_info = kernel_module[CompileCommandsInfo], ) # Cross compiler name is not always the same as the linux arch
diff --git a/kleaf/tests/ddk_examples/ddk_library/BUILD.bazel b/kleaf/tests/ddk_examples/ddk_library/BUILD.bazel index 5ba390f..c4b1bb8 100644 --- a/kleaf/tests/ddk_examples/ddk_library/BUILD.bazel +++ b/kleaf/tests/ddk_examples/ddk_library/BUILD.bazel
@@ -1,6 +1,7 @@ load( "@kleaf//build/kernel/kleaf:kernel.bzl", "ddk_module", + "kernel_compile_commands", ) ddk_module( @@ -22,3 +23,8 @@ "//build/kernel/kleaf/tests/ddk_examples/ddk_library/libfoo", ], ) + +kernel_compile_commands( + name = "mymod_compile_commands", + deps = [":mymod"], +)
diff --git a/kleaf/tests/integration_test/ddk_workspace_test/out_of_tree/BUILD.bazel b/kleaf/tests/integration_test/ddk_workspace_test/out_of_tree/BUILD.bazel index d3408a3..2f4a347 100644 --- a/kleaf/tests/integration_test/ddk_workspace_test/out_of_tree/BUILD.bazel +++ b/kleaf/tests/integration_test/ddk_workspace_test/out_of_tree/BUILD.bazel
@@ -1,5 +1,6 @@ load( "@kleaf//build/kernel/kleaf:kernel.bzl", + "ddk_library", "ddk_module", "kernel_compile_commands", "kernel_config_devicetree_library", @@ -10,11 +11,19 @@ load("@rules_devicetree//devicetree:dtb.bzl", "dtb") # Test building no-op DDK module against kernel from sources +ddk_library( + name = "mylib", + srcs = ["mylib.c"], + hdrs = ["mylib.h"], + kernel_build = "//tests:kernel", +) + ddk_module( name = "out_of_tree", srcs = ["mydriver.c"], out = "out_of_tree.ko", kernel_build = "//tests:kernel", + deps = [":mylib"], ) kernel_modules_install(
diff --git a/kleaf/tests/integration_test/ddk_workspace_test/out_of_tree/mydriver.c b/kleaf/tests/integration_test/ddk_workspace_test/out_of_tree/mydriver.c index c1b826e..d834d11 100644 --- a/kleaf/tests/integration_test/ddk_workspace_test/out_of_tree/mydriver.c +++ b/kleaf/tests/integration_test/ddk_workspace_test/out_of_tree/mydriver.c
@@ -24,4 +24,16 @@ MODULE_DESCRIPTION("A test module for DDK testing purposes"); MODULE_AUTHOR("Yifan Hong <elsk@google.com>"); MODULE_LICENSE("GPL v2"); +#include "mylib.h" +#include <linux/init.h> +static int __init mydriver_init(void) { + mylib_function(); + return 0; +} + +static void __exit mydriver_exit(void) { +} + +module_init(mydriver_init); +module_exit(mydriver_exit);
diff --git a/kleaf/tests/integration_test/ddk_workspace_test/out_of_tree/mylib.c b/kleaf/tests/integration_test/ddk_workspace_test/out_of_tree/mylib.c new file mode 100644 index 0000000..9e09f61 --- /dev/null +++ b/kleaf/tests/integration_test/ddk_workspace_test/out_of_tree/mylib.c
@@ -0,0 +1,8 @@ +#include "mylib.h" +#include <linux/kernel.h> +#include <linux/module.h> + +void mylib_function(void) { + pr_info("Hello from mylib\n"); +} +EXPORT_SYMBOL_GPL(mylib_function);
diff --git a/kleaf/tests/integration_test/ddk_workspace_test/out_of_tree/mylib.h b/kleaf/tests/integration_test/ddk_workspace_test/out_of_tree/mylib.h new file mode 100644 index 0000000..a84ef30 --- /dev/null +++ b/kleaf/tests/integration_test/ddk_workspace_test/out_of_tree/mylib.h
@@ -0,0 +1 @@ +void mylib_function(void);
diff --git a/kleaf/tests/integration_test/integration_test.py b/kleaf/tests/integration_test/integration_test.py index a552d86..be03197 100644 --- a/kleaf/tests/integration_test/integration_test.py +++ b/kleaf/tests/integration_test/integration_test.py
@@ -829,6 +829,14 @@ f"found {staged_modinfos}", ) + with open(json_file) as f: + commands = json.load(f) + files = [entry["file"] for entry in commands] + self.assertTrue(any(f.endswith("out_of_tree/mydriver.c") for f in files), + f"mydriver.c not found in {json_file}") + self.assertTrue(any(f.endswith("out_of_tree/mylib.c") for f in files), + f"mylib.c not found in {json_file}") + def _run_test_setup_with_local_prebuilts(