2
votes

I'm porting code from IAR on Windows for an STM32F4 to OSX/GNU/CMake.

I've defined a toolchain file ARM.cmake to use arm-none-eabi-g++/gcc. When I run cmake (referencing the toolchain file) I get an error when it tries to link the simple test program. It complains that _exit() is not defined.

I understand that exit() is being called and it calls _exit() which it expects to find elsewhere. Perhaps when I eventually link against my RTOS it will have this defined or perhaps I have to define it myself. In the meantime how do I get past the compiler checks?

set(CMAKE_SYSTEM_NAME Generic)

set(CMAKE_SYSTEM_PROCESSOR STM32F407)

set(CMAKE_C_COMPILER arm-none-eabi-gcc)

set(CMAKE_CXX_COMPILER arm-none-eabi-g++)

4

4 Answers

2
votes

Including the CMake include file CMakeForceCompiler and using the "FORCE" macros solved the problem. Answered indirectly here.

include(CMakeForceCompiler)

set(CMAKE_SYSTEM_NAME Generic)

set(CMAKE_SYSTEM_PROCESSOR STM32F407)

CMAKE_FORCE_C_COMPILER(arm-none-eabi-gcc GNU)

CMAKE_FORCE_CXX_COMPILER(arm-none-eabi-g++ GNU)

1
votes

If you don't need or want syscalls, you can use nosys.specs.

Here's a snippet from our arm-gcc CMake toolchain file targeting Cortex-M:

string(CONCAT CM4_LINK_FLAGS
    "--specs=nosys.specs "  # firmware has no syscall implementation
    "-lnosys "              # syscalls are empty stubs
    "-lc"                   # libc with nosys.spec uses newlib-nano
    )

set(CMAKE_EXE_LINKER_FLAGS "${CM4_LINK_FLAGS}" CACHE INTERNAL "")

If this is in your toolchain file, you can load it from the command line by invoking CMake with -DCMAKE_TOOLCHAIN_FILE=<path-to-your-toolchain>. Since it's loaded before your first project directive, CMake uses these flags during compiler exploration and its small test files will compile and link successfully.

Alternately, skip compiler exploration entirely with:

set(CMAKE_C_COMPILER_WORKS ON)
set(CMAKE_CXX_COMPILER_WORKS ON)

You're explicitly setting your known compiler for a fixed architecture; maybe you're also explicitly setting your flags and don't need CMake to interrogate your toolchain.

0
votes

Setting CMAKE_TRY_COMPILE_TARGET_TYPE to STATIC_LIBRARY skips the linking step, and solves problems with both missing functions during linking and missing linker files.

So in the toolchain file:

set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)

(Forcing the compiler is a deprecated function and should be avoided if possible)