我正在尝试为我的裸机项目制作一个CMAKE脚本。目标是STM32F4,类似主机的arch-linux。
我使用了 CMakeLists.txt :
IF(WIN32)
cmake_minimum_required(VERSION 2.6)
ELSE(WIN32)
cmake_minimum_required(VERSION 2.4)
ENDIF(WIN32)
INCLUDE(CMakeForceCompiler)
# set cross compilation information
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR arm)
# specify the toolchain
set(TOOLCHAIN_PREFIX /usr/bin/arm-none-eabi-)
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}gcc)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}g++)
#set(CMAKE_LD ${TOOLCHAIN_PREFIX}ld)
set(CMAKE_ASM_COMPILER ${TOOLCHAIN_PREFIX}as)
set(CMAKE_AR ${TOOLCHAIN_PREFIX}ar)
set(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}objcopy)
set(CMAKE_OBJDUMP ${TOOLCHAIN_PREFIX}objdump)
CMAKE_FORCE_C_COMPILER(arm-none-eabi-gcc GNU)
CMAKE_FORCE_CXX_COMPILER(arm-none-eabi-g++ GNU)
#specify the linker
#SET(CMAKE_C_LINK_EXECUTABLE /usr/bin/arm-none-eabi-ld)
#SET(CMAKE_CXX_LINK_EXECUTABLE /usr/bin/arm-none-eabi-ld)
#SET(CMAKE_LINKER /usr/bin/arm-none-eabi-ld)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
enable_language(ASM)
# set compiler flags
set(CPU "-mcpu=cortex-m4")
set(FPU "-mfpu=fpv4-sp-d16 -mfloat-abi=softfp")
set(CMAKE_ASM_FLAGS "-mthumb ${CPU} ${FPU} -MD")
set(CMAKE_C_FLAGS "-mthumb ${CPU} ${FPU} -std=gnu99 -Os -ffunction-sections -fdata-sections -MD -Wall -pedantic ")
set(CMAKE_CXX_FLAGS "-mthumb ${CPU} ${FPU} -Os -ffunction-sections -fdata-sections -MD -Wall -pedantic -std=c++11 -fno-exceptions -fno-rtti")
# set linker flags
set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
set(CMAKE_EXE_LINKER_FLAGS " -specs=rdimon.specs -lgcc -lc -lm -lrdimon")
# The directory with all the FindXXX modules
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
# The macro below forces the build directory to be different from source directory:
INCLUDE( MacroEnsureOutOfSourceBuild )
MACRO_ENSURE_OUT_OF_SOURCE_BUILD(
"${PROJECT_NAME} requires an out of source build."
)
SET(PROJECT_NAME "R")
# Start a project.
PROJECT(${PROJECT_NAME})
# Find packages
#FIND_PACKAGE(YARP REQUIRED)
# Header files
#INCLUDE_DIRECTORIES(${YARP_INCLUDE_DIRS})
INCLUDE_DIRECTORIES(thd)
# Shared libraries
#SET(LIBS ${LIBS} ${YARP_LIBRARIES})
# Some debug information
MESSAGE("${PROJECT_NAME} is using CXX flags: ${CMAKE_CXX_FLAGS}")
MESSAGE ("Libraries included: ${LIBS}")
# Search for source code.
FILE(GLOB folder_source src/*.cpp src/*.cc src/*.c thd/inv/*.cpp thd/eigenvalues/*.cpp)
FILE(GLOB folder_header inc/*.h thd/inv/*.h thd/eigenvalues/*.h src/*.h)
SOURCE_GROUP("Source Files" FILES ${folder_source})
SOURCE_GROUP("Header Files" FILES ${folder_header})
# Automatically add include directories if needed.
FOREACH(header_file ${folder_header})
GET_FILENAME_COMPONENT(p ${header_file} PATH)
INCLUDE_DIRECTORIES(${p})
ENDFOREACH(header_file ${folder_header})
# Testing
# enable_testing()
# add_subdirectory(harness)
# Set up our main executable.
IF (folder_source)
ADD_EXECUTABLE(${PROJECT_NAME} ${folder_source} ${folder_header})
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${LIBS})
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin)
ELSE (folder_source)
MESSAGE(FATAL_ERROR "No source code files found. Please add something")
ENDIF (folder_source)
和 Makefile :
#!/bin/make -f
all:
mkdir -p build
cd build && cmake ..
cd build && make all
clean:
cd build && make clean
.PHONY: all clean
当我做“make”时,我在编译所有文件后得到了这些链接错误:
[ 88%] Building CXX object CMakeFiles/R.dir/thd/eigenvalues/blas.obj
[ 94%] Building CXX object CMakeFiles/R.dir/thd/eigenvalues/hsschur.obj
[100%] Linking CXX executable R
/usr/lib/gcc/arm-none-eabi/5.2.0/../../../../arm-none-eabi/lib/libc.a(lib_a-exit.o): In function `exit':
exit.c:(.text.exit+0x2c): undefined reference to `_exit'
/usr/lib/gcc/arm-none-eabi/5.2.0/../../../../arm-none-eabi/lib/libc.a(lib_a-abort.o): In function `abort':
abort.c:(.text.abort+0x10): undefined reference to `_exit'
/usr/lib/gcc/arm-none-eabi/5.2.0/../../../../arm-none-eabi/lib/libc.a(lib_a-fstatr.o): In function `_fstat_r':
fstatr.c:(.text._fstat_r+0x20): undefined reference to `_fstat'
/usr/lib/gcc/arm-none-eabi/5.2.0/../../../../arm-none-eabi/lib/libc.a(lib_a-openr.o): In function `_open_r':
openr.c:(.text._open_r+0x24): undefined reference to `_open'
/usr/lib/gcc/arm-none-eabi/5.2.0/../../../../arm-none-eabi/lib/libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
sbrkr.c:(.text._sbrk_r+0x18): undefined reference to `_sbrk'
/usr/lib/gcc/arm-none-eabi/5.2.0/../../../../arm-none-eabi/lib/libc.a(lib_a-signalr.o): In function `_kill_r':
signalr.c:(.text._kill_r+0x20): undefined reference to `_kill'
/usr/lib/gcc/arm-none-eabi/5.2.0/../../../../arm-none-eabi/lib/libc.a(lib_a-signalr.o): In function `_getpid_r':
signalr.c:(.text._getpid_r+0x4): undefined reference to `_getpid'
/usr/lib/gcc/arm-none-eabi/5.2.0/../../../../arm-none-eabi/lib/libc.a(lib_a-writer.o): In function `_write_r':
writer.c:(.text._write_r+0x24): undefined reference to `_write'
/usr/lib/gcc/arm-none-eabi/5.2.0/../../../../arm-none-eabi/lib/libc.a(lib_a-closer.o): In function `_close_r':
closer.c:(.text._close_r+0x18): undefined reference to `_close'
/usr/lib/gcc/arm-none-eabi/5.2.0/../../../../arm-none-eabi/lib/libc.a(lib_a-gettimeofdayr.o): In function `_gettimeofday_r':
gettimeofdayr.c:(.text._gettimeofday_r+0x20): undefined reference to `_gettimeofday'
/usr/lib/gcc/arm-none-eabi/5.2.0/../../../../arm-none-eabi/lib/libc.a(lib_a-isattyr.o): In function `_isatty_r':
isattyr.c:(.text._isatty_r+0x18): undefined reference to `_isatty'
/usr/lib/gcc/arm-none-eabi/5.2.0/../../../../arm-none-eabi/lib/libc.a(lib_a-lseekr.o): In function `_lseek_r':
lseekr.c:(.text._lseek_r+0x24): undefined reference to `_lseek'
/usr/lib/gcc/arm-none-eabi/5.2.0/../../../../arm-none-eabi/lib/libc.a(lib_a-readr.o): In function `_read_r':
readr.c:(.text._read_r+0x24): undefined reference to `_read'
collect2: error: ld returned 1 exit status
CMakeFiles/R.dir/build.make:484: recipe for target 'R' failed
make[3]: *** [R] Error 1
make[3]: Leaving directory
我不明白为什么,因为使用这些链接器标志-specs=rdimon.specs -lgcc -lc -lm -lrdimon
我应该能够避免这种问题。
答案 0 :(得分:3)
您正在编译裸机应用程序,下面没有OS服务。这意味着编译器无法执行某些操作,例如退出(由于断言或异常导致的异常终止),将错误消息写入标准输出/错误等等......这意味着您必须自己提供此类服务。通常它们是空的存根,或者将写入尝试重定向到用于调试的正确UART设备。
我建议特别阅读Practical Guide to Bare Metal C++和章Know Your Compiler Output。