将CMake与同一语言的多个编译器一起使用

Using CMake with multiple compilers for the same language

本文关键字:编译器 一起 CMake 语言      更新时间:2023-10-16

CMake似乎在其观点中根深蒂固,即所有C++源文件都应该有一个,而且只有一个,CMake_CXX_COMPILER。我找不到在每个目标的基础上覆盖这一点的方法。这使得使用内置的CMake工具在单个CMakeLists.txt中混合主机和交叉编译变得非常困难。

因此,我的问题是:对于同一种语言(即C++),使用多个编译器的最佳方式是什么?

使用CMake不可能做到这一点。

CMake在CMakeLists.txt文件中只保留一组由所有目标共享的编译器属性。如果要使用两个编译器,则需要运行两次CMake。例如,从同一编译器工具链构建32位和64位二进制文件也是如此。

解决这一问题的快速而肮脏的方法是使用自定义命令。但最终你得到的基本上是荣耀的shell脚本,这可能不是你想要的。

干净的解决方案是:不要把它们放在同一个CMakeLists.txt中!无论如何,您不能在不同的体系结构之间进行链接,因此不需要将它们放在同一个文件中。您可以通过将CMake脚本的公共部分重构为单独的文件并include()来减少冗余。

这里的主要缺点是您失去了使用单个命令进行构建的能力,但您可以通过用您喜欢的脚本语言编写一个包装器来解决这个问题,该包装器负责调用不同的CMake makefile。

您可能需要查看ExternalProject:http://www.kitware.com/media/html/BuildingExternalProjectsWithCMake2.8.html

正如上面的答案所示,这并非不可能。我和OP有同样的问题。我有一些源代码用于交叉编译树莓皮微微,然后我在主机系统上运行一些单元测试。

为了使这个工作,我使用了非常可耻的"设置";为我的测试文件夹覆盖CMakeLists.txt中的编译器。效果很好。

if(DEFINED ENV{HOST_CXX_COMPILER})
  set(CMAKE_CXX_COMPILER $ENV{HOST_CXX_COMPILER})
else()
  set(CMAKE_CXX_COMPILER "g++")
endif()
set(CMAKE_CXX_FLAGS "")

由于某种原因,cmake devs/社区似乎非常反对使用set来更改编译器。他们认为整个项目需要使用一个编译器,这对嵌入式系统项目来说是不正确的假设。

我上面的解决方案是有效的,并且符合我认为的哲学。用户仍然可以通过环境变量更改他们选择的编译器,如果没有设置,那么我假设g++。set只更改当前作用域的变量,所以这不会影响项目的其余部分。

扩展@Bill Hoffman的回答:通过使用像这里这样的模板,将您的项目构建为超级构建https://github.com/Sarcasm/cmake-superbuild它将把依赖项和您的项目配置为ExternalProject(独立的cmake配置/构建/安装环境)。

对于那些使用现代(CMake>=v3.19)的用户,请查看预设。

有了这些,您可以有一个用于与一个编译器构建的预设,以及另一个用于另一个编译器的预设。

它并不能完全解决问题,但有了现代编辑器(与代码相比),编译器之间的切换变得轻而易举。