Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

kconfig: fix IS_ENABLED to not require all options to be defined

Using IS_ENABLED() within C (vs. within CPP #if statements) in its
current form requires us to actually define every possible bool/tristate
Kconfig option twice (__enabled_* and __enabled_*_MODULE variants).

This results in a huge autoconf.h file, on the order of 16k lines for a
x86_64 defconfig.

Fixing IS_ENABLED to be able to work on the smaller subset of just
things that we really have defined is step one to fixing this. Which
means it has to not choke when fed non-enabled options, such as:

include/linux/netdevice.h:964:1: warning: "__enabled_CONFIG_FCOE_MODULE" is not defined [-Wundef]

The original prototype of how to implement a C and preprocessor
compatible way of doing this came from the Google+ user "comex ." in
response to Linus' crowdsourcing challenge for a possible improvement on
his earlier C specific solution:

#define config_enabled(x) (__stringify(x)[0] == '1')

In this implementation, I've chosen variable names that hopefully make
how it works more understandable.

Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Paul Gortmaker and committed by
Linus Torvalds
69349c2d 7c427f45

+18 -4
+18 -4
include/linux/kconfig.h
··· 4 4 #include <generated/autoconf.h> 5 5 6 6 /* 7 - * Helper macros to use CONFIG_ options in C expressions. Note that 7 + * Helper macros to use CONFIG_ options in C/CPP expressions. Note that 8 8 * these only work with boolean and tristate options. 9 9 */ 10 + 11 + /* 12 + * Getting something that works in C and CPP for an arg that may or may 13 + * not be defined is tricky. Here, if we have "#define CONFIG_BOOGER 1" 14 + * we match on the placeholder define, insert the "0," for arg1 and generate 15 + * the triplet (0, 1, 0). Then the last step cherry picks the 2nd arg (a one). 16 + * When CONFIG_BOOGER is not defined, we generate a (... 1, 0) pair, and when 17 + * the last step cherry picks the 2nd arg, we get a zero. 18 + */ 19 + #define __ARG_PLACEHOLDER_1 0, 20 + #define config_enabled(cfg) _config_enabled(cfg) 21 + #define _config_enabled(value) __config_enabled(__ARG_PLACEHOLDER_##value) 22 + #define __config_enabled(arg1_or_junk) ___config_enabled(arg1_or_junk 1, 0) 23 + #define ___config_enabled(__ignored, val, ...) val 10 24 11 25 /* 12 26 * IS_ENABLED(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y' or 'm', ··· 28 14 * 29 15 */ 30 16 #define IS_ENABLED(option) \ 31 - (__enabled_ ## option || __enabled_ ## option ## _MODULE) 17 + (config_enabled(option) || config_enabled(option##_MODULE)) 32 18 33 19 /* 34 20 * IS_BUILTIN(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y', 0 35 21 * otherwise. For boolean options, this is equivalent to 36 22 * IS_ENABLED(CONFIG_FOO). 37 23 */ 38 - #define IS_BUILTIN(option) __enabled_ ## option 24 + #define IS_BUILTIN(option) config_enabled(option) 39 25 40 26 /* 41 27 * IS_MODULE(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'm', 0 42 28 * otherwise. 43 29 */ 44 - #define IS_MODULE(option) __enabled_ ## option ## _MODULE 30 + #define IS_MODULE(option) config_enabled(option##_MODULE) 45 31 46 32 #endif /* __LINUX_KCONFIG_H */