【问题标题】:Parameterizing custom CMake toolchain [duplicate]参数化自定义 CMake 工具链 [重复]
【发布时间】:2020-07-08 13:28:24
【问题描述】:

我正在编写用于交叉编译的 CMake 工具链文件。

我有几个工具链,它们的差别非常小。我想为 cmake 创建一个描述所有工具链的文件,并让用户从命令行指定它们:cmake -DCMAKE_TOOLCHAIN_FILE=/path/to/toolchain.cmake -DTOOLCHAIN_NAME=<name>

不过,TOOLCHAIN_NAME 似乎有时会变成一个空字符串。

这里是工具链文件的例子:

set(tools /opt/toolchains/Custom/toolchains/toolchain)
set(sdk   /opt/toolchains/Custom/platforms/)

message(STATUS "toolchain_name ${TOOLCHAIN_NAME}")
if(NOT TOOLCHAIN_NAME) 
    message(SEND_ERROR "Please specify toolchain name in -DTOOLCHAIN_NAME parameter")
endif()

set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR ARM)

# further processing

然后我调用 CMake:

mkdir build
cd build
cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/toolchain.cmake -DTOOLCHAIN_NAME=proc-os-gnueabi-gcc_6_3
  

并得到以下错误输出:

-- toolchain name proc-os-gnueabi-gcc_6_3
-- toolchain name proc-os-gnueabi-gcc_6_3
-- The C compiler identification is GNU 6.3.1
-- The CXX compiler identification is GNU 6.3.1
-- Check for working C compiler: /opt/toolchains/.../bin/arm-os-gnueabi-gcc
CMake Error at /home/user/project/cmake/toolchain.cmake:59 (message):
  Please specify toolchain name in -DTOOLCHAIN_NAME parameter

Call Stack (most recent call first):
  /home/user/project/build/CMakeFiles/3.15.4/CMakeSystem.cmake:6 (include)
  /home/user/project/build/CMakeFiles/CMakeTmp/CMakeLists.txt:2 (project)


CMake Error at /usr/local/share/cmake-3.15/Modules/CMakeTestCCompiler.cmake:44 (try_compile):
  Failed to configure test project build system.
Call Stack (most recent call first):
  CMakeLists.txt:15 (project)


-- Configuring incomplete, errors occurred!
See also "/home/user/project/build/CMakeFiles/CMakeOutput.log".
See also "/home/user/project/build/CMakeFiles/CMakeError.log".

CMakeOutput.log 和 CMakeError.log 包含消息,表示编译器没有找到某些库。

如果我打开生成的文件/home/user/project/build/CMakeFiles/3.15.4/CMakeSystem.cmake 我可以看到以下内容

set(CMAKE_HOST_SYSTEM "Linux-4.2.0-27-generic")
set(CMAKE_HOST_SYSTEM_NAME "Linux")
set(CMAKE_HOST_SYSTEM_VERSION "4.2.0-27-generic")
set(CMAKE_HOST_SYSTEM_PROCESSOR "x86_64")

include("/home/user/project/cmake/toolchain.cmake")

set(CMAKE_SYSTEM "Generic")
set(CMAKE_SYSTEM_NAME "Generic")
set(CMAKE_SYSTEM_VERSION "")
set(CMAKE_SYSTEM_PROCESSOR "ARM")

set(CMAKE_CROSSCOMPILING "TRUE")

set(CMAKE_SYSTEM_LOADED 1)

根据 CMake 手册,其-D 参数用于指定缓存条目。

我从上面的输出中得出结论,提供的工具链文件由 CMake 处理至少 3 次。在前两次有适当的缓存条目,在第三次运行时它们不存在。

那么,如何避免工具链文件的代码重复?

UPD。在阅读this question 之后,我尝试了CMake 命令行参数的几种排列:在工具链之后但在选项之前指定源路径,在选项之后指定它,使用-S-B 选项显式指定源路径和构建路径。没有任何帮助。

【问题讨论】:

  • 也许您遇到了回复here中描述的问题。
  • 感谢您的指出。我已经尝试过并且失败了。问题已更新。

标签: c++ cmake cross-compiling


【解决方案1】:

我从上面的输出中得出结论,提供的工具链文件由 CMake 处理至少 3 次。前两次有正确的缓存条目,在第三次运行时它们不存在。

是的,这是非常好的观察。从技术上讲,只有在 project() 调用中的第一个工具链调用才能保证看到 CACHE 条目(使用 -D 参数创建到 cmake 或使用 set() 命令在 project() 调用之前创建)。

在不同工具链调用之间传递 CACHE 条目的一种方法是将它们存储在环境变量中:

下面的示例使用MY_TOOLCHAIN_NAME 环境变量作为TOOLCHAIN_NAME CMake 变量的存储。

if(DEFINED ENV{MY_TOOLCHAIN_NAME})
    # Environment variable is set.
    if (TOOLCHAIN_NAME)
        # CMake variable is set too.
        # It is up to your which one to use.
        # Uncomment line below for prefer environment variable to CMake one.
        # set(TOOLCHAIN_NAME $ENV{MY_TOOLCHAIN_NAME})
    else ()
        # CMake variable is not set. Use environment one.
        set(TOOLCHAIN_NAME $ENV{MY_TOOLCHAIN_NAME})
    endif()
else()
    # Environment variable is not set.
    if (TOOLCHAIN_NAME)
        # But CMake variable is set.
        # Store it into the environment and use it.
        set(ENV{MY_TOOLCHAIN_NAME} ${TOOLCHAIN_NAME})
    else()
        # Neither environment nor CMake variable is set.
        message(SEND_ERROR "Please specify toolchain name in -DTOOLCHAIN_NAME parameter")
    endif()
endif()

如果您有多个“调整”变量,您可以为上述所有步骤编写一个宏,并为您需要的每个变量应用(调用)这个宏。

【讨论】:

  • > 在不同工具链调用之间传递 CACHE 条目的一种方法 你知道其他的吗?你能分享一下吗?这种方法效果很好,但我想知道更多:)
  • "你认识其他人吗?" - 很不幸的是,不行。实际上,我在一些 cmake 邮件中看到了这种方法(只有方法,而不是代码),经过一些考虑,我发现它是“正确的”。如果一个人知道正确的方式,为什么他/她需要另一种方式?:) 特别是在 CMake 工具链这样复杂的主题的情况下,哪些文档还有很多不足之处。
猜你喜欢
  • 2018-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-03
  • 1970-01-01
  • 2020-10-21
  • 1970-01-01
相关资源
最近更新 更多