I have a C project which compiles successfully. Now I want to use C++ code in the same project, so I renamed main.c to main.cpp. The project is for an embedded microcontroller, so I'm cross compiling with the arm-none-eabi toolchain.
When I have renamed the main file to .cpp, I get the following error:
Linking CXX executable discovery_simple_test.elf /usr/lib/gcc/arm-none-eabi/<long_path>/fpu/libg.a(lib_a-abort.o): In function `abort': /build/<long_path>/newlib/libc/stdlib/abort.c:63: undefined reference to `_exit' This is because some standard libraries are not available for this "bare metal" target. (see https://stackoverflow.com/a/13237079/507369)
This is solved in my linker script:
/* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } The linker script is added by my CMake toolchain file:
INCLUDE(CMakeForceCompiler) SET(CMAKE_SYSTEM_NAME Generic) SET(CMAKE_SYSTEM_VERSION 1) # specify the cross compiler CMAKE_FORCE_C_COMPILER(arm-none-eabi-gcc GNU) CMAKE_FORCE_CXX_COMPILER(arm-none-eabi-g++ GNU) SET(LINKER_SCRIPT ${CMAKE_SOURCE_DIR}/STM32F407VGTx_FLASH.ld) SET(COMMON_FLAGS "-mcpu=cortex-m4 -mthumb -mthumb-interwork -mfloat-abi=hard -mfpu=fpv4-sp-d16 -ffunction-sections -fdata-sections -g -fno-common -fmessage-length=0") UNSET(CMAKE_CXX_FLAGS CACHE) UNSET(CMAKE_C_FLAGS CACHE) UNSET(CMAKE_EXE_LINKER_FLAGS CACHE) SET(CMAKE_CXX_FLAGS "${COMMON_FLAGS} -std=c++11" CACHE STRING "" FORCE) SET(CMAKE_C_FLAGS "${COMMON_FLAGS} -std=gnu99" CACHE STRING "" FORCE) SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--gc-sections -Wl,-T ${LINKER_SCRIPT}" CACHE STRING "" FORCE) My CMakeLists.txt looks like:
project(discovery_simple_test CXX C ASM) add_definitions(-DSTM32F407xx) file(GLOB_RECURSE USER_SOURCES "Src/*.c" "Src/*.cpp") include_directories(Inc) add_executable(${PROJECT_NAME}.elf ${USER_SOURCES} ${LINKER_SCRIPT}) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-Map=${PROJECT_SOURCE_DIR}/build/${PROJECT_NAME}.map") When linking as a C executable, this works. When linking as a C++ executable I get the undefined reference error.
Update
I looked at the exact linker commands composed by CMake and those are:
For GCC (successful):
/usr/bin/arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mthumb-interwork -mfloat-abi=hard -mfpu=fpv4-sp-d16 -ffunction-sections -fdata-sections -g -fno-common -fmessage-length=0 -std=gnu99 -Wl,-gc-sections -T /path/STM32F407VGTx_FLASH.ld -Wl, -Map=/path/build/discovery_simple_test.map CMakeFiles/discovery_simple_test.elf.dir/Src/main.c.obj <list of obj files> -o discovery_simple_test.elf libCMSIS.a For G++ (Error):
/usr/bin/arm-none-eabi-g++ -mcpu=cortex-m4 -mthumb -mthumb-interwork -mfloat-abi=hard -mfpu=fpv4-sp-d16 -ffunction-sections -fdata-sections -g -fno-common -fmessage-length=0 -std=c++11 -Wl,-gc-sections -T /home/niels/Dev/stm32/discovery_simple_test/STM32F407VGTx_FLASH.ld -Wl -Map=/path/discovery_simple_test/build/discovery_simple_test.map CMakeFiles/discovery_simple_test.elf.dir/Src/stm32f4xx_hal_msp.c.obj CMakeFiles/discovery_simple_test.elf.dir/Src/stm32f4xx_it.c.obj CMakeFiles/discovery_simple_test.elf.dir/Src/main.cpp.obj <List of obj files> -o discovery_simple_test.elf libCMSIS.a So at least the parameters passed to g++ are the ones I expected. I tried removing --gc-sections in combination with adding -nostartfiles, but this didn't help.