【问题标题】:CMake: how to change compiler for individual targetCMake:如何更改单个目标的编译器
【发布时间】:2014-11-27 10:17:10
【问题描述】:

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

简单地说:
我有 3 个不同的目标并用 3 个不同的编译器编译它们。如何在CMakeLists.txt中表达?我试过SET_TARGET_PROPERTIES;
但是用这个命令设置CXX variable似乎是不可能的!

【问题讨论】:

    标签: cmake target


    【解决方案1】:

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

    【讨论】:

    • 我在同一条船上,我需要针对不同目标使用不同的编译器。我已经尝试了您的示例,但无法使其正常工作。添加的可执行文件总是使用 clang 而不是我的替代编译器构建的。有什么建议可以完成这项工作吗?
    • 很难说您何时无法访问代码,但您可以尝试在调用add_executable(或add_library 或其他任何内容之前)使用message() 打印出变量的值您正在使用)查看它们是否仍根据您当时的需要进行设置。还要确保使用macro()not function(),因为在函数中设置变量会使其在调用者的范围内保持不变,而在macro() 中设置的变量会保持在调用者范围内的那个值。
    • 感谢您的回复。是的,我在宏而不是函数中做到了这一点。而且我已经尝试打印出变量值。这是定义可执行文件之前的输出 -- 将编译器切换到 TEST... -- CMAKE_SYSTEM_NAME: TEST_SYSTEM -- CMAKE_SYSTEM_PROCESSOR: -- CMAKE_C_COMPILER: /home/me/scripts/clang_wrapper.py -- CMAKE_CXX_COMPILER: /home/me/scripts /clang_wrapper++.py -- CMAKE_C_FLAGS: -- CMAKE_CXX_FLAGS: -- CURRENT_COMPILER: TEST
    • 我不熟悉你的这个clang_wrapper.pyclang_wrapper.py 可能不接受与 gcc/g++ 相同类型的参数,这会导致 CMake 使用 gcc 的参数调用它,例如 -o outputfile.o -c inputfile.c,这可能是 clang_wrapper.py 的无效参数。
    • 我们的包装脚本旨在处理 clang/gcc 参数。没有迹象表明那是失败的。似乎不可能为相同的 CMake 配置构建定义 N 个编译器。如果没有多次配置传递,我找不到任何方法来执行此操作,为每次传递指定编译器和不同的构建目录。我决定扭转这个问题,并用我们的包装器构建我们所有的目标,对于大多数目标,它只是调用clang,而在其他情况下,它会做我们需要做的特殊事情。这对我来说解决了这个问题。
    【解决方案2】:

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

    根据 cmake 手册“一旦设置,您不能更改此变量”。这是关于CMAKE_<LANG>_COMPILER

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

    【讨论】:

    • IMO 这不应该作为答案发布,而是作为评论发布。
    • 我没有尝试重现,但如果 CMake 更新不再有效,可能会破坏它。它肯定曾经工作过;我们构建了一个项目,该项目将使用我在答案中发布的代码交叉编译一些程序。
    • 您使用的是哪个 CMake 版本,而其他答案中的代码不起作用?
    • 我的 Ubuntu 19.04 上有 3.13.4。
    【解决方案3】:

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

    所以你想做的不是in CMake,而是with CMake:你可以创建一个多次调用CMake的shell脚本。

    【讨论】:

    • 我倾向于同意这一点,但您可以创建 custom_target 调用 cmake 与其他一些工具链文件,构建并将其安装到一些中间阶段目录,导出-导入可执行文件......虽然可能更困难然后是外部脚本,这可能从外部看起来更好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-06
    • 1970-01-01
    • 1970-01-01
    • 2014-08-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多