Cum se specifică un compilator în CMake? (Programare, Cmake, Iar)

nowox a intrebat.
a intrebat.

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?

5 răspunsuri
Antwane

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ă…

Comentarii

  • Nu înțeleg de ce ar trebui evitată a treia metodă. Cu prima metodă, utilizatorul trebuie să cunoască compilatorul pe care dorește să îl folosească, ceea ce nu ar trebui să fie cazul, deoarece proiectul respectiv se construiește numai cu compilatorul specificat. Cu a doua țintă, utilizatorul trebuie să scrie o linie foarte lungă pentru a configura proiectul. Prefer mai degrabă să pun comanda din metoda 2 într-un fișier bash. Acest lucru este foarte confuz pentru mine. –  > Por nowox.
  • Metoda 3d are dezavantajul că codifică dur nu numai un compilator, ci și un calea către acesta. Sau cere unui utilizator să aibă compilatorul sub PATH. În orice caz, utilizatorul trebuie să știe ce compilator este utilizat. –  > Por Tsyvarev.
  • puteți trece numele compilatorului, fără a seta calea completă către acesta. În acest caz, acesta este căutat în variabila de mediu PATH –  > Por Antwane.
  • Pagina CMake FAQ s-a mutat aici. Vă rugăm să editați. –  > Por CaTx.
  • Pentru „path/to/your/source” vă referiți la directorul sursă CMake sau la directorul sursă al compilatorului gcc/g++? –  > Por Frank Tocci.
Tsyvarev

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:

  1. treceți -DCMAKE_C_COMPILER=<compiler> la cmake atunci când configurați proiectul. În acest fel CMake va folosi acest compilator în loc de cel implicit, iar pe pagina project() apelul va ajusta toate stegulețele pentru compilatorul specificat.

  2. Setați CC variabila de mediu (CXX pentru compilatorul C++). CMake verifică această variabilă atunci când selectează un compilator implicit.

  3. (Numai în cazuri rare) Setați CMAKE_C_COMPILER variabila înainte de project() 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 cu gcc.
  • 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.

Comentarii

  • 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. –  > Por Dimitrios Menounos.
Samuel Peter

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 .

Comentarii

  • 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șier Makefile el apasă make, , care este simplu. Cu CMake pare un pic mai complicat 🙁 –  > Por nowox.
  • Puteți face un script wrapper pentru a apela cmake. Eu am un script numit build.sh la rădăcina tuturor proiectelor mele –  > Por Samuel Peter.
  • Primesc The CMAKE_FORCE_C_COMPILER macro is deprecated –  > Por nowox.
  • @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! –  > Por Samuel Peter.
robert

Puteți apela cmake în felul următor:

cmake -DCMAKE_C_COMPILER=iccarm ...

sau

cmake -DCMAKE_CXX_COMPILER=...

Florian

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

Comentarii

  • Mai trebuie să setez CMAKE_C_COMPILER sau există o altă modalitate? Dacă fac cmake . se încearcă în continuare să se utilizeze gcc –  > Por nowox.
  • @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. –  > Por Florian.

Tags:,