CMake传递的变量编译器无法编译简单的程序

     2023-02-17     20

关键词:

【中文标题】CMake传递的变量编译器无法编译简单的程序【英文标题】:CMake Passed variables compiler is not able to compile a simple program 【发布时间】:2017-07-28 21:24:10 【问题描述】:

我正在尝试使用 CMake 交叉编译应用程序。当我对交叉编译器的路径进行硬编码时,一切正常。但是,当我通过命令行参数传递路径时,它似乎无法正确跟踪它们。

这是我的 shell 脚本,我从中克隆一个 repo,应用补丁,然后尝试 cmake 构建:

   cmake -D BASE=$PATH_TO_TOOLCHAIN_ROOT -D BOOST_ROOT=$BOOST_ROOT -D CMAKE_TOOLCHAIN_FILE=../toolchain.cmake ../$GIT_PATH/src/

这是我的 toolchain.cmake 文件:

set( CMAKE_SYSTEM_NAME Linux )
set( CMAKE_SYSTEM_VERSION 1 )
set(PKG_CONFIG_EXECUTABLE "/usr/bin/pkg-config")

message("Base: $BASE")
message("Boost: $BOOST_ROOT")

set(CMAKE_SYSROOT "$BASE/sysroot")

set(CMAKE_C_COMPILER "$BASE/sysroot/usr/bin/mipsel-linux-gcc")
set(CMAKE_CXX_COMPILER "$BASE/sysroot/usr/bin/mipsel-linux-g++") 

set( CMAKE_FIND_ROOT_PATH "$BASE/sysroot")

set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH)
# for libraries and headers in the target directories
set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH)
set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH)


include_directories($CMAKE_SYSROOT/usr/local/include/)

set(BOOST_INCLUDEDIR $BOOST_ROOT/include)
set(BOOST_LIBRARYDIR $BOOST_ROOT/lib)

include_directories($BOOST_INCLUDEDIR)

set(OPENSSL_ROOT_DIR $BASE/sysroot/usr/lib/)
set(OPENSSL_SSL_LIBRARY libssl.so)
set(OPENSSL_CRYPTO_LIBRARY libcrypto.so)

同样,如果我在这个工具链文件中将 $BASE 硬编码为 /path/to/mipsel-linux-gcc,它可以工作。

但是,当我真正调用它时,我得到了这个打印输出:

+ cmake -D BASE=/path/to/toolchain/root -D BOOST_ROOT=/home/matthew/boost/out -D CMAKE_TOOLCHAIN_FILE=../toolchain.cmake ../build/src/
Base: /path/to/toolchain/root
Boost: /home/matthew/boost/out
Base: /path/to/toolchain/root
Boost: /home/matthew/boost/out
-- The C compiler identification is GNU 4.7.3
-- The CXX compiler identification is GNU 4.7.3
-- Check for working C compiler: /path/to/toolchain/root/sysroot/usr/bin/mipsel-linux-gcc
Base: 
Boost: 
-- Check for working C compiler: /path/to/toolchain/root/sysroot/usr/bin/mipsel-linux-gcc -- broken
CMake Error at /usr/local/share/cmake-3.8/Modules/CMakeTestCCompiler.cmake:51 (message):
  The C compiler
  "/path/to/toolchain/root/sysroot/usr/bin/mipsel-linux-gcc"
  is not able to compile a simple test program.

  It fails with the following output:

   Change Dir: /home/matthew/Desktop/clones/build/CMakeFiles/CMakeTmp

在这里您可以清楚地看到它确实找到了编译器,并将它们都标识为 GNU 4.7.3。但是,请注意打印输出 Base: /path/to/toolchain/root。这个 message() 指令在 toolchain.cmake 中只列出了一次,但它在这里打印了几次,最终显示为一个空白变量。之后,它抱怨 C 编译器不工作,即使它清楚地打印出该编译器的完整路径。

我见过其他人的类似问题,但这似乎不同,因为当我将 toolchain.cmake 中的路径硬编码到 C 和 CXX 编译器时,它工作正常。我尝试过在 C 和 CXX 编译器指令周围加上引号,以及不加引号。

