Rename deprecated Kconfig options in a backward compatible way
This commit is contained in:
parent
cf9f2aa466
commit
23ee93ea76
14 changed files with 314 additions and 48 deletions
6
Kconfig
6
Kconfig
|
@ -25,14 +25,14 @@ mainmenu "Espressif IoT Development Framework Configuration"
|
||||||
|
|
||||||
|
|
||||||
menu "SDK tool configuration"
|
menu "SDK tool configuration"
|
||||||
config TOOLPREFIX
|
config SDK_TOOLPREFIX
|
||||||
string "Compiler toolchain path/prefix"
|
string "Compiler toolchain path/prefix"
|
||||||
default "xtensa-esp32-elf-"
|
default "xtensa-esp32-elf-"
|
||||||
help
|
help
|
||||||
The prefix/path that is used to call the toolchain. The default setting assumes
|
The prefix/path that is used to call the toolchain. The default setting assumes
|
||||||
a crosstool-ng gcc setup that is in your PATH.
|
a crosstool-ng gcc setup that is in your PATH.
|
||||||
|
|
||||||
config PYTHON
|
config SDK_PYTHON
|
||||||
string "Python 2 interpreter"
|
string "Python 2 interpreter"
|
||||||
depends on !IDF_CMAKE
|
depends on !IDF_CMAKE
|
||||||
default "python"
|
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
|
(Note: This option is used with the GNU Make build system only, not idf.py
|
||||||
or CMake-based builds.)
|
or CMake-based builds.)
|
||||||
|
|
||||||
config MAKE_WARN_UNDEFINED_VARIABLES
|
config SDK_MAKE_WARN_UNDEFINED_VARIABLES
|
||||||
bool "'make' warns on undefined variables"
|
bool "'make' warns on undefined variables"
|
||||||
default "y"
|
default "y"
|
||||||
help
|
help
|
||||||
|
|
|
@ -8,7 +8,7 @@ ESPFLASHSIZE ?= $(CONFIG_ESPTOOLPY_FLASHSIZE)
|
||||||
|
|
||||||
CONFIG_ESPTOOLPY_COMPRESSED ?=
|
CONFIG_ESPTOOLPY_COMPRESSED ?=
|
||||||
|
|
||||||
PYTHON ?= $(call dequote,$(CONFIG_PYTHON))
|
PYTHON ?= $(call dequote,$(CONFIG_SDK_PYTHON))
|
||||||
|
|
||||||
# two commands that can be used from other components
|
# two commands that can be used from other components
|
||||||
# to invoke esptool.py (with or without serial port args)
|
# 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 ?=
|
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
|
monitor: $(call prereq_if_explicit,%flash) | check_python_dependencies
|
||||||
$(summary) MONITOR
|
$(summary) MONITOR
|
||||||
|
|
|
@ -7,7 +7,7 @@ PROJECT_NAME := gcov_example
|
||||||
|
|
||||||
include $(IDF_PATH)/make/project.mk
|
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
|
REPORT_DIR := $(BUILD_DIR_BASE)/coverage_report
|
||||||
|
|
||||||
lcov-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`:
|
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
|
REPORT_DIR := $(BUILD_DIR_BASE)/coverage_report
|
||||||
|
|
||||||
lcov-report:
|
lcov-report:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# and component makefiles (component_wrapper.mk)
|
# and component makefiles (component_wrapper.mk)
|
||||||
#
|
#
|
||||||
|
|
||||||
PYTHON=$(call dequote,$(CONFIG_PYTHON))
|
PYTHON=$(call dequote,$(CONFIG_SDK_PYTHON))
|
||||||
|
|
||||||
# Include project config makefile, if it exists.
|
# Include project config makefile, if it exists.
|
||||||
#
|
#
|
||||||
|
@ -34,7 +34,7 @@ details := @true
|
||||||
MAKEFLAGS += --silent
|
MAKEFLAGS += --silent
|
||||||
endif # $(V)==1
|
endif # $(V)==1
|
||||||
|
|
||||||
ifdef CONFIG_MAKE_WARN_UNDEFINED_VARIABLES
|
ifdef CONFIG_SDK_MAKE_WARN_UNDEFINED_VARIABLES
|
||||||
MAKEFLAGS += --warn-undefined-variables
|
MAKEFLAGS += --warn-undefined-variables
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
@ -471,13 +471,13 @@ export CFLAGS CPPFLAGS CXXFLAGS ARFLAGS
|
||||||
|
|
||||||
# Set target compiler. Defaults to whatever the user has
|
# Set target compiler. Defaults to whatever the user has
|
||||||
# configured as prefix + ye olde gcc commands
|
# configured as prefix + ye olde gcc commands
|
||||||
CC := $(call dequote,$(CONFIG_TOOLPREFIX))gcc
|
CC := $(call dequote,$(CONFIG_SDK_TOOLPREFIX))gcc
|
||||||
CXX := $(call dequote,$(CONFIG_TOOLPREFIX))c++
|
CXX := $(call dequote,$(CONFIG_SDK_TOOLPREFIX))c++
|
||||||
LD := $(call dequote,$(CONFIG_TOOLPREFIX))ld
|
LD := $(call dequote,$(CONFIG_SDK_TOOLPREFIX))ld
|
||||||
AR := $(call dequote,$(CONFIG_TOOLPREFIX))ar
|
AR := $(call dequote,$(CONFIG_SDK_TOOLPREFIX))ar
|
||||||
OBJCOPY := $(call dequote,$(CONFIG_TOOLPREFIX))objcopy
|
OBJCOPY := $(call dequote,$(CONFIG_SDK_TOOLPREFIX))objcopy
|
||||||
OBJDUMP := $(call dequote,$(CONFIG_TOOLPREFIX))objdump
|
OBJDUMP := $(call dequote,$(CONFIG_SDK_TOOLPREFIX))objdump
|
||||||
SIZE := $(call dequote,$(CONFIG_TOOLPREFIX))size
|
SIZE := $(call dequote,$(CONFIG_SDK_TOOLPREFIX))size
|
||||||
export CC CXX LD AR OBJCOPY OBJDUMP SIZE
|
export CC CXX LD AR OBJCOPY OBJDUMP SIZE
|
||||||
|
|
||||||
COMPILER_VERSION_STR := $(shell $(CC) -dumpversion)
|
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
|
# The output normally looks as follows
|
||||||
# xtensa-esp32-elf-gcc (crosstool-NG crosstool-ng-1.22.0-80-g6c4433a) 5.2.0
|
# 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
|
# The part in brackets is extracted into TOOLCHAIN_COMMIT_DESC variable
|
||||||
ifdef CONFIG_TOOLPREFIX
|
ifdef CONFIG_SDK_TOOLPREFIX
|
||||||
ifndef MAKE_RESTARTS
|
ifndef MAKE_RESTARTS
|
||||||
|
|
||||||
TOOLCHAIN_HEADER := $(shell $(CC) --version | head -1)
|
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 # TOOLCHAIN_COMMIT_DESC
|
||||||
|
|
||||||
endif #MAKE_RESTARTS
|
endif #MAKE_RESTARTS
|
||||||
endif #CONFIG_TOOLPREFIX
|
endif #CONFIG_SDK_TOOLPREFIX
|
||||||
|
|
||||||
#####################################################################
|
#####################################################################
|
||||||
endif #CONFIG_IDF_TARGET
|
endif #CONFIG_IDF_TARGET
|
||||||
|
|
|
@ -42,8 +42,24 @@ $(SDKCONFIG): defconfig
|
||||||
endif
|
endif
|
||||||
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.
|
# macro for the commands to run kconfig tools conf-idf or mconf-idf.
|
||||||
# $1 is the name (& args) of the conf tool to run
|
# $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
|
define RunConf
|
||||||
mkdir -p $(BUILD_DIR_BASE)/include/config
|
mkdir -p $(BUILD_DIR_BASE)/include/config
|
||||||
cd $(BUILD_DIR_BASE); KCONFIG_AUTOHEADER=$(abspath $(BUILD_DIR_BASE)/include/sdkconfig.h) \
|
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
|
# depend on any prerequisite that may cause a make restart as part of
|
||||||
# the prerequisite's own recipe.
|
# the prerequisite's own recipe.
|
||||||
|
|
||||||
menuconfig: $(KCONFIG_TOOL_DIR)/mconf-idf
|
menuconfig: $(KCONFIG_TOOL_DIR)/mconf-idf | check_python_dependencies
|
||||||
$(summary) MENUCONFIG
|
$(summary) MENUCONFIG
|
||||||
ifdef BATCH_BUILD
|
ifdef BATCH_BUILD
|
||||||
@echo "Can't run interactive configuration inside non-interactive build process."
|
@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."
|
@echo "See esp-idf documentation for more details."
|
||||||
@exit 1
|
@exit 1
|
||||||
else
|
else
|
||||||
|
$(call RunConfGen)
|
||||||
|
# RunConfGen before mconf-idf ensures that deprecated options won't be ignored (they've got renamed)
|
||||||
$(call RunConf,mconf-idf)
|
$(call RunConf,mconf-idf)
|
||||||
|
# RunConfGen after mconf-idf ensures that deprecated options are appended to $(SDKCONFIG) for backward compatibility
|
||||||
|
$(call RunConfGen)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# defconfig creates a default config, based on SDKCONFIG_DEFAULTS if present
|
# defconfig creates a default config, based on SDKCONFIG_DEFAULTS if present
|
||||||
defconfig: $(KCONFIG_TOOL_DIR)/conf-idf
|
defconfig: | check_python_dependencies
|
||||||
$(summary) DEFCONFIG
|
$(summary) DEFCONFIG
|
||||||
ifneq ("$(wildcard $(SDKCONFIG_DEFAULTS))","")
|
ifneq ("$(wildcard $(SDKCONFIG_DEFAULTS))","")
|
||||||
cat $(SDKCONFIG_DEFAULTS) >> $(SDKCONFIG) # append defaults to sdkconfig, will override existing values
|
cat $(SDKCONFIG_DEFAULTS) >> $(SDKCONFIG) # append defaults to sdkconfig, will override existing values
|
||||||
endif
|
endif
|
||||||
$(call RunConf,conf-idf --olddefconfig)
|
$(call RunConfGen)
|
||||||
|
|
||||||
# if neither defconfig or menuconfig are requested, use the GENCONFIG rule to
|
# if neither defconfig or menuconfig are requested, use the GENCONFIG rule to
|
||||||
# ensure generated config files are up to date
|
# 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
|
$(summary) GENCONFIG
|
||||||
ifdef BATCH_BUILD # can't prompt for new config values like on terminal
|
$(call RunConfGen)
|
||||||
$(call RunConf,conf-idf --olddefconfig)
|
|
||||||
endif
|
|
||||||
$(call RunConf,conf-idf --silentoldconfig)
|
|
||||||
touch $(SDKCONFIG_MAKEFILE) $(BUILD_DIR_BASE)/include/sdkconfig.h # ensure newer than sdkconfig
|
touch $(SDKCONFIG_MAKEFILE) $(BUILD_DIR_BASE)/include/sdkconfig.h # ensure newer than sdkconfig
|
||||||
|
|
||||||
else # "$(MAKE_RESTARTS)" != ""
|
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 esp32
|
||||||
rm -rf mycomponents
|
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"
|
print_status "All tests completed"
|
||||||
if [ -n "${FAILURES}" ]; then
|
if [ -n "${FAILURES}" ]; then
|
||||||
echo "Some failures were detected:"
|
echo "Some failures were detected:"
|
||||||
|
|
|
@ -366,6 +366,35 @@ EOF
|
||||||
export PATH="$OLDPATH"
|
export PATH="$OLDPATH"
|
||||||
rm ./python
|
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"
|
print_status "All tests completed"
|
||||||
if [ -n "${FAILURES}" ]; then
|
if [ -n "${FAILURES}" ]; then
|
||||||
echo "Some failures were detected:"
|
echo "Some failures were detected:"
|
||||||
|
|
|
@ -138,7 +138,11 @@ function(kconfig_process_config)
|
||||||
"IDF_TARGET=${IDF_TARGET}"
|
"IDF_TARGET=${IDF_TARGET}"
|
||||||
${MCONF} ${ROOT_KCONFIG}
|
${MCONF} ${ROOT_KCONFIG}
|
||||||
VERBATIM
|
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
|
# Custom target to run confserver.py from the build tool
|
||||||
add_custom_target(confserver
|
add_custom_target(confserver
|
||||||
|
|
|
@ -22,12 +22,13 @@
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
import fnmatch
|
||||||
|
import json
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
import tempfile
|
|
||||||
import json
|
|
||||||
import re
|
import re
|
||||||
|
import sys
|
||||||
|
import tempfile
|
||||||
|
|
||||||
import gen_kconfig_doc
|
import gen_kconfig_doc
|
||||||
import kconfiglib
|
import kconfiglib
|
||||||
|
@ -38,6 +39,108 @@ if "IDF_CMAKE" not in os.environ:
|
||||||
os.environ["IDF_CMAKE"] = ""
|
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():
|
def main():
|
||||||
parser = argparse.ArgumentParser(description='confgen.py v%s - Config Generation Tool' % __version__, prog=os.path.basename(sys.argv[0]))
|
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)
|
raise RuntimeError("Defaults file not found: %s" % name)
|
||||||
config.load_config(name, replace=False)
|
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 config file previously exists, load it
|
||||||
if args.config and os.path.exists(args.config):
|
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
|
# Output the files specified in the arguments
|
||||||
for output_type, filename in args.output:
|
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:
|
try:
|
||||||
output_function = OUTPUT_FORMATS[output_type]
|
output_function = OUTPUT_FORMATS[output_type]
|
||||||
output_function(config, temp_file)
|
output_function(deprecated_options, config, temp_file)
|
||||||
update_if_changed(temp_file, filename)
|
update_if_changed(temp_file, filename)
|
||||||
finally:
|
finally:
|
||||||
try:
|
try:
|
||||||
|
@ -112,16 +229,56 @@ def main():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def write_config(config, filename):
|
def write_config(deprecated_options, config, filename):
|
||||||
CONFIG_HEADING = """#
|
CONFIG_HEADING = """#
|
||||||
# Automatically generated file. DO NOT EDIT.
|
# Automatically generated file. DO NOT EDIT.
|
||||||
# Espressif IoT Development Framework (ESP-IDF) Project Configuration
|
# Espressif IoT Development Framework (ESP-IDF) Project Configuration
|
||||||
#
|
#
|
||||||
"""
|
"""
|
||||||
config.write_config(filename, header=CONFIG_HEADING)
|
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 = """/*
|
CONFIG_HEADING = """/*
|
||||||
* Automatically generated file. DO NOT EDIT.
|
* Automatically generated file. DO NOT EDIT.
|
||||||
* Espressif IoT Development Framework (ESP-IDF) Configuration Header
|
* Espressif IoT Development Framework (ESP-IDF) Configuration Header
|
||||||
|
@ -129,10 +286,12 @@ def write_header(config, filename):
|
||||||
#pragma once
|
#pragma once
|
||||||
"""
|
"""
|
||||||
config.write_autoconf(filename, header=CONFIG_HEADING)
|
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:
|
with open(filename, "w") as f:
|
||||||
|
tmp_dep_list = []
|
||||||
write = f.write
|
write = f.write
|
||||||
prefix = config.config_prefix
|
prefix = config.config_prefix
|
||||||
|
|
||||||
|
@ -155,8 +314,15 @@ def write_cmake(config, filename):
|
||||||
val = "" # write unset values as empty variables
|
val = "" # write unset values as empty variables
|
||||||
write("set({}{} \"{}\")\n".format(
|
write("set({}{} \"{}\")\n".format(
|
||||||
prefix, sym.name, val))
|
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)
|
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):
|
def get_json_values(config):
|
||||||
config_dict = {}
|
config_dict = {}
|
||||||
|
@ -179,7 +345,7 @@ def get_json_values(config):
|
||||||
return config_dict
|
return config_dict
|
||||||
|
|
||||||
|
|
||||||
def write_json(config, filename):
|
def write_json(deprecated_options, config, filename):
|
||||||
config_dict = get_json_values(config)
|
config_dict = get_json_values(config)
|
||||||
with open(filename, "w") as f:
|
with open(filename, "w") as f:
|
||||||
json.dump(config_dict, f, indent=4, sort_keys=True)
|
json.dump(config_dict, f, indent=4, sort_keys=True)
|
||||||
|
@ -209,7 +375,7 @@ def get_menu_node_id(node):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def write_json_menus(config, filename):
|
def write_json_menus(deprecated_options, config, filename):
|
||||||
existing_ids = set()
|
existing_ids = set()
|
||||||
result = [] # root level items
|
result = [] # root level items
|
||||||
node_lookup = {} # lookup from MenuNode to an item in result
|
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))
|
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):
|
def update_if_changed(source, destination):
|
||||||
with open(source, "r") as f:
|
with open(source, "r") as f:
|
||||||
source_contents = f.read()
|
source_contents = f.read()
|
||||||
|
@ -313,9 +484,10 @@ def update_if_changed(source, destination):
|
||||||
|
|
||||||
|
|
||||||
OUTPUT_FORMATS = {"config": write_config,
|
OUTPUT_FORMATS = {"config": write_config,
|
||||||
|
"makefile": write_makefile, # only used with make in order to generate auto.conf
|
||||||
"header": write_header,
|
"header": write_header,
|
||||||
"cmake": write_cmake,
|
"cmake": write_cmake,
|
||||||
"docs": gen_kconfig_doc.write_docs,
|
"docs": write_docs,
|
||||||
"json": write_json,
|
"json": write_json,
|
||||||
"json_menus": write_json_menus,
|
"json_menus": write_json_menus,
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,11 +5,12 @@
|
||||||
#
|
#
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
import argparse
|
import argparse
|
||||||
|
import confgen
|
||||||
import json
|
import json
|
||||||
import kconfiglib
|
import kconfiglib
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import confgen
|
import tempfile
|
||||||
from confgen import FatalError, __version__
|
from confgen import FatalError, __version__
|
||||||
|
|
||||||
# Min/Max supported protocol versions
|
# Min/Max supported protocol versions
|
||||||
|
@ -58,6 +59,13 @@ def main():
|
||||||
|
|
||||||
def run_server(kconfig, sdkconfig, default_version=MAX_PROTOCOL_VERSION):
|
def run_server(kconfig, sdkconfig, default_version=MAX_PROTOCOL_VERSION):
|
||||||
config = kconfiglib.Kconfig(kconfig)
|
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)
|
config.load_config(sdkconfig)
|
||||||
|
|
||||||
print("Server running, waiting for requests on stdin...", file=sys.stderr)
|
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:
|
else:
|
||||||
sdkconfig = req["save"]
|
sdkconfig = req["save"]
|
||||||
|
|
||||||
error = handle_request(config, req)
|
error = handle_request(deprecated_options, config, req)
|
||||||
|
|
||||||
after = confgen.get_json_values(config)
|
after = confgen.get_json_values(config)
|
||||||
after_ranges = get_ranges(config)
|
after_ranges = get_ranges(config)
|
||||||
|
@ -136,7 +144,7 @@ def run_server(kconfig, sdkconfig, default_version=MAX_PROTOCOL_VERSION):
|
||||||
print("\n")
|
print("\n")
|
||||||
|
|
||||||
|
|
||||||
def handle_request(config, req):
|
def handle_request(deprecated_options, config, req):
|
||||||
if "version" not in req:
|
if "version" not in req:
|
||||||
return ["All requests must have a 'version'"]
|
return ["All requests must have a 'version'"]
|
||||||
|
|
||||||
|
@ -161,7 +169,7 @@ def handle_request(config, req):
|
||||||
if "save" in req:
|
if "save" in req:
|
||||||
try:
|
try:
|
||||||
print("Saving config to %s..." % req["save"], file=sys.stderr)
|
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:
|
except Exception as e:
|
||||||
error += ["Failed to save to %s: %s" % (req["save"], e)]
|
error += ["Failed to save to %s: %s" % (req["save"], e)]
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
#
|
#
|
||||||
# SDK tool configuration
|
# SDK tool configuration
|
||||||
#
|
#
|
||||||
CONFIG_TOOLPREFIX="xtensa-esp32-elf-"
|
CONFIG_SDK_TOOLPREFIX="xtensa-esp32-elf-"
|
||||||
CONFIG_PYTHON="python"
|
CONFIG_SDK_PYTHON="python"
|
||||||
CONFIG_MAKE_WARN_UNDEFINED_VARIABLES=y
|
CONFIG_SDK_MAKE_WARN_UNDEFINED_VARIABLES=y
|
||||||
|
|
||||||
#
|
#
|
||||||
# Bootloader config
|
# Bootloader config
|
||||||
|
|
Loading…
Reference in a new issue