如何在CMake中指定编译器?

时间:2017-08-29 08:01:31

标签: cmake iar

我想使用IAR编译器。我注意到CMake已经有一堆关于这个编译器的文件:

https://github.com/jevinskie/cmake/blob/master/Modules/Compiler/IAR.cmake

从我读到的常见解决方案是手动指定CMakeLists.txt中的所有工具链:

set(CMAKE_C_COMPILER iccarm)
set(CMAKE_CPP_COMPILER iccarm)

CMake如何将这些定义与`Modules / Compiler / IAR.cmake"?

联系起来

我以为我只需要做

include("Modules/Compiler/IAR.cmake")

指定IAR编译器的正确方法是什么?

当我这样做时

cmake .

它仍然尝试使用gcc而不是我的IAR编译器。为什么呢?

5 个答案:

答案 0 :(得分:7)

要选择特定的编译器,您可以使用CMake wiki中的一个解决方案:

方法1:使用环境变量

对于C和C ++,设置CCCXX环境变量。不保证此方法适用于所有生成器。 (具体来说,如果您尝试设置Xcode' GCC_VERSION,此方法会混淆Xcode。) 例如:

CC=gcc-4.2 CXX=/usr/bin/g++-4.2 cmake -G "Your Generator" path/to/your/source

方法2:使用cmake -D

使用CMAKE_FOO_COMPILER在命令行上将相应的cmake -D变量设置为有效的编译器名称或完整路径。 例如:

cmake -G "Your Generator" -D CMAKE_C_COMPILER=gcc-4.2 -D CMAKE_CXX_COMPILER=g++-4.2 path/to/your/source

方法3(避免):使用set()

使用CMAKE_FOO_COMPILER将相应的set()变量设置为列表文件中的有效编译器名称或完整路径。这必须在设置任何语言之前完成(即:在任何project()enable_language()命令之前)。 例如:

set(CMAKE_C_COMPILER "gcc-4.2")
set(CMAKE_CXX_COMPILER "/usr/bin/g++-4.2")

project("YourProjectName")

wiki没有提供为什么应该避免第三种方法的原因......

答案 1 :(得分:4)

我看到越来越多的人在CMAKE_C_COMPILER调用之后的CMakeLists.txt 之后中设置project和其他与编译器相关的变量,并想知道为什么这种方法会中断有时。

实际上发生了什么

当CMake执行project()调用时,它将查找默认编译器可执行文件,并确定其使用方式:默认编译器标志,默认链接器标志,compile features,等

然后CMake在CMAKE_C_COMPILER变量中存储该默认编译器可执行文件的路径。

CMAKE_C_COMPILER调用之后设置project()变量时,此 only 会更改编译器可执行文件:默认标志,所有功能均保留为默认编译器设置。

结果:构建项目时,构建系统将调用项目指定编译器 executable ,但使用参数< / em>适用于默认编译器

您可能会猜到,这种方法只有在用高度兼容替换默认编译器时才有效。例如。有时可以用gcc替换clang

这种方法永远不会起作用,无法用cl替换gcc编译器(在Visual Studio中使用)。将 native 编译器替换为 cross -compiler时,这也不起作用。

该做什么

从不CMakeLists.txt中设置编译器。

例如,如果您想使用clang而不是默认的gcc,则可以选择以下一种方法:

  1. 在配置项目时将-DCMAKE_C_COMPILER=<compiler>传递给cmake。这样,CMake将使用此编译器而不是默认编译器,并且在project()调用时,它将调整指定编译器的所有标志。

  2. 设置CC环境变量(对于C ++编译器为CXX)。选择默认的编译器时,CMake会检查此变量。

  3. (仅在极少数情况下)在CMAKE_C_COMPILER调用之前之前设置project()变量。这种方法类似于第一种方法,但是使项目的灵活性降低。

如果上述方法不起作用

如果在命令行中设置CMAKE_C_COMPILER时出现CMake错误,表明编译器无法“编译简单项目”,则说明您的环境有问题。.或者您为不兼容指定了编译器选择generator或平台。

示例:

  • Visual Studio生成器可与cl编译器一起使用,但不能与gcc一起使用。
  • MinGW编译器通常需要MinGW Makefiles生成器。

不兼容的生成器 无法在CMakeLists.txt中修复。需要将适当的-G选项传递给cmake可执行文件(或在CMake GUI中选择适当的生成器)。

交叉编译

交叉编译通常需要设置CMAKE_SYSTEM_NAME变量,并且此设置通常应在toolchain file中进行。该 toolchain文件还负责设置编译器。

CMAKE_SYSTEM_NAME中设置CMakeLists.txt几乎总是错误

答案 2 :(得分:1)

如果您不想使用PC的标准编译器,则必须为CMake提供编译器的路径。您可以通过环境变量,工具链文件或CMake命令行中的直接定义来执行此操作(请参阅例如CMake Error at CMakeLists.txt:30 (project): No CMAKE_C_COMPILER could be found)。

将编译器的名称/路径放入CMakeLists.txt会阻止您的项目跨平台。

CMake通过编译special C/C++ files来检查编译器ID。因此,无需手动添加Module/CompilerModule/Platform

这将由CMake根据其编译器和平台检查自动完成。

<强>参考

答案 3 :(得分:1)

您可以像这样致电cmake

cmake -DCMAKE_C_COMPILER=iccarm ...

cmake -DCMAKE_CXX_COMPILER=...

答案 4 :(得分:0)

您需要创建一个工具链文件,并使用CmakeForceCompiler模块。

以下是使用IAR进行裸机ARM开发的示例工具链文件:

include(CMakeForceCompiler)

set(CMAKE_SYSTEM_NAME Generic) # Or name of your OS if you have one
set(CMAKE_SYSTEM_PROCESSOR arm) # Or whatever
set(CMAKE_CROSSCOMPILING 1)

set(CMAKE_C_COMPILER iccarm) # Change the arm suffix if appropriate
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) # Required to make the previous line work for a target that requires a custom linker file

最后一行是必要的,因为CMake将尝试使用编译器编译测试程序以确保其工作并从预处理器定义中获取一些版本信息。如果没有这一行,CMake将使用add_executable()作为测试程序,你将得到错误“The C compiler”XXX“无法编译一个简单的测试程序。”这是因为测试程序无法链接,因为它没有您的自定义链接器文件(我假设是裸机开发,因为这是IAR通常用于的)。该行告诉CMake使用add_library()代替,这使得测试在没有链接器文件的情况下成功。此解决方法的来源:this CMake mailing list post

然后,假设您的工具链文件名为iar-toolchain.cmake,请像这样调用CMake:

cmake -DCMAKE_TOOLCHAIN_FILE=iar-toolchain.cmake .