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

问题描述 投票:0回答:5

我有使用交叉编译器的嵌入式项目。我想介绍一下谷歌测试,用原生的GCC编译器编译。另外使用 CTC 编译器构建一些单元测试目标。

简述:
我有 3 个不同的目标并使用 3 个不同的编译器编译它们。在CMakeLists.txt中如何表达?我试过了

SET_TARGET_PROPERTIES
;
但似乎不可能用这个命令设置
CXX variable

cmake target
5个回答
14
投票

我现在刚遇到同样的问题,但其他答案对我没有帮助。我也在交叉编译,我需要一些实用程序用 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()

在您的 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`).

6
投票

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

根据 cmake 手册“一旦设置,您将无法更改此变量”。这是关于

CMAKE_<LANG>_COMPILER
.

AnthonyD973 建议的解决方案似乎不起作用,这当然很可悲。在没有 custom_command 的情况下在项目中使用多个编译器的能力非常有用。


1
投票

一个解决方案(我还没有尝试过)是使用

set_target_properties(your_target CXX_COMPILER_LAUNCHER foo_wrapper)

然后制作

foo_wrapper
一个只删除第一个参数的脚本(这将是默认编译器,例如
c++
)然后调用你想要的编译器。

还有

CXX_LINKER_LAUNCHER
C_...
一样。


0
投票

实现此目的的规范方法是使用

add_subdirectory
引入单独的范围。一个简单的示例项目布局:

project
├── foo
│   └── CMakeLists.txt
├── bar
│   └── CMakeLists.txt
├── CMakeLists.txt
└── main.c
# ./project/CMakeLists.txt:
cmake_minimum_required(VERSION 3.0)
project(demo)
add_subdirectory(./foo)
add_subdirectory(./bar)
# ./project/foo/CMakeLists.txt:
set(CMAKE_C_COMPILER clang)
add_executable(foo ../main.c)
# ./project/bar/CMakeLists.txt:
set(CMAKE_C_COMPILER gcc)
add_executable(bar ../main.c)

共享变量总是可以 在父母

CMakeLists.txt
中设置,因为它们是继承的。

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


-9
投票

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

所以你想做的事在CMake中是不可能的,但是withCMake:你可以创建一个多次调用CMake的shell脚本。

© www.soinside.com 2019 - 2024. All rights reserved.