使用特定链接器进行CMake交叉编译不会将参数传递给armlink

我正在尝试交叉编译嵌入式ARM Cortex构建的项目,但我无法使链接器工作。 我想使用armlink,但没有文件传递给armlink,因此没有生成.elf文件。

我的CMakeLists.txt非常简单,如下所示。 之后显示失败,表明makefile在没有任何参数的情况下调用了armlink。

任何指针都会有所帮助 – 我搜索并阅读了很多post,但他们似乎都有更多的参与要求。

cmake_minimum_required(VERSION 2.8) project(test_arm) enable_language(C ASM) # Cross-compilation for ARM SET(CMAKE_C_COMPILER armcc) SET(CMAKE_LINKER armlink) SET(CMAKE_C_LINK_EXECUTABLE armlink) SET(CMAKE_C_FLAGS "--cpu=Cortex-M3") SET(LINK_FLAGS "--map --ro-base=0x0 --rw-base=0x0008000 --first='boot.o(RESET)' --datacompressor=off") SET(CMAKE_EXE_LINKER_FLAGS "--map --ro-base=0x0 --rw-base=0x0008000 --first='boot.o(RESET)' --datacompressor=off") include_directories(../include) add_executable(blinky blinky.c) set_target_properties(blinky PROPERTIES LINKER_LANGUAGE C) 

失败如下,但我想对于我的CMakeLists中有一些愚蠢问题的人来说很明显:

 $ make VERBOSE=1 [100%] Building C object CMakeFiles/blinky.dir/blinky.co /usr/bin/cmake -E cmake_link_script CMakeFiles/blinky.dir/link.txt --verbose=1 armlink Linking C executable blinky Product: DS-5 Professional 5.21.0 [5210017] Component: ARM Compiler 5.05 update 1 (build 106) Tool: armlink [4d0efa] For support see http://www.arm.com/support/ Software supplied by: ARM Limited Usage: armlink option-list input-file-list where .... 

我期待CMake生成的Makefile用以下内容调用armlink:

 armlink --map --ro-base=0x0 --rw-base=0x0008000 \ --first='boot.o(RESET)' --datacompressor=off \ CMakeFiles/blinky.dir/blinky.co -o blinky.elf 

从CMake v3.5开始,您不再需要Keil ARM C / C ++编译工具的工具链:

为编译器ID为ARMCC的ARM编译器(arm.com)添加了支持。

只需相应地设置C / CXX编译器变量即可

 cmake -DCMAKE_C_COMPILER:PATH="C:\Program Files (x86)\DS-5\bin\armcc.exe" -DCMAKE_CXX_COMPILER:PATH="C:\Program Files (x86)\DS-5\bin\armcc.exe" ... 

参考

  • ARMCC工具链支持
  • 添加对ARM编译器的支持(arm.com)
  • CMakeLists.txt的CMake错误:30(项目):找不到CMAKE_C_COMPILER

根据我的经验,您无法在CMakeLists.txt文件中设置CMAKE_EXE_LINKER_FLAGS 。 当第一次在构建目录中调用CMake时,必须通过CMAKE_TOOLCHAIN_FILE传递它。

我没有找到任何关于这个问题的文档,但是如果你进行交叉编译,就会有使用CMake页面的交叉编译。

首先,将set -calls放在工具链文件中并运行

 cmake -DCMAKE_TOOLCHAIN_FILE= 

在一个干净的构建目录中。

