Docs: Omit kconfig configurations not available for the target
This commit is contained in:
parent
86034ad049
commit
5454c268f7
|
@ -1,4 +1,5 @@
|
||||||
menu "Bluetooth"
|
menu "Bluetooth"
|
||||||
|
visible if IDF_TARGET_ESP32
|
||||||
|
|
||||||
config BT_ENABLED
|
config BT_ENABLED
|
||||||
bool "Bluetooth"
|
bool "Bluetooth"
|
||||||
|
@ -432,6 +433,7 @@ endmenu
|
||||||
|
|
||||||
menuconfig BLE_MESH
|
menuconfig BLE_MESH
|
||||||
bool "ESP BLE Mesh Support"
|
bool "ESP BLE Mesh Support"
|
||||||
|
depends on BT_ENABLED
|
||||||
help
|
help
|
||||||
This option enables ESP BLE Mesh support. The specific features that are
|
This option enables ESP BLE Mesh support. The specific features that are
|
||||||
available may depend on other features that have been enabled in the
|
available may depend on other features that have been enabled in the
|
||||||
|
|
|
@ -83,6 +83,7 @@ menu "Driver configurations"
|
||||||
endmenu # UART Configuration
|
endmenu # UART Configuration
|
||||||
|
|
||||||
menu "RTCIO configuration"
|
menu "RTCIO configuration"
|
||||||
|
visible if IDF_TARGET_ESP32
|
||||||
|
|
||||||
config RTCIO_SUPPORT_RTC_GPIO_DESC
|
config RTCIO_SUPPORT_RTC_GPIO_DESC
|
||||||
bool "Support array `rtc_gpio_desc` for ESP32"
|
bool "Support array `rtc_gpio_desc` for ESP32"
|
||||||
|
|
|
@ -95,11 +95,6 @@ kconfigs = find_component_files("../../components", "Kconfig")
|
||||||
kconfig_projbuilds = find_component_files("../../components", "Kconfig.projbuild")
|
kconfig_projbuilds = find_component_files("../../components", "Kconfig.projbuild")
|
||||||
sdkconfig_renames = find_component_files("../../components", "sdkconfig.rename")
|
sdkconfig_renames = find_component_files("../../components", "sdkconfig.rename")
|
||||||
|
|
||||||
# trim the esp32s2 component, until we have proper multi-target support
|
|
||||||
kconfigs = [k for k in kconfigs if "esp32s2" not in k]
|
|
||||||
kconfig_projbuilds = [k for k in kconfig_projbuilds if "esp32s2" not in k]
|
|
||||||
sdkconfig_renames = [r for r in sdkconfig_renames if "esp32s2" not in r]
|
|
||||||
|
|
||||||
kconfigs_source_path = '{}/inc/kconfigs_source.in'.format(builddir)
|
kconfigs_source_path = '{}/inc/kconfigs_source.in'.format(builddir)
|
||||||
kconfig_projbuilds_source_path = '{}/inc/kconfig_projbuilds_source.in'.format(builddir)
|
kconfig_projbuilds_source_path = '{}/inc/kconfig_projbuilds_source.in'.format(builddir)
|
||||||
|
|
||||||
|
@ -123,6 +118,7 @@ confgen_args = [sys.executable,
|
||||||
"--env", "COMPONENT_KCONFIGS_SOURCE_FILE={}".format(kconfigs_source_path),
|
"--env", "COMPONENT_KCONFIGS_SOURCE_FILE={}".format(kconfigs_source_path),
|
||||||
"--env", "COMPONENT_KCONFIGS_PROJBUILD_SOURCE_FILE={}".format(kconfig_projbuilds_source_path),
|
"--env", "COMPONENT_KCONFIGS_PROJBUILD_SOURCE_FILE={}".format(kconfig_projbuilds_source_path),
|
||||||
"--env", "IDF_PATH={}".format(idf_path),
|
"--env", "IDF_PATH={}".format(idf_path),
|
||||||
|
"--env", "IDF_TARGET={}".format(os.environ.get('IDF_TARGET', 'esp32')),
|
||||||
"--output", "docs", kconfig_inc_path + '.in'
|
"--output", "docs", kconfig_inc_path + '.in'
|
||||||
]
|
]
|
||||||
subprocess.check_call(confgen_args)
|
subprocess.check_call(confgen_args)
|
||||||
|
|
|
@ -160,9 +160,15 @@ test_multi_heap_on_host:
|
||||||
test_confserver:
|
test_confserver:
|
||||||
extends: .host_test_template
|
extends: .host_test_template
|
||||||
script:
|
script:
|
||||||
- cd tools/kconfig_new/test
|
- cd tools/kconfig_new/test/confserver
|
||||||
- ${IDF_PATH}/tools/ci/multirun_with_pyenv.sh ./test_confserver.py
|
- ${IDF_PATH}/tools/ci/multirun_with_pyenv.sh ./test_confserver.py
|
||||||
|
|
||||||
|
test_gen_kconfig_doc:
|
||||||
|
extends: .host_test_template
|
||||||
|
script:
|
||||||
|
- cd tools/kconfig_new/test/gen_kconfig_doc/
|
||||||
|
- ${IDF_PATH}/tools/ci/multirun_with_pyenv.sh ./test_target_visibility.py
|
||||||
|
|
||||||
test_idf_monitor:
|
test_idf_monitor:
|
||||||
extends: .host_test_template
|
extends: .host_test_template
|
||||||
artifacts:
|
artifacts:
|
||||||
|
|
|
@ -75,7 +75,8 @@ tools/kconfig/merge_config.sh
|
||||||
tools/kconfig/streamline_config.pl
|
tools/kconfig/streamline_config.pl
|
||||||
tools/kconfig_new/confgen.py
|
tools/kconfig_new/confgen.py
|
||||||
tools/kconfig_new/confserver.py
|
tools/kconfig_new/confserver.py
|
||||||
tools/kconfig_new/test/test_confserver.py
|
tools/kconfig_new/test/confserver/test_confserver.py
|
||||||
|
tools/kconfig_new/test/gen_kconfig_doc/test_target_visibility.py
|
||||||
tools/ldgen/ldgen.py
|
tools/ldgen/ldgen.py
|
||||||
tools/ldgen/test/test_fragments.py
|
tools/ldgen/test/test_fragments.py
|
||||||
tools/ldgen/test/test_generation.py
|
tools/ldgen/test/test_generation.py
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
# Used internally by the ESP-IDF build system. But designed to be
|
# Used internally by the ESP-IDF build system. But designed to be
|
||||||
# non-IDF-specific.
|
# non-IDF-specific.
|
||||||
#
|
#
|
||||||
# Copyright 2018 Espressif Systems (Shanghai) PTE LTD
|
# Copyright 2018-2020 Espressif Systems (Shanghai) PTE LTD
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
|
@ -112,10 +112,10 @@ class DeprecatedOptions(object):
|
||||||
print('{}:{} {} was replaced with {}'.format(sdkconfig_in, line_num, depr_opt, new_opt))
|
print('{}:{} {} was replaced with {}'.format(sdkconfig_in, line_num, depr_opt, new_opt))
|
||||||
f_out.write(line)
|
f_out.write(line)
|
||||||
|
|
||||||
def append_doc(self, config, path_output):
|
def append_doc(self, config, visibility, path_output):
|
||||||
|
|
||||||
def option_was_written(opt):
|
def option_was_written(opt):
|
||||||
return any(gen_kconfig_doc.node_should_write(node) for node in config.syms[opt].nodes)
|
return any(visibility.visible(node) for node in config.syms[opt].nodes)
|
||||||
|
|
||||||
if len(self.r_dic) > 0:
|
if len(self.r_dic) > 0:
|
||||||
with open(path_output, 'a') as f_o:
|
with open(path_output, 'a') as f_o:
|
||||||
|
@ -572,8 +572,15 @@ def write_json_menus(deprecated_options, config, filename):
|
||||||
|
|
||||||
|
|
||||||
def write_docs(deprecated_options, config, filename):
|
def write_docs(deprecated_options, config, filename):
|
||||||
gen_kconfig_doc.write_docs(config, filename)
|
try:
|
||||||
deprecated_options.append_doc(config, filename)
|
target = os.environ['IDF_TARGET']
|
||||||
|
except KeyError:
|
||||||
|
print('IDF_TARGET environment variable must be defined!')
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
visibility = gen_kconfig_doc.ConfigTargetVisibility(config, target)
|
||||||
|
gen_kconfig_doc.write_docs(config, visibility, filename)
|
||||||
|
deprecated_options.append_doc(config, visibility, filename)
|
||||||
|
|
||||||
|
|
||||||
def update_if_changed(source, destination):
|
def update_if_changed(source, destination):
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
# generated, allowing options to be referenced in other documents
|
# generated, allowing options to be referenced in other documents
|
||||||
# (using :ref:`CONFIG_FOO`)
|
# (using :ref:`CONFIG_FOO`)
|
||||||
#
|
#
|
||||||
# Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
|
# Copyright 2017-2020 Espressif Systems (Shanghai) PTE LTD
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
|
@ -42,13 +42,126 @@ INITIAL_HEADING_LEVEL = 3
|
||||||
MAX_HEADING_LEVEL = len(HEADING_SYMBOLS) - 1
|
MAX_HEADING_LEVEL = len(HEADING_SYMBOLS) - 1
|
||||||
|
|
||||||
|
|
||||||
def write_docs(config, filename):
|
class ConfigTargetVisibility(object):
|
||||||
|
"""
|
||||||
|
Determine the visibility of Kconfig options based on IDF targets. Note that other environment variables should not
|
||||||
|
imply invisibility and neither dependencies on visible options with default disabled state. This difference makes
|
||||||
|
it necessary to implement our own visibility and cannot use the visibility defined inside Kconfiglib.
|
||||||
|
"""
|
||||||
|
def __init__(self, config, target):
|
||||||
|
# target actually is not necessary here because kconfiglib.expr_value() will evaluate it internally
|
||||||
|
self.config = config
|
||||||
|
self.visibility = dict() # node name to (x, y) mapping where x is the visibility (True/False) and y is the
|
||||||
|
# name of the config which implies the visibility
|
||||||
|
self.target_env_var = 'IDF_TARGET'
|
||||||
|
self.direct_eval_set = frozenset([kconfiglib.EQUAL, kconfiglib.UNEQUAL, kconfiglib.LESS, kconfiglib.LESS_EQUAL,
|
||||||
|
kconfiglib.GREATER, kconfiglib.GREATER_EQUAL])
|
||||||
|
|
||||||
|
def _implies_invisibility(self, item):
|
||||||
|
if isinstance(item, tuple):
|
||||||
|
if item[0] == kconfiglib.NOT:
|
||||||
|
(invisibility, source) = self._implies_invisibility(item[1])
|
||||||
|
if source is not None and source.startswith(self.target_env_var):
|
||||||
|
return (not invisibility, source)
|
||||||
|
else:
|
||||||
|
# we want to be visible all configs which are not dependent on target variables,
|
||||||
|
# e.g. "depends on XY" and "depends on !XY" as well
|
||||||
|
return (False, None)
|
||||||
|
elif item[0] == kconfiglib.AND:
|
||||||
|
(invisibility, source) = self._implies_invisibility(item[1])
|
||||||
|
if invisibility:
|
||||||
|
return (True, source)
|
||||||
|
(invisibility, source) = self._implies_invisibility(item[2])
|
||||||
|
if invisibility:
|
||||||
|
return (True, source)
|
||||||
|
return (False, None)
|
||||||
|
elif item[0] == kconfiglib.OR:
|
||||||
|
implication_list = [self._implies_invisibility(item[1]), self._implies_invisibility(item[2])]
|
||||||
|
if all([implies for (implies, _) in implication_list]):
|
||||||
|
source_list = [s for (_, s) in implication_list if s.startswith(self.target_env_var)]
|
||||||
|
if len(set(source_list)) != 1: # set removes the duplicates
|
||||||
|
print('[WARNING] list contains targets: {}'.format(source_list))
|
||||||
|
return (True, source_list[0])
|
||||||
|
return (False, None)
|
||||||
|
elif item[0] in self.direct_eval_set:
|
||||||
|
def node_is_invisible(item):
|
||||||
|
return all([node.prompt is None for node in item.nodes])
|
||||||
|
if node_is_invisible(item[1]) or node_is_invisible(item[1]):
|
||||||
|
# it makes no sense to call self._implies_invisibility() here because it won't generate any useful
|
||||||
|
# "source"
|
||||||
|
return (not kconfiglib.expr_value(item), None)
|
||||||
|
else:
|
||||||
|
# expressions with visible configs can be changed to make the item visible
|
||||||
|
return (False, None)
|
||||||
|
else:
|
||||||
|
raise RuntimeError('Unimplemented operation in {}'.format(item))
|
||||||
|
else: # Symbol or Choice
|
||||||
|
vis_list = [self._visible(node) for node in item.nodes]
|
||||||
|
if len(vis_list) > 0 and all([not visible for (visible, _) in vis_list]):
|
||||||
|
source_list = [s for (_, s) in vis_list if s is not None and s.startswith(self.target_env_var)]
|
||||||
|
if len(set(source_list)) != 1: # set removes the duplicates
|
||||||
|
print('[WARNING] list contains targets: {}'.format(source_list))
|
||||||
|
return (True, source_list[0])
|
||||||
|
|
||||||
|
if item.name.startswith(self.target_env_var):
|
||||||
|
return (not kconfiglib.expr_value(item), item.name)
|
||||||
|
|
||||||
|
if len(vis_list) == 1:
|
||||||
|
(visible, source) = vis_list[0]
|
||||||
|
if visible:
|
||||||
|
return (False, item.name) # item.name is important here in case the result will be inverted: if
|
||||||
|
# the dependency is on another config then it can be still visible
|
||||||
|
|
||||||
|
return (False, None)
|
||||||
|
|
||||||
|
def _visible(self, node):
|
||||||
|
if isinstance(node.item, kconfiglib.Symbol) or isinstance(node.item, kconfiglib.Choice):
|
||||||
|
dependencies = node.item.direct_dep # "depends on" for configs
|
||||||
|
name_id = node.item.name
|
||||||
|
simple_def = len(node.item.nodes) <= 1 # defined only in one source file
|
||||||
|
# Probably it is not necessary to check the default statements.
|
||||||
|
else:
|
||||||
|
dependencies = node.visibility # "visible if" for menu
|
||||||
|
name_id = node.prompt[0]
|
||||||
|
simple_def = False # menus can be defined with the same name at multiple locations and they don't know
|
||||||
|
# about each other like configs through node.item.nodes. Therefore, they cannot be stored and have to be
|
||||||
|
# re-evaluated always.
|
||||||
|
|
||||||
|
try:
|
||||||
|
(visib, source) = self.visibility[name_id]
|
||||||
|
except KeyError:
|
||||||
|
def invert_first_arg(_tuple):
|
||||||
|
return (not _tuple[0], _tuple[1])
|
||||||
|
|
||||||
|
(visib, source) = self._visible(node.parent) if node.parent else (True, None)
|
||||||
|
|
||||||
|
if visib:
|
||||||
|
(visib, source) = invert_first_arg(self._implies_invisibility(dependencies))
|
||||||
|
|
||||||
|
if simple_def:
|
||||||
|
# Configs defined at multiple places are not stored because they could have different visibility based
|
||||||
|
# on different targets. kconfiglib.expr_value() will handle the visibility.
|
||||||
|
self.visibility[name_id] = (visib, source)
|
||||||
|
|
||||||
|
return (visib, source) # not used in "finally" block because failure messages from _implies_invisibility are
|
||||||
|
# this way more understandable
|
||||||
|
|
||||||
|
def visible(self, node):
|
||||||
|
if not node.prompt:
|
||||||
|
# don't store this in self.visibility because don't want to stop at invisible nodes when recursively
|
||||||
|
# searching for invisible targets
|
||||||
|
return False
|
||||||
|
|
||||||
|
return self._visible(node)[0]
|
||||||
|
|
||||||
|
|
||||||
|
def write_docs(config, visibility, filename):
|
||||||
""" Note: writing .rst documentation ignores the current value
|
""" Note: writing .rst documentation ignores the current value
|
||||||
of any items. ie the --config option can be ignored.
|
of any items. ie the --config option can be ignored.
|
||||||
(However at time of writing it still needs to be set to something...) """
|
(However at time of writing it still needs to be set to something...) """
|
||||||
with open(filename, "w") as f:
|
with open(filename, "w") as f:
|
||||||
for node in config.node_iter():
|
for node in config.node_iter():
|
||||||
write_menu_item(f, node)
|
write_menu_item(f, node, visibility)
|
||||||
|
|
||||||
|
|
||||||
def node_is_menu(node):
|
def node_is_menu(node):
|
||||||
|
@ -108,18 +221,12 @@ def format_rest_text(text, indent):
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
|
||||||
def node_should_write(node):
|
def write_menu_item(f, node, visibility):
|
||||||
if not node.prompt:
|
def is_choice(node):
|
||||||
return False # Don't do anything for invisible menu items
|
""" Skip choice nodes, they are handled as part of the parent (see below) """
|
||||||
|
return isinstance(node.parent.item, kconfiglib.Choice)
|
||||||
|
|
||||||
if isinstance(node.parent.item, kconfiglib.Choice):
|
if is_choice(node) or not visibility.visible(node):
|
||||||
return False # Skip choice nodes, they are handled as part of the parent (see below)
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def write_menu_item(f, node):
|
|
||||||
if not node_should_write(node):
|
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -175,7 +282,7 @@ def write_menu_item(f, node):
|
||||||
child = node.list
|
child = node.list
|
||||||
while child:
|
while child:
|
||||||
try:
|
try:
|
||||||
if node_should_write(child):
|
if not is_choice(child) and child.prompt and visibility.visible(child):
|
||||||
if first:
|
if first:
|
||||||
f.write("Contains:\n\n")
|
f.write("Contains:\n\n")
|
||||||
first = False
|
first = False
|
||||||
|
|
|
@ -56,12 +56,12 @@ def main():
|
||||||
with tempfile.NamedTemporaryFile(delete=False) as f:
|
with tempfile.NamedTemporaryFile(delete=False) as f:
|
||||||
temp_kconfig_projbuilds_source_file = os.path.join(tempfile.gettempdir(), f.name)
|
temp_kconfig_projbuilds_source_file = os.path.join(tempfile.gettempdir(), f.name)
|
||||||
|
|
||||||
cmdline = '''../confserver.py --env "COMPONENT_KCONFIGS_SOURCE_FILE=%s" \
|
cmdline = '''../../confserver.py --env "COMPONENT_KCONFIGS_SOURCE_FILE=%s" \
|
||||||
--env "COMPONENT_KCONFIGS_PROJBUILD_SOURCE_FILE=%s" \
|
--env "COMPONENT_KCONFIGS_PROJBUILD_SOURCE_FILE=%s" \
|
||||||
--env "COMPONENT_KCONFIGS=" \
|
--env "COMPONENT_KCONFIGS=" \
|
||||||
--env "COMPONENT_KCONFIGS_PROJBUILD=" \
|
--env "COMPONENT_KCONFIGS_PROJBUILD=" \
|
||||||
--kconfig Kconfig \
|
--kconfig Kconfig \
|
||||||
--config %s \
|
--config %s \
|
||||||
''' % (temp_kconfigs_source_file, temp_kconfig_projbuilds_source_file, temp_sdkconfig_path)
|
''' % (temp_kconfigs_source_file, temp_kconfig_projbuilds_source_file, temp_sdkconfig_path)
|
||||||
|
|
||||||
cmdline = re.sub(r' +', ' ', cmdline)
|
cmdline = re.sub(r' +', ' ', cmdline)
|
137
tools/kconfig_new/test/gen_kconfig_doc/Kconfig
Normal file
137
tools/kconfig_new/test/gen_kconfig_doc/Kconfig
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
config IDF_TARGET
|
||||||
|
string
|
||||||
|
default "$IDF_TARGET"
|
||||||
|
|
||||||
|
config IDF_TARGET_CHIPA
|
||||||
|
bool
|
||||||
|
default "y" if IDF_TARGET="chipa"
|
||||||
|
|
||||||
|
config IDF_TARGET_CHIPB
|
||||||
|
bool
|
||||||
|
default "y" if IDF_TARGET="chipb"
|
||||||
|
|
||||||
|
config ALWAYS_VISIBLE
|
||||||
|
bool "Always visible option"
|
||||||
|
|
||||||
|
choice ALWAYS_VISIBLE_CHOICE
|
||||||
|
prompt "Always visible choice"
|
||||||
|
default ALWAYS_VISIBLE_CHOICE_OP1
|
||||||
|
|
||||||
|
config ALWAYS_VISIBLE_CHOICE_OP1
|
||||||
|
bool "op1"
|
||||||
|
|
||||||
|
config ALWAYS_VISIBLE_CHOICE_OP2
|
||||||
|
bool "op2"
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
config CONFIG_FOR_CHIPA
|
||||||
|
bool "Config for chip A"
|
||||||
|
depends on IDF_TARGET_CHIPA
|
||||||
|
default n
|
||||||
|
|
||||||
|
config CONFIG_FOR_CHIPB
|
||||||
|
bool "Config for chip B"
|
||||||
|
depends on IDF_TARGET_CHIPB
|
||||||
|
|
||||||
|
choice CHOICE_FOR_CHIPA
|
||||||
|
prompt "Always visible choice"
|
||||||
|
default CHOICE_FOR_CHIPA_OP1
|
||||||
|
depends on IDF_TARGET_CHIPA
|
||||||
|
|
||||||
|
config CHOICE_FOR_CHIPA_OP1
|
||||||
|
bool "op1"
|
||||||
|
|
||||||
|
config CHOICE_FOR_CHIPA_OP2
|
||||||
|
bool "op2"
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
choice CHOICE_FOR_CHIPB
|
||||||
|
prompt "Always visible choice"
|
||||||
|
default CHOICE_FOR_CHIPB_OP1
|
||||||
|
depends on IDF_TARGET_CHIPB
|
||||||
|
|
||||||
|
config CHOICE_FOR_CHIPB_OP1
|
||||||
|
bool "op1"
|
||||||
|
|
||||||
|
config CHOICE_FOR_CHIPB_OP2
|
||||||
|
bool "op2"
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
source "Kconfig.chipa"
|
||||||
|
source "Kconfig.chipb"
|
||||||
|
|
||||||
|
config DEEP_DEPENDENT_CONFIG
|
||||||
|
bool "Config depends on another config with default no value"
|
||||||
|
depends on CONFIG_FOR_CHIPA
|
||||||
|
|
||||||
|
config DEEP_DEPENDENT_CONFIG_INV
|
||||||
|
bool "Config depends on the inverted value of another config"
|
||||||
|
depends on !CONFIG_FOR_CHIPA
|
||||||
|
|
||||||
|
choice DEEP_DEPENDENT_CHOICE
|
||||||
|
prompt "depends on target-specific config"
|
||||||
|
default DEEP_DEPENDENT_CHOICE_OP1
|
||||||
|
depends on DEEP_DEPENDENT_CONFIG
|
||||||
|
|
||||||
|
config DEEP_DEPENDENT_CHOICE_OP1
|
||||||
|
bool "op1"
|
||||||
|
|
||||||
|
config DEEP_DEPENDENT_CHOICE_OP2
|
||||||
|
bool "op2"
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
config INVISIBLE1
|
||||||
|
bool "depends on cannot be satified at the same time"
|
||||||
|
depends on CONFIG_FOR_CHIPA && IDF_TARGET_CHIPB
|
||||||
|
|
||||||
|
config VISIBLE1
|
||||||
|
bool "makes no sense, just for testing OR dependencies"
|
||||||
|
depends on CONFIG_FOR_CHIPA || IDF_TARGET_CHIPB
|
||||||
|
|
||||||
|
config CONFIG_FOR_CHIPA_DEPENDS_VAR1
|
||||||
|
bool "redundant AND in depends on"
|
||||||
|
depends on CONFIG_FOR_CHIPA && IDF_TARGET_CHIPA
|
||||||
|
|
||||||
|
config CONFIG_FOR_CHIPA_DEPENDS_VAR2
|
||||||
|
bool "test AND + NOT"
|
||||||
|
depends on CONFIG_FOR_CHIPA && !IDF_TARGET_CHIPB
|
||||||
|
|
||||||
|
config CONFIG_FOR_CHIPA_DEPENDS_VAR3
|
||||||
|
bool "test NOT"
|
||||||
|
depends on !IDF_TARGET_CHIPB
|
||||||
|
|
||||||
|
config CONFIG_DEPENDS_ENV_VAR1
|
||||||
|
bool "test other environment variable (should be visible because only IDF_TARGET should make something invisible)"
|
||||||
|
depends on IDF_XYZ
|
||||||
|
|
||||||
|
config CONFIG_DEPENDS_ENV_VAR2
|
||||||
|
bool "test other environment variable (should be visible because only IDF_TARGET should make something invisible)"
|
||||||
|
depends on !IDF_XYZ
|
||||||
|
|
||||||
|
choice CHIPA_VERSION
|
||||||
|
prompt "CHIPA version"
|
||||||
|
default CHIPA_VERSION2
|
||||||
|
depends on CONFIG_FOR_CHIPA
|
||||||
|
|
||||||
|
config CHIPA_VERSION1
|
||||||
|
bool "Version 1"
|
||||||
|
config CHIPA_VERSION2
|
||||||
|
bool "Version 2"
|
||||||
|
config CHIPA_VERSION3
|
||||||
|
bool "Version 3"
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
config CHIPA_REV_MIN
|
||||||
|
int
|
||||||
|
default 1 if CHIPA_VERSION1
|
||||||
|
default 2 if CHIPA_VERSION2
|
||||||
|
default 3 if CHIPA_VERSION3
|
||||||
|
|
||||||
|
config CHIPA_FEATURE_FROM_V1
|
||||||
|
depends on CONFIG_FOR_CHIPA && (CHIPA_REV_MIN <= 1)
|
||||||
|
bool "Feature available from version 1"
|
||||||
|
|
||||||
|
config CHIPA_FEATURE_FROM_V3
|
||||||
|
depends on CONFIG_FOR_CHIPA && (CHIPA_REV_MIN <= 3)
|
||||||
|
bool "Feature available from version 3"
|
||||||
|
|
19
tools/kconfig_new/test/gen_kconfig_doc/Kconfig.chipa
Normal file
19
tools/kconfig_new/test/gen_kconfig_doc/Kconfig.chipa
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
menu "Menu for CHIPA"
|
||||||
|
visible if IDF_TARGET_CHIPA
|
||||||
|
|
||||||
|
config EXT_CONFIG1_FOR_CHIPA_MENU
|
||||||
|
bool "Config for chip A"
|
||||||
|
depends on IDF_TARGET_CHIPA
|
||||||
|
|
||||||
|
config EXT_CONFIG2_FOR_CHIPA_MENU
|
||||||
|
bool "Config for chip A (depend on the visibility of the menu)"
|
||||||
|
|
||||||
|
endmenu
|
||||||
|
|
||||||
|
config EXT_CONFIG3_FOR_CHIPA
|
||||||
|
bool "Config for chip A"
|
||||||
|
depends on IDF_TARGET_CHIPA
|
||||||
|
|
||||||
|
config EXT_CONFIG4
|
||||||
|
bool "Config for every chip (note that the config is defined at multiple places)"
|
||||||
|
depends on IDF_TARGET_CHIPA
|
19
tools/kconfig_new/test/gen_kconfig_doc/Kconfig.chipb
Normal file
19
tools/kconfig_new/test/gen_kconfig_doc/Kconfig.chipb
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
menu "Menu for CHIPB"
|
||||||
|
visible if IDF_TARGET_CHIPB
|
||||||
|
|
||||||
|
config EXT_CONFIG1_FOR_CHIPB_MENU
|
||||||
|
bool "Config for chip B"
|
||||||
|
depends on IDF_TARGET_CHIPB
|
||||||
|
|
||||||
|
config EXT_CONFIG2_FOR_CHIPB_MENU
|
||||||
|
bool "Config for chip B (depend on the visibility of the menu)"
|
||||||
|
|
||||||
|
endmenu
|
||||||
|
|
||||||
|
config EXT_CONFIG3_FOR_CHIPB
|
||||||
|
bool "Config for chip B"
|
||||||
|
depends on IDF_TARGET_CHIPB
|
||||||
|
|
||||||
|
config EXT_CONFIG4
|
||||||
|
bool "Config for every chip (note that the config is defined at multiple places)"
|
||||||
|
depends on IDF_TARGET_CHIPB
|
111
tools/kconfig_new/test/gen_kconfig_doc/test_target_visibility.py
Executable file
111
tools/kconfig_new/test/gen_kconfig_doc/test_target_visibility.py
Executable file
|
@ -0,0 +1,111 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
try:
|
||||||
|
from . import kconfiglib
|
||||||
|
except Exception:
|
||||||
|
sys.path.insert(0, os.path.normpath(os.path.join(os.path.dirname(os.path.realpath(__file__)), '../..')))
|
||||||
|
import kconfiglib
|
||||||
|
import gen_kconfig_doc
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigTargetVisibilityTestCase(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.target = os.environ['IDF_TARGET']
|
||||||
|
self.config = kconfiglib.Kconfig('Kconfig')
|
||||||
|
self.v = gen_kconfig_doc.ConfigTargetVisibility(self.config, self.target)
|
||||||
|
|
||||||
|
def _get_config(self, name):
|
||||||
|
sym = self.config.syms.get(name)
|
||||||
|
if sym:
|
||||||
|
return sym.nodes[0]
|
||||||
|
choice = self.config.named_choices.get(name)
|
||||||
|
if choice:
|
||||||
|
return choice.nodes[0]
|
||||||
|
raise RuntimeError('Unimplemented {}'.format(name))
|
||||||
|
|
||||||
|
def visible(self, config_name):
|
||||||
|
self.assertTrue(self.v.visible(self._get_config(config_name)))
|
||||||
|
|
||||||
|
def invisible(self, config_name):
|
||||||
|
self.assertFalse(self.v.visible(self._get_config(config_name)))
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigTargetVisibilityChipA(ConfigTargetVisibilityTestCase):
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
os.environ['IDF_TARGET'] = 'chipa'
|
||||||
|
|
||||||
|
def test_config_visibility(self):
|
||||||
|
self.invisible('IDF_TARGET')
|
||||||
|
self.invisible('IDF_TARGET_CHIPA')
|
||||||
|
self.visible('ALWAYS_VISIBLE')
|
||||||
|
self.visible('ALWAYS_VISIBLE_CHOICE')
|
||||||
|
self.visible('CONFIG_FOR_CHIPA')
|
||||||
|
self.invisible('CONFIG_FOR_CHIPB')
|
||||||
|
self.visible('CHOICE_FOR_CHIPA')
|
||||||
|
self.invisible('CHOICE_FOR_CHIPB')
|
||||||
|
self.visible('EXT_CONFIG1_FOR_CHIPA_MENU')
|
||||||
|
self.visible('EXT_CONFIG2_FOR_CHIPA_MENU')
|
||||||
|
self.visible('EXT_CONFIG3_FOR_CHIPA')
|
||||||
|
self.invisible('EXT_CONFIG1_FOR_CHIPB_MENU')
|
||||||
|
self.invisible('EXT_CONFIG2_FOR_CHIPB_MENU')
|
||||||
|
self.invisible('EXT_CONFIG3_FOR_CHIPB')
|
||||||
|
self.visible('EXT_CONFIG4')
|
||||||
|
self.visible('DEEP_DEPENDENT_CONFIG')
|
||||||
|
self.visible('DEEP_DEPENDENT_CONFIG_INV')
|
||||||
|
self.visible('DEEP_DEPENDENT_CHOICE')
|
||||||
|
self.invisible('INVISIBLE1')
|
||||||
|
self.visible('VISIBLE1')
|
||||||
|
self.visible('CONFIG_FOR_CHIPA_DEPENDS_VAR1')
|
||||||
|
self.visible('CONFIG_FOR_CHIPA_DEPENDS_VAR2')
|
||||||
|
self.visible('CONFIG_FOR_CHIPA_DEPENDS_VAR3')
|
||||||
|
self.visible('CONFIG_DEPENDS_ENV_VAR1')
|
||||||
|
self.visible('CONFIG_DEPENDS_ENV_VAR2')
|
||||||
|
self.visible('CHIPA_VERSION')
|
||||||
|
self.invisible('CHIPA_REV_MIN')
|
||||||
|
self.visible('CHIPA_FEATURE_FROM_V1')
|
||||||
|
self.visible('CHIPA_FEATURE_FROM_V3')
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigTargetVisibilityChipB(ConfigTargetVisibilityTestCase):
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
os.environ['IDF_TARGET'] = 'chipb'
|
||||||
|
|
||||||
|
def test_config_visibility(self):
|
||||||
|
self.invisible('IDF_TARGET')
|
||||||
|
self.invisible('IDF_TARGET_CHIPA')
|
||||||
|
self.visible('ALWAYS_VISIBLE')
|
||||||
|
self.visible('ALWAYS_VISIBLE_CHOICE')
|
||||||
|
self.invisible('CONFIG_FOR_CHIPA')
|
||||||
|
self.visible('CONFIG_FOR_CHIPB')
|
||||||
|
self.invisible('CHOICE_FOR_CHIPA')
|
||||||
|
self.visible('CHOICE_FOR_CHIPB')
|
||||||
|
self.invisible('EXT_CONFIG1_FOR_CHIPA_MENU')
|
||||||
|
self.invisible('EXT_CONFIG2_FOR_CHIPA_MENU')
|
||||||
|
self.invisible('EXT_CONFIG3_FOR_CHIPA')
|
||||||
|
self.visible('EXT_CONFIG1_FOR_CHIPB_MENU')
|
||||||
|
self.visible('EXT_CONFIG2_FOR_CHIPB_MENU')
|
||||||
|
self.visible('EXT_CONFIG3_FOR_CHIPB')
|
||||||
|
self.visible('EXT_CONFIG4')
|
||||||
|
self.invisible('DEEP_DEPENDENT_CONFIG')
|
||||||
|
self.visible('DEEP_DEPENDENT_CONFIG_INV')
|
||||||
|
self.invisible('DEEP_DEPENDENT_CHOICE')
|
||||||
|
self.invisible('INVISIBLE1')
|
||||||
|
self.visible('VISIBLE1')
|
||||||
|
self.invisible('CONFIG_FOR_CHIPA_DEPENDS_VAR1')
|
||||||
|
self.invisible('CONFIG_FOR_CHIPA_DEPENDS_VAR2')
|
||||||
|
self.invisible('CONFIG_FOR_CHIPA_DEPENDS_VAR3')
|
||||||
|
self.visible('CONFIG_DEPENDS_ENV_VAR1')
|
||||||
|
self.visible('CONFIG_DEPENDS_ENV_VAR2')
|
||||||
|
self.invisible('CHIPA_VERSION')
|
||||||
|
self.invisible('CHIPA_REV_MIN')
|
||||||
|
self.invisible('CHIPA_FEATURE_FROM_V1')
|
||||||
|
self.invisible('CHIPA_FEATURE_FROM_V3')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
Loading…
Reference in a new issue