CMake -DCMAKE_CXX_COMPILER 有效但 SET(CMAKE_CXX_COMPILER ...) 被忽略?

Jim*_*mbo 4 cmake

一直在尝试将 CPP 编译器设置为g++在我的工具链文件中使用以下行。

# specify the cross compiler
SET(CMAKE_CXX_COMPILER:FILEPATH /opt/qnx641/host/linux/x86/usr/bin/arm-unknown-nto-qnx6.4.0-g++)
Run Code Online (Sandbox Code Playgroud)

这似乎没有被使用,所以我尝试了一些东西只是为了起诉

SET(CMAKE_C_COMPILER:FILEPATH   /junk/gcc)
Run Code Online (Sandbox Code Playgroud)

好的,矫枉过正,但这样我绝对确定 CMake 不会从我传入的路径和命令结构中进行任何有趣的推断。

我通过查看有关工具链文件的CMake 交叉编译页面沿着这条路线走下去。

因此,仔细阅读并决定从命令行执行此操作,因为此 QA 线程显示命令行将-D覆盖缓存的变量。

这有效!

所以我的问题是,有谁知道为什么当我使用-D命令行选项时 CMake 如何找到我的交叉编译器路径和 exename 但忽略SET(CMAKE_CXX_COMPILER...我的工具链中的行。

我在每次构建之前删除了build目录和CMakeCache.txt文件。

为了完整起见,我使用的命令行是

rm CMakeCache.txt; 
rm -fr build; 
cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=./build 
-DMAKE_TOOLCHAIN_FILE=/path/to/toolchain-file.cmake 
-C CMakeCrossCompile-TryRunResult-qnx-armle.cmake . 
Run Code Online (Sandbox Code Playgroud)

该文件CMakeCrossCompile-TryRunResult-qnx-armle.cmake不包含CMAKE_CXX_COMPILER.

任何关于 giong 的线索都非常感谢!

我还使用了硫辛酸的命令行选项来查看正在使用的缓存变量,它绝对不是从获得正确的值SET命令时,命令茯苓-D...存在...

编辑:我发现以下CMake 支持请求建议使用环境变量,通过这个 SO thread找到。

似乎在这个过程中使用 ToolChain 文件中的变量可能为时已晚?奇怪,因为它在上面链接的指南中显示了这种方法。任何人都可以确认/否认这一点吗?谢谢。

gui*_*ini 5

您链接到的 SO 答案有一个指向CMake FAQ的链接。它说:

如何使用不同的编译器?

...

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

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

例如:

设置(CMAKE_C_COMPILER“gcc-4.2”)
设置(CMAKE_CXX_COMPILER“/usr/bin/g++ -4.2 ”)

项目(“你的项目名称”)


小智 5

您只需要将其设置为CACHE. 对于例如

set(CMAKE_C_COMPILER gcc CACHE STRING "C compiler" FORCE)
set(CMAKE_CXX_COMPILER g++ CACHE STRING "C++ compiler" FORCE)
Run Code Online (Sandbox Code Playgroud)


Jim*_*mbo 4

感谢所有回答的人。这两个答案实际上都没有涵盖真正的原因,但都是非常好的尝试并且非常相关,所以感谢您抽出时间来帮助我......非常感谢。

问题与解决方案

我最终遇到的问题归结为进行源内构建......我现在已经了解了进行源外构建的美妙之处和重要性!这确实是一个缓存问题。我以为我正在删除所有必要的内容,但我在源代码构建中发现工具链文件没有被访问......由于缓存。

因此答案是USE OUT-OF-SOURCE-BUILDS。然后你可以杀死二进制目录来模拟cmake clean类似的命令。然后你就可以保证一切都从头开始,并且没有任何内容被缓存......耶!

一路上我发现一些有用的东西

查看缓存变量

使用cmake选项-LA。这将列出 CMake 缓存中未标记为内部的缓存变量。

用于-N仅加载缓存而不运行脚本

CMake 相当于#error

发现工具链文件没有被重新读取,这对我来说是一中要害。为了解决这个问题,我在工具链文件中添加了以下行......

MESSAGE(FATAL_ERROR "I am included")
Run Code Online (Sandbox Code Playgroud)

你猜怎么着?没有发生错误。然而,一旦我清理了所有必要的废话以使其干净,cmake错误就被触发了。

平台 CMake 配置...自动包含

这个让我一时糊涂了......

来自http://www.cmake.org/Wiki/CMake_Cross_Compiling

一旦确定了系统和编译器CMake,它就会按以下顺序加载相应的文件:( Platform/${CMAKE_SYSTEM_NAME}.cmake强制)

我最初看到过这个,但已经搜索过了<CMakeList.txt directory>/Platform。我应该搜索<CMakeList.txt directory>/Modfules/Platform(也?)

在我的工具链文件中,我有以下行...

SET(CMAKE_SYSTEM_NAME QNX)
Run Code Online (Sandbox Code Playgroud)

因此,CMake正在Platform/QNX.cmake按照交叉编译指南所述进行搜索。我没有意识到的是这个意思Modules/Platform/QNX.cmake

这里最有趣的一行,我认为这给了我一个问题,但最终没有(我仍然发现这个文件的自动包含和有趣的一点,一些选项来自哪里等等......)

# force the language to be c++ since qnx only has gcc and not g++ and c++?     
set(CMAKE_CXX_COMPILE_OBJECT 
    "<CMAKE_CXX_COMPILER> -x c++ <DEFINES> <FLAGS> -o <OBJECT> -c <SOURCE>")
Run Code Online (Sandbox Code Playgroud)

希望有人觉得这很有用:)