Could not find CMAKE_C_COMPILER using the following names: arm-none-eabi-gcc

I need to write a toolchain file that allows the user to specify the compiler binary’s directory, because the user may install different toolchains with the same compiler name.

# This file depends on TOOLCHAIN_BIN_PATH provided by user
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR ARM)
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
set(CMAKE_C_COMPILER "${TOOLCHAIN_BIN_PATH}/arm-none-eabi-gcc.exe")
set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER})
set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN_BIN_PATH})
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

The above toolchain file works. But it uses the non-portable .exe extension. I want to make it portable so I replace the line set(CMAKE_C_COMPILER "${TOOLCHAIN_BIN_PATH}/arm-none-eabi-gcc.exe") with find_program(CMAKE_C_COMPILER arm-none-eabi-gcc PATHS ${TOOLCHAIN_BIN_PATH} REQUIRED NO_DEFAULT_PATH)

The error message is

– The C compiler identification is GNU 11.3.1
– The ASM compiler identification is GNU
– Found assembler: D:/Program/STM32CubeIDE/STM32CubeIDE/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.11.3.rel1.win32_1.1.100.202309141235/tools/bin/arm-none-eabi-gcc.exe
– Check for working C compiler: D:/Program/STM32CubeIDE/STM32CubeIDE/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.11.3.rel1.win32_1.1.100.202309141235/tools/bin/arm-none-eabi-gcc.exe
CMake Error at D:/repo/toolchain.cmake:8 (find_program):
Could not find CMAKE_C_COMPILER using the following names:
arm-none-eabi-gcc
Call Stack (most recent call first):
D:/repo/build/CMakeFiles/3.28.0/CMakeSystem.cmake:6 (include)
D:/repo/build/CMakeFiles/CMakeScratch/TryCompile-fjk3in/CMakeLists.txt:4 (project)
CMake Error at C:/msys64/mingw64/share/cmake/Modules/CMakeTestCCompiler.cmake:56 (try_compile):
Failed to configure test project build system.
Call Stack (most recent call first):
CMakeLists.txt:12 (project)
– Configuring incomplete, errors occurred!

It seems the toolchain file was evaluated more than once. In the second run, the TOOLCHAIN_BIN_PATH was empty.

TOOLCHAIN_BIN_PATH is supposed to be passed from command line like cmake .. -DTOOLCHAIN_BIN_PATH=<path>. The toolchain file is set in the CMakeLists via set(CMAKE_TOOLCHAIN_FILE toolchain.cmake)

Where? It really should be a user setting, but if you’re doing this it must be before any project() calls.

Structure of my CMakeLists.txt:

cmake_minimum_required(VERSION 3.16)
set(CMAKE_TOOLCHAIN_FILE toolchain.cmake)
project(hello LANGUAGES C ASM)
add_executable(hello
# files
)
# target_include_directories, target_compile_options, target_link_options