Come istruire CMake a utilizzare il compilatore di architettura di compilazione

Quando si utilizza CMake per la compilazione incrociata, in genere si specifica un file toolchain tramite l’opzione CMAKE_TOOLCHAIN_FILE . Nella terminologia GNU , è ansible specificare il set di strumenti dell’architettura host utilizzando questo file. Tuttavia, generalmente non ci si può aspettare di essere in grado di eseguire qualsiasi cosa creata con questa toolchain. Abbastanza spesso, alcuni strumenti di compilazione devono essere compilati per l’architettura di compilazione.

Considera la seguente configurazione. Ho due file sorgente genfoo.c e bar.c Durante la compilazione, genfoo.c deve essere compilato ed eseguito. Il suo output deve essere scritto su foo.h Quindi posso compilare bar.c , che #include "foo.h" . Poiché CMake utilizza per impostazione predefinita la toolchain dell’architettura host, le istruzioni per bar.c sono semplici. Ma come posso dire di usare l’architettura build toolchain per compilare genfoo.c ? add_executable(genfoo genfoo.c) semplicemente add_executable(genfoo genfoo.c) comporterà l’utilizzo del compilatore sbagliato.

CMake può gestire solo un compilatore alla volta. Quindi, se non si è in grado di configurare l’altro compilatore come una nuova lingua, si avranno due cicli di configurazione.

Vedo i seguenti approcci per automatizzare questo processo:

  1. Prendendo l’esempio “Compilazione CMake Cross – Usando gli eseguibili nella build creata durante la compilazione?” dalle pagine di CMake come punto di partenza otterrò:

    CMakeLists.txt

     cmake_minimum_required(VERSION 3.0) project(FooBarTest) # When crosscompiling import the executable targets if (CMAKE_CROSSCOMPILING) set(IMPORT_PATH "IMPORTFILE-NOTFOUND" CACHE FILEPATH "Point it to the export file path from a native build") file(TO_CMAKE_PATH "${IMPORT_PATH}" IMPORT_PATH_CMAKE) include(${IMPORT_PATH_CMAKE}/genfooTargets.cmake) # Then use the target name as COMMAND, CMake >= 2.6 knows how to handle this add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/foo.h COMMAND genfoo ) add_executable(bar bar.cpp ${CMAKE_CURRENT_BINARY_DIR}/foo.h) target_include_directories(bar PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) endif() # Only build the generator if not crosscompiling if (NOT CMAKE_CROSSCOMPILING) add_executable(genfoo genfoo.cpp) export(TARGETS genfoo FILE "${CMAKE_CURRENT_BINARY_DIR}/genfooTargets.cmake") endif() 

    Quindi usando uno script come:

    build.sh

     #!/bin/bash if [ ! -d hostBuild ]; then cmake -E make_directory hostBuild cmake -E chdir hostBuild cmake .. fi cmake --build hostBuild if [ ! -d crossBuild ]; then cmake -E make_directory crossBuild cmake -E chdir crossBuild cmake .. -DIMPORT_PATH=${PWD}/hostBuild -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake fi cmake --build crossBuild 

    ./build.sh risultati desiderati chiamando ./build.sh .

  2. Dividere il file CMakeLists.txt e magari persino sostituire export() / include() con qualcosa in cui so che il percorso di output dei miei strumenti di build, ad esempio utilizzando CMAKE_RUNTIME_OUTPUT_DIRECTORY , semplificherebbe le cose:

    CMakeLists.txt

     cmake_minimum_required(VERSION 3.0) project(FooBarTest) # Then use the target name as COMMAND. CMake >= 2.6 knows how to handle this add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/foo.h COMMAND genfoo ) add_executable(bar bar.cpp ${CMAKE_CURRENT_BINARY_DIR}/foo.h) target_include_directories(bar PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) 

    buildtools / CMakeLists.txt

     cmake_minimum_required(VERSION 3.0) project(BuildTools) add_executable(genfoo genfoo.cpp) 

    build.sh

     #!/bin/bash if [ ! -d crossBuild ]; then cmake -E make_directory crossBuild cmake -E chdir crossBuild cmake .. -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake fi if [ ! -d hostBuild ]; then cmake -E make_directory hostBuild cmake -E chdir hostBuild cmake ../buildTools -DCMAKE_RUNTIME_OUTPUT_DIRECTORY:PATH=${PWD}/crossBuild fi cmake --build hostBuild cmake --build crossBuild 

Riferimenti

  • Rendere automaticamente una libreria CMake accessibile da altri pacchetti di CMake
  • CMake crea più target in diverse directory di compilazione
  • Come faccio a rendere l’output di CMake in una directory “bin”?