idf.py: fail and show instructions on IDF_TARGET mismatch

Closes IDF-869
This commit is contained in:
Ivan Grokhotkov 2020-01-31 11:08:22 +01:00
parent 036a29bb3d
commit 9bff344ef5
2 changed files with 68 additions and 15 deletions

View file

@ -307,7 +307,7 @@ function run_tests()
rm sdkconfig
rm sdkconfig.defaults
# the next four tests use the esp32s2 target
# the next tests use the esp32s2 target
export other_target=esp32s2
print_status "Can override IDF_TARGET from environment"
@ -368,6 +368,20 @@ function run_tests()
rm sdkconfig.defaults
unset IDF_TARGET
print_status "idf.py fails if IDF_TARGET settings don't match in sdkconfig, CMakeCache.txt, and the environment"
clean_build_dir
rm sdkconfig
idf.py set-target ${other_target} || failure "Couldn't set target to ${other_target}"
# Change to a different IDF_TARGET in the environment
export IDF_TARGET=esp32
! idf.py reconfigure || failure "Build did't fail when IDF_TARGET was set to an incompatible value in the environment"
# Now make sdkconfig consistent with the environement (note: not really consistent, just for the purpose of the test)
echo "CONFIG_IDF_TARGET=\"esp32\"" >> sdkconfig
! idf.py reconfigure || failure "Build did't fail when IDF_TARGET in CMakeCache.txt didn't match the environment"
# Now unset IDF_TARGET in the environment, sdkconfig and CMakeCache.txt are still inconsistent
unset IDF_TARGET
! idf.py reconfigure || failure "Build did't fail when IDF_TARGET in CMakeCache.txt didn't match the sdkconfig"
unset other_target # done changing target from the default
clean_build_dir
rm sdkconfig

View file

@ -170,19 +170,13 @@ def ensure_build_directory(args, prog_name, always_run_cmake=False):
build_dir = args.build_dir
if not os.path.isdir(build_dir):
os.makedirs(build_dir)
# Parse CMakeCache, if it exists
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)
cache = _parse_cmakecache(cache_path) if os.path.exists(cache_path) else {}
# Validate or set IDF_TARGET
_guess_or_check_idf_target(args, prog_name, cache)
args.define_cache_entry.append("CCACHE_ENABLE=%d" % args.ccache)
@ -212,8 +206,6 @@ def ensure_build_directory(args, prog_name, always_run_cmake=False):
os.remove(cache_path)
raise
# Learn some things from the CMakeCache.txt file in the build directory
cache = _parse_cmakecache(cache_path)
try:
generator = cache["CMAKE_GENERATOR"]
except KeyError:
@ -265,3 +257,50 @@ def get_sdkconfig_value(sdkconfig_file, key):
if match:
value = match.group(1)
return value
def _guess_or_check_idf_target(args, prog_name, cache):
"""
If CMakeCache.txt doesn't exist, and IDF_TARGET is not set in the environment, guess the value from
sdkconfig or sdkconfig.defaults, and pass it to CMake in IDF_TARGET variable.
Otherwise, cross-check the three settings (sdkconfig, CMakeCache, environment) and if there is
mismatch, fail with instructions on how to fix this.
"""
# Default locations of sdkconfig files.
# FIXME: they may be overridden in the project or by a CMake variable (IDF-1369).
sdkconfig_path = os.path.join(args.project_dir, "sdkconfig")
sdkconfig_defaults_path = os.path.join(args.project_dir, "sdkconfig.defaults")
# These are used to guess the target from sdkconfig, or set the default target by sdkconfig.defaults.
idf_target_from_sdkconfig = get_sdkconfig_value(sdkconfig_path, "CONFIG_IDF_TARGET")
idf_target_from_sdkconfig_defaults = get_sdkconfig_value(sdkconfig_defaults_path, "CONFIG_IDF_TARGET")
idf_target_from_env = os.environ.get("IDF_TARGET")
idf_target_from_cache = cache.get("IDF_TARGET")
if not cache and not idf_target_from_env:
# CMakeCache.txt does not exist yet, and IDF_TARGET is not set in the environment.
guessed_target = idf_target_from_sdkconfig or idf_target_from_sdkconfig_defaults
if guessed_target:
if args.verbose:
print("IDF_TARGET is not set, guessed '%s' from sdkconfig" % (guessed_target))
args.define_cache_entry.append("IDF_TARGET=" + guessed_target)
elif idf_target_from_env:
# Let's check that IDF_TARGET values are consistent
if idf_target_from_sdkconfig and idf_target_from_sdkconfig != idf_target_from_env:
raise FatalError("Project sdkconfig was generated for target '{t_conf}', but environment variable IDF_TARGET "
"is set to '{t_env}'. Run '{prog} set-target {t_env}' to generate new sdkconfig file for target {t_env}."
.format(t_conf=idf_target_from_sdkconfig, t_env=idf_target_from_env, prog=prog_name))
if idf_target_from_cache and idf_target_from_cache != idf_target_from_env:
raise FatalError("Target settings are not consistent: '{t_env}' in the environment, '{t_cache}' in CMakeCache.txt. "
"Run '{prog} fullclean' to start again."
.format(t_env=idf_target_from_env, t_cache=idf_target_from_cache, prog=prog_name))
elif idf_target_from_cache and idf_target_from_sdkconfig and idf_target_from_cache != idf_target_from_sdkconfig:
# This shouldn't happen, unless the user manually edits CMakeCache.txt or sdkconfig, but let's check anyway.
raise FatalError("Project sdkconfig was generated for target '{t_conf}', but CMakeCache.txt contains '{t_cache}'. "
"To keep the setting in sdkconfig ({t_conf}) and re-generate CMakeCache.txt, run '{prog} fullclean'. "
"To re-generate sdkconfig for '{t_cache}' target, run '{prog} set-target {t_cache}'."
.format(t_conf=idf_target_from_sdkconfig, t_cache=idf_target_from_cache, prog=prog_name))