mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feature/kconfig_backward_comp' into 'master'
Rename deprecated Kconfig options in a backward compatible way Closes IDF-155 See merge request idf/esp-idf!4551
This commit is contained in:
commit
df9113e0e1
6
Kconfig
6
Kconfig
@ -25,14 +25,14 @@ mainmenu "Espressif IoT Development Framework Configuration"
|
||||
|
||||
|
||||
menu "SDK tool configuration"
|
||||
config TOOLPREFIX
|
||||
config SDK_TOOLPREFIX
|
||||
string "Compiler toolchain path/prefix"
|
||||
default "xtensa-esp32-elf-"
|
||||
help
|
||||
The prefix/path that is used to call the toolchain. The default setting assumes
|
||||
a crosstool-ng gcc setup that is in your PATH.
|
||||
|
||||
config PYTHON
|
||||
config SDK_PYTHON
|
||||
string "Python 2 interpreter"
|
||||
depends on !IDF_CMAKE
|
||||
default "python"
|
||||
@ -43,7 +43,7 @@ mainmenu "Espressif IoT Development Framework Configuration"
|
||||
(Note: This option is used with the GNU Make build system only, not idf.py
|
||||
or CMake-based builds.)
|
||||
|
||||
config MAKE_WARN_UNDEFINED_VARIABLES
|
||||
config SDK_MAKE_WARN_UNDEFINED_VARIABLES
|
||||
bool "'make' warns on undefined variables"
|
||||
default "y"
|
||||
help
|
||||
|
@ -8,7 +8,7 @@ ESPFLASHSIZE ?= $(CONFIG_ESPTOOLPY_FLASHSIZE)
|
||||
|
||||
CONFIG_ESPTOOLPY_COMPRESSED ?=
|
||||
|
||||
PYTHON ?= $(call dequote,$(CONFIG_PYTHON))
|
||||
PYTHON ?= $(call dequote,$(CONFIG_SDK_PYTHON))
|
||||
|
||||
# two commands that can be used from other components
|
||||
# to invoke esptool.py (with or without serial port args)
|
||||
@ -99,7 +99,7 @@ simple_monitor: $(call prereq_if_explicit,%flash) | check_python_dependencies
|
||||
|
||||
PRINT_FILTER ?=
|
||||
|
||||
MONITOR_OPTS := --baud $(MONITORBAUD) --port $(ESPPORT) --toolchain-prefix $(CONFIG_TOOLPREFIX) --make "$(MAKE)" --print_filter "$(PRINT_FILTER)"
|
||||
MONITOR_OPTS := --baud $(MONITORBAUD) --port $(ESPPORT) --toolchain-prefix $(CONFIG_SDK_TOOLPREFIX) --make "$(MAKE)" --print_filter "$(PRINT_FILTER)"
|
||||
|
||||
monitor: $(call prereq_if_explicit,%flash) | check_python_dependencies
|
||||
$(summary) MONITOR
|
||||
|
@ -7,7 +7,7 @@ PROJECT_NAME := gcov_example
|
||||
|
||||
include $(IDF_PATH)/make/project.mk
|
||||
|
||||
GCOV := $(call dequote,$(CONFIG_TOOLPREFIX))gcov
|
||||
GCOV := $(call dequote,$(CONFIG_SDK_TOOLPREFIX))gcov
|
||||
REPORT_DIR := $(BUILD_DIR_BASE)/coverage_report
|
||||
|
||||
lcov-report:
|
||||
|
@ -109,7 +109,7 @@ There are several ways to process collected data. Two of the most common are:
|
||||
Add the following lines to you project's `Makefile` after the line including `project.mk`:
|
||||
|
||||
```
|
||||
GCOV := $(call dequote,$(CONFIG_TOOLPREFIX))gcov
|
||||
GCOV := $(call dequote,$(CONFIG_SDK_TOOLPREFIX))gcov
|
||||
REPORT_DIR := $(BUILD_DIR_BASE)/coverage_report
|
||||
|
||||
lcov-report:
|
||||
@ -160,4 +160,4 @@ Overall coverage rate:
|
||||
```
|
||||
|
||||
NOTE: Since `lcov` tool is not part of GCC bundle it can happen that format of GCOV binary data has been changed and your local version of `lcov` fails to understand it.
|
||||
So it always better to use the latest `lcov` version from [LCOV repo](https://github.com/linux-test-project/lcov).
|
||||
So it always better to use the latest `lcov` version from [LCOV repo](https://github.com/linux-test-project/lcov).
|
||||
|
@ -2,7 +2,7 @@
|
||||
# and component makefiles (component_wrapper.mk)
|
||||
#
|
||||
|
||||
PYTHON=$(call dequote,$(CONFIG_PYTHON))
|
||||
PYTHON=$(call dequote,$(CONFIG_SDK_PYTHON))
|
||||
|
||||
# Include project config makefile, if it exists.
|
||||
#
|
||||
@ -34,7 +34,7 @@ details := @true
|
||||
MAKEFLAGS += --silent
|
||||
endif # $(V)==1
|
||||
|
||||
ifdef CONFIG_MAKE_WARN_UNDEFINED_VARIABLES
|
||||
ifdef CONFIG_SDK_MAKE_WARN_UNDEFINED_VARIABLES
|
||||
MAKEFLAGS += --warn-undefined-variables
|
||||
endif
|
||||
|
||||
|
@ -471,13 +471,13 @@ export CFLAGS CPPFLAGS CXXFLAGS ARFLAGS
|
||||
|
||||
# Set target compiler. Defaults to whatever the user has
|
||||
# configured as prefix + ye olde gcc commands
|
||||
CC := $(call dequote,$(CONFIG_TOOLPREFIX))gcc
|
||||
CXX := $(call dequote,$(CONFIG_TOOLPREFIX))c++
|
||||
LD := $(call dequote,$(CONFIG_TOOLPREFIX))ld
|
||||
AR := $(call dequote,$(CONFIG_TOOLPREFIX))ar
|
||||
OBJCOPY := $(call dequote,$(CONFIG_TOOLPREFIX))objcopy
|
||||
OBJDUMP := $(call dequote,$(CONFIG_TOOLPREFIX))objdump
|
||||
SIZE := $(call dequote,$(CONFIG_TOOLPREFIX))size
|
||||
CC := $(call dequote,$(CONFIG_SDK_TOOLPREFIX))gcc
|
||||
CXX := $(call dequote,$(CONFIG_SDK_TOOLPREFIX))c++
|
||||
LD := $(call dequote,$(CONFIG_SDK_TOOLPREFIX))ld
|
||||
AR := $(call dequote,$(CONFIG_SDK_TOOLPREFIX))ar
|
||||
OBJCOPY := $(call dequote,$(CONFIG_SDK_TOOLPREFIX))objcopy
|
||||
OBJDUMP := $(call dequote,$(CONFIG_SDK_TOOLPREFIX))objdump
|
||||
SIZE := $(call dequote,$(CONFIG_SDK_TOOLPREFIX))size
|
||||
export CC CXX LD AR OBJCOPY OBJDUMP SIZE
|
||||
|
||||
COMPILER_VERSION_STR := $(shell $(CC) -dumpversion)
|
||||
@ -665,7 +665,7 @@ print_flash_cmd: partition_table_get_info blank_ota_data
|
||||
# The output normally looks as follows
|
||||
# xtensa-esp32-elf-gcc (crosstool-NG crosstool-ng-1.22.0-80-g6c4433a) 5.2.0
|
||||
# The part in brackets is extracted into TOOLCHAIN_COMMIT_DESC variable
|
||||
ifdef CONFIG_TOOLPREFIX
|
||||
ifdef CONFIG_SDK_TOOLPREFIX
|
||||
ifndef MAKE_RESTARTS
|
||||
|
||||
TOOLCHAIN_HEADER := $(shell $(CC) --version | head -1)
|
||||
@ -704,7 +704,7 @@ $(info WARNING: Failed to find Xtensa toolchain, may need to alter PATH or set o
|
||||
endif # TOOLCHAIN_COMMIT_DESC
|
||||
|
||||
endif #MAKE_RESTARTS
|
||||
endif #CONFIG_TOOLPREFIX
|
||||
endif #CONFIG_SDK_TOOLPREFIX
|
||||
|
||||
#####################################################################
|
||||
endif #CONFIG_IDF_TARGET
|
||||
|
@ -42,8 +42,24 @@ $(SDKCONFIG): defconfig
|
||||
endif
|
||||
endif
|
||||
|
||||
# macro for running confgen.py
|
||||
define RunConfGen
|
||||
mkdir -p $(BUILD_DIR_BASE)/include/config
|
||||
$(PYTHON) $(IDF_PATH)/tools/kconfig_new/confgen.py \
|
||||
--kconfig $(IDF_PATH)/Kconfig \
|
||||
--config $(SDKCONFIG) \
|
||||
--env "COMPONENT_KCONFIGS=$(strip $(COMPONENT_KCONFIGS))" \
|
||||
--env "COMPONENT_KCONFIGS_PROJBUILD=$(strip $(COMPONENT_KCONFIGS_PROJBUILD))" \
|
||||
--env "IDF_CMAKE=n" \
|
||||
--output config ${SDKCONFIG} \
|
||||
--output makefile $(SDKCONFIG_MAKEFILE) \
|
||||
--output header $(BUILD_DIR_BASE)/include/sdkconfig.h
|
||||
endef
|
||||
|
||||
# macro for the commands to run kconfig tools conf-idf or mconf-idf.
|
||||
# $1 is the name (& args) of the conf tool to run
|
||||
# Note: Currently only mconf-idf is used for compatibility with the CMake build system. The header file used is also
|
||||
# the same.
|
||||
define RunConf
|
||||
mkdir -p $(BUILD_DIR_BASE)/include/config
|
||||
cd $(BUILD_DIR_BASE); KCONFIG_AUTOHEADER=$(abspath $(BUILD_DIR_BASE)/include/sdkconfig.h) \
|
||||
@ -65,7 +81,7 @@ ifndef MAKE_RESTARTS
|
||||
# depend on any prerequisite that may cause a make restart as part of
|
||||
# the prerequisite's own recipe.
|
||||
|
||||
menuconfig: $(KCONFIG_TOOL_DIR)/mconf-idf
|
||||
menuconfig: $(KCONFIG_TOOL_DIR)/mconf-idf | check_python_dependencies
|
||||
$(summary) MENUCONFIG
|
||||
ifdef BATCH_BUILD
|
||||
@echo "Can't run interactive configuration inside non-interactive build process."
|
||||
@ -74,25 +90,26 @@ ifdef BATCH_BUILD
|
||||
@echo "See esp-idf documentation for more details."
|
||||
@exit 1
|
||||
else
|
||||
$(call RunConfGen)
|
||||
# RunConfGen before mconf-idf ensures that deprecated options won't be ignored (they've got renamed)
|
||||
$(call RunConf,mconf-idf)
|
||||
# RunConfGen after mconf-idf ensures that deprecated options are appended to $(SDKCONFIG) for backward compatibility
|
||||
$(call RunConfGen)
|
||||
endif
|
||||
|
||||
# defconfig creates a default config, based on SDKCONFIG_DEFAULTS if present
|
||||
defconfig: $(KCONFIG_TOOL_DIR)/conf-idf
|
||||
defconfig: | check_python_dependencies
|
||||
$(summary) DEFCONFIG
|
||||
ifneq ("$(wildcard $(SDKCONFIG_DEFAULTS))","")
|
||||
cat $(SDKCONFIG_DEFAULTS) >> $(SDKCONFIG) # append defaults to sdkconfig, will override existing values
|
||||
endif
|
||||
$(call RunConf,conf-idf --olddefconfig)
|
||||
$(call RunConfGen)
|
||||
|
||||
# if neither defconfig or menuconfig are requested, use the GENCONFIG rule to
|
||||
# ensure generated config files are up to date
|
||||
$(SDKCONFIG_MAKEFILE) $(BUILD_DIR_BASE)/include/sdkconfig.h: $(KCONFIG_TOOL_DIR)/conf-idf $(SDKCONFIG) $(COMPONENT_KCONFIGS) $(COMPONENT_KCONFIGS_PROJBUILD) | $(call prereq_if_explicit,defconfig) $(call prereq_if_explicit,menuconfig)
|
||||
$(SDKCONFIG_MAKEFILE) $(BUILD_DIR_BASE)/include/sdkconfig.h: $(SDKCONFIG) $(COMPONENT_KCONFIGS) $(COMPONENT_KCONFIGS_PROJBUILD) | check_python_dependencies $(call prereq_if_explicit,defconfig) $(call prereq_if_explicit,menuconfig)
|
||||
$(summary) GENCONFIG
|
||||
ifdef BATCH_BUILD # can't prompt for new config values like on terminal
|
||||
$(call RunConf,conf-idf --olddefconfig)
|
||||
endif
|
||||
$(call RunConf,conf-idf --silentoldconfig)
|
||||
$(call RunConfGen)
|
||||
touch $(SDKCONFIG_MAKEFILE) $(BUILD_DIR_BASE)/include/sdkconfig.h # ensure newer than sdkconfig
|
||||
|
||||
else # "$(MAKE_RESTARTS)" != ""
|
||||
|
7
sdkconfig.rename
Normal file
7
sdkconfig.rename
Normal file
@ -0,0 +1,7 @@
|
||||
# sdkconfig replacement configurations for deprecated options formatted as
|
||||
# CONFIG_DEPRECATED_OPTION CONFIG_NEW_OPTION
|
||||
|
||||
# SDK tool configuration
|
||||
CONFIG_TOOLPREFIX CONFIG_SDK_TOOLPREFIX
|
||||
CONFIG_PYTHON CONFIG_SDK_PYTHON
|
||||
CONFIG_MAKE_WARN_UNDEFINED_VARIABLES CONFIG_SDK_MAKE_WARN_UNDEFINED_VARIABLES
|
@ -310,6 +310,35 @@ function run_tests()
|
||||
rm -rf esp32
|
||||
rm -rf mycomponents
|
||||
|
||||
print_status "Handling deprecated Kconfig options"
|
||||
make clean > /dev/null;
|
||||
rm -f sdkconfig.defaults;
|
||||
rm -f sdkconfig;
|
||||
echo "" > ${IDF_PATH}/sdkconfig.rename;
|
||||
make defconfig > /dev/null;
|
||||
echo "CONFIG_TEST_OLD_OPTION=y" >> sdkconfig;
|
||||
echo "CONFIG_TEST_OLD_OPTION CONFIG_TEST_NEW_OPTION" >> ${IDF_PATH}/sdkconfig.rename;
|
||||
echo -e "\n\
|
||||
menu \"test\"\n\
|
||||
config TEST_NEW_OPTION\n\
|
||||
bool \"test\"\n\
|
||||
default \"n\"\n\
|
||||
help\n\
|
||||
TEST_NEW_OPTION description\n\
|
||||
endmenu\n" >> ${IDF_PATH}/Kconfig;
|
||||
make defconfig > /dev/null;
|
||||
grep "CONFIG_TEST_OLD_OPTION=y" sdkconfig || failure "CONFIG_TEST_OLD_OPTION should be in sdkconfig for backward compatibility"
|
||||
grep "CONFIG_TEST_NEW_OPTION=y" sdkconfig || failure "CONFIG_TEST_NEW_OPTION should be now in sdkconfig"
|
||||
grep "#define CONFIG_TEST_NEW_OPTION 1" build/include/sdkconfig.h || failure "sdkconfig.h should contain the new macro"
|
||||
grep "#define CONFIG_TEST_OLD_OPTION CONFIG_TEST_NEW_OPTION" build/include/sdkconfig.h || failure "sdkconfig.h should contain the compatibility macro"
|
||||
grep "CONFIG_TEST_OLD_OPTION=y" build/include/config/auto.conf || failure "CONFIG_TEST_OLD_OPTION should be in auto.conf for backward compatibility"
|
||||
grep "CONFIG_TEST_NEW_OPTION=y" build/include/config/auto.conf || failure "CONFIG_TEST_NEW_OPTION should be now in auto.conf"
|
||||
rm -f sdkconfig sdkconfig.defaults
|
||||
pushd ${IDF_PATH}
|
||||
git checkout -- sdkconfig.rename Kconfig
|
||||
popd
|
||||
make defconfig
|
||||
|
||||
print_status "All tests completed"
|
||||
if [ -n "${FAILURES}" ]; then
|
||||
echo "Some failures were detected:"
|
||||
|
@ -366,6 +366,35 @@ EOF
|
||||
export PATH="$OLDPATH"
|
||||
rm ./python
|
||||
|
||||
print_status "Handling deprecated Kconfig options"
|
||||
idf.py clean > /dev/null;
|
||||
rm -f sdkconfig.defaults;
|
||||
rm -f sdkconfig;
|
||||
echo "" > ${IDF_PATH}/sdkconfig.rename;
|
||||
idf.py build > /dev/null;
|
||||
echo "CONFIG_TEST_OLD_OPTION=y" >> sdkconfig;
|
||||
echo "CONFIG_TEST_OLD_OPTION CONFIG_TEST_NEW_OPTION" >> ${IDF_PATH}/sdkconfig.rename;
|
||||
echo -e "\n\
|
||||
menu \"test\"\n\
|
||||
config TEST_NEW_OPTION\n\
|
||||
bool \"test\"\n\
|
||||
default \"n\"\n\
|
||||
help\n\
|
||||
TEST_NEW_OPTION description\n\
|
||||
endmenu\n" >> ${IDF_PATH}/Kconfig;
|
||||
idf.py build > /dev/null;
|
||||
grep "CONFIG_TEST_OLD_OPTION=y" sdkconfig || failure "CONFIG_TEST_OLD_OPTION should be in sdkconfig for backward compatibility"
|
||||
grep "CONFIG_TEST_NEW_OPTION=y" sdkconfig || failure "CONFIG_TEST_NEW_OPTION should be now in sdkconfig"
|
||||
grep "#define CONFIG_TEST_NEW_OPTION 1" build/config/sdkconfig.h || failure "sdkconfig.h should contain the new macro"
|
||||
grep "#define CONFIG_TEST_OLD_OPTION CONFIG_TEST_NEW_OPTION" build/config/sdkconfig.h || failure "sdkconfig.h should contain the compatibility macro"
|
||||
grep "set(CONFIG_TEST_OLD_OPTION \"y\")" build/config/sdkconfig.cmake || failure "CONFIG_TEST_OLD_OPTION should be in auto.conf for backward compatibility"
|
||||
grep "set(CONFIG_TEST_NEW_OPTION \"y\")" build/config/sdkconfig.cmake || failure "CONFIG_TEST_NEW_OPTION should be now in auto.conf"
|
||||
rm -f sdkconfig sdkconfig.defaults
|
||||
pushd ${IDF_PATH}
|
||||
git checkout -- sdkconfig.rename Kconfig
|
||||
popd
|
||||
idf.py build
|
||||
|
||||
print_status "All tests completed"
|
||||
if [ -n "${FAILURES}" ]; then
|
||||
echo "Some failures were detected:"
|
||||
|
@ -138,7 +138,11 @@ function(kconfig_process_config)
|
||||
"IDF_TARGET=${IDF_TARGET}"
|
||||
${MCONF} ${ROOT_KCONFIG}
|
||||
VERBATIM
|
||||
USES_TERMINAL)
|
||||
USES_TERMINAL
|
||||
# additional run of confgen esures that the deprecated options will be inserted into sdkconfig (for backward
|
||||
# compatibility)
|
||||
COMMAND ${confgen_basecommand} --env "IDF_TARGET=${IDF_TARGET}" --output config ${SDKCONFIG}
|
||||
)
|
||||
|
||||
# Custom target to run confserver.py from the build tool
|
||||
add_custom_target(confserver
|
||||
@ -191,4 +195,4 @@ function(kconfig_process_config)
|
||||
ADDITIONAL_MAKE_CLEAN_FILES
|
||||
"${SDKCONFIG_HEADER}" "${SDKCONFIG_CMAKE}")
|
||||
|
||||
endfunction()
|
||||
endfunction()
|
||||
|
@ -22,12 +22,13 @@
|
||||
# limitations under the License.
|
||||
from __future__ import print_function
|
||||
import argparse
|
||||
import sys
|
||||
import fnmatch
|
||||
import json
|
||||
import os
|
||||
import os.path
|
||||
import tempfile
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
import gen_kconfig_doc
|
||||
import kconfiglib
|
||||
@ -38,6 +39,108 @@ if "IDF_CMAKE" not in os.environ:
|
||||
os.environ["IDF_CMAKE"] = ""
|
||||
|
||||
|
||||
class DeprecatedOptions(object):
|
||||
_REN_FILE = 'sdkconfig.rename'
|
||||
_DEP_OP_BEGIN = '# Deprecated options for backward compatibility'
|
||||
_DEP_OP_END = '# End of deprecated options'
|
||||
_RE_DEP_OP_BEGIN = re.compile(_DEP_OP_BEGIN)
|
||||
_RE_DEP_OP_END = re.compile(_DEP_OP_END)
|
||||
|
||||
def __init__(self, config_prefix, path_rename_files):
|
||||
self.config_prefix = config_prefix
|
||||
# r_dic maps deprecated options to new options; rev_r_dic maps in the opposite direction
|
||||
self.r_dic, self.rev_r_dic = self._parse_replacements(path_rename_files)
|
||||
|
||||
# note the '=' at the end of regex for not getting partial match of configs
|
||||
self._RE_CONFIG = re.compile(r'{}(\w+)='.format(self.config_prefix))
|
||||
|
||||
def _parse_replacements(self, repl_dir):
|
||||
rep_dic = {}
|
||||
rev_rep_dic = {}
|
||||
|
||||
for root, dirnames, filenames in os.walk(repl_dir):
|
||||
for filename in fnmatch.filter(filenames, self._REN_FILE):
|
||||
rep_path = os.path.join(root, filename)
|
||||
|
||||
with open(rep_path) as f_rep:
|
||||
for line_number, line in enumerate(f_rep, start=1):
|
||||
sp_line = line.split()
|
||||
if len(sp_line) == 0 or sp_line[0].startswith('#'):
|
||||
# empty line or comment
|
||||
continue
|
||||
if len(sp_line) != 2 or not all(x.startswith(self.config_prefix) for x in sp_line):
|
||||
raise RuntimeError('Syntax error in {} (line {})'.format(rep_path, line_number))
|
||||
if sp_line[0] in rep_dic:
|
||||
raise RuntimeError('Error in {} (line {}): Replacement {} exist for {} and new '
|
||||
'replacement {} is defined'.format(rep_path, line_number,
|
||||
rep_dic[sp_line[0]], sp_line[0],
|
||||
sp_line[1]))
|
||||
(dep_opt, new_opt) = (x.lstrip(self.config_prefix) for x in sp_line)
|
||||
rep_dic[dep_opt] = new_opt
|
||||
rev_rep_dic[new_opt] = dep_opt
|
||||
return rep_dic, rev_rep_dic
|
||||
|
||||
def get_deprecated_option(self, new_option):
|
||||
return self.rev_r_dic.get(new_option, None)
|
||||
|
||||
def get_new_option(self, deprecated_option):
|
||||
return self.r_dic.get(deprecated_option, None)
|
||||
|
||||
def replace(self, sdkconfig_in, sdkconfig_out):
|
||||
replace_enabled = True
|
||||
with open(sdkconfig_in, 'r') as f_in, open(sdkconfig_out, 'w') as f_out:
|
||||
for line_num, line in enumerate(f_in, start=1):
|
||||
if self._RE_DEP_OP_BEGIN.search(line):
|
||||
replace_enabled = False
|
||||
elif self._RE_DEP_OP_END.search(line):
|
||||
replace_enabled = True
|
||||
elif replace_enabled:
|
||||
m = self._RE_CONFIG.search(line)
|
||||
if m and m.group(1) in self.r_dic:
|
||||
depr_opt = self.config_prefix + m.group(1)
|
||||
new_opt = self.config_prefix + self.r_dic[m.group(1)]
|
||||
line = line.replace(depr_opt, new_opt)
|
||||
print('{}:{} {} was replaced with {}'.format(sdkconfig_in, line_num, depr_opt, new_opt))
|
||||
f_out.write(line)
|
||||
|
||||
def append_doc(self, config, path_output):
|
||||
if len(self.r_dic) > 0:
|
||||
with open(path_output, 'a') as f_o:
|
||||
header = 'Deprecated options and their replacements'
|
||||
f_o.write('{}\n{}\n\n'.format(header, '-' * len(header)))
|
||||
for key in sorted(self.r_dic):
|
||||
f_o.write('- {}{}: :ref:`{}{}`\n'.format(config.config_prefix, key,
|
||||
config.config_prefix, self.r_dic[key]))
|
||||
|
||||
def append_config(self, config, path_output):
|
||||
tmp_list = []
|
||||
|
||||
def append_config_node_process(node):
|
||||
item = node.item
|
||||
if isinstance(item, kconfiglib.Symbol) and item.env_var is None:
|
||||
if item.name in self.rev_r_dic:
|
||||
c_string = item.config_string
|
||||
if c_string:
|
||||
tmp_list.append(c_string.replace(self.config_prefix + item.name,
|
||||
self.config_prefix + self.rev_r_dic[item.name]))
|
||||
|
||||
config.walk_menu(append_config_node_process)
|
||||
|
||||
if len(tmp_list) > 0:
|
||||
with open(path_output, 'a') as f_o:
|
||||
f_o.write('\n{}\n'.format(self._DEP_OP_BEGIN))
|
||||
f_o.writelines(tmp_list)
|
||||
f_o.write('{}\n'.format(self._DEP_OP_END))
|
||||
|
||||
def append_header(self, config, path_output):
|
||||
if len(self.r_dic) > 0:
|
||||
with open(path_output, 'a') as f_o:
|
||||
f_o.write('\n/* List of deprecated options */\n')
|
||||
for dep_opt in sorted(self.r_dic):
|
||||
new_opt = self.r_dic[dep_opt]
|
||||
f_o.write('#define {}{} {}{}\n'.format(self.config_prefix, dep_opt, self.config_prefix, new_opt))
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='confgen.py v%s - Config Generation Tool' % __version__, prog=os.path.basename(sys.argv[0]))
|
||||
|
||||
@ -94,16 +197,30 @@ def main():
|
||||
raise RuntimeError("Defaults file not found: %s" % name)
|
||||
config.load_config(name, replace=False)
|
||||
|
||||
deprecated_options = DeprecatedOptions(config.config_prefix, path_rename_files=os.environ["IDF_PATH"])
|
||||
|
||||
# If config file previously exists, load it
|
||||
if args.config and os.path.exists(args.config):
|
||||
config.load_config(args.config, replace=False)
|
||||
# ... but replace deprecated options before that
|
||||
with tempfile.NamedTemporaryFile(prefix="confgen_tmp", delete=False) as f:
|
||||
temp_file = f.name
|
||||
try:
|
||||
deprecated_options.replace(sdkconfig_in=args.config, sdkconfig_out=temp_file)
|
||||
config.load_config(temp_file, replace=False)
|
||||
update_if_changed(temp_file, args.config)
|
||||
finally:
|
||||
try:
|
||||
os.remove(temp_file)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
# Output the files specified in the arguments
|
||||
for output_type, filename in args.output:
|
||||
temp_file = tempfile.mktemp(prefix="confgen_tmp")
|
||||
with tempfile.NamedTemporaryFile(prefix="confgen_tmp", delete=False) as f:
|
||||
temp_file = f.name
|
||||
try:
|
||||
output_function = OUTPUT_FORMATS[output_type]
|
||||
output_function(config, temp_file)
|
||||
output_function(deprecated_options, config, temp_file)
|
||||
update_if_changed(temp_file, filename)
|
||||
finally:
|
||||
try:
|
||||
@ -112,16 +229,56 @@ def main():
|
||||
pass
|
||||
|
||||
|
||||
def write_config(config, filename):
|
||||
def write_config(deprecated_options, config, filename):
|
||||
CONFIG_HEADING = """#
|
||||
# Automatically generated file. DO NOT EDIT.
|
||||
# Espressif IoT Development Framework (ESP-IDF) Project Configuration
|
||||
#
|
||||
"""
|
||||
config.write_config(filename, header=CONFIG_HEADING)
|
||||
deprecated_options.append_config(config, filename)
|
||||
|
||||
|
||||
def write_header(config, filename):
|
||||
def write_makefile(deprecated_options, config, filename):
|
||||
CONFIG_HEADING = """#
|
||||
# Automatically generated file. DO NOT EDIT.
|
||||
# Espressif IoT Development Framework (ESP-IDF) Project Makefile Configuration
|
||||
#
|
||||
"""
|
||||
with open(filename, "w") as f:
|
||||
tmp_dep_lines = []
|
||||
f.write(CONFIG_HEADING)
|
||||
|
||||
def get_makefile_config_string(name, value, orig_type):
|
||||
if orig_type in (kconfiglib.BOOL, kconfiglib.TRISTATE):
|
||||
return "{}{}={}\n".format(config.config_prefix, name, '' if value == 'n' else value)
|
||||
elif orig_type in (kconfiglib.INT, kconfiglib.HEX):
|
||||
return "{}{}={}\n".format(config.config_prefix, name, value)
|
||||
elif orig_type == kconfiglib.STRING:
|
||||
return '{}{}="{}"\n'.format(config.config_prefix, name, kconfiglib.escape(value))
|
||||
else:
|
||||
raise RuntimeError('{}{}: unknown type {}'.format(config.config_prefix, name, orig_type))
|
||||
|
||||
def write_makefile_node(node):
|
||||
item = node.item
|
||||
if isinstance(item, kconfiglib.Symbol) and item.env_var is None:
|
||||
# item.config_string cannot be used because it ignores hidden config items
|
||||
val = item.str_value
|
||||
f.write(get_makefile_config_string(item.name, val, item.orig_type))
|
||||
|
||||
dep_opt = deprecated_options.get_deprecated_option(item.name)
|
||||
if dep_opt:
|
||||
# the same string but with the deprecated name
|
||||
tmp_dep_lines.append(get_makefile_config_string(dep_opt, val, item.orig_type))
|
||||
|
||||
config.walk_menu(write_makefile_node, True)
|
||||
|
||||
if len(tmp_dep_lines) > 0:
|
||||
f.write('\n# List of deprecated options\n')
|
||||
f.writelines(tmp_dep_lines)
|
||||
|
||||
|
||||
def write_header(deprecated_options, config, filename):
|
||||
CONFIG_HEADING = """/*
|
||||
* Automatically generated file. DO NOT EDIT.
|
||||
* Espressif IoT Development Framework (ESP-IDF) Configuration Header
|
||||
@ -129,10 +286,12 @@ def write_header(config, filename):
|
||||
#pragma once
|
||||
"""
|
||||
config.write_autoconf(filename, header=CONFIG_HEADING)
|
||||
deprecated_options.append_header(config, filename)
|
||||
|
||||
|
||||
def write_cmake(config, filename):
|
||||
def write_cmake(deprecated_options, config, filename):
|
||||
with open(filename, "w") as f:
|
||||
tmp_dep_list = []
|
||||
write = f.write
|
||||
prefix = config.config_prefix
|
||||
|
||||
@ -155,8 +314,15 @@ def write_cmake(config, filename):
|
||||
val = "" # write unset values as empty variables
|
||||
write("set({}{} \"{}\")\n".format(
|
||||
prefix, sym.name, val))
|
||||
dep_opt = deprecated_options.get_deprecated_option(sym.name)
|
||||
if dep_opt:
|
||||
tmp_dep_list.append("set({}{} \"{}\")\n".format(prefix, dep_opt, val))
|
||||
config.walk_menu(write_node)
|
||||
|
||||
if len(tmp_dep_list) > 0:
|
||||
write('\n# List of deprecated options for backward compatibility\n')
|
||||
f.writelines(tmp_dep_list)
|
||||
|
||||
|
||||
def get_json_values(config):
|
||||
config_dict = {}
|
||||
@ -179,7 +345,7 @@ def get_json_values(config):
|
||||
return config_dict
|
||||
|
||||
|
||||
def write_json(config, filename):
|
||||
def write_json(deprecated_options, config, filename):
|
||||
config_dict = get_json_values(config)
|
||||
with open(filename, "w") as f:
|
||||
json.dump(config_dict, f, indent=4, sort_keys=True)
|
||||
@ -209,7 +375,7 @@ def get_menu_node_id(node):
|
||||
return result
|
||||
|
||||
|
||||
def write_json_menus(config, filename):
|
||||
def write_json_menus(deprecated_options, config, filename):
|
||||
existing_ids = set()
|
||||
result = [] # root level items
|
||||
node_lookup = {} # lookup from MenuNode to an item in result
|
||||
@ -298,6 +464,11 @@ def write_json_menus(config, filename):
|
||||
f.write(json.dumps(result, sort_keys=True, indent=4))
|
||||
|
||||
|
||||
def write_docs(deprecated_options, config, filename):
|
||||
gen_kconfig_doc.write_docs(config, filename)
|
||||
deprecated_options.append_doc(config, filename)
|
||||
|
||||
|
||||
def update_if_changed(source, destination):
|
||||
with open(source, "r") as f:
|
||||
source_contents = f.read()
|
||||
@ -313,9 +484,10 @@ def update_if_changed(source, destination):
|
||||
|
||||
|
||||
OUTPUT_FORMATS = {"config": write_config,
|
||||
"makefile": write_makefile, # only used with make in order to generate auto.conf
|
||||
"header": write_header,
|
||||
"cmake": write_cmake,
|
||||
"docs": gen_kconfig_doc.write_docs,
|
||||
"docs": write_docs,
|
||||
"json": write_json,
|
||||
"json_menus": write_json_menus,
|
||||
}
|
||||
|
@ -5,11 +5,12 @@
|
||||
#
|
||||
from __future__ import print_function
|
||||
import argparse
|
||||
import confgen
|
||||
import json
|
||||
import kconfiglib
|
||||
import os
|
||||
import sys
|
||||
import confgen
|
||||
import tempfile
|
||||
from confgen import FatalError, __version__
|
||||
|
||||
# Min/Max supported protocol versions
|
||||
@ -58,6 +59,13 @@ def main():
|
||||
|
||||
def run_server(kconfig, sdkconfig, default_version=MAX_PROTOCOL_VERSION):
|
||||
config = kconfiglib.Kconfig(kconfig)
|
||||
deprecated_options = confgen.DeprecatedOptions(config.config_prefix, path_rename_files=os.environ["IDF_PATH"])
|
||||
with tempfile.NamedTemporaryFile(mode='w+b') as f_o:
|
||||
with open(sdkconfig, mode='rb') as f_i:
|
||||
f_o.write(f_i.read())
|
||||
f_o.flush()
|
||||
f_o.seek(0)
|
||||
deprecated_options.replace(sdkconfig_in=f_o.name, sdkconfig_out=sdkconfig)
|
||||
config.load_config(sdkconfig)
|
||||
|
||||
print("Server running, waiting for requests on stdin...", file=sys.stderr)
|
||||
@ -111,7 +119,7 @@ def run_server(kconfig, sdkconfig, default_version=MAX_PROTOCOL_VERSION):
|
||||
else:
|
||||
sdkconfig = req["save"]
|
||||
|
||||
error = handle_request(config, req)
|
||||
error = handle_request(deprecated_options, config, req)
|
||||
|
||||
after = confgen.get_json_values(config)
|
||||
after_ranges = get_ranges(config)
|
||||
@ -136,7 +144,7 @@ def run_server(kconfig, sdkconfig, default_version=MAX_PROTOCOL_VERSION):
|
||||
print("\n")
|
||||
|
||||
|
||||
def handle_request(config, req):
|
||||
def handle_request(deprecated_options, config, req):
|
||||
if "version" not in req:
|
||||
return ["All requests must have a 'version'"]
|
||||
|
||||
@ -161,7 +169,7 @@ def handle_request(config, req):
|
||||
if "save" in req:
|
||||
try:
|
||||
print("Saving config to %s..." % req["save"], file=sys.stderr)
|
||||
confgen.write_config(config, req["save"])
|
||||
confgen.write_config(deprecated_options, config, req["save"])
|
||||
except Exception as e:
|
||||
error += ["Failed to save to %s: %s" % (req["save"], e)]
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
#
|
||||
# SDK tool configuration
|
||||
#
|
||||
CONFIG_TOOLPREFIX="xtensa-esp32-elf-"
|
||||
CONFIG_PYTHON="python"
|
||||
CONFIG_MAKE_WARN_UNDEFINED_VARIABLES=y
|
||||
CONFIG_SDK_TOOLPREFIX="xtensa-esp32-elf-"
|
||||
CONFIG_SDK_PYTHON="python"
|
||||
CONFIG_SDK_MAKE_WARN_UNDEFINED_VARIABLES=y
|
||||
|
||||
#
|
||||
# Bootloader config
|
||||
|
Loading…
Reference in New Issue
Block a user