【问题标题】:CMake Command Line Definitions Not Perpetuating To Toolchain FileCMake 命令行定义不会延续到工具链文件
【发布时间】:2016-09-18 07:48:09
【问题描述】:

我有一个cmake交叉编译工具链文件,简写为:

set(CMAKE_SYSTEM_NAME Linux)
if( DEFINED TC_PATH )
    message( STATUS " TC_PATH IS defined. ${TC_PATH}" )
else()
    message( FATAL_ERROR " TC_PATH not defined." )
endif()

set(CMAKE_C_COMPILER ${TC_PATH}/usr/bin/i586-linux/i586-linux-gcc )
set(CMAKE_CXX_COMPILER ${TC_PATH}/usr/bin/i586-linux/i586-linux-g++ )
set(CMAKE_LINKER ${TC_PATH}/usr/bin/i586-linux/i586-linux-ld )

我调用 cmake,设置 TC_PATH 以及工具链文件:

~/CMakeTest/output $ cmake -DTC_PATH:PATH=/opt/toolchain -DCMAKE_TOOLCHAIN_FILE=../toolchain.cmake ../

似乎 cmake 正在多次调用工具链文件。前两次,TC_PATH检查成功,但后来识别编译器后,抛出错误:

--  TC_PATH IS defined. /opt/toolchain
--  TC_PATH IS defined. /opt/toolchain
-- The C compiler identification is GNU 4.9.1
-- The CXX compiler identification is GNU 4.9.1
-- Check for working C compiler: /opt/toolchain/usr/bin/i586-linux/i586-linux-gcc
CMake Error at /home/gnac/CMakeTest/toolchain.cmake:4 (message):
   TC_PATH not defined.
Call Stack (most recent call first):
  /home/gnac/CMakeTest/output/CMakeFiles/3.0.2/CMakeSystem.cmake:6 (include)
  CMakeLists.txt:2 (project)

那么,除了在 shell 中设置永久环境变量之外,我如何通过命令行设置 TC_PATH 变量,以便在执行 cmake generate 命令时保持在上下文中?

【问题讨论】:

    标签: c++ cmake cross-compiling


    【解决方案1】:

    在编译测试项目时,CMake 默认不向其传递变量。

    CMAKE_TRY_COMPILE_PLATFORM_VARIABLES 选项用于将变量传递到测试项目。 为了解决您的问题,应将此行放入工具链文件中:

    set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES TC_PATH)
    

    【讨论】:

      【解决方案2】:

      您的工具链需要自给自足。失败的步骤是try_compile(),它没有获取您的缓存变量。

      您的工具链文件看起来不像是在进行交叉编译(它没有 CMAKE_SYSTEM_NAME),因此您可以执行以下操作之一(除了设置 CCCXX 环境变量之外)提到):

      1. 提供C 和/或CXX 编译器的完整路径就足够了(取决于您启用的语言),CMake 将自动检测您的 GNU 工具链的其余部分

        cmake -DCMAKE_C_COMPILER:PATH=/opt/toolchain/usr/bin/i586-linux/i586-linux-gcc 
              -DCMAKE_CXX_COMPILER:PATH=/opt/toolchain/usr/bin/i586-linux/i586-linux-g++ ...
        
      2. 将以下内容添加到您的工具链以跳过编译器测试(因为并非所有选项都可能传递给它,或者因为您选择的编译器/链接器不会生成有效的可执行文件)

        set(CMAKE_C_COMPILER_WORKS 1 CACHE INTERNAL "")
        set(CMAKE_CXX_COMPILER_WORKS 1 CACHE INTERNAL "")
        

        或者只使用CMakeForceCompiler 宏,但使用是“不鼓励。尽可能避免使用此模块。”

      3. 使用configure_file() 将路径放入您的工具链文件(只需确保在调用project() 之前完成)

      4. 如果您的工具链的可能路径已知而不是从外部设置它,则首选find_program()(参见例如here

      参考文献

      【讨论】:

      • 弗洛里安,我的工具链文件确实设置了 CMAKE_SYSTEM_NAME。我把它排除在“删节”版本之外,以使问题更简洁。我现在添加它以提供更完整/正确的问题。谢谢。
      • 这有点老了,但只是对处理这个问题的策略感到好奇。我想为 iOS 构建并且有可用的 iOS 工具链文件。一个问题是设置称为最低部署版本的东西。这对于人们来说可能会有所不同,因此理想情况下会作为参数传入。我可以看到的几个选项是使用环境变量来传递它,创建一个临时 cmake 文件,或者每个部署版本具有不同版本的工具链。都有自己的问题。
      【解决方案3】:

      很抱歉,我必须恢复它,但我仍然想知道为什么我需要使用这样的技巧来将变量传播到工具链配置文件:

      ...
      elseif(${OS_FSFW} STREQUAL linux AND TGT_BSP)
          if(NOT SOME_VARIABLE_USED_BY_TOOLCHAINFILE)
              set(ENV{SOME_VARIABLE_USED_BY_TOOLCHAINFILE} "$ENV{HOME}/raspberrypi/rootfs")
          else()
              set(ENV{SOME_VARIABLE_USED_BY_TOOLCHAINFILE} "${SOME_VARIABLE_USED_BY_TOOLCHAINFILE}")
          endif()
          set(CMAKE_TOOLCHAIN_FILE 
              ${CMAKE_CURRENT_SOURCE_DIR}/buildsystem/cmake/CrossCompileConfig.cmake
          )
      endif()
      

      我的意思是,它可以工作,但是为什么工具链文件无法正确处理上层 CMakeList 设置的变量? CMake 甚至可以打印出以这种方式设置的变量,但是除非它们是环境变量,否则检查它们的存在之类的操作似乎不起作用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-11-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-13
        • 1970-01-01
        • 1970-01-01
        • 2021-10-31
        相关资源
        最近更新 更多