mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
tools: cmake: check tool supported version with idf_tools.py
This commit is contained in:
parent
d6aacbc9ce
commit
e6f7b1a3a0
@ -2,9 +2,12 @@
|
||||
# Warn if the toolchain version doesn't match
|
||||
#
|
||||
if(NOT (${target} STREQUAL "linux" OR CMAKE_C_COMPILER_ID MATCHES "Clang"))
|
||||
get_expected_ctng_version(expected_toolchain expected_gcc)
|
||||
gcc_version_check("${expected_gcc}")
|
||||
crosstool_version_check("${expected_toolchain}")
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_C_COMPILER} -dumpmachine
|
||||
OUTPUT_VARIABLE toolchain_name
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
ERROR_QUIET)
|
||||
check_expected_tool_version(${toolchain_name} ${CMAKE_C_COMPILER})
|
||||
endif()
|
||||
|
||||
if(NOT ${target} STREQUAL "linux" AND CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
|
@ -1,35 +1,16 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
include(${IDF_PATH}/tools/cmake/utilities.cmake)
|
||||
include(${IDF_PATH}/tools/cmake/idf.cmake)
|
||||
project(${ULP_APP_NAME} ASM C)
|
||||
add_executable(${ULP_APP_NAME})
|
||||
|
||||
option(ULP_COCPU_IS_RISCV "Use RISC-V based ULP" OFF)
|
||||
|
||||
set(version_pattern "[a-z0-9\.-_]+")
|
||||
|
||||
# Check assembler version
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_ASM_COMPILER} --version
|
||||
OUTPUT_VARIABLE as_output
|
||||
ERROR_QUIET)
|
||||
|
||||
string(REGEX MATCH "\\(GNU Binutils\\) (${version_pattern})" as_version ${as_output})
|
||||
set(as_version ${CMAKE_MATCH_1})
|
||||
|
||||
|
||||
message(STATUS "Building ULP app ${ULP_APP_NAME}")
|
||||
|
||||
# Check the supported assembler version
|
||||
if(NOT ULP_COCPU_IS_RISCV)
|
||||
message(STATUS "ULP assembler version: ${as_version}")
|
||||
set(as_supported_version 2.35_20220830)
|
||||
|
||||
if(NOT as_version STREQUAL as_supported_version)
|
||||
message(WARNING "WARNING: ULP assembler version ${as_version} is not supported. Expected to see version: \
|
||||
${as_supported_version}. Please check ESP-IDF ULP setup instructions and update \
|
||||
the toolchain, or proceed at your own risk.")
|
||||
endif()
|
||||
check_expected_tool_version("esp32ulp-elf" ${CMAKE_ASM_COMPILER})
|
||||
endif()
|
||||
|
||||
|
||||
|
@ -190,7 +190,6 @@ extensions += ['sphinx_copybutton',
|
||||
# connected to another extension
|
||||
'esp_docs.idf_extensions.build_system',
|
||||
'esp_docs.idf_extensions.esp_err_definitions',
|
||||
'esp_docs.idf_extensions.gen_toolchain_links',
|
||||
'esp_docs.idf_extensions.gen_defines',
|
||||
'esp_docs.idf_extensions.gen_version_specific_includes',
|
||||
'esp_docs.idf_extensions.kconfig_reference',
|
||||
|
@ -39,4 +39,3 @@ tools/set-submodules-to-github.sh
|
||||
tools/templates/sample_component/CMakeLists.txt
|
||||
tools/templates/sample_component/include/main.h
|
||||
tools/templates/sample_component/main.c
|
||||
tools/toolchain_versions.mk
|
||||
|
@ -10,7 +10,7 @@ error\.d
|
||||
/.*error\S*.d
|
||||
reassigning to symbol
|
||||
changes choice state
|
||||
crosstool_version_check\.cmake
|
||||
tool_version_check\.cmake
|
||||
CryptographyDeprecationWarning
|
||||
Warning: \d+/\d+ app partitions are too small for binary
|
||||
CMake Deprecation Warning at main/lib/tinyxml2/CMakeLists\.txt:11 \(cmake_policy\)
|
||||
|
@ -1,59 +0,0 @@
|
||||
# Function to check the toolchain used the expected version
|
||||
# of crosstool, and warn otherwise
|
||||
|
||||
set(ctng_version_warning "Check Getting Started documentation or proceed at own risk.\n")
|
||||
|
||||
function(gcc_version_check expected_gcc_version)
|
||||
if(NOT "${CMAKE_C_COMPILER_VERSION}" STREQUAL "${expected_gcc_version}")
|
||||
message(WARNING "Toolchain ${CMAKE_C_COMPILER} version ${CMAKE_C_COMPILER_VERSION} "
|
||||
"is not the supported version ${expected_gcc_version}. ${ctng_version_warning}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(crosstool_version_check expected_ctng_version)
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_C_COMPILER} --version
|
||||
OUTPUT_VARIABLE toolchain_version
|
||||
ERROR_QUIET)
|
||||
|
||||
string(REGEX REPLACE ".*(crosstool-NG ([^\)]+)).*\n" "\\2" ctng_version "${toolchain_version}")
|
||||
# We use FIND to match version instead of STREQUAL because some toolchains are built
|
||||
# with longer git hash strings than others. This will match any version which starts with
|
||||
# the expected version string.
|
||||
string(FIND "${ctng_version}" "${expected_ctng_version}" found_expected_version)
|
||||
if(NOT ctng_version)
|
||||
message(WARNING "Toolchain ${CMAKE_C_COMPILER} does not appear to be built with crosstool-ng. "
|
||||
"${ctng_version_warning}")
|
||||
elseif(found_expected_version EQUAL -1)
|
||||
set(wrong_compiler_msg "\nToolchain: ${CMAKE_C_COMPILER}, "
|
||||
"crosstool-ng version ${ctng_version} doesn't match supported version ${expected_ctng_version}"
|
||||
"\nPlease try to run 'idf.py fullclean' to solve it quickly.\n")
|
||||
set(IDF_MAINTAINER $ENV{IDF_MAINTAINER})
|
||||
if(IDF_MAINTAINER)
|
||||
message(WARNING ${wrong_compiler_msg} ${ctng_version_warning})
|
||||
else()
|
||||
set(ctng_version_error "Check Getting Started documentation if the error continues."
|
||||
"\nYou can override this error and proceed with build by defining the IDF_MAINTAINER environment variable.\n")
|
||||
message(FATAL_ERROR ${wrong_compiler_msg} ${ctng_version_error})
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(get_expected_ctng_version _toolchain_ver _gcc_ver)
|
||||
idf_build_get_property(idf_path IDF_PATH)
|
||||
file(STRINGS ${idf_path}/tools/toolchain_versions.mk config_contents)
|
||||
foreach(name_and_value ${config_contents})
|
||||
# Strip spaces
|
||||
string(REPLACE " " "" name_and_value ${name_and_value})
|
||||
# Find variable name
|
||||
string(REGEX MATCH "^[^=]+" name ${name_and_value})
|
||||
# Find the value
|
||||
string(REPLACE "${name}=" "" value ${name_and_value})
|
||||
# Getting values
|
||||
if("${name}" STREQUAL "SUPPORTED_TOOLCHAIN_COMMIT_DESC")
|
||||
set("${_toolchain_ver}" "${value}" PARENT_SCOPE)
|
||||
elseif("${name}" STREQUAL "SUPPORTED_TOOLCHAIN_GCC_VERSIONS")
|
||||
set(${_gcc_ver} "${value}" PARENT_SCOPE)
|
||||
endif()
|
||||
endforeach()
|
||||
endfunction()
|
@ -39,7 +39,7 @@ if(NOT __idf_env_set)
|
||||
include(CheckCCompilerFlag)
|
||||
include(CheckCXXCompilerFlag)
|
||||
include(git_submodules)
|
||||
include(crosstool_version_check)
|
||||
include(tool_version_check)
|
||||
include(kconfig)
|
||||
include(component)
|
||||
include(utilities)
|
||||
|
44
tools/cmake/tool_version_check.cmake
Normal file
44
tools/cmake/tool_version_check.cmake
Normal file
@ -0,0 +1,44 @@
|
||||
function(check_expected_tool_version tool_name tool_path)
|
||||
# Function to check the tool used the expected version and warn otherwise
|
||||
set(tool_version_warning "Check Getting Started documentation or proceed at own risk.\n")
|
||||
set(tool_version_error "Check Getting Started documentation if the error continues.\n"
|
||||
"You can override this error and proceed with build by defining the IDF_MAINTAINER environment variable.\n")
|
||||
set(fixing_hint "Please try to run 'idf.py fullclean' to solve it.\n")
|
||||
|
||||
idf_build_get_property(python PYTHON)
|
||||
idf_build_get_property(idf_path IDF_PATH)
|
||||
|
||||
set(ENV{IDF_TOOLS_VERSION_HELPER} "1")
|
||||
# Use idf_tools.py to check if tool version is supported
|
||||
execute_process(
|
||||
COMMAND ${python} "${idf_path}/tools/idf_tools.py"
|
||||
"check-tool-supported" "--tool-name" "${tool_name}"
|
||||
"--exec-path" "${tool_path}"
|
||||
OUTPUT_VARIABLE is_version_supported
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
ERROR_QUIET)
|
||||
|
||||
if(is_version_supported STREQUAL "False")
|
||||
# Version is not supported. Need to get supported versions list to print them to user
|
||||
execute_process(
|
||||
COMMAND ${python} "${idf_path}/tools/idf_tools.py"
|
||||
"get-tool-supported-versions" "--tool-name" "${tool_name}"
|
||||
OUTPUT_VARIABLE tool_supported_versions
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
ERROR_QUIET)
|
||||
# IDF maintainers can build projects with not supported versions with just a warning
|
||||
if($ENV{IDF_MAINTAINER})
|
||||
set(message_mode "WARNING")
|
||||
else()
|
||||
set(message_mode "FATAL_ERROR")
|
||||
endif()
|
||||
|
||||
message(${message_mode} "\n"
|
||||
"Tool doesn't match supported version from list "
|
||||
"${tool_supported_versions}: ${tool_path}\n"
|
||||
${fixing_hint})
|
||||
elseif(NOT is_version_supported STREQUAL "True")
|
||||
message(WARNING "Can not get version for tool: ${tool_path}\n" ${tool_version_warning})
|
||||
endif()
|
||||
unset(ENV{IDF_TOOLS_VERSION_HELPER})
|
||||
endfunction()
|
@ -646,7 +646,7 @@ class IDFTool(object):
|
||||
result[k] = v_repl
|
||||
return result
|
||||
|
||||
def check_version(self, extra_paths=None): # type: (Optional[List[str]]) -> str
|
||||
def get_version(self, extra_paths=None, executable_path=None): # type: (Optional[List[str]], Optional[str]) -> str
|
||||
"""
|
||||
Execute the tool, optionally prepending extra_paths to PATH,
|
||||
extract the version string and return it as a result.
|
||||
@ -658,6 +658,8 @@ class IDFTool(object):
|
||||
# this function can not be called for a different platform
|
||||
assert self._platform == CURRENT_PLATFORM
|
||||
cmd = self._current_options.version_cmd # type: ignore
|
||||
if executable_path:
|
||||
cmd[0] = executable_path
|
||||
try:
|
||||
version_cmd_result = run_cmd_check_output(cmd, None, extra_paths)
|
||||
except OSError:
|
||||
@ -673,6 +675,10 @@ class IDFTool(object):
|
||||
return UNKNOWN_VERSION
|
||||
return re.sub(self._current_options.version_regex, self._current_options.version_regex_replace, match.group(0)) # type: ignore
|
||||
|
||||
def check_version(self, executable_path): # type: (Optional[str]) -> bool
|
||||
version = self.get_version(executable_path=executable_path)
|
||||
return version in self.versions
|
||||
|
||||
def get_install_type(self): # type: () -> Callable[[str], None]
|
||||
return self._current_options.install # type: ignore
|
||||
|
||||
@ -715,7 +721,7 @@ class IDFTool(object):
|
||||
assert self._platform == CURRENT_PLATFORM
|
||||
# First check if the tool is in system PATH
|
||||
try:
|
||||
ver_str = self.check_version()
|
||||
ver_str = self.get_version()
|
||||
except ToolNotFound:
|
||||
# not in PATH
|
||||
pass
|
||||
@ -738,7 +744,7 @@ class IDFTool(object):
|
||||
self.versions_installed.append(version)
|
||||
continue
|
||||
try:
|
||||
ver_str = self.check_version(self.get_export_paths(version))
|
||||
ver_str = self.get_version(self.get_export_paths(version))
|
||||
except ToolNotFound:
|
||||
warn('directory for tool {} version {} is present, but tool was not found'.format(
|
||||
self.name, version))
|
||||
@ -2380,6 +2386,40 @@ More info: {info_url}
|
||||
print_out('')
|
||||
|
||||
|
||||
def action_check_tool_supported(args): # type: (Any) -> None
|
||||
"""
|
||||
Print "True"/"False" to stdout as a result that tool is supported in IDF
|
||||
Print erorr message to stderr otherwise and set exit code to 1
|
||||
"""
|
||||
try:
|
||||
tools_info = load_tools_info()
|
||||
for _, v in tools_info.items():
|
||||
if v.name == args.tool_name:
|
||||
print(v.check_version(args.exec_path))
|
||||
break
|
||||
except (RuntimeError, ToolNotFound, ToolExecError) as err:
|
||||
fatal(f'Failed to check tool support: (name: {args.tool_name}, exec: {args.exec_path})')
|
||||
fatal(f'{err}')
|
||||
raise SystemExit(1)
|
||||
|
||||
|
||||
def action_get_tool_supported_versions(args): # type: (Any) -> None
|
||||
"""
|
||||
Print supported versions of a tool to stdout
|
||||
Print erorr message to stderr otherwise and set exit code to 1
|
||||
"""
|
||||
try:
|
||||
tools_info = load_tools_info()
|
||||
for _, v in tools_info.items():
|
||||
if v.name == args.tool_name:
|
||||
print(list(v.versions.keys()))
|
||||
break
|
||||
except RuntimeError as err:
|
||||
fatal(f'Failed to get tool supported versions. (tool: {args.tool_name})')
|
||||
fatal(f'{err}')
|
||||
raise SystemExit(1)
|
||||
|
||||
|
||||
def main(argv): # type: (list[str]) -> None
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
@ -2477,6 +2517,15 @@ def main(argv): # type: (list[str]) -> None
|
||||
'to manage package versions by yourself. It can be set with the IDF_PYTHON_CHECK_CONSTRAINTS '
|
||||
'environment variable.')
|
||||
|
||||
if os.environ.get('IDF_TOOLS_VERSION_HELPER'):
|
||||
check_tool_supported = subparsers.add_parser('check-tool-supported',
|
||||
help='Check that selected tool is compatible with IDF. Writes "True"/"False" to stdout in success.')
|
||||
check_tool_supported.add_argument('--tool-name', required=True, help='Tool name (from tools.json)')
|
||||
check_tool_supported.add_argument('--exec-path', required=True, help='Full path to executable under the test')
|
||||
|
||||
get_tool_supported_versions = subparsers.add_parser('get-tool-supported-versions', help='Prints a list of tool\'s supported versions')
|
||||
get_tool_supported_versions.add_argument('--tool-name', required=True, help='Tool name (from tools.json)')
|
||||
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
if args.action is None:
|
||||
|
@ -1,6 +0,0 @@
|
||||
SUPPORTED_TOOLCHAIN_COMMIT_DESC = esp-2022r1
|
||||
SUPPORTED_TOOLCHAIN_GCC_VERSIONS = 11.2.0
|
||||
|
||||
CURRENT_TOOLCHAIN_COMMIT_DESC = esp-2022r1
|
||||
CURRENT_TOOLCHAIN_COMMIT_DESC_SHORT = esp-2022r1
|
||||
CURRENT_TOOLCHAIN_GCC_VERSION = 11.2.0
|
Loading…
Reference in New Issue
Block a user