Documentation: kbuild: explain handling optional dependencies
Subsystems (3)
PATCH 1/1 Documentation: kbuild: explain handling optional dependencies
From: Arnd Bergmann <[email protected]>
This problem frequently comes up in randconfig testing, with drivers failing to link because of a dependency on an optional feature.
The Kconfig language for this is very confusing, so try to document it in "Kconfig hints" section.
--- Documentation/kbuild/kconfig-language.rst | 26 +++++++++++++++++++++++ 1 file changed, 26 insertions(+)
Documentation/kbuild/kconfig-language.rst +26 -0
@@ -573,6 +573,32 @@ above, leading to: bool "Support for foo hardware" depends on ARCH_FOO_VENDOR || COMPILE_TEST +Optional dependencies +~~~~~~~~~~~~~~~~~~~~~ + +Some drivers are able to optionally use a feature from another module +or build cleanly with that module disabled, but cause a link failure +when trying to use that loadable module from a built-in driver. + +The most common way to express this optional dependency in Kconfig logic +uses the slighly counterintuitive + + config FOO + bool "Support for foo hardware" + depends on BAR || !BAR + +This means that there is either a dependency on BAR that disallows +the combination of FOO=y with BAR=m, or BAR is completely disabled. +For a more formalized approach if there are multiple drivers that have +the same dependency, a helper symbol can be used, like + + config FOO + bool "Support for foo hardware" + depends on BAR_OPTIONAL + + config BAR_OPTIONAL + def_tristate BAR || !BAR + Kconfig recursive dependency limitations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Signature · 1 line
2.39.2
Arnd Bergmann <[email protected]> writes:
Hello Arnd,
Quoted 11 lines
From: Arnd Bergmann <[email protected]>
This problem frequently comes up in randconfig testing, with drivers failing to link because of a dependency on an optional feature.
The
Kconfiglanguage for this is very confusing, so try to document it in "Kconfighints" section.Signed-off-by Arnd Bergmann <[email protected]>---
Thanks for writing this since as you mention that Kconfig idiom is not intuitive. The docs looks great to me!
Signature · 5 lines
Best regards, Javier Martinez Canillas Core Platforms Red Hat
Quoted 10 lines · Arnd Bergmann
From: Arnd Bergmann <[email protected]>
This problem frequently comes up in randconfig testing, with drivers failing to link because of a dependency on an optional feature.
The
Kconfiglanguage for this is very confusing, so try to document it in "Kconfighints" section.Signed-off-by Arnd Bergmann <[email protected]>
Signature · 1 line
Sakari Ailus
Quoted 11 lines · On Wed, Sep 13, 2023 at 01:37:52PM +0200 Arnd Bergmann wrote:
From: Arnd Bergmann <[email protected]>
This problem frequently comes up in randconfig testing, with drivers failing to link because of a dependency on an optional feature.
The
Kconfiglanguage for this is very confusing, so try to document it in "Kconfighints" section.Signed-off-by Arnd Bergmann <[email protected]>---
Hi Arnd,
thanks for documenting this! Three questions below:
Quoted 10 lines
Documentation/kbuild/kconfig-language.rst | 26 +++++++++++++++++++++++ 1 file changed, 26 insertions(+)Documentation/kbuild/kconfig-language.rst +0
-0@@ -573,6 +573,32 @@ above, leading to: bool "Support for foo hardware" depends on ARCH_FOO_VENDOR || COMPILE_TEST
Documentation/kbuild/kconfig-language.rst above, leading to: · line 584
Quoted 10 lines
Documentation/kbuild/kconfig-language.rst +9
-0+Optional dependencies +~~~~~~~~~~~~~~~~~~~~~ + +Some drivers are able to optionally use a feature from another module +or build cleanly with that module disabled, but cause a link failure +when trying to use that loadable module from a built-in driver. + +The most common way to express this optional dependency in Kconfig logic +uses the slighly counterintuitive
slighly -> slightly
For better RST compliance: could you explicitly start the code block e.g. by appending '::' as in "... counterintuitive::"?
Documentation/kbuild/kconfig-language.rst above, leading to: · line 588
Quoted 4 lines
Documentation/kbuild/kconfig-language.rst +4
-0+ + config FOO + bool "Support for foo hardware" + depends on BAR || !BAR
are you sure that this is enough? While testing, I needed to explicitly use =y|=n:
depends on BAR=y || BAR=n
to prevent FOO to be selectable iff BAR=m.
Documentation/kbuild/kconfig-language.rst above, leading to: · line 591
Quoted 3 lines
Documentation/kbuild/kconfig-language.rst +3
-0+ +This means that there is either a dependency on BAR that disallows +the combination of FOO=y with BAR=m, or BAR is completely disabled.
For me, this sentence is hard to parse (but I am not a native speaker); what about something like this:
This means that FOO can only be enabled, iff BAR is either built-in or completely disabled. If BAR is built as a module, FOO cannot be enabled.
Kind regards,
Nicolas
Quoted 13 lines · Nicolas Schier
Quoted 11 lines · On Wed, Sep 13, 2023 at 01:37:52PM +0200 Arnd Bergmann wrote:
Documentation/kbuild/kconfig-language.rst | 26 +++++++++++++++++++++++ 1 file changed, 26 insertions(+)Documentation/kbuild/kconfig-language.rst +0
-0@@ -573,6 +573,32 @@ above, leading to: bool "Support for foo hardware" depends on ARCH_FOO_VENDOR || COMPILE_TEST
Quoted 11 lines
Documentation/kbuild/kconfig-language.rst above, leading to: · line 584
Quoted 9 lines
Documentation/kbuild/kconfig-language.rst +9
-0+Optional dependencies +~~~~~~~~~~~~~~~~~~~~~ + +Some drivers are able to optionally use a feature from another module +or build cleanly with that module disabled, but cause a link failure +when trying to use that loadable module from a built-in driver. + +The most common way to express this optional dependency in Kconfig logic +uses the slighly counterintuitiveslighly -> slightly
Fixed, thanks
Quoted 2 lines
For better RST compliance: could you explicitly start the code block e.g. by appending '::' as in "... counterintuitive::"?
Ok, done.
Quoted 11 lines
Documentation/kbuild/kconfig-language.rst above, leading to: · line 588
Quoted 4 lines
Documentation/kbuild/kconfig-language.rst +4
-0+ + config FOO + bool "Support for foo hardware" + depends on BAR || !BARare you sure that this is enough? While testing, I needed to explicitly use =y|=n:
depends on BAR=y || BAR=nto prevent FOO to be selectable iff BAR=m.
I see my problem, I made a different mistake here. Your version is correct for a 'bool' symbol as I had here, but the intention of this was to make it work for tristate symbols, which are the interesting case. I've fixed it up this way now, hope it now makes sense to you:
Documentation/kbuild/kconfig-language.rst +4 -4
@@ -581,19 +581,19 @@ or build cleanly with that module disabled, but cause a link failure when trying to use that loadable module from a built-in driver. The most common way to express this optional dependency in Kconfig logic -uses the slighly counterintuitive +uses the slightly counterintuitive:: config FOO - bool "Support for foo hardware" + tristate "Support for foo hardware" depends on BAR || !BAR This means that there is either a dependency on BAR that disallows the combination of FOO=y with BAR=m, or BAR is completely disabled. For a more formalized approach if there are multiple drivers that have -the same dependency, a helper symbol can be used, like +the same dependency, a helper symbol can be used, like:: config FOO - bool "Support for foo hardware" + tristate "Support for foo hardware" depends on BAR_OPTIONAL config BAR_OPTIONAL
Quoted 8 lines
Documentation/kbuild/kconfig-language.rst above, leading to: · line 590
Quoted 2 lines
Documentation/kbuild/kconfig-language.rst +2
-0+This means that there is either a dependency on BAR that disallows +the combination of FOO=y with BAR=m, or BAR is completely disabled.For me, this sentence is hard to parse (but I am not a native speaker); what about something like this:
This means that FOO can only be enabled, iff BAR is either built-in or completely disabled. If BAR is built as a module, FOO cannot be enabled.
That would describe the version you suggested, but that's a different issue. Let me know if you still think it needs clarification after fixing the example.
Arnd
Quoted 54 lines · On Wed, Sep 13, 2023 at 09:55:36PM +0200 Arnd Bergmann wrote:
Quoted 13 lines · Nicolas Schier
Quoted 11 lines · On Wed, Sep 13, 2023 at 01:37:52PM +0200 Arnd Bergmann wrote:
Documentation/kbuild/kconfig-language.rst | 26 +++++++++++++++++++++++ 1 file changed, 26 insertions(+)Documentation/kbuild/kconfig-language.rst +0
-0@@ -573,6 +573,32 @@ above, leading to: bool "Support for foo hardware" depends on ARCH_FOO_VENDOR || COMPILE_TESTQuoted 11 lines
Documentation/kbuild/kconfig-language.rst above, leading to: · line 584
Quoted 9 lines
Documentation/kbuild/kconfig-language.rst +9
-0+Optional dependencies +~~~~~~~~~~~~~~~~~~~~~ + +Some drivers are able to optionally use a feature from another module +or build cleanly with that module disabled, but cause a link failure +when trying to use that loadable module from a built-in driver. + +The most common way to express this optional dependency in Kconfig logic +uses the slighly counterintuitiveslighly -> slightly
Fixed, thanks
Quoted 2 lines
For better RST compliance: could you explicitly start the code block e.g. by appending '::' as in "... counterintuitive::"?
Ok, done.
Quoted 11 lines
Documentation/kbuild/kconfig-language.rst above, leading to: · line 588
Quoted 4 lines
Documentation/kbuild/kconfig-language.rst +4
-0+ + config FOO + bool "Support for foo hardware" + depends on BAR || !BARare you sure that this is enough? While testing, I needed to explicitly use =y|=n:
depends on BAR=y || BAR=nto prevent FOO to be selectable iff BAR=m.
I see my problem, I made a different mistake here. Your version is correct for a 'bool' symbol as I had here, but the intention of this was to make it work for tristate symbols, which are the interesting case. I've fixed it up this way now, hope it now makes sense to you:
Documentation/kbuild/kconfig-language.rst or build cleanly with that module disabled, but cause a link failure · line 588
Quoted 10 lines
Documentation/kbuild/kconfig-language.rst +2
-2@@ -581,19 +581,19 @@ or build cleanly with that module disabled, but cause a link failure when trying to use that loadable module from a built-in driver. The most common way to express this optional dependency in Kconfig logic -uses the slighly counterintuitive +uses the slightly counterintuitive:: config FOO - bool "Support for foo hardware" + tristate "Support for foo hardware" depends on BAR || !BAR
ah, thanks, tristate kconfig symbols are really more interesting. But I am still not sure, whether this works as proposed:
With the 'config FOO' above and
config BAR
tristate "Support for bar feature"
kconfig allows me to choose between these:
BAR=y => FOO={N/m/y}
BAR=m => FOO={N/m}
BAR=n => FOO={N/m/y}But with
config FOO
tristate "Support for foo hardware"
depends on !BAR=m
I can choose between:
BAR=y => FOO={N/m/y}
BAR=m => FOO is not selectable
BAR=n => FOO={N/m/y}(Re-checked with BAR=IPV6 and FOO=WIREGUARD; CONFIG_WIREGUARD as 'depends on IPV6 || !IPV6' in its kconfig definition, and both are tristate kconfig symbols.)
Thus, it seems to me, that the intuitive way is the way forward (and several Kconfigs are out-of-date with regard to 'depends on !X=m'. Or do I still miss your point?
Kind regards,
Nicolas
Quoted 27 lines
Documentation/kbuild/kconfig-language.rst +2
-2This means that there is either a dependency on BAR that disallows the combination of FOO=y with BAR=m, or BAR is completely disabled. For a more formalized approach if there are multiple drivers that have -the same dependency, a helper symbol can be used, like +the same dependency, a helper symbol can be used, like:: config FOO - bool "Support for foo hardware" + tristate "Support for foo hardware" depends on BAR_OPTIONAL config BAR_OPTIONALQuoted 8 lines
Documentation/kbuild/kconfig-language.rst above, leading to: · line 590
Quoted 2 lines
Documentation/kbuild/kconfig-language.rst +2
-0+This means that there is either a dependency on BAR that disallows +the combination of FOO=y with BAR=m, or BAR is completely disabled.For me, this sentence is hard to parse (but I am not a native speaker); what about something like this:
This means that FOO can only be enabled, iff BAR is either built-in or completely disabled. If BAR is built as a module, FOO cannot be enabled.
That would describe the version you suggested, but that's a different issue. Let me know if you still think it needs clarification after fixing the example.
Arnd
Quoted 27 lines · Nicolas Schier
Documentation/kbuild/kconfig-language.rst or build cleanly with that module disabled, but cause a link failure · line 588
Quoted 4 lines · On Wed, Sep 13, 2023 at 09:55:36PM +0200 Arnd Bergmann wrote:
config FOO
Documentation/kbuild/kconfig-language.rst +1
-1- bool "Support for foo hardware" + tristate "Support for foo hardware" depends on BAR || !BARah, thanks, tristate kconfig symbols are really more interesting. But I am still not sure, whether this works as proposed:
With the 'config FOO' above and
config BAR
tristate "Support for bar feature"kconfig allows me to choose between these:
BAR=y => FOO={N/m/y} BAR=m => FOO={N/m} BAR=n => FOO={N/m/y}But with
config FOO
tristate "Support for foo hardware"
depends on !BAR=m
Quoted 5 lines
I can choose between:
BAR=y => FOO={N/m/y} BAR=m => FOO is not selectable BAR=n => FOO={N/m/y}
That is indeed the point: if BAR=m, we want to be able to pick FOO=m here, otherwise it is impossible to enabled everything as modules.
Another correct way to express the same thing as the first would be
config FOO
tristate "Support for foo hardware"
depends on !BAR=m || m
which I find even more confusing than the 'BAR || !BAR' convention, though we have that in a couple of places.
I just found another variant that I had not seen before:
Quoted 7 lines
(Re-checked with BAR=IPV6 and FOO=WIREGUARD;
CONFIG_WIREGUARDas 'depends on IPV6 || !IPV6' in its kconfig definition, and both are tristate kconfig symbols.)Thus, it seems to me, that the intuitive way is the way forward (and several Kconfigs are out-of-date with regard to 'depends on !X=m'. Or do I still miss your point?
I'm not sure what you mean here, but it appears that one of us is missing the point ;-)
Arnd
Nicolas Schier
Reviewed-byQuoted 28 lines · Arnd Bergmann
Quoted 27 lines · Nicolas Schier
Documentation/kbuild/kconfig-language.rst or build cleanly with that module disabled, but cause a link failure · line 588
Quoted 4 lines · On Wed, Sep 13, 2023 at 09:55:36PM +0200 Arnd Bergmann wrote:
config FOO
Documentation/kbuild/kconfig-language.rst +1
-1- bool "Support for foo hardware" + tristate "Support for foo hardware" depends on BAR || !BARah, thanks, tristate kconfig symbols are really more interesting. But I am still not sure, whether this works as proposed:
With the 'config FOO' above and
config BAR
tristate "Support for bar feature"kconfig allows me to choose between these:
BAR=y => FOO={N/m/y} BAR=m => FOO={N/m} BAR=n => FOO={N/m/y}But with
config FOO
tristate "Support for foo hardware"
depends on !BAR=m
Quoted 8 lines
Quoted 5 lines
I can choose between:
BAR=y => FOO={N/m/y} BAR=m => FOO is not selectable BAR=n => FOO={N/m/y}That is indeed the point: if BAR=m, we want to be able to pick FOO=m here, otherwise it is impossible to enabled everything as modules.
oh, I misinterpreted your very first sentence; thanks for clarifying it to me and sorry for the noise.
With the minor fixes:
Kind regards,
Nicolas
Quoted 7 lines · Nicolas Schier
Quoted 6 lines · Arnd Bergmann
Quoted 4 lines · Nicolas Schier
BAR=y => FOO={N/m/y} BAR=m => FOO is not selectable BAR=n => FOO={N/m/y}
Quoted 9 lines
Quoted 2 lines
That is indeed the point: if BAR=m, we want to be able to pick FOO=m here, otherwise it is impossible to enabled everything as modules.
oh, I misinterpreted your very first sentence; thanks for clarifying it to me and sorry for the noise.
With the minor fixes:Reviewed-by Nicolas Schier <[email protected]>
Ok, thanks!
I understand that the text is still confusing, so if anyone has an idea for how to improve it further, let me know, otherwise I'll send what I have now with type fixes as v2.
Arnd
"Arnd Bergmann" <[email protected]> writes:
Hello Nicolas,
Quoted 3 lines · Nicolas Schier
Quoted 1 line · On Wed, Sep 13, 2023 at 09:55:36PM +0200 Arnd Bergmann wrote:
[...]
Quoted 12 lines
Quoted 5 lines
I can choose between:
BAR=y => FOO={N/m/y} BAR=m => FOO is not selectable BAR=n => FOO={N/m/y}That is indeed the point: if BAR=m, we want to be able to pick FOO=m here, otherwise it is impossible to enabled everything as modules.
Another correct way to express the same thing as the first would be
Quoted 13 lines
config FOO
tristate "Support for foo hardware"
depends on !BAR=m || mwhich I find even more confusing than the 'BAR || !BAR' convention, though we have that in a couple of places.
I just found another variant that I had not seen before:
Quoted 4 lines
(Re-checked with BAR=IPV6 and FOO=WIREGUARD;
CONFIG_WIREGUARDas 'depends on IPV6 || !IPV6' in its kconfig definition, and both are tristate kconfig symbols.)
Which is correct because WIREGUARD can be built with IPV6 disabled, but if both options are enabled then WIREGUARD can only be built-in if the IPV6 option is also built-in.
WIREGUARD must be a module if IPV6 is also a module, but can still be a module if IPV6 is built-in.
In other words, what this idiom express is that the following configs are possible:
IPV6=n => WIREGUARD=y
IPV6=n => WIREGUARD=m
IPV6=y => WIREGUARD=y
IPV6=y => WIREGUARD=m
IPV6=m => WIREGUARD=m
but the following option is not possible:
IPV6=m => WIREGUARD=y
Signature · 5 lines
Best regards, Javier Martinez Canillas Core Platforms Red Hat
Quoted 62 lines · Nicolas Schier
Quoted 60 lines · On Wed, Sep 13, 2023 at 09:55:36PM +0200 Arnd Bergmann wrote:
Quoted 13 lines · Nicolas Schier
Quoted 11 lines · On Wed, Sep 13, 2023 at 01:37:52PM +0200 Arnd Bergmann wrote:
Documentation/kbuild/kconfig-language.rst | 26 +++++++++++++++++++++++ 1 file changed, 26 insertions(+)Documentation/kbuild/kconfig-language.rst +0
-0@@ -573,6 +573,32 @@ above, leading to: bool "Support for foo hardware" depends on ARCH_FOO_VENDOR || COMPILE_TESTQuoted 11 lines
Documentation/kbuild/kconfig-language.rst above, leading to: · line 584
Quoted 9 lines
Documentation/kbuild/kconfig-language.rst +9
-0+Optional dependencies +~~~~~~~~~~~~~~~~~~~~~ + +Some drivers are able to optionally use a feature from another module +or build cleanly with that module disabled, but cause a link failure +when trying to use that loadable module from a built-in driver. + +The most common way to express this optional dependency in Kconfig logic +uses the slighly counterintuitiveslighly -> slightly
Fixed, thanks
Quoted 2 lines
For better RST compliance: could you explicitly start the code block e.g. by appending '::' as in "... counterintuitive::"?
Ok, done.
Quoted 11 lines
Documentation/kbuild/kconfig-language.rst above, leading to: · line 588
Quoted 4 lines
Documentation/kbuild/kconfig-language.rst +4
-0+ + config FOO + bool "Support for foo hardware" + depends on BAR || !BARare you sure that this is enough? While testing, I needed to explicitly use =y|=n:
depends on BAR=y || BAR=nto prevent FOO to be selectable iff BAR=m.
I see my problem, I made a different mistake here. Your version is correct for a 'bool' symbol as I had here, but the intention of this was to make it work for tristate symbols, which are the interesting case. I've fixed it up this way now, hope it now makes sense to you:
Documentation/kbuild/kconfig-language.rst +1
-1@@ -581,19 +581,19 @@ or build cleanly with that module disabled, but cause a link failure when trying to use that loadable module from a built-in driver. The most common way to express this optional dependency in Kconfig logic -uses the slighly counterintuitive +uses the slightly counterintuitive::
Quoted 6 lines
Documentation/kbuild/kconfig-language.rst or build cleanly with that module disabled, but cause a link failure · line 588
Quoted 4 lines
Documentation/kbuild/kconfig-language.rst +1
-1config FOO - bool "Support for foo hardware" + tristate "Support for foo hardware" depends on BAR || !BARah, thanks, tristate kconfig symbols are really more interesting.
Both FOO and BAR MUST be tristate
to make this documentation sensible.
If FOO is bool type, "depends on BAR || !BAR"
becomes a no-op.
As you notice, FOO and BAR become independent of
each other.
You may wonder why.
Here, another unclear rule applies:
'depends on m' for a bool option is promoted to
'depends on y'.
https://github.com/torvalds/linux/blob/v6.5/scripts/kconfig/symbol.c#L214
Signature · 2 lines
Best Regards Masahiro Yamada
Quoted 8 lines · Arnd Bergmann
From: Arnd Bergmann <[email protected]>
This problem frequently comes up in randconfig testing, with drivers failing to link because of a dependency on an optional feature.
The
Kconfiglanguage for this is very confusing, so try to document it in "Kconfighints" section.
Thanks for doing this.
Quoted 17 lines
Signed-off-by Arnd Bergmann <[email protected]>--- Documentation/kbuild/kconfig-language.rst | 26 +++++++++++++++++++++++ 1 file changed, 26 insertions(+)Documentation/kbuild/kconfig-language.rst +3
-0@@ -573,6 +573,32 @@ above, leading to: bool "Support for foo hardware" depends on ARCH_FOO_VENDOR || COMPILE_TEST +Optional dependencies +~~~~~~~~~~~~~~~~~~~~~ +
Documentation/kbuild/kconfig-language.rst above, leading to: · line 588
Quoted 10 lines
Documentation/kbuild/kconfig-language.rst +10
-0+Some drivers are able to optionally use a feature from another module +or build cleanly with that module disabled, but cause a link failure +when trying to use that loadable module from a built-in driver. + +The most common way to express this optional dependency in Kconfig logic +uses the slighly counterintuitive + + config FOO + bool "Support for foo hardware" + depends on BAR || !BAR
depends on BAR || BAR=n
seems to be an alternative that's about as common:
$ git grep "depends on \([A-Z0-9_]\+\) || \!\1" | wc -l 109 $ git grep "depends on \([A-Z0-9_]\+\) || \1=n" | wc -l 107
Maybe worth mentioning both?
BR,
Jani.
Quoted 15 lines
Documentation/kbuild/kconfig-language.rst +13
-0+ +This means that there is either a dependency on BAR that disallows +the combination of FOO=y with BAR=m, or BAR is completely disabled. +For a more formalized approach if there are multiple drivers that have +the same dependency, a helper symbol can be used, like + + config FOO + bool "Support for foo hardware" + depends on BAR_OPTIONAL + + config BAR_OPTIONAL + def_tristate BAR || !BAR + Kconfig recursive dependency limitations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Signature · 1 line
Jani Nikula, Intel
Quoted 19 lines · Jani Nikula
Quoted 5 lines · Arnd Bergmann
From: Arnd Bergmann <[email protected]>
Documentation/kbuild/kconfig-language.rst +3
-0+Optional dependencies +~~~~~~~~~~~~~~~~~~~~~ +Documentation/kbuild/kconfig-language.rst above, leading to: · line 588
Quoted 10 lines
Documentation/kbuild/kconfig-language.rst +10
-0+Some drivers are able to optionally use a feature from another module +or build cleanly with that module disabled, but cause a link failure +when trying to use that loadable module from a built-in driver. + +The most common way to express this optional dependency in Kconfig logic +uses the slighly counterintuitive + + config FOO + bool "Support for foo hardware" + depends on BAR || !BARdepends on BAR || BAR=n
Quoted 8 lines
seems to be an alternative that's about as common:
$ git grep "depends on \([A-Z0-9_]\+\) || \!\1" | wc -l 109 $ git grep "depends on \([A-Z0-9_]\+\) || \1=n" | wc -l 107Maybe worth mentioning both?
I fear that would add more confusion than it avoids:
"!BAR" is actually different from "BAR=n", but "BAR || !BAR" is the same as "BAR || BAR=n" here, and trying to explain this in the documentation would either make it incorrect or unhelpfully complicated.
Arnd
Quoted 27 lines · Arnd Bergmann
Quoted 26 lines · Jani Nikula
Quoted 5 lines · Arnd Bergmann
From: Arnd Bergmann <[email protected]>
Documentation/kbuild/kconfig-language.rst +3
-0+Optional dependencies +~~~~~~~~~~~~~~~~~~~~~ +Documentation/kbuild/kconfig-language.rst above, leading to: · line 588
Quoted 10 lines
Documentation/kbuild/kconfig-language.rst +10
-0+Some drivers are able to optionally use a feature from another module +or build cleanly with that module disabled, but cause a link failure +when trying to use that loadable module from a built-in driver. + +The most common way to express this optional dependency in Kconfig logic +uses the slighly counterintuitive + + config FOO + bool "Support for foo hardware" + depends on BAR || !BARdepends on BAR || BAR=nseems to be an alternative that's about as common:
$ git grep "depends on \([A-Z0-9_]\+\) || \!\1" | wc -l 109 $ git grep "depends on \([A-Z0-9_]\+\) || \1=n" | wc -l 107
Quoted 4 lines
Quoted 1 line
Maybe worth mentioning both?
I fear that would add more confusion than it avoids:
"!BAR" is actually different from "BAR=n", but
*head explodes*
Quoted 3 lines
"BAR || !BAR" is the same as "BAR || BAR=n" here, and trying to explain this in the documentation would either make it incorrect or unhelpfully complicated.
Fair enough.
BR,
Jani.
Signature · 1 line
Jani Nikula, Intel
Quoted 28 lines · Arnd Bergmann
Quoted 26 lines · Jani Nikula
Quoted 5 lines · Arnd Bergmann
From: Arnd Bergmann <[email protected]>
Documentation/kbuild/kconfig-language.rst +3
-0+Optional dependencies +~~~~~~~~~~~~~~~~~~~~~ +Documentation/kbuild/kconfig-language.rst above, leading to: · line 588
Quoted 10 lines
Documentation/kbuild/kconfig-language.rst +10
-0+Some drivers are able to optionally use a feature from another module +or build cleanly with that module disabled, but cause a link failure +when trying to use that loadable module from a built-in driver. + +The most common way to express this optional dependency in Kconfig logic +uses the slighly counterintuitive + + config FOO + bool "Support for foo hardware" + depends on BAR || !BARdepends on BAR || BAR=nseems to be an alternative that's about as common:
$ git grep "depends on \([A-Z0-9_]\+\) || \!\1" | wc -l 109 $ git grep "depends on \([A-Z0-9_]\+\) || \1=n" | wc -l 107
Quoted 7 lines
Quoted 1 line
Maybe worth mentioning both?
I fear that would add more confusion than it avoids:
"!BAR" is actually different from "BAR=n", but "BAR || !BAR" is the same as "BAR || BAR=n" here, and trying to explain this in the documentation would either make it incorrect or unhelpfully complicated.
The rules are already explained in line 231-278 of Documentation/kbuild/kconfig-language.rst
y, m, n are internally 2, 1, 0.
!A returns (2 - A).
A=B returns 2 if the equation is true, 0 otherwise. A||B returns max(A,B)
Given those in my mind, this is simple math.
For each case of BAR=y, =m, =n,
BAR 2 1 0 !BAR 0 1 2 BAR=n 0 0 2 BAR||!BAR 2 1 2 BAR||BAR=n 2 1 2 BAR!=m||m 2 1 2
So, the last three are equivalent.
They are equally complicated and confusing, though.
After all, what we are doing is to create this matrix:
| WIREGUARD
| y m n
----------------------------
y | O O O
IPV6 m | X O O
n | O O OIt is unclear why WIREGUARD must be entirely disabled just because of the optional feature being modular.
My preference is to use IS_REACHABLE(CONFIG_IPV6) instead of IS_ENABLED(CONFIG_IPV6)
under drivers/net/wireguard, then
get rid of "depends on IPV6 || !IPV6)
If you want to make it clearer on the Kconfig level, perhaps the following is also possible.
config WIREGUARD
tristate "WireGuard"
config WIREGUARD_IPV6
def_bool y
depends on WIREGUARD
depends on IPV6 >= WIREGUARD
config IPV6
tristate "IPV6"
Signature · 2 lines
Best Regards Masahiro Yamada
Quoted 5 lines · Masahiro Yamada
Quoted 1 line · Arnd Bergmann
On Thu, Sep 14, 2023, at 15:42, Jani Nikula wrote:
It is unclear why WIREGUARD must be entirely disabled just because of the optional feature being modular.
I don't think anyone is asking for that, and the current "depends on IPV6 || !IPV6" seems fine here, and is consistent with dozens of other symbols.
Quoted 4 lines
My preference is to use
IS_REACHABLE(CONFIG_IPV6)
instead ofIS_ENABLED(CONFIG_IPV6)
underdrivers/net/wireguard, then
get rid of "depends on IPV6 || !IPV6)
My feeling is that this would be significantly worse from a usability point of view even if it made it a little easier for maintainers:
When a user selects both IPV6 and WIREGUARD, they expect to be able to use them together, and a normal user setting WIREGUARD=y would have a hard time figuring out why that leads it becoming IPv4-only.
Quoted 7 lines
If you want to make it clearer on the
Kconfiglevel, perhaps the following is also possible.config WIREGUARD
tristate "WireGuard"
Quoted 7 lines
config
WIREGUARD_IPV6
def_booly
depends on WIREGUARD
depends on IPV6 >= WIREGUARDconfig IPV6
tristate "IPV6"
That has the same downside, with the added problem of also confusing kernel developers with the '>=' Kconfig syntax, which IMHO makes no sense unless one knows way too much about Kconfig internals.
Arnd
Quoted 16 lines · Arnd Bergmann
Quoted 5 lines · Masahiro Yamada
Quoted 1 line · Arnd Bergmann
On Thu, Sep 14, 2023, at 15:42, Jani Nikula wrote:
It is unclear why WIREGUARD must be entirely disabled just because of the optional feature being modular.
I don't think anyone is asking for that, and the current "depends on IPV6 || !IPV6" seems fine here, and is consistent with dozens of other symbols.
Quoted 4 lines
My preference is to use
IS_REACHABLE(CONFIG_IPV6)
instead ofIS_ENABLED(CONFIG_IPV6)
underdrivers/net/wireguard, then
get rid of "depends on IPV6 || !IPV6)
Quoted 8 lines
My feeling is that this would be significantly worse from a usability point of view even if it made it a little easier for maintainers:
When a user selects both IPV6 and WIREGUARD, they expect to be able to use them together, and a normal user setting WIREGUARD=y would have a hard time figuring out why that leads it becoming IPv4-only.
I think IS_REACHABLE() is in most cases just plain wrong, and should only be used as the last resort.
I think the kconfig should express what the dependencies are, and you should get kconfig or build errors if you get it wrong, and not paper over them with IS_REACHABLE().
Configuring the kernel is hard enough, and IS_REACHABLE() silences the issues with no messages to the user at any point. If the user gets it wrong, it just doesn't work like they expect, they have no clues why, and they have to peruse the kernel source to figure it out. (Or, more likely, file a bug and waste the kernel developer/maintainer time to get the configuration right.)
IS_REACHABLE() considered harmful.
BR,
Jani.
Quoted 22 lines
Quoted 8 lines
If you want to make it clearer on the
Kconfiglevel, perhaps the following is also possible.config WIREGUARD
tristate "WireGuard"Quoted 7 lines
config
WIREGUARD_IPV6
def_booly
depends on WIREGUARD
depends on IPV6 >= WIREGUARDconfig IPV6
tristate "IPV6"That has the same downside, with the added problem of also confusing kernel developers with the '>='
Kconfigsyntax, which IMHO makes no sense unless one knows way too much aboutKconfiginternals.Arnd
Signature · 1 line
Jani Nikula, Intel
Quoted 2 lines · Jani Nikula
IS_REACHABLE()considered harmful.
Absolutely agreed, and I'm sorry I introduced it in the first place in commit 9b174527e7b75 ("[media] Add and use IS_REACHABLE macro").
At the time, it was only used by drivers/media, which used to have a lot of open-coded instances of it and a lot of wrong checks.
Having a formal syntax for it was an improvement for drivers/media since it was more broken before, but it's usually a mistake to use it when there is another solution, and we probably should have tried harder to fix the dependencies in drivers/media at the time.
Arnd
Randy Dunlap
reviewerQuoted 4 lines · Arnd Bergmann
Quoted 2 lines · Jani Nikula
IS_REACHABLE()considered harmful.
+1 absolutely.
Quoted 15 lines
Absolutely agreed, and I'm sorry I introduced it in the first place in commit
9b174527e7b75("[media] Add and useIS_REACHABLEmacro").At the time, it was only used by
drivers/media, which used to have a lot of open-coded instances of it and a lot of wrong checks.Having a formal syntax for it was an improvement for
drivers/mediasince it was more broken before, but it's usually a mistake to use it when there is another solution, and we probably should have tried harder to fix the dependencies indrivers/mediaat the time.Arnd
Signature · 1 line
~Randy