@@ -5,108 +5,249 @@ set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
55set (STM32_CLT_REQUIRED_VERSION "1.21.0" CACHE STRING "Required STM32CubeCLT version" )
66set (TOOLCHAIN_PREFIX arm-none-eabi-)
77
8- set (_stm32_clt_candidate_roots "" )
9-
10- if (DEFINED ENV{STM32_CLT_ROOT} AND NOT "$ENV{STM32_CLT_ROOT} " STREQUAL "" )
11- list (APPEND _stm32_clt_candidate_roots "$ENV{STM32_CLT_ROOT} " )
8+ if (CMAKE_HOST_WIN32 )
9+ set (_stm32_host_os "Windows" )
10+ set (_stm32_host_exe_suffix ".exe" )
11+ elseif (CMAKE_HOST_APPLE )
12+ set (_stm32_host_os "macOS" )
13+ set (_stm32_host_exe_suffix "" )
14+ else ()
15+ set (_stm32_host_os "Linux" )
16+ set (_stm32_host_exe_suffix "" )
1217endif ()
18+
19+ function (_stm32_resolve_path _input _out_var )
20+ if ("${_input} " STREQUAL "" )
21+ set (${_out_var} "" PARENT_SCOPE )
22+ return ()
23+ endif ()
24+
25+ if (IS_ABSOLUTE "${_input} " )
26+ set (_absolute "${_input} " )
27+ else ()
28+ get_filename_component (_absolute "${_input} " ABSOLUTE BASE_DIR "${CMAKE_CURRENT_LIST_DIR} " )
29+ endif ()
30+
31+ get_filename_component (_resolved "${_absolute} " REALPATH )
32+ set (${_out_var} "${_resolved} " PARENT_SCOPE )
33+ endfunction ()
34+
35+ function (_stm32_extract_version _path _out_var )
36+ _stm32_resolve_path ("${_path} " _resolved )
37+ string (REGEX MATCH "STM32CubeCLT[_-]([0-9]+\\ .[0-9]+\\ .[0-9]+)" _match "${_resolved} " )
38+ set (${_out_var} "${CMAKE_MATCH_1} " PARENT_SCOPE )
39+ endfunction ()
40+
41+ function (_stm32_normalize_root _input _out_var )
42+ _stm32_resolve_path ("${_input} " _resolved )
43+ if (NOT EXISTS "${_resolved} " )
44+ set (${_out_var} "" PARENT_SCOPE )
45+ return ()
46+ endif ()
47+
48+ set (_root "" )
49+
50+ if (EXISTS "${_resolved} /GNU-tools-for-STM32/bin/${TOOLCHAIN_PREFIX} gcc${_stm32_host_exe_suffix} " )
51+ set (_root "${_resolved} " )
52+ elseif (IS_DIRECTORY "${_resolved} " )
53+ get_filename_component (_resolved_name "${_resolved} " NAME )
54+ if (_resolved_name STREQUAL "GNU-tools-for-STM32" )
55+ get_filename_component (_root "${_resolved} " DIRECTORY )
56+ elseif (_resolved_name STREQUAL "bin" )
57+ get_filename_component (_gnu_dir "${_resolved} " DIRECTORY )
58+ get_filename_component (_gnu_name "${_gnu_dir} " NAME )
59+ if (_gnu_name STREQUAL "GNU-tools-for-STM32" )
60+ get_filename_component (_root "${_gnu_dir} " DIRECTORY )
61+ endif ()
62+ endif ()
63+ else ()
64+ get_filename_component (_filename "${_resolved} " NAME )
65+ if (_filename STREQUAL "${TOOLCHAIN_PREFIX} gcc${_stm32_host_exe_suffix} "
66+ OR _filename STREQUAL "${TOOLCHAIN_PREFIX} gcc" )
67+ get_filename_component (_bin_dir "${_resolved} " DIRECTORY )
68+ get_filename_component (_gnu_dir "${_bin_dir} " DIRECTORY )
69+ get_filename_component (_gnu_name "${_gnu_dir} " NAME )
70+ if (_gnu_name STREQUAL "GNU-tools-for-STM32" )
71+ get_filename_component (_root "${_gnu_dir} " DIRECTORY )
72+ endif ()
73+ endif ()
74+ endif ()
75+
76+ if (_root STREQUAL "" )
77+ set (_root "${_resolved} " )
78+ endif ()
79+
80+ _stm32_resolve_path ("${_root} " _resolved_root )
81+ if (EXISTS "${_resolved_root} /GNU-tools-for-STM32/bin/${TOOLCHAIN_PREFIX} gcc${_stm32_host_exe_suffix} " )
82+ set (${_out_var} "${_resolved_root} " PARENT_SCOPE )
83+ else ()
84+ set (${_out_var} "" PARENT_SCOPE )
85+ endif ()
86+ endfunction ()
87+
88+ function (_stm32_validate_explicit_root _env_name _env_value _out_var )
89+ _stm32_normalize_root ("${_env_value} " _root )
90+ if (NOT _root)
91+ message (FATAL_ERROR
92+ "${_env_name} is set, but it does not resolve to a STM32CubeCLT installation root, "
93+ "GNU-tools bin directory, or arm-none-eabi-gcc binary:\n ${_env_value} "
94+ )
95+ endif ()
96+
97+ _stm32_extract_version ("${_root} " _version )
98+ if (NOT _version)
99+ message (FATAL_ERROR
100+ "${_env_name} resolves to a STM32CubeCLT installation, but its version cannot be "
101+ "inferred from the real path:\n ${_root} "
102+ )
103+ endif ()
104+
105+ if (NOT _version STREQUAL STM32_CLT_REQUIRED_VERSION)
106+ message (FATAL_ERROR
107+ "${_env_name} resolves to STM32CubeCLT ${_version} , but ${STM32_CLT_REQUIRED_VERSION} "
108+ "is required:\n ${_root} "
109+ )
110+ endif ()
111+
112+ set (${_out_var} "${_root} " PARENT_SCOPE )
113+ endfunction ()
114+
115+ set (STM32_CLT_ROOT "" )
116+
13117if (DEFINED ENV{HYPER_STM32CLT_ROOT} AND NOT "$ENV{HYPER_STM32CLT_ROOT} " STREQUAL "" )
14- list (APPEND _stm32_clt_candidate_roots "$ENV{HYPER_STM32CLT_ROOT} " )
118+ _stm32_validate_explicit_root ("HYPER_STM32CLT_ROOT" "$ENV{HYPER_STM32CLT_ROOT} " STM32_CLT_ROOT )
119+ elseif (DEFINED ENV{STM32_CLT_ROOT} AND NOT "$ENV{STM32_CLT_ROOT} " STREQUAL "" )
120+ _stm32_validate_explicit_root ("STM32_CLT_ROOT" "$ENV{STM32_CLT_ROOT} " STM32_CLT_ROOT )
15121endif ()
16122
17- if (WIN32 )
18- if (DEFINED ENV{ProgramFiles} AND NOT "$ENV{ProgramFiles} " STREQUAL "" )
123+ if (NOT STM32_CLT_ROOT)
124+ set (_stm32_clt_search_bases "" )
125+
126+ if (CMAKE_HOST_WIN32 )
127+ if (DEFINED ENV{ProgramFiles} AND NOT "$ENV{ProgramFiles} " STREQUAL "" )
128+ list (APPEND _stm32_clt_search_bases
129+ "$ENV{ProgramFiles} /STMicroelectronics/STM32Cube"
130+ "$ENV{ProgramFiles} /STMicroelectronics"
131+ )
132+ endif ()
133+ list (APPEND _stm32_clt_search_bases
134+ "C:/ST"
135+ )
136+ elseif (CMAKE_HOST_APPLE )
137+ list (APPEND _stm32_clt_search_bases
138+ "/Applications/STMicroelectronics/STM32Cube"
139+ "/Applications/STMicroelectronics"
140+ "/opt/ST"
141+ "$ENV{HOME} /ST"
142+ )
143+ else ()
144+ list (APPEND _stm32_clt_search_bases
145+ "/opt/ST"
146+ "$ENV{HOME} /ST"
147+ )
148+ endif ()
149+
150+ list (REMOVE_DUPLICATES _stm32_clt_search_bases)
151+
152+ set (_stm32_clt_candidate_roots "" )
153+ foreach (_base_dir IN LISTS _stm32_clt_search_bases)
154+ if ("${_base_dir} " STREQUAL "" )
155+ continue ()
156+ endif ()
157+
19158 list (APPEND _stm32_clt_candidate_roots
20- "$ENV{ProgramFiles} /STMicroelectronics/STM32Cube /STM32CubeCLT_${STM32_CLT_REQUIRED_VERSION} "
21- "$ENV{ProgramFiles} /STMicroelectronics/STM32CubeCLT_ ${STM32_CLT_REQUIRED_VERSION} "
159+ "${_base_dir} /STM32CubeCLT_${STM32_CLT_REQUIRED_VERSION} "
160+ "${_base_dir} /STM32CubeCLT- ${STM32_CLT_REQUIRED_VERSION} "
22161 )
162+
23163 file (GLOB _stm32_clt_globbed LIST_DIRECTORIES true
24- "$ENV{ProgramFiles} /STMicroelectronics/STM32Cube/STM32CubeCLT_${STM32_CLT_REQUIRED_VERSION} *"
25- "$ENV{ProgramFiles} /STMicroelectronics/STM32Cube/STM32CubeCLT-${STM32_CLT_REQUIRED_VERSION} *"
26- "$ENV{ProgramFiles} /STMicroelectronics/STM32CubeCLT_${STM32_CLT_REQUIRED_VERSION} *"
27- "$ENV{ProgramFiles} /STMicroelectronics/STM32CubeCLT-${STM32_CLT_REQUIRED_VERSION} *"
164+ "${_base_dir} /STM32CubeCLT_${STM32_CLT_REQUIRED_VERSION} *"
165+ "${_base_dir} /STM32CubeCLT-${STM32_CLT_REQUIRED_VERSION} *"
28166 )
29167 list (APPEND _stm32_clt_candidate_roots ${_stm32_clt_globbed} )
30- endif ()
31- list (APPEND _stm32_clt_candidate_roots
32- "C:/ST/STM32CubeCLT_${STM32_CLT_REQUIRED_VERSION} "
33- "C:/ST/STM32CubeCLT-${STM32_CLT_REQUIRED_VERSION} "
34- )
35- file (GLOB _stm32_clt_globbed_c LIST_DIRECTORIES true
36- "C:/ST/STM32CubeCLT_${STM32_CLT_REQUIRED_VERSION} *"
37- "C:/ST/STM32CubeCLT-${STM32_CLT_REQUIRED_VERSION} *"
38- )
39- list (APPEND _stm32_clt_candidate_roots ${_stm32_clt_globbed_c} )
40- else ()
41- list (APPEND _stm32_clt_candidate_roots
42- "/opt/ST/STM32CubeCLT_${STM32_CLT_REQUIRED_VERSION} "
43- "/opt/ST/STM32CubeCLT-${STM32_CLT_REQUIRED_VERSION} "
44- "$ENV{HOME} /ST/STM32CubeCLT_${STM32_CLT_REQUIRED_VERSION} "
45- "$ENV{HOME} /ST/STM32CubeCLT-${STM32_CLT_REQUIRED_VERSION} "
46- )
47- file (GLOB _stm32_clt_globbed LIST_DIRECTORIES true
48- "/opt/ST/STM32CubeCLT_${STM32_CLT_REQUIRED_VERSION} *"
49- "/opt/ST/STM32CubeCLT-${STM32_CLT_REQUIRED_VERSION} *"
50- "$ENV{HOME} /ST/STM32CubeCLT_${STM32_CLT_REQUIRED_VERSION} *"
51- "$ENV{HOME} /ST/STM32CubeCLT-${STM32_CLT_REQUIRED_VERSION} *"
52- )
53- list (APPEND _stm32_clt_candidate_roots ${_stm32_clt_globbed} )
54- endif ()
168+ endforeach ()
55169
56- list (REMOVE_DUPLICATES _stm32_clt_candidate_roots)
170+ list (REMOVE_DUPLICATES _stm32_clt_candidate_roots)
57171
58- set (STM32_CLT_ROOT "" )
59- foreach (_candidate IN LISTS _stm32_clt_candidate_roots)
60- if (EXISTS "${_candidate} /GNU-tools-for-STM32/bin/${TOOLCHAIN_PREFIX} gcc" )
61- set (STM32_CLT_ROOT "${_candidate} " )
62- break ()
63- endif ()
64- endforeach ()
172+ foreach (_candidate IN LISTS _stm32_clt_candidate_roots)
173+ _stm32_normalize_root ("${_candidate} " _candidate_root )
174+ if (NOT _candidate_root)
175+ continue ()
176+ endif ()
177+
178+ _stm32_extract_version ("${_candidate_root} " _candidate_version )
179+ if (_candidate_version STREQUAL STM32_CLT_REQUIRED_VERSION)
180+ set (STM32_CLT_ROOT "${_candidate_root} " )
181+ break ()
182+ endif ()
183+ endforeach ()
184+ endif ()
65185
66186if (NOT STM32_CLT_ROOT)
67- find_program (_stm32_arm_gcc NAMES ${TOOLCHAIN_PREFIX} gcc )
187+ find_program (_stm32_arm_gcc
188+ NAMES
189+ ${TOOLCHAIN_PREFIX} gcc
190+ ${TOOLCHAIN_PREFIX} gcc${_stm32_host_exe_suffix}
191+ )
68192 if (NOT _stm32_arm_gcc)
69193 message (FATAL_ERROR
70194 "STM32CubeCLT ${STM32_CLT_REQUIRED_VERSION} is required, but arm-none-eabi-gcc was not found. "
71- "Install the required CLT and/or set STM32_CLT_ROOT."
195+ "Install the required CLT and/or set HYPER_STM32CLT_ROOT or STM32_CLT_ROOT."
72196 )
73197 endif ()
74198
75- get_filename_component (_stm32_arm_gcc_realpath "${_stm32_arm_gcc} " REALPATH )
76- string (REGEX MATCH "STM32CubeCLT[_-]([0-9]+\\ .[0-9]+\\ .[0-9]+)" _stm32_path_match "${_stm32_arm_gcc_realpath} " )
199+ _stm32_normalize_root ("${_stm32_arm_gcc} " _stm32_path_root )
200+ if (NOT _stm32_path_root)
201+ message (FATAL_ERROR
202+ "STM32CubeCLT ${STM32_CLT_REQUIRED_VERSION} is required, but the compiler found in PATH "
203+ "does not belong to a STM32CubeCLT GNU-tools-for-STM32 layout:\n ${_stm32_arm_gcc} "
204+ )
205+ endif ()
77206
78- if (NOT CMAKE_MATCH_1)
207+ _stm32_extract_version ("${_stm32_path_root} " _stm32_path_version )
208+ if (NOT _stm32_path_version)
79209 message (FATAL_ERROR
80- "STM32CubeCLT ${STM32_CLT_REQUIRED_VERSION} is required, but the compiler in PATH "
81- "does not point to a versioned STM32CubeCLT installation :\n ${_stm32_arm_gcc_realpath } "
210+ "STM32CubeCLT ${STM32_CLT_REQUIRED_VERSION} is required, but the compiler found in PATH "
211+ "comes from a CLT install whose real path does not expose a version :\n ${_stm32_path_root } "
82212 )
83213 endif ()
84214
85- if (NOT CMAKE_MATCH_1 STREQUAL STM32_CLT_REQUIRED_VERSION)
215+ if (NOT _stm32_path_version STREQUAL STM32_CLT_REQUIRED_VERSION)
86216 message (FATAL_ERROR
87- "STM32CubeCLT ${STM32_CLT_REQUIRED_VERSION} is required, but found ${CMAKE_MATCH_1} :\n ${_stm32_arm_gcc_realpath} "
217+ "STM32CubeCLT ${STM32_CLT_REQUIRED_VERSION} is required, but PATH resolves to "
218+ "${_stm32_path_version} :\n ${_stm32_path_root} "
88219 )
89220 endif ()
90221
91- get_filename_component (_stm32_bin_dir "${_stm32_arm_gcc_realpath} " DIRECTORY )
92- get_filename_component (_stm32_gnu_dir "${_stm32_bin_dir} " DIRECTORY )
93- get_filename_component (STM32_CLT_ROOT "${_stm32_gnu_dir} " DIRECTORY )
222+ set (STM32_CLT_ROOT "${_stm32_path_root} " )
94223endif ()
95224
96- string (REGEX MATCH "STM32CubeCLT[_-]([0-9]+\\ .[0-9]+\\ .[0-9]+)" _stm32_root_match "${STM32_CLT_ROOT} " )
97- if (CMAKE_MATCH_1 AND NOT CMAKE_MATCH_1 STREQUAL STM32_CLT_REQUIRED_VERSION)
98- message (FATAL_ERROR
99- "STM32CubeCLT ${STM32_CLT_REQUIRED_VERSION} is required, but selected root is ${CMAKE_MATCH_1} :\n ${STM32_CLT_ROOT} "
100- )
101- endif ()
225+ set (STM32_CLT_ROOT "${STM32_CLT_ROOT} " CACHE PATH "Resolved STM32CubeCLT root" FORCE )
102226
103227set (ARM_TOOLCHAIN_DIR "${STM32_CLT_ROOT} /GNU-tools-for-STM32/bin" )
104- set (CMAKE_C_COMPILER "${ARM_TOOLCHAIN_DIR} /${TOOLCHAIN_PREFIX} gcc" )
228+ set (CMAKE_C_COMPILER "${ARM_TOOLCHAIN_DIR} /${TOOLCHAIN_PREFIX} gcc${_stm32_host_exe_suffix} " )
105229set (CMAKE_ASM_COMPILER "${CMAKE_C_COMPILER} " )
106- set (CMAKE_CXX_COMPILER "${ARM_TOOLCHAIN_DIR} /${TOOLCHAIN_PREFIX} g++" )
230+ set (CMAKE_CXX_COMPILER "${ARM_TOOLCHAIN_DIR} /${TOOLCHAIN_PREFIX} g++${_stm32_host_exe_suffix} " )
231+
232+ set (CMAKE_OBJCOPY "${ARM_TOOLCHAIN_DIR} /${TOOLCHAIN_PREFIX} objcopy${_stm32_host_exe_suffix} " CACHE INTERNAL "objcopy tool" )
233+ set (CMAKE_OBJDUMP "${ARM_TOOLCHAIN_DIR} /${TOOLCHAIN_PREFIX} objdump${_stm32_host_exe_suffix} " CACHE INTERNAL "objdump tool" )
234+ set (CMAKE_SIZE_UTIL "${ARM_TOOLCHAIN_DIR} /${TOOLCHAIN_PREFIX} size${_stm32_host_exe_suffix} " CACHE INTERNAL "size tool" )
235+ set (CMAKE_NM "${ARM_TOOLCHAIN_DIR} /${TOOLCHAIN_PREFIX} nm${_stm32_host_exe_suffix} " CACHE INTERNAL "nm tool" )
236+ set (CMAKE_STRIP "${ARM_TOOLCHAIN_DIR} /${TOOLCHAIN_PREFIX} strip${_stm32_host_exe_suffix} " CACHE INTERNAL "strip tool" )
107237
108- set (CMAKE_OBJCOPY "${ARM_TOOLCHAIN_DIR} /${TOOLCHAIN_PREFIX} objcopy" CACHE INTERNAL "objcopy tool" )
109- set (CMAKE_SIZE_UTIL "${ARM_TOOLCHAIN_DIR} /${TOOLCHAIN_PREFIX} size" CACHE INTERNAL "size tool" )
238+ if (EXISTS "${ARM_TOOLCHAIN_DIR} /${TOOLCHAIN_PREFIX} gcc-ar${_stm32_host_exe_suffix} " )
239+ set (CMAKE_C_COMPILER_AR "${ARM_TOOLCHAIN_DIR} /${TOOLCHAIN_PREFIX} gcc-ar${_stm32_host_exe_suffix} " )
240+ set (CMAKE_CXX_COMPILER_AR "${ARM_TOOLCHAIN_DIR} /${TOOLCHAIN_PREFIX} gcc-ar${_stm32_host_exe_suffix} " )
241+ endif ()
242+ if (EXISTS "${ARM_TOOLCHAIN_DIR} /${TOOLCHAIN_PREFIX} gcc-ranlib${_stm32_host_exe_suffix} " )
243+ set (CMAKE_C_COMPILER_RANLIB "${ARM_TOOLCHAIN_DIR} /${TOOLCHAIN_PREFIX} gcc-ranlib${_stm32_host_exe_suffix} " )
244+ set (CMAKE_CXX_COMPILER_RANLIB "${ARM_TOOLCHAIN_DIR} /${TOOLCHAIN_PREFIX} gcc-ranlib${_stm32_host_exe_suffix} " )
245+ endif ()
246+
247+ if (NOT DEFINED _STM32_CLT_STATUS_EMITTED)
248+ message (STATUS "Using STM32CubeCLT ${STM32_CLT_REQUIRED_VERSION} on ${_stm32_host_os} : ${STM32_CLT_ROOT} " )
249+ set (_STM32_CLT_STATUS_EMITTED TRUE CACHE INTERNAL "STM32 toolchain status emitted" FORCE )
250+ endif ()
110251
111252set (CMAKE_FIND_ROOT_PATH "${STM32_CLT_ROOT} " )
112253set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
0 commit comments