工具链文件可能是个好主意。 这是我上次尝试使用DS-5工具链的CMake 2.8.10时出现的内容(它仍然可以优化,但它应该给你一个起点):

 INCLUDE(CMakeForceCompiler) # This one is important SET(CMAKE_SYSTEM_NAME Generic) SET(CMAKE_SYSTEM_PROCESSOR arm) # Specify the cross compiler SET(CMAKE_C_COMPILER "C:/Program Files (x86)/DS-5/bin/armcc.exe") SET(CMAKE_CXX_COMPILER "C:/Program Files (x86)/DS-5/bin/armcc.exe") SET(CMAKE_AR "C:/Program Files (x86)/DS-5/bin/armar.exe" CACHE FILEPATH "Archiver") #CMAKE_FORCE_C_COMPILER("C:/Program Files (x86)/DS-5/sw/gcc/bin/arm-linux-gnueabihf-gcc.exe" GNU) #CMAKE_FORCE_CXX_COMPILER("C:/Program Files (x86)/DS-5/sw/gcc/bin/arm-linux-gnueabihf-g++.exe" GNU) UNSET(CMAKE_C_FLAGS CACHE) SET(CMAKE_C_FLAGS "--cpu=Cortex-A9 --thumb -Ospace" CACHE STRING "" FORCE) UNSET(CMAKE_CXX_FLAGS CACHE) SET(CMAKE_CXX_FLAGS ${CMAKE_C_FLAGS} CACHE STRING "" FORCE) UNSET(CMAKE_EXE_LINKER_FLAGS CACHE) SET(CMAKE_EXE_LINKER_FLAGS "" CACHE STRING "" FORCE) UNSET(CMAKE_AR_FLAGS CACHE) SET(CMAKE_AR_FLAGS "-p -armcc,-Ospace" CACHE STRING "" FORCE) # set(CMAKE_C_ARCHIVE_CREATE " cr   ") SET(CMAKE_C_ARCHIVE_CREATE " ${CMAKE_AR_FLAGS} -o  " CACHE STRING "C Archive Create") # set(CMAKE_CXX_ARCHIVE_CREATE " cr   ") SET(CMAKE_CXX_ARCHIVE_CREATE " ${CMAKE_AR_FLAGS} -o  " CACHE STRING "CXX Archive Create") include_directories("C:/Program Files (x86)/DS-5/include") #include_directories("C:/Program Files (x86)/DS-5/sw/gcc/arm-linux-gnueabihf/libc/usr/include/arm-linux-gnueabi") # Where is the target environment SET(CMAKE_FIND_ROOT_PATH "C:/Program Files (x86)/DS-5") # Search for programs in the build host directories SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) # For libraries and headers in the target directories SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 

关于你的问题

一些失败分析

您尝试过的应该可以工作(另请参阅例如如何在CMake文件中添加链接器或编译标志? )。 但在配置步骤中似乎出现了问题。

我不知道你的命令行调用CMake的配置/生成步骤,所以一些一般提示找到根本原因:

你可以尝试打电话

 cmake.exe --trace ... 

查看您的CMAKE_EXE_LINKER_FLAGS变量出了什么问题。 这会产生很多输出,所以这里有一些关于CMake的基础知识:

  • project()命令将触发编译器评估
  • 这会将CMAKE_EXE_LINKER_FLAGS写入您的CMakeCache.txt
  • 您使用局部变量覆盖它(请参阅此处的变量范围文档)

如果你看看share\cmake-2.8\Modules\CMakeCommonLanguageInclude.cmake

 set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS_INIT} $ENV{LDFLAGS}" CACHE STRING "Flags used by the linker.") 

您可以使用CMAKE_EXE_LINKER_FLAGS_INIT ,但必须在project()命令之前或工具链文件中设置它。

因为您将链接语言设置为C请查看share\cmake-2.8\Modules\CMakeCInformation.cmake

 if(NOT CMAKE_C_LINK_EXECUTABLE) set(CMAKE_C_LINK_EXECUTABLE "     -o  ") endif() 

因此,您可以使用CMAKE_C_LINK_EXECUTABLE覆盖完整的链接器调用,也可以使用CMAKE_C_LINK_FLAGS设置其他标志。

“官方”的方式

设置目标链接器和编译器标志的官方方法是(在CMake 2.8.12之前):

 set_property(TARGET blinky APPEND_STRING PROPERTY COMPILE_FLAGS "--cpu=Cortex-M3") set_property(TARGET blinky APPEND_STRING PROPERTIES LINK_FLAGS "--map --ro-base=0x0 --rw-base=0x0008000 --first='boot.o(RESET)' --datacompressor=off") 

从CMake 2.8.12开始,它将是这样的:

 add_compile_options("--cpu=Cortex-M3")