如何在CMake中指定编译器?

cotxawn7  于 2022-12-18  发布在  其他
关注(0)|答案(7)|浏览(627)

我想使用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编译器。为什么?

w41d8nur

w41d8nur1#

要选择一个特定的编译器,您有几种解决方案,如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 -D将相应的CMAKE_FOO_COMPILER变量设置为有效的编译器名称或完整路径。例如:

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

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

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

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

project("YourProjectName")

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

qlzsbp2j

qlzsbp2j2#

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

事实上

当CMake执行project()调用时,它会查找默认编译器可执行文件并确定使用它的方式:默认编译器标志、默认链接器标志、compile features等。
CMake将默认编译器可执行文件路径存储在CMAKE_C_COMPILER变量中。
当在**project()调用之后设置CMAKE_C_COMPILER变量时,更改编译器可执行文件**:默认标志、功能都保持为 * 默认编译器 * 设置。

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

正如人们所猜测的,这种方法只有在用一个高度兼容的编译器替换默认编译器时才有效。例如,用clang替换gcc有时也有效。
此方法永远不会用于将cl编译器(在Visual Studio中使用)替换为gcc编译器。当将 * 本机 * 编译器替换为 * 交叉 * 编译器时,此方法也不会起作用。

该怎么做

切勿CMakeLists.txt中设置编译器。

例如,如果要使用clang而不是默认的gcc,则可以:
1.在配置项目时将-DCMAKE_C_COMPILER=<compiler>传递给cmake。这样CMake将使用此编译器而不是默认编译器,并且在调用project()时,它将调整指定编译器的所有标志。
1.设置CC环境变量(对于C++编译器为CXX)。CMake在选择默认编译器时检查此变量。
1.(仅在极少数情况下)在project()调用之前设置CMAKE_C_COMPILER变量。这种方法与第一种方法类似,但会降低项目的灵活性。

如果以上方法不起作用

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

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

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

交叉编译

交叉编译通常需要设置CMAKE_SYSTEM_NAME变量,这个设置一般在toolchain file中完成,那个 * 工具链文件 * 也负责设置编译器。
CMakeLists.txt中设置CMAKE_SYSTEM_NAME几乎总是错误

pkln4tw6

pkln4tw63#

您需要创建一个刀具链文件,并使用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(),则会出现错误“C编译器“XXX”无法编译简单的测试程序”,这是因为测试程序链接失败,因为它没有你的自定义链接器文件(我假设是裸机开发,因为这是IAR通常使用的)。这一行告诉CMake使用add_library()代替,这使得测试在没有链接器文件的情况下成功。this CMake mailing list post .
然后,假设您的工具链文件名为iar-toolchain.cmake,按如下方式调用CMake:

cmake -DCMAKE_TOOLCHAIN_FILE=iar-toolchain.cmake .
yqkkidmi

yqkkidmi4#

可以这样调用cmake

cmake -DCMAKE_C_COMPILER=iccarm ...

cmake -DCMAKE_CXX_COMPILER=...
cbwuti44

cbwuti445#

如果您不想使用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根据其编译器和平台检查自动完成。

参考资料

ymdaylpp

ymdaylpp6#

IAR系统最近发布了一个basic CMake tutorial,在他们的GitHub配置文件下有一些例子。
我喜欢通用工具链文件的想法,它可以无缝地用于使用find_program()的Windows和Linux编译器。
以下代码段将用于使用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 )

对于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 )

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

cdmah0mi

cdmah0mi7#

如果你想在cmake中指定一个编译器,那么就...

cmake_minimum_required(VERSION 3.22)

set(CMAKE_C_COMPILER "clang")
set(CMAKE_CXX_COMPILER "clang++")

选项1只在你想指定你想用什么编译器作为你电脑上所有编译器的默认编译器时使用,而且我甚至不认为它能在windows上工作。
如果您只想暂时使用不同的,则使用选项2。
如果编译器应该用于特定的项目,那么就使用选项3,而且选项3是最具交叉兼容性的。

相关问题