Is there any efficient way (maybe by abusing the gcc preprocessor?) to get a set of stripped kernel sources where all code not needed according to .config is left out?
Well got some steps into a solution.
First, one can obtain the used compiler commands by
make KBUILD_VERBOSE=1 | tee build.log
grep '^ gcc' build.log
For now, I select only one gcc command line for further steps. For example the build of kernel/kmod.c, it looks like:
gcc <LIST OF MANY OPTIONS> -c -o kernel/kmod.o kernel/kmod.c
I now remove the option -c
, -o ...
and add -E
, thus disabling compilation and writing preprocessor output to the screen. Further I add -fdirectives-only
to prevent macro expansion and -undef
to remove the GNU defined macro definitions. -nostdinc
to remove the standard c headers is already added by the kernel makefile.
Now includes are still included and thus expanded on the preprocessor output. Thus I pipe the input file through grep removing them: grep -v '#include' kernel/kmod.c
. Now only one include is left: autoconf.h is included by the Makefile's command line. This is great as it actually defines the macros used by #ifdef CONFIG_...
to select the active kernel code.
The only thing left is to filter out the preprocessor comments and the remaining #define
s from autoconf.h by means of grep -v '^#'
.
The whole pipe looks like:
grep -v '#include' kernel/kmod.c | gcc -E -fdirectives-only -undef <ORIGINAL KERNEL BUILD GCC OPTIONS WITHOUT -c AND -o ...> - |grep -v '^#'
and the result is a filtered version of kernel/kmod.c containing the code that is actually build into kmod.o.
Questions remain: How to do that for the whole source tree? Are there files that are actually build but never used and stripped at linking?