Aș dori să folosesc compilatorul IAR. Am observat că CMake are deja o grămadă de fișiere despre acest compilator:
https://github.com/jevinskie/cmake/blob/master/Modules/Compiler/IAR.cmake
Din ceea ce am citit, soluția obișnuită este să specific manual TOATE toolchain-urile din CMakeLists.txt
:
set(CMAKE_C_COMPILER iccarm)
set(CMAKE_CPP_COMPILER iccarm)
Cum poate CMake să lege aceste definiții cu `Modules/Compiler/IAR.cmake”?
Am crezut că va trebui să fac doar
include("Modules/Compiler/IAR.cmake")
Care este modul corect de a specifica compilatorul meu IAR?
Când fac
cmake .
Încă încearcă să folosească gcc
în loc de compilatorul meu IAR. De ce?
Pentru a selecta un anumit compilator, aveți mai multe soluții, așa cum este exaplicat în CMake wiki:
Metoda 1: utilizați variabilele de mediu
Pentru C și C++, setați valorile CC
și CXX
variabilele de mediu. Nu se garantează că această metodă funcționează pentru toate generatoarele. (Mai exact, dacă încercați să setați variabilele Xcode’s GCC_VERSION
, , această metodă confundă Xcode.)De exemplu:
CC=gcc-4.2 CXX=/usr/bin/g++-4.2 cmake -G "Your Generator" path/to/your/source
Metoda 2: utilizați cmake -D
Setați variabilele corespunzătoare CMAKE_FOO_COMPILER
variabilele la un nume de compilator valid sau la calea completă pe linia de comandă folosind cmake -D
.de exemplu:
cmake -G "Your Generator" -D CMAKE_C_COMPILER=gcc-4.2 -D CMAKE_CXX_COMPILER=g++-4.2 path/to/your/source
Metoda 3 (de evitat): use set()
Setați variabilele corespunzătoare CMAKE_FOO_COMPILER
la un nume de compilator valid sau la o cale completă într-un fișier listă folosind set()
. Acest lucru trebuie făcut înainte de a se seta orice limbaj (adică: înainte de orice project()
sau enable_language()
).De exemplu:
set(CMAKE_C_COMPILER "gcc-4.2")
set(CMAKE_CXX_COMPILER "/usr/bin/g++-4.2")
project("YourProjectName")
Wiki nu oferă niciun motiv pentru care a treia metodă ar trebui evitată…
Văd din ce în ce mai mulți oameni care setează CMAKE_C_COMPILER
și alte variabile legate de compilator în fișierul CMakeLists.txt
după project
apel și se întreabă de ce această abordare se strică uneori.
Ce se întâmplă de fapt
Atunci când CMake execută apelul project()
caută un apel executabil implicit al compilatorului și determină modul de utilizare a acestuia: stegulețe de compilator implicite, stegulețe de linker implicite, caracteristicile de compilare, , etc.
Iar CMake stochează calea către acel executabil de compilare implicit în fișierul CMAKE_C_COMPILER
variabilă.
Atunci când se setează CMAKE_C_COMPILER
variabila după project()
apel, acest lucru doar modifică compilatorul executabil: stegulețe implicite, caracteristicile rămân toate setate pentru compilatorul implicit.
CA REZULTAT: Atunci când proiectul este construit, un sistem de construire apelează la specificat în proiect compilator executabil dar cu parametrii adecvați pentru compilatorul implicit.
După cum se poate ghici, această abordare ar funcționa numai atunci când se înlocuiește un compilator implicit cu un compilator foarte compatibil unul foarte compatibil. De exemplu, înlocuirea lui gcc
cu clang
ar putea funcționa uneori.
Această abordare va nu va funcționa niciodată pentru înlocuirea lui cl
compilator (utilizat în Visual Studio) cu gcc
unul. Nici acest lucru nu va funcționa la înlocuirea unui nativ compilator cu un compilator cross-compiler.
Ce trebuie făcut
Niciodată setați un compilator în CMakeLists.txt
.
Dacă doriți, de exemplu, să utilizați clang
în loc de cea implicită gcc
, , atunci fie:
-
treceți
-DCMAKE_C_COMPILER=<compiler>
lacmake
atunci când configurați proiectul. În acest fel CMake va folosi acest compilator în loc de cel implicit, iar pe paginaproject()
apelul va ajusta toate stegulețele pentru compilatorul specificat. -
Setați
CC
variabila de mediu (CXX
pentru compilatorul C++). CMake verifică această variabilă atunci când selectează un compilator implicit. -
(Numai în cazuri rare) Setați
CMAKE_C_COMPILER
variabila înainte deproject()
apel. Această abordare este similară cu prima, dar face ca proiectul să fie mai puțin flexibil.
În cazul în care modalitățile de mai sus nu funcționează
Dacă la setarea CMAKE_C_COMPILER
în linia de comandă CMake dă eroare că un compilator nu poate „compila un proiect simplu”, atunci ceva nu este în regulă în mediul dvs.. sau dacă specificați un compilator incompatibil pentru compilatorul ales generatorul sau platforma.
Exemple:
- Generatoarele Visual Studio funcționează cu
cl
compilator, dar nu pot funcționa cugcc
. - Un compilator MinGW necesită de obicei MinGW Makefiles generator.
Generator incompatibil nu poate fi utilizat fi reparat în CMakeLists.txt
. Este necesar să se treacă codul -G
la cmake
executabil (sau să selectați generatorul corespunzător în CMake GUI).
Compilare încrucișată
Compilarea încrucișată necesită, de obicei, setarea CMAKE_SYSTEM_NAME iar această setare ar trebui să se facă în mod normal în fișierul fișierul toolchain. Pe fișier toolchain este, de asemenea, responsabil pentru setarea unui compilator.
Setarea CMAKE_SYSTEM_NAME
în fișierul CMakeLists.txt
este aproape întotdeauna o eroare.
- Bună explicație pentru întrebare. BTW, cred că acest lucru dezvăluie o problemă cu limbajul CMake. Trebuie să știți cum funcționează algoritmul lor în spatele comenzilor, adică nu urmează un model declarativ mai degrabă decât unul procedural. – > .
Trebuie să creați un fișier toolchain și să utilizați modulul CmakeForceCompiler.
Iată un exemplu de fișier toolchain pentru dezvoltarea ARM bare-metal cu IAR:
include(CMakeForceCompiler)
set(CMAKE_SYSTEM_NAME Generic) # Or name of your OS if you have one
set(CMAKE_SYSTEM_PROCESSOR arm) # Or whatever
set(CMAKE_CROSSCOMPILING 1)
set(CMAKE_C_COMPILER iccarm) # Change the arm suffix if appropriate
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) # Required to make the previous line work for a target that requires a custom linker file
Ultima linie este necesară deoarece CMake va încerca să compileze un program de testare cu compilatorul pentru a se asigura că funcționează și pentru a obține unele informații despre versiune din definițiile preprocesorului. Fără această linie, CMake va utiliza add_executable() pentru programul de test și veți primi eroarea „The C compiler „XXX” is not able to compile a simple test program.” (Compilatorul C „XXX” nu este capabil să compileze un program de test simplu). Acest lucru se datorează faptului că programul de testare nu reușește să se lege, deoarece nu are fișierul dvs. de legătură personalizat (presupun că este vorba de dezvoltare bare-metal, deoarece pentru asta este folosit de obicei IAR). Această linie îi spune lui CMake să folosească în schimb add_library(), ceea ce face ca testul să reușească fără fișierul linker. Sursa acestei soluții de rezolvare: această postare din lista de discuții CMake.
Apoi, presupunând că fișierul toolchain se numește iar-toolchain.cmake, invocați CMake astfel:
cmake -DCMAKE_TOOLCHAIN_FILE=iar-toolchain.cmake .
- Cum știe dezvoltatorul că trebuie să scrie
cmake -DCMAKE_TOOLCHAIN_FILE=iar-toolchain.cmake .
. În mod tradițional, cu GNU Make, dezvoltatorul vede un fișierMakefile
el apasămake
, , care este simplu. Cu CMake pare un pic mai complicat 🙁 – > . - Puteți face un script wrapper pentru a apela cmake. Eu am un script numit build.sh la rădăcina tuturor proiectelor mele – > .
- Primesc
The CMAKE_FORCE_C_COMPILER macro is deprecated
– > . - @nowox Este adevărat că este depreciat. Eu văd aceste avertismente de ceva vreme, dar când am încercat să o schimb am primit eroarea: „Compilatorul C XXX nu este capabil să compileze un program de test simplu”. La momentul respectiv nu am găsit o soluție așa că am trăit cu avertismentul. Mulțumită ție tocmai am căutat din nou și am găsit o soluție, vezi editarea mea! – > .
Puteți apela cmake
în felul următor:
cmake -DCMAKE_C_COMPILER=iccarm ...
sau
cmake -DCMAKE_CXX_COMPILER=...
Dacă nu doriți să folosiți compilatorul standard al PC-ului, trebuie să îi dați lui CMake calea către compilator. Faceți acest lucru prin variabile de mediu, un fișier toolchain sau definiții directe în linia de comandă CMake (vezi de exemplu CMake Error at CMakeLists.txt:30 (proiect): Nu a putut fi găsit niciun CMAKE_C_COMPILER).
Introducerea numelui/căii de acces a compilatorului în CMakeLists.txt ar împiedica proiectul dvs. să fie cross-platform.
CMake verifică ID-urile compilatorului prin compilarea fișiere C/C++ speciale. Așadar, nu este nevoie să includeți manual din Module/Compiler
sau Module/Platform
.
Acest lucru va fi făcut automat de CMake pe baza verificărilor compilatorului și platformei sale.
Referințe
- CMake: În ce ordine sunt analizate fișierele (Cache, Toolchain, …)?
- CMake GitLab Commit: Adăugați fișiere de suport pentru C, C++ și ASM pentru lanțul de instrumente IAR.
- Mai trebuie să setez
CMAKE_C_COMPILER
sau există o altă modalitate? Dacă faccmake .
se încearcă în continuare să se utilizezegcc
– > . - @nowox Trebuie să îi dai lui CMake calea către compilator. Puteți face acest lucru prin variabile de mediu, un fișier toolchain sau definiții directe în linia de comandă CMake (a se vedea, de exemplu, aici). Punând acest lucru în
CMakeLists.txt
ar împiedica proiectul dvs. să fie cross-platform. – > .
PATH
. În orice caz, utilizatorul trebuie să știe ce compilator este utilizat. – > Por Tsyvarev.