Re: [PATCH] gen_compile_commands: honor the build directory for modules
From: Nicolas Schier
Date: Fri Oct 16 2026 - 09:49:24 EST
On Fri, Oct 16, 2026 at 01:25:33PM +0700, Van Vo wrote:
> Hi Nathan,
>
> > How was this discovered?
>
> This came from code inspection of standalone use of -d with an explicit
> modules.order argument, followed initially by a constructed reproducer.
> It was not a failure encountered through Kbuild's compile_commands.json
> target.
>
> I have now reproduced it using real Kbuild-generated artifacts from
> 0fcb05b72344f40806cbe810de8872f1698bf053 on Linux/aarch64, with Python
> 3.11.13 and GCC 12.2.0. This was a partial lib/ build with CONFIG_TEST_LKM=m.
>
> The following uses a disposable source tree at that base. The guards
> prevent overwriting an existing output directory or result file:
>
> (
> set -eu
> test ! -e out
> test ! -e outside.json
> test ! -e inside.json
> make O=out -j1 allnoconfig
> bash scripts/config --file out/.config --enable MODULES \
> --enable RUNTIME_TESTING_MENU --module TEST_LKM
> make O=out -j1 olddefconfig
> make O=out -j1 V=1 lib/
>
> outside_exit=0
> python3 -B scripts/clang-tools/gen_compile_commands.py -a ar \
> -d out -o outside.json out/lib/modules.order ||
> outside_exit=$?
> printf 'outside_exit=%s\n' "$outside_exit"
>
> inside_exit=0
> (cd out &&
> python3 -B ../scripts/clang-tools/gen_compile_commands.py -a ar \
> -o ../inside.json lib/modules.order) ||
> inside_exit=$?
> printf 'inside_exit=%s\n' "$inside_exit"
> test "$outside_exit" -eq 1
> test "$inside_exit" -eq 0
> python3 -c \
> 'import json; assert len(json.load(open("inside.json"))) == 1'
> )
>
> Kbuild generated lib/test_module.o, lib/test_module.mod,
> lib/.test_module.o.cmd and lib/modules.order under out/. Both .mod and
> modules.order contain lib/test_module.o.
>
> The old script's invocation from the source directory fails with:
>
> FileNotFoundError: [Errno 2] No such file or directory:
> 'lib/test_module.mod'
> outside_exit=1
>
> The same artifacts work when the old script is invoked from out/:
>
> inside_exit=0
>
> The successful invocation produces one JSON entry for lib/test_module.c.
> The patched script succeeds from the source directory and produces an
> identical entry. The old script also fails with absolute paths for -d
> and modules.order; the patched script succeeds with those paths too.
>
> Only the standalone generator invocation is outside the build directory;
> compilation itself runs under out/. This is not a full kernel build or
> a boot/runtime test.
Thanks for the detailed reproducer.
Quoting from Nathan:
| How was this discovered? This cannot happen within Kbuild because this
| script is always invoked from within the build folder, so was it a
| manual invocation or something else?
So, if I get youre reply correctly, the issue this was not discovered
"in the wild" but can only be reproduced by manual use of
gen_compile_commands.py.
--
Nicolas