クロスコンパイルに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)
と言うと、間違ったコンパイラが使用されることになります。
CMakeは、一度に1つのコンパイラのみを処理できます。したがって、他のコンパイラを新しい言語としてセットアップするために長い道のりを歩まなければ、2つの構成サイクルになってしまいます。
このプロセスを自動化するための次のアプローチがあります。
例をとると "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
_を呼び出すと、目的の結果が得られます。
_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
_
参照