web-dev-qa-db-ja.com

ビルドアーキテクチャコンパイラを使用するようにCMakeに指示する方法

クロスコンパイルにCMakeを使用する場合、通常は_CMAKE_TOOLCHAIN_FILE_オプションを使用してツールチェーンファイルを指定します。 GNU用語 では、このファイルを使用してホストアーキテクチャツールセットを指定できます。ただし、通常、このツールチェーンで構築されたものを実行できるとは期待できません。多くの場合、ビルドアーキテクチャ用にいくつかのビルドツールをコンパイルする必要があります。

次の設定を検討してください。 2つのソースファイル_genfoo.c_と_bar.c_があります。ビルド中に、_genfoo.c_をコンパイルして実行する必要があります。その出力は_foo.h_に書き込む必要があります。次に、_bar.c_をコンパイルできます。これは_#include "foo.h"_です。 CMakeはデフォルトでホストアーキテクチャツールチェーンを使用するため、_bar.c_の手順は簡単です。しかし、_genfoo.c_をコンパイルするためにビルドアーキテクチャツールチェーンを使用するように指示するにはどうすればよいですか?単にadd_executable(genfoo genfoo.c)と言うと、間違ったコンパイラが使用されることになります。

13
Helmut

CMakeは、一度に1つのコンパイラのみを処理できます。したがって、他のコンパイラを新しい言語としてセットアップするために長い道のりを歩まなければ、2つの構成サイクルになってしまいます。

このプロセスを自動化するための次のアプローチがあります。

  1. 例をとると "CMakeクロスコンパイル-ビルド中に作成されたビルドで実行可能ファイルを使用しますか?" CMakeページから開始点として次のようになります。

    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()
    _

    次に、次のようなスクリプトを使用します。

    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_を呼び出すと、目的の結果が得られます。

  2. _CMakeLists.txt_を分割し、export()/include()を、ビルドツールの出力パスがわかっているものに置き換えることもできます。 _CMAKE_RUNTIME_OUTPUT_DIRECTORY_ を使用すると、作業が簡単になります。

    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
    _

参照

8
Florian