如何在CMake中指定编译器?

now*_*wox 7 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)
Run Code Online (Sandbox Code Playgroud)

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

我以为我只需要这样做

include("Modules/Compiler/IAR.cmake")
Run Code Online (Sandbox Code Playgroud)

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

当我做

cmake .
Run Code Online (Sandbox Code Playgroud)

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

Tsy*_*rev 14

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

实际发生了什么

当 CMake 执行project()调用时,它会查找默认编译器可执行文件并确定使用它的方式:默认编译器标志、默认链接器标志、编译功能等。

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

当一个组CMAKE_C_COMPILER变量以后project()调用,这只是改变了编译器可执行文件:默认标志的所有功能仍然是设置默认的编译器

结果:构建项目时,构建系统调用项目指定的编译器可执行文件,参数适用于默认编译器

可以猜到,这种方法只有在用高度兼容的编译器替换默认编译器时才有效。例如,替换gccwithclang有时可以工作。

这种方法永远不会cl用于用gcc一个替换编译器(在 Visual Studio 中使用)。当用交叉编译器替换本机编译器时,这也不起作用。

该怎么办

永远不要CMakeLists.txt.

如果你想,例如,使用clang而不是 defaulted gcc,那么要么:

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

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

  3. (仅在极少数情况下)在调用之前设置CMAKE_C_COMPILER变量。这种方法与第一种方法类似,但使项目不那么灵活。project()

如果上述方法不起作用

如果在CMAKE_C_COMPILER命令行中设置CMake 错误,即编译器无法“编译一个简单的项目”,则说明您的环境有问题……或者您指定的编译器与所选生成器或平台不兼容

例子:

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

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

交叉编译

交叉编译通常需要设置CMAKE_SYSTEM_NAME变量,这个设置通常应该在工具链文件中完成。该工具链文件还负责设置编译器。

设置CMAKE_SYSTEM_NAMECMakeLists.txt几乎总是错误

  • 对这个问题的很好的解释。顺便说一句,我认为这揭示了 CMake 语言的一个问题。您必须知道他们的算法在命令背后是如何工作的,即它不遵循声明性模型而不是过程性模型。 (2认同)

Ant*_*ane 10

要选择特定的编译器,您可以使用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
Run Code Online (Sandbox Code Playgroud)

方法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
Run Code Online (Sandbox Code Playgroud)

方法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")
Run Code Online (Sandbox Code Playgroud)

维基没有提供为什么要避免第三种方法的原因......

  • 我不明白为什么应该避免第三种方法。使用第一种方法,用户必须知道他想要使用的编译器,但事实并非如此,因为该项目仅使用指定的编译器构建。对于第二个目标,用户必须编写很长的一行来配置项目。我更喜欢将方法 2 的命令放在 bash 文件中。这让我很困惑。 (4认同)
  • 3d 方法的缺点是它不仅**硬编码**编译器,而且还**它的**路径**。或者用户要求在“PATH”下有编译器。无论如何,用户应该知道使用的是哪个编译器。 (2认同)
  • 您可以传递编译器的名称,而无需设置它的完整路径。在这种情况下,会在 PATH 环境变量中搜索它 (2认同)

Sam*_*ter 6

您需要创建一个工具链文件,并使用 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
Run Code Online (Sandbox Code Playgroud)

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

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

cmake -DCMAKE_TOOLCHAIN_FILE=iar-toolchain.cmake .
Run Code Online (Sandbox Code Playgroud)

  • 我得到“CMAKE_FORCE_C_COMPILER 宏已弃用” (2认同)

sha*_*eek 5

IAR Systems 最近在其 GitHub 个人资料下发布了一个基本的 CMake 教程,其中包含示例。

我喜欢通用工具链文件的想法,它可以在使用find_program().

以下代码片段将在使用时使用C,并且可以类似地用于CXX

# IAR C Compiler
find_program(CMAKE_C_COMPILER
  NAMES icc${CMAKE_SYSTEM_PROCESSOR}
  PATHS ${TOOLKIT}
        "$ENV{ProgramFiles}/IAR Systems/*"
        "$ENV{ProgramFiles\(x86\)}/IAR Systems/*"
        /opt/iarsystems/bx${CMAKE_SYSTEM_PROCESSOR}
  PATH_SUFFIXES bin ${CMAKE_SYSTEM_PROCESSOR}/bin
  REQUIRED )
Run Code Online (Sandbox Code Playgroud)

对于ASM,我最初对此感到困惑,NAMES但后来我意识到工具链文件是这样制作的,用于与 XLINK 附带的旧汇编程序一起使用:

find_program(CMAKE_ASM_COMPILER
  NAMES iasm${CMAKE_SYSTEM_PROCESSOR} a${CMAKE_SYSTEM_PROCESSOR}
  PATHS ${TOOLKIT}
        "$ENV{PROGRAMFILES}/IAR Systems/*"
        "$ENV{ProgramFiles\(x86\)}/IAR Systems/*"
        /opt/iarsystems/bx${CMAKE_SYSTEM_PROCESSOR}
  PATH_SUFFIXES bin ${CMAKE_SYSTEM_PROCESSOR}/bin
  REQUIRED )
Run Code Online (Sandbox Code Playgroud)

另外,请查看完整的工具链文件。当工具安装在默认位置时,它将自动为“Arm”工作,否则它只是更新变量TOOLKIT,所有支持语言的编译器应该自动调整。