使用特定链接器的 CMake 交叉编译不会将参数传递给 armlink [英] CMake cross-compile with specific linker doesn't pass arguments to armlink

查看:30
本文介绍了使用特定链接器的 CMake 交叉编译不会将参数传递给 armlink的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to cross-compile a project for embedded ARM Cortex builds, but I am unable to get the linker working. I want to use armlink, but no files are passed to armlink and hence no .elf file is produced.

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

My CMakeLists.txt is pretty simple and given below. The failure is shown after that which shows that armlink was invoked by the makefile without any arguments.

任何指示都会有所帮助 - 我搜索并阅读了许多帖子,但它们似乎都有更多涉及的要求.

Any pointers will help - I searched and read many posts, but they all seem to have more involved requirements.

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 中有一些愚蠢的问题:

The failure is as follows, but I guess it would be obvious to someone given that I have some stupid issue in my CMakeLists:

$ make VERBOSE=1
[100%] Building C object CMakeFiles/blinky.dir/blinky.c.o
/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:

I was expecting the CMake generated Makefile to invoke armlink with something like:

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

推荐答案

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

A toolchain file may be a good idea. Here is what I've came up the last time I tried CMake 2.8.10 with the DS-5 toolchain (it could still be optimized, but it should give you a starting point):

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 "<CMAKE_AR> cr <TARGET> <LINK_FLAGS> <OBJECTS>")
SET(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> ${CMAKE_AR_FLAGS} -o <TARGET> <OBJECTS>" CACHE STRING "C Archive Create")
# set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> cr <TARGET> <LINK_FLAGS> <OBJECTS>")
SET(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> ${CMAKE_AR_FLAGS} -o <TARGET> <OBJECTS>" 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 文件中添加链接器或编译标志?).但是好像在配置步骤中出了点问题.

Regarding your question

Some failure analysis

What you have tried should work (see also e.g. How do I add a linker or compile flag in a CMake file?). But it seems something goes wrong during the configuration step.

我不知道您对 CMake 的配置/生成步骤的命令行调用,因此一些查找根本原因的一般提示:

I don't know your command line call for CMake's configuration/generation steps, so some general tips to find the root cause:

你可以试试打电话

cmake.exe --trace ...

查看您的 CMAKE_EXE_LINKER_FLAGS 变量出了什么问题.这将产生大量输出,因此这里有一些关于 CMake 功能的基础知识:

to see what went wrong with your CMAKE_EXE_LINKER_FLAGS variable. This will generate a lot of output, so here are some basics on what CMake does:

  • project() 命令将触发编译器评估
  • 这会将 CMAKE_EXE_LINKER_FLAGS 写入您的 CMakeCache.txt
  • 您正在使用局部变量覆盖它(请参阅变量范围文档 这里)
  • The project() command will trigger the compiler evaluation
  • This will write CMAKE_EXE_LINKER_FLAGS into your CMakeCache.txt
  • You are overwriting it with a local variable (see variable scope docu here)

如果你查看 sharecmake-2.8ModulesCMakeCommonLanguageInclude.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() 命令之前或在工具链文件中设置它.

You could use CMAKE_EXE_LINKER_FLAGS_INIT, but you have to set it before the project() command or in the toolchain file.

因为您将链接语言设置为C,请查看sharecmake-2.8ModulesCMakeCInformation.cmake:

Because you set the link language to C take a look into sharecmake-2.8ModulesCMakeCInformation.cmake:

if(NOT CMAKE_C_LINK_EXECUTABLE)
  set(CMAKE_C_LINK_EXECUTABLE
    "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> <LINK_LIBRARIES>")
endif()

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

So you can use CMAKE_C_LINK_EXECUTABLE to overwrite the complete linker call or you could use CMAKE_C_LINK_FLAGS to set additional flags.

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

The official way to set the target's linker and compiler flags would be (before 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 开始,它将类似于:

Starting with CMake 2.8.12 it would be something like:

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

这篇关于使用特定链接器的 CMake 交叉编译不会将参数传递给 armlink的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