2

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++)

Kenny
  • 675
  • 10
  • 24

4 Answers4

2

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)

Community
  • 1
  • 1
Kenny
  • 675
  • 10
  • 24
2

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.

Charles Nicholson
  • 888
  • 1
  • 8
  • 21
0

Just add an empty function void _exit(int status) {}. Check here if you want more info: http://stm32discovery.nano-age.co.uk/open-source-development-with-the-stm32-discovery/getting-newlib-to-work-with-stm32-and-code-sourcery-lite-eabi

  • Thanks. I understand how this would help link my application but will this get me past the compiler checks cmake performs? I'm not sure I understand how the checks would be aware of some object file or library I created that contains my empty _exit(). – Kenny Apr 15 '14 at 04:43
  • And I apologize: I haven't yet read the link. I'll do that tomorrow when I resume this project. Thought I'd get the question in the hopper in case my original post was not clear. – Kenny Apr 15 '14 at 04:48
  • If you're at the linking stage, then your source is already checked by the compiler and compiled. Or am I missing something? – Michal Ksiezopolski Apr 15 '14 at 15:33
  • 1
    CMake seems to have some test file that it compiles as a check before it gets started. Maybe it's an empty main or something. I should be clear and state that it fails the compile/link step when testing the C/C++ compilers. CMake then bails out with an error and my project make files are not generated. If I were to get past this step then I can add my _exit() definition and my project will link OK. Just not sure how to tell the test code to use it. – Kenny Apr 15 '14 at 16:04
0

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)

Daid Braam
  • 173
  • 4