CMake:如何为单个目标更改编译器

And*_*123 15 cmake target

我使用交叉编译器嵌入项目.我想介绍一下使用本机GCC编译器编译的Google测试.另外用CTC编译器构建一些单元测试目标.

简而言之:
我有3个不同的目标,并使用3个不同的编译器进行编译.如何在CMakeLists.txt中表达它?我试过SET_TARGET_PROPERTIES;
但似乎不可能CXX variable使用此命令设置!

Ant*_*973 10

我现在才遇到同样的问题,但另一个答案对我没有帮助.我也是交叉编译的,我需要一些用GCC编译的实用程序,但我的核心代码是用avr-gcc编译的.

基本上,如果你有一个CMakeLists.txt,并且你希望用另一个编译器编译这个文件中的所有目标,你可以手动设置变量.

在某处定义这些宏:

macro(use_host_compiler)
  if (${CURRENT_COMPILER} STREQUAL "NATIVE")
    # Save current native flags
    set(NATIVE_C_FLAGS ${CMAKE_C_FLAGS} CACHE STRING "GCC flags for the native compiler." FORCE)

    # Change compiler
    set(CMAKE_SYSTEM_NAME ${CMAKE_HOST_SYSTEM_NAME})
    set(CMAKE_SYSTEM_PROCESSOR ${CMAKE_HOST_SYSTEM_PROCESSOR})
    set(CMAKE_C_COMPILER ${HOST_C_COMPILER})
    set(CMAKE_C_FLAGS ${HOST_C_FLAGS})
    set(CURRENT_COMPILER "HOST" CACHE STRING "Which compiler we are using." FORCE)
  endif()
endmacro()


macro(use_native_compiler)
  if (CMAKE_CROSSCOMPILING AND ${CURRENT_COMPILER} STREQUAL "HOST")
    # Save current host flags
    set(HOST_C_FLAGS ${CMAKE_C_FLAGS} CACHE STRING "GCC flags for the host compiler." FORCE)

    # Change compiler
    set(CMAKE_SYSTEM_NAME ${NATIVE_SYSTEM_NAME})
    set(CMAKE_SYSTEM_PROCESSOR ${NATIVE_SYSTEM_PROCESSOR})
    set(CMAKE_C_COMPILER ${NATIVE_C_COMPILER})
    set(CMAKE_C_FLAGS ${NATIVE_C_FLAGS})
    set(CURRENT_COMPILER "NATIVE" CACHE STRING "Which compiler we are using." FORCE)
  endif()
endmacro()
Run Code Online (Sandbox Code Playgroud)

在CMakeLists.txt脚本的最开头(或在工具链文件中),根据您的需要设置以下变量:

  • CURRENT_COMPILER
  • HOST_C_COMPILER
  • HOST_C_FLAGS
  • NATIVE_SYSTEM_NAME
  • NATIVE_C_COMPILER
  • NATIVE_C_FLAGS

这个想法是CMAKE_C_COMPILER(和公司)是一个变量,就像任何其他变量一样,因此将其设置在某个范围内只会使其在该范围内发生变化.


用法示例:

use_host_compiler()
add_executable(foo foo.c) # Compiled with your host (computer)'s compiler.
use_native_compiler()
add_executable(bar bar.c) # Compiled with your native compiler (e.g. `avr-gcc`).
Run Code Online (Sandbox Code Playgroud)


小智 7

没有正确的方法来更改单个目标的编译器。

根据cmake手册“一旦设置,就无法更改此变量”。这是关于CMAKE_<LANG>_COMPILER.

AnthonyD973 建议的解决方案似乎不起作用,这当然令人难过。在一个项目中使用多个编译器而不需要 custom_command 的能力非常有用。

  • IMO 这不应该作为答案发布,而应该作为评论发布。 (2认同)

Chr*_*isB 5

可以通过变量设置编译器CMAKE_C_COMPILERCMAKE_CXX_COMPILER如果您使用的是 C++)。

\n

在完整的构建脚本完成后,CMake 仅检查此变量的值一次。这意味着,如果多次设置该变量,则只有最后设置的值才有意义。\n(注意:根据文档,多次设置此变量不受官方支持)。

\n

如果我们想使用多个编译器,我们需要使用add_subdirectory. 然后我们可以CMAKE_C_COMPILER在每个范围内将变量设置为不同的值。这是一个简单的项目布局示例:

\n
project\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 foo\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 CMakeLists.txt\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 bar\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 CMakeLists.txt\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 CMakeLists.txt\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 main.c\n
Run Code Online (Sandbox Code Playgroud)\n
project\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 foo\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 CMakeLists.txt\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 bar\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 CMakeLists.txt\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 CMakeLists.txt\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 main.c\n
Run Code Online (Sandbox Code Playgroud)\n
# ./project/CMakeLists.txt:\ncmake_minimum_required(VERSION 3.0)\nproject(demo)\nadd_subdirectory(./foo)\nadd_subdirectory(./bar)\n
Run Code Online (Sandbox Code Playgroud)\n
# ./project/foo/CMakeLists.txt:\nset(CMAKE_C_COMPILER clang)\nadd_executable(foo ../main.c)\n
Run Code Online (Sandbox Code Playgroud)\n

CMakeLists.txt在调用之前在父级中设置的变量add_subdirectory将由子作用域继承。

\n

理想情况下,这些范围在某种程度上与您项目的实际目录布局相对应,因此您不需要添加一堆虚拟文件夹。

\n


And*_*urg -9

CMake 是一个 make 文件生成器。它会生成一个文件,然后您可以使用该文件来构建。如果您想要多个目标平台,则需要使用不同的生成器多次运行 CMake。

因此,您想要做的事情CMake 中是不可能的,但是使用CMake:您可以创建一个多次调用 CMake 的 shell 脚本。