2015-10-17 161 views
1

我想爲我的裸機項目做一個CMAKE腳本。目標是一個STM32F4,像主機一樣的arch-linux。鏈接錯誤與cmake項目裸機目標

我用這個的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 

,當我做 「讓」 我所有FLES的編譯後得到了這些鏈接錯誤工作:

[ 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

如果您嘗試使用'--specs = rdimon.specs'(注意雙標誌)是否有效? – josaphatv

回答

3

您正在編譯裸機應用程序,下面沒有OS服務。這意味着編譯器無法執行某些操作,如退出(由於斷言或異常導致的異常終止),將錯誤消息寫入標準輸出/錯誤等等。這意味着您必須自己提供這樣的服務。通常它們是空的存根,或將寫入嘗試重定向到用於調試的正確UART設備。

我建議您特別閱讀Practical Guide to Bare Metal C++和章節Know Your Compiler Output