我也有兴趣了解为什么我的消息指令会打印这么多次!

谢谢

【问题讨论】:

I am also interested in learning why my message directives print out so many times! - 它似乎第三次在编译器检查期间打印。此检查实际上是一个(单独的)CMake 项目,它“继承”您的工具链......但不是传递给cmake 的其他定义。看起来使用 CMake 变量参数化工具链不是一个好主意:这些变量不会传递给子项目。顺便说一句,CMake 有一个用于 sysroot 的特殊变量:CMAKE_SYSROOT。 【参考方案1】:

CMake 正在进行测试构建,以确定编译器是否能够构建一个简单的应用程序(基本上只包含 main())。这可能由于多种原因而失败,例如编译器无法使用默认的 CMake 检测标志等。

您应该检查CMakeError.logCMakeOutput.log 以了解测试编译失败的原因。

要跳过编译器测试,不妨将以下内容放到工具链文件中:

set(CMAKE_C_COMPILER_WORKS 1)
set(CMAKE_CXX_COMPILER_WORKS 1)

这将跳过编译器测试,但是当您实际构建项目时,当然编译可能会失败。

【讨论】:

首先,我发现 CMAKE_C_COMPILER_WORKS 及其 CXX 等效项不起作用。我不得不使用-DCMAKE_C_COMPILER_FORCED=true。其次,跳过编译器测试没有意义,因为 cmake 内省可能会在后面的步骤中出错。有一些方法可以规避它,但它只是把一个面具放在一个问题的面具上【参考方案2】:

在这里查看我的回复:

https://intellij-support.jetbrains.com/hc/en-us/community/posts/207460115/comments/360002077699

基本上cmake在其系统自省时会通过try_compile命令生成一些文件(测试C/CXX文件、Makefiles甚至是一个新的CMake项目)然后默认删除。

如果您希望能够禁用删除这些生成的文件并调试您的问题,您可以在运行 cmake 时添加--debug_trycompile,您会在 root/cmake_build/CMakeFiles/CMakeTmp 中找到一些非常有用的信息

【讨论】:

cmake入门——简单cmakelists的编写(代码片段)

...一种跨平台的开源项目管理工具,所做的事其实就是告诉编译器如何去编译链接源代码。与之相似的是直接编写makefile文件,但makefile最大的缺点就是不能跨平台,一旦更换环境就要重新编写,于是我们可以使用CMake编写CMakeLists... 查看详情

使用 cmake 和 mingw-w64 错误编译测试程序

...-w64和cmake进行简单的编译。但由于某种原因,我不能。它无法验证gcc是否可以编译一个奇怪的C程序。有任何想法吗?谢谢保罗C:\\work\\opencv\\myown\\hello& 查看详情

cmake交叉编译的使用(代码片段)

...置文件  文件命名为toolchain.cmake,配置文件中主要是对编译器的说明,指明编译器的sysroot,CC,CXX以及其他的选项设置,不同的交叉工具链配置略有不同,基本配置都是相同的。1#目标机target所在的操作系统名称,比如ARM或者L... 查看详情

在 cmake 中将目标文件名作为编译定义传递

】在cmake中将目标文件名作为编译定义传递【英文标题】:Passtargetfilenameascompiledefinitionincmake【发布时间】:2014-12-0815:03:34【问题描述】:我有许多目标的CMakeLists.txt,并且目标定义了特定于配置的后缀。另外我想知道程序中可执... 查看详情

CMAKE 使用环境变量而不将它们作为命令行参数传递?

...我在RHEL5上使用模块,并在我的机器上安装了各种版本的编译器/binutils。因此,我最终定义了指向我的工具的环境变量并相应地更新了路径,因此RHEL5附带的旧工具不 查看详情

cmake基础教程cmake生成debug和release两个版本程序(如何编译-g版本)(代码片段)

...绝对有很大的帮助。这是cmake的一个神坑。可以通过设置变量CMAKE_BUILD_TYPE生成debug版和release版的程序。该变量可以的取值是DebugReleaseRelWithDebInfo和MinSizeRel。当这个变量值为Debug的时候,CMake会使用变量CMAKE_CXX_FLAGS_DEBUG和CMAKE_C_FLAGS_DE... 查看详情

