如何指示CMake使用构build体系结构编译器?

当使用CMake进行交叉编译时,通常通过CMAKE_TOOLCHAIN_FILE选项指定一个工具链文件。 在GNU术语中 ,可以使用这个文件指定主机体系结构工具集。 但是,通常不能期望能够执行任何使用该工具链构build的任何东西。 因此,经常需要为构build体系结构编译一些构build工具。

考虑以下设置。 我有两个源文件genfoo.cbar.c 在构build过程中,需要编译并运行genfoo.c 。 它的输出需要写入foo.h 然后我可以编译bar.c ,其中#include "foo.h" 。 由于CMake默认使用主机架构工具链,所以bar.c的说明很简单。 但是,我如何告诉它使用构build体系结构工具链来编译genfoo.c ? 简单地说add_executable(genfoo genfoo.c)将导致使用错误的编译器。

把我的意见转换成答案

CMake一次只能处理一个编译器。 所以 – 如果你不想把另一个编译器设置成一门新的语言,那么你最终会有两个configuration周期。

我看到以下方法来自动执行此过程:

  1. 以“CMake交叉编译 – 在构build期间创build的构build中使用可执行文件”为例 从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 ,甚至可以用我知道构build工具的输出path的东西include()比如通过使用CMAKE_RUNTIME_OUTPUT_DIRECTORY export()replaceexport() / include()将简化一些事情:

    的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}) 

    编译工具/的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 

参考

  • 使cmake库可以被其他cmake软件包自动访问
  • cmake在不同的目录下build立多个目标
  • 如何使cmake输出成为“bin”目录?