idf.py: guess IDF_TARGET from sdkconfig if CMakeCache doesn't exist

This solves the issue that target is changed to the default one after
idf.py fullclean.

Also allow setting the default target using sdkconfig.defaults, e.g.
CONFIG_IDF_TARGET="esp32s2"

Closes IDF-1040
This commit is contained in:
Ivan Grokhotkov 2020-01-30 17:18:20 +01:00
parent ca735340f9
commit b76a10dd4f
2 changed files with 60 additions and 0 deletions

View file

@ -325,6 +325,34 @@ function run_tests()
grep "CONFIG_IDF_TARGET=\"${other_target}\"" sdkconfig || failure "Project not configured correctly using idf.py set-target"
grep "IDF_TARGET:STRING=${other_target}" build/CMakeCache.txt || failure "IDF_TARGET not set in CMakeCache.txt using idf.py set-target"
print_status "Can guess target from sdkconfig, if CMakeCache does not exist"
idf.py fullclean || failure "Failed to clean the build directory"
idf.py reconfigure || failure "Failed to reconfigure after fullclean"
grep "CONFIG_IDF_TARGET=\"${other_target}\"" sdkconfig || failure "Didn't find the expected CONFIG_IDF_TARGET value"
grep "IDF_TARGET:STRING=${other_target}" build/CMakeCache.txt || failure "IDF_TARGET not set in CMakeCache.txt after fullclean and reconfigure"
print_status "Can set the default target using sdkconfig.defaults"
clean_build_dir
rm sdkconfig
echo "CONFIG_IDF_TARGET=\"${other_target}\"" > sdkconfig.defaults
idf.py reconfigure || failure "Failed to reconfigure with default target set in sdkconfig.defaults"
grep "CONFIG_IDF_TARGET=\"${other_target}\"" sdkconfig || failure "Didn't find the expected CONFIG_IDF_TARGET value"
grep "CONFIG_IDF_TARGET_${other_target^^}=y" sdkconfig || failure "Didn't find CONFIG_IDF_TARGET_${other_target^^} value"
grep "IDF_TARGET:STRING=${other_target}" build/CMakeCache.txt || failure "IDF_TARGET not set in CMakeCache.txt after fullclean and reconfigure"
rm sdkconfig.defaults
print_status "IDF_TARGET takes precedence over the value of CONFIG_IDF_TARGET in sdkconfig.defaults"
clean_build_dir
rm sdkconfig
echo "CONFIG_IDF_TARGET=\"${other_target}\"" > sdkconfig.defaults
export IDF_TARGET=esp32
idf.py reconfigure || failure "Failed to reconfigure with default target set in sdkconfig.defaults and different IDF_TARGET in the environment"
grep "CONFIG_IDF_TARGET=\"esp32\"" sdkconfig || failure "Didn't find the expected CONFIG_IDF_TARGET value"
grep "CONFIG_IDF_TARGET_ESP32=y" sdkconfig || failure "Didn't find CONFIG_IDF_TARGET_${other_target^^} value"
grep "IDF_TARGET:STRING=esp32" build/CMakeCache.txt || failure "IDF_TARGET not set in CMakeCache.txt after fullclean and reconfigure"
rm sdkconfig.defaults
unset IDF_TARGET
unset other_target # done changing target from the default
clean_build_dir
rm sdkconfig

View file

@ -158,6 +158,18 @@ def ensure_build_directory(args, prog_name, always_run_cmake=False):
if not os.path.isdir(build_dir):
os.makedirs(build_dir)
cache_path = os.path.join(build_dir, "CMakeCache.txt")
if not os.path.exists(cache_path) and not os.environ.get("IDF_TARGET"):
# CMakeCache.txt does not exist yet, and IDF_TARGET is not set in the environment.
# Try to guess the target from sdkconfig, so that it doesn't get reset to the default ("esp32").
sdkconfig_path = os.path.join(args.project_dir, "sdkconfig")
# Also consider the CONFIG_IDF_TARGET value in sdkconfig.defaults.
sdkconfig_defaults_path = os.path.join(args.project_dir, "sdkconfig.defaults")
idf_target_from_sdkconfig = (get_sdkconfig_value(sdkconfig_path, "CONFIG_IDF_TARGET") or
get_sdkconfig_value(sdkconfig_defaults_path, "CONFIG_IDF_TARGET"))
if idf_target_from_sdkconfig:
if args.verbose:
print("IDF_TARGET is not set, guessed '%s' from sdkconfig" % (idf_target_from_sdkconfig))
args.define_cache_entry.append("IDF_TARGET=" + idf_target_from_sdkconfig)
args.define_cache_entry.append("CCACHE_ENABLE=%d" % args.ccache)
@ -220,3 +232,23 @@ def merge_action_lists(*action_lists):
merged_actions["actions"].update(action_list.get("actions", {}))
merged_actions["global_action_callbacks"].extend(action_list.get("global_action_callbacks", []))
return merged_actions
def get_sdkconfig_value(sdkconfig_file, key):
"""
Return the value of given key from sdkconfig_file.
If sdkconfig_file does not exist or the option is not present, returns None.
"""
assert key.startswith("CONFIG_")
if not os.path.exists(sdkconfig_file):
return None
# keep track of the last seen value for the given key
value = None
# if the value is quoted, this excludes the quotes from the value
pattern = re.compile(r"^{}=\"?([^\"]*)\"?$".format(key))
with open(sdkconfig_file, "r") as f:
for line in f:
match = re.match(pattern, line)
if match:
value = match.group(1)
return value