CMake cross-compile con linker specifico non passa argomenti a armlink

Sto cercando di compilare un progetto cross-built per build ARM Cortex, ma non riesco a far funzionare il linker. Voglio usare armlink, ma nessun file viene passato a armlink e quindi non viene prodotto nessun file.

Il mio CMakeLists.txt è piuttosto semplice e viene fornito di seguito. L’errore viene mostrato dopo quello che mostra che il collegamento arm è stato richiamato dal makefile senza argomenti.

Qualsiasi suggerimento aiuterà – Ho cercato e letto molti post, ma sembrano tutti avere requisiti più coinvolti.

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) 

Il fallimento è il seguente, ma suppongo che sarebbe ovvio per qualcuno dato che ho qualche problema stupido nelle mie 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 .... 

Mi aspettavo che CMake generasse Makefile per invocare armlink con qualcosa del tipo:

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

A partire da CMake v3.5 non è più necessaria una toolchain per gli strumenti di compilazione Keil ARM C / C ++:

È stato aggiunto il supporto per ARM Compiler (arm.com) con il compilatore id ARMCC.

Basta impostare le variabili del compilatore C / CXX di conseguenza

 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" ... 

Riferimenti

  • Supporto per toolchain ARMCC
  • Aggiungi il supporto per ARM Compiler (arm.com)
  • Errore CMake in CMakeLists.txt: 30 (progetto): imansible trovare CMAKE_C_COMPILER

Dalla mia esperienza, non puoi impostare CMAKE_EXE_LINKER_FLAGS in un file CMakeLists.txt. Deve essere passato tramite un CMAKE_TOOLCHAIN_FILE quando CMake viene richiamato per la prima volta in una directory di build.

Non trovo alcuna documentazione riguardo a questo problema, ma c’è la cross-compilation con la pagina di CMake che dovresti usare se fai cross-compilation.

Per cominciare, metti le tue set -di sicurezza in un file toolchain ed esegui

 cmake -DCMAKE_TOOLCHAIN_FILE= 

in una directory di compilazione pulita.

Un file toolchain può essere una buona idea. Ecco cosa ho scoperto l’ultima volta che ho provato CMake 2.8.10 con la toolchain DS-5 (potrebbe ancora essere ottimizzato, ma dovrebbe darti un punto di partenza):

 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) 

Per quanto riguarda la tua domanda

Qualche analisi di fallimento

Quello che hai provato dovrebbe funzionare (vedi anche ad esempio Come posso aggiungere un linker o compilare un flag in un file CMake? ). Ma sembra che qualcosa vada storto durante la fase di configurazione.

Non conosco la tua richiesta da riga di comando per i passaggi di generazione / generazione di CMake, quindi alcuni suggerimenti generali per trovare la causa principale:

Potresti provare a chiamare

 cmake.exe --trace ... 

per vedere cosa è andato storto con la tua variabile CMAKE_EXE_LINKER_FLAGS . Questo genererà molto output, quindi ecco alcune basi su ciò che fa CMake:

  • Il comando project() attiverà la valutazione del compilatore
  • Questo scriverà CMAKE_EXE_LINKER_FLAGS nel tuo CMakeCache.txt
  • Lo stai sovrascrivendo con una variabile locale (vedi docu scope scope qui )

Se si guarda in 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.") 

È ansible utilizzare CMAKE_EXE_LINKER_FLAGS_INIT , ma è necessario impostarlo prima del comando project() o nel file toolchain.

Poiché imposti la lingua del collegamento su C un’occhiata a share\cmake-2.8\Modules\CMakeCInformation.cmake :

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

Pertanto puoi utilizzare CMAKE_C_LINK_EXECUTABLE per sovrascrivere la chiamata al linker completo oppure puoi utilizzare CMAKE_C_LINK_FLAGS per impostare altri flag.

Il modo “ufficiale”

Il modo ufficiale per impostare il linker del target e i flag del compilatore sarebbe (prima di 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") 

A partire da CMake 2.8.12 sarebbe qualcosa di simile:

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