使用ARM工具进行CMake _start符号未定义

时间:2017-08-02 18:22:24

标签: gcc cmake linker arm startup

我通过CMake构建一个可执行文件。可执行文件链接到各种静态库,也通过CMake在同一个项目中构建。但是,链接没有正确发生。

我运行arm-none-eabi objdump -tT executable并看到符号_start和我定义的许多其他函数都是未定义的。

这是主CMakeLists.txt文件:

set(CMAKE_BUILD_TYPE DEBUG)

# Set C/C++ compile and linking flags
set(GCC_COVERAGE_COMPILE_FLAGS "-march=armv7e-m -mthumb \
-mfloat-abi=softfp -mfpu=fpv4-sp-d16 -Og -fmessage-length=0 \
-fsigned-char -ffunction-sections -fdata-sections -ffreestanding \
-fno-move-loop-invariants -Wall -Wextra -g3")

set(GCC_COVERAGE_LINK_FLAGS
"-T \"${PROJECT_SOURCE_DIR}/ldscripts/mem.ld\" \
-T \"${PROJECT_SOURCE_DIR}/ldscripts/libs.ld\" \
-T \"${PROJECT_SOURCE_DIR}/ldscripts/sections.ld\" \
-nostartfiles -Xlinker --gc-sections -Wl,-Map,\"elka.map\" \
--specs=nano.specs")
#--specs=nano.specs -o \"elka.elf\"")

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER__FLAGS} ${GCC_COVERAGE_LINK_FLAGS}")

set(ELKA_LINK_LIBS "")

add_definitions(-DUSE_STDPERIPH_DRIVER)

# Add libraries, subdirectories, etc to include all source and header files
include_directories(${PROJECT_SOURCE_DIR}/inc
${PROJECT_SOURCE_DIR}/inc/CMSIS
${PROJECT_SOURCE_DIR}/inc/Device/STM32F4xx
${PROJECT_SOURCE_DIR}/inc/drivers
${PROJECT_SOURCE_DIR}/inc/elka_hal
${PROJECT_SOURCE_DIR}/inc/FreeRTOS
${PROJECT_SOURCE_DIR}/inc/FreeRTOS/GCC/ARM_CM4F
${PROJECT_SOURCE_DIR}/inc/modules
${PROJECT_SOURCE_DIR}/inc/nvicconf
${PROJECT_SOURCE_DIR}/inc/STM32F4xx_StdPeriph_Driver
${PROJECT_SOURCE_DIR}/inc/utils
)

add_subdirectory(src)

#FIXME make sure that this will create elka executable file
#TODO link against libraries
add_executable(elka
  src/main.c
  src/_write.c
)

add_dependencies(elka
  ${ELKA_LINK_LIBS}
)

子目录中还有其他CMakeLists.txt个文件。它们用于构建静态库并将它们添加到ELKA_LINK_LIBS变量中。主CMakeLists.txt文件在CMake中生成以下命令。执行链接,然后是警告:

/usr/bin/arm-none-eabi-gcc   -march=armv7e-m -mthumb -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -Wall -Wextra -g3 -g   -T /Programs/elka/elka_firmware/elka_firmware/ldscripts/mem.ld -T /Programs/elka/elka_firmware/elka_firmware/ldscripts/libs.ld -T /Programs/elka/elka_firmware/elka_firmware/ldscripts/sections.ld -nostartfiles -Xlinker --gc-sections -Wl,-Map,elka.map --specs=nano.specs CMakeFiles/elka.dir/src/main.c.obj CMakeFiles/elka.dir/src/_write.c.obj  -o elka src/drivers/libelka_drivers.a src/elka_hal/libelka_hal.a src/FreeRTOS/libFreeRTOS.a src/modules/libelka_modules.a src/STM32F4xx_StdPeriph_Driver/libSTM32F4xx_StdPeriph_Driver.a src/utils/libelka_utils.a
/usr/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000008000028

为什么_start未定义,首先?如果这是一个简单的答案,那么为什么这个可执行文件中的其他符号未定义?如果相关,我可以发布objdump或其他文件。

最后,我发现我在其他库中定义的函数符号在其他静态库中是未定义的。以下是一个库的示例CMakeLists.txt

# src/elka_hal
include_directories(
  ${CMAKE_CURRENT_BINARY_DIR}
  ${PROJECT_SOURCE_DIR}/inc/elka_hal
)

add_library(elka_hal STATIC
    imu.c
)

set(ELKA_LINK_LIBS 
  ${ELKA_LINK_LIBS} elka_hal
  PARENT_SCOPE
)

修改:如果我从-nostartfiles取走GCC_COVERAGE_LINK_FLAGS标记并将--specs=nano.specs更改为--specs=nosys.specs

,似乎可以正确链接符号

0 个答案:

没有答案