2016-03-23 18 views
11

Quando si utilizza CMake per la compilazione incrociata, in genere si specifica un file toolchain tramite l'opzione CMAKE_TOOLCHAIN_FILE. In GNU terminology, è possibile 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.Come istruire CMake a utilizzare il compilatore di architettura di compilazione?

Prendere in considerazione la seguente configurazione. Ho due file sorgente genfoo.c e bar.c. Durante la compilazione, è necessario compilare ed eseguire genfoo.c. 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 facili. Ma come posso dire di usare l'architettura build toolchain per compilare genfoo.c? Dire semplicemente add_executable(genfoo genfoo.c) comporterà l'utilizzo del compilatore sbagliato.

+0

Come hai affermato, nella terminologia GNU si userebbe il comando 'configure' per specificare l'architettura host. E dovresti eseguire 'configure' due volte se vuoi costruire per due diversi ambienti host. Quindi vedo due possibilità con CMake: utilizzare uno script di build che crea ed esegue i due ambienti necessari (vedere [qui] (http://stackoverflow.com/questions/30999130/cmake-build-multiple-targets-in-different- build-directory)) o utilizzare [ExternalProject_Add()] (https://cmake.org/cmake/help/v3.2/module/ExternalProject.html) e dividere il tuo CMakeLists.txt in sottoprogetti dedicati. – Florian

+0

No, con gli autotools si usa semplicemente 'CC_FOR_BUILD'. Vedi 'ax_cc_for_build'. – Helmut

+0

Ok, non lo sapevo. Se ho capito bene, stiamo parlando del caso d'uso descritto in [Compilazione CMake Cross: utilizzo degli eseguibili nella build creata durante la compilazione] (https://cmake.org/Wiki/CMake_Cross_Compiling#Using_executables_in_the_build_created_during_the_build)? – Florian

risposta

7

Girando i miei commenti in una risposta

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 "CMake Cross Compiling - Using executables in the build created during the build?" dalle pagine CMake come punto di partenza prendo:

    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 utilizzare 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 
    

    io ottenere i risultati desiderati chiamando ./build.sh

  2. Splitting il CMakeLists.txt e forse anche sostituire il export()/include() con qualcosa dove so che il percorso di uscita del mio costruire strumenti per es 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