CMake кросс-компиляция с определенным компоновщиком не передает аргументы в armlink

Я пытаюсь кросс-компилировать проект для встроенных сборок ARM Cortex, но я не могу заставить работать компоновщик. Я хочу использовать armlink, но файлы не передаются в armlink и, следовательно, файл.elf не создается.

Мой CMakeLists.txt довольно прост и приведен ниже. Ошибка появляется после того, что показывает, что armlink был вызван make-файлом без каких-либо аргументов.

Любые указатели помогут - я искал и читал много постов, но все они, кажется, имеют более сложные требования.

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.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 с чем-то вроде:

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

3 ответа

Файл цепочки инструментов может быть хорошей идеей. Вот что я сделал в последний раз, когда я пробовал CMake 2.8.10 с набором инструментов DS-5 (он все еще может быть оптимизирован, но он должен дать вам отправную точку):

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?). Но, кажется, что-то идет не так во время шага настройки.

Я не знаю, как ваша командная строка вызывает шаги конфигурирования / генерации 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
    "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> <LINK_LIBRARIES>")
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")

Исходя из моего опыта, вы не можете установить CMAKE_EXE_LINKER_FLAGS в файле CMakeLists.txt. Он должен быть передан через CMAKE_TOOLCHAIN_FILE, когда CMake вызывается в самый первый раз в каталоге сборки.

Я не нахожу документации по этой проблеме, но есть кросс-компиляция со страницей CMake, которую вы должны использовать, если вы делаете кросс-компиляцию.

Для начала просто поставьте set -звонить в файл цепочки инструментов и запустить

cmake -DCMAKE_TOOLCHAIN_FILE=<yourfile.toolchain>

в чистой директории сборки.

Начиная с CMake v3.5, вам больше не нужен набор инструментов для инструментов компиляции Keil ARM C/C++:

Добавлена ​​поддержка компилятора ARM (arm.com) с идентификатором компилятора ARMCC.

Просто установите переменные вашего компилятора 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"
      ...

Рекомендации

Другие вопросы по тегам