【发布时间】:2017-05-11 21:59:23
【问题描述】:
我有一个编译成功的 C 项目。现在我想在同一个项目中使用C++代码,所以我将main.c重命名为main.cpp。该项目是针对嵌入式微控制器的,所以我使用arm-none-eabi 工具链进行交叉编译。
当我将主文件重命名为 .cpp 时,我收到以下错误:
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'
这是因为某些标准库不适用于此“裸机”目标。 (见https://stackoverflow.com/a/13237079/507369)
这已在我的链接器脚本中解决:
/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
链接器脚本由我的 CMake 工具链文件添加:
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)
我的CMakeLists.txt 看起来像:
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")
当链接为 C 可执行文件时,这是可行的。当链接为 C++ 可执行文件时,我收到 undefined reference 错误。
更新
我查看了由 CMake 组成的确切链接器命令,它们是:
对于 GCC(成功):
/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
对于 G++(错误):
/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
所以至少传递给 g++ 的参数是我所期望的。我尝试删除 --gc-sections 并结合添加 -nostartfiles,但这没有帮助。
【问题讨论】:
-
谢谢 πάντα ῥεῖ,我检查了 main.cpp 中包含的所有头文件,代码已经包含在“extern C”中。
-
这真的是 CMake 问题还是与 C 和 C++ 有关?
-
@usr1234567 我不知道。最后它是一个 C(++) 链接器问题,但它可能需要在 CMake 级别修复。
-
@i.amniels 当然可以,但是您必须在没有 CMake 的情况下找出标志/包含,然后将它们添加到您的 CMake 文件中。但是您的问题不是由 CMake 引起的。
标签: c++ gcc linker cmake cross-compiling