将错误与cmake项目链接到裸机目标

时间:2015-10-17 15:26:16

标签: c++ cmake bare-metal

我正在尝试为我的裸机项目制作一个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我应该能够避免这种问题。

1 个答案:

答案 0 :(得分:3)

您正在编译裸机应用程序,下面没有OS服务。这意味着编译器无法执行某些操作,例如退出(由于断言或异常导致的异常终止),将错误消息写入标准输出/错误等等......这意味着您必须自己提供此类服务。通常它们是空的存根,或者将写入尝试重定向到用于调试的正确UART设备。

我建议特别阅读Practical Guide to Bare Metal C++和章Know Your Compiler Output