使用cmake编译c/c++程序

参考技术ACMakeTutorialCMakeReference定义程序编译规则生成可执行文件的最简单版本的CMakeLists.txt以上CMakeLists.txt定义的编译规则是将源文件tutorial.c编译成名为Tutorial的可执行文件。一般用法是,新建一个文件夹,一般命名为build,在... 查看详情

cmake如何编译成debug版?

...回复7#qfmeal这些参数是make工具的,--debug只会让make在调用编译器gcc/g++干活的时候打印更多的东西,让你看到它详细的分析和处理指令的过程。参考技术A谢谢可以了。就是这个变量。SET(CMAKE_BUILD_TYPEDebug) 参考技术B……好像没有。M... 查看详情

qt之qmake编译转换为cmake编译(代码片段)

...都是用来控制编译过程的构建系统,最终生成可在选择的编译器环境中使用的本机makefile和工作区。简单来说,QMake和CMake就像类似于作曲,makefile类似于乐谱,最终由编译器完成乐章的演奏。那么QMake和CMake有什么区别呢?-对于... 查看详情

如何检查 cmake 内部变量?

...述】:作为我们构建过程的一部分,我们需要记录机器和编译器的详细信息。由于可以通过设置CMAKE_CXX_COMPILER从系统默认值更改编译器,我认为检测编译器最安全的方法是询问cmake自己它正在使用什么。这是我们用于项目的工具... 查看详情

传递编译器选项 cmake

】传递编译器选项cmake【英文标题】:Passingcompileroptionscmake【发布时间】:2017-05-3112:02:01【问题描述】:我知道如何使用cmake命令传递编译器选项set(CMAKE_CXX_FLAGS"-Wall-Wno-dev-Wl,-rpath=/home/abcd/libs/")还有什么方法可以从命令行传递选项... 查看详情

cmake小总结(代码片段)

...Make能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的automake。CMake不仅可以编译源代码、制作程序库、产生适配器(wrapper)、还可以用任意的顺序建构执行档 查看详情

cmake小总结(代码片段)

...Make能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的automake。CMake不仅可以编译源代码、制作程序库、产生适配器(wrapper)、还可以用任意的顺序建构执行档 查看详情

无法编译简单的 Qt QFtp 程序

】无法编译简单的QtQFtp程序【英文标题】:CannotcompilesimpleQtQFtpprogram【发布时间】:2012-03-0401:51:44【问题描述】:我在使用QFtp时遇到问题。它根本不适合我(程序无法编译)。我打破了我正在编写的主程序,为它做一个小测试应... 查看详情

gcc/make/makefile/cmake/qmake的区别与联系

...使用时:04参考材料01概述gcc是GNUCompilerCollection(就是GNU编译器套件),也可以简单认为是编译器,它可以编译很多种编程语言(括C、C++、Objective-C、Fortran、Java等等)。当你的程序只有一个源文件时,直接就可以用gcc命令编译它... 查看详情

无法编译简单的 Bullet Physics 应用程序

】无法编译简单的BulletPhysics应用程序【英文标题】:Can\'tcompileasimpleBulletPhysicsapplication【发布时间】:2012-12-1013:39:18【问题描述】:我正在尝试在VisualStudio2012Express中编译BullelPhysicsWiki中的theHelloWorld程序。我能够生成并导入运行... 查看详情

在 CLion 中编译简单程序时出错

...简单的“HelloWorld”程序时遇到问题。可能是因为错误的编译器设置,或者类似的东西,但我没有想法,所以如果你们中的任何人有解决方案,我会很高兴。我已经安装了gcc、gdb和cmake,所以我认为没 查看详情

centos6.6中安装cmake时出现无c++程序可关联

...riableCXX.Seecmake_bootstrap.logforcompilersattempted.说你缺少需要的编译器,你安装g++了吗?可以看一下你的cmake安装包里面的readme文件,看看需要的是什么版本的gcc和g++编译器,然后在机器上执行一下gcc-v和g++-v看看是不是版本对不上。如... 查看详情