我通过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