【问题标题】:Guard code depending on CMake version保护代码取决于 CMake 版本
【发布时间】:2016-06-17 12:00:44
【问题描述】:

我们的项目有一个CMakeList.txt,但它不是我们的主要构建系统。在 Mac OS X 上,使用 Cmake generates a warning(这里没有新内容):

MACOSX_RPATH is not specified for the following targets...

引用的问题/答案说明使用set(CMAKE_MACOSX_RPATH 0)set(CMAKE_MACOSX_RPATH 1)。我们的问题是,the feature is too new 它破坏了现有的 Cmake 安装,就像在 Ubuntu LTS 或 CentOS 上发现的那样。我们需要保护它在 Cmake >= 2.8.12 时的使用,但是blog post 没有讨论如何去做。

搜索没有产生有用的结果:how to guard cmake directive。我无法找到相关结果可能是由于我对 Cmake 缺乏经验(其他人应该维护它)。

我们如何保护set(CMAKE_MACOSX_RPATH 0)set(CMAKE_MACOSX_RPATH 1)


请注意,我不是在寻找cmake_minimum_required(VERSION 2.8.5 FATAL_ERROR)。我能说的最好的一点是它不会做任何该死的事情。通过测试,我们知道它不会拒绝 target_include_directories,即使 target_include_directories 不满足最低要求并导致 Ubuntu LTS 等低级客户端出现故障。

我认为我正在寻找更接近 C 预处理器宏:

#define 2_8_12 ...
#if CMAKE_VERSION >= 2_8_12
set(CMAKE_MACOSX_RPATH 0)
#endif

【问题讨论】:

    标签: cmake versioning


    【解决方案1】:
    if (CMAKE_VERSION VERSION_LESS 2.8.12)
      message("Not setting RPATH")
    else()
      set(CMAKE_MACOSX_RPATH 0)
    endif()
    

    此处为 2.8.10 的文档:https://cmake.org/cmake/help/v2.8.10/cmake.html#variable:CMAKE_VERSION

    【讨论】:

    • 完美,谢谢。让我测试一下,然后重新接受。
    【解决方案2】:

    或者,如果您只是想克服警告,您可以检查生成此警告的策略是否存在

    if(POLICY CMP0042)
        set(CMAKE_MACOSX_RPATH 0)
    endif()
    

    documentation 中描述了这种“如果”形式。

    【讨论】:

    • 我可能错了,但是对于知道 CMP0042 的旧版本,CMake 会发出警告甚至错误。
    • 您的意思是“对于不知道 CMP0042 ...的旧版本...”?否则我的答案没有问题。
    • 嗯,我相信政策描述了与旧 CMake 版本的所有不兼容。因此,如果项目已在 2.8.12 之前成功构建,并且在新版本的 CMake 上为其生成了警告/错误,则可以使用策略机制禁用此警告/错误。
    • 当然。我的观点是,如果 CMake 版本比 CMP0042 旧,它将失败。检查版本可能是更好的选择,具体取决于其他版本限制。
    【解决方案3】:

    为什么不为 CMake 正确处理它?有一个名为 CMake RPATH handling 的 wiki 页面。据此,您可以添加如下内容:

    string (TOLOWER ${CMAKE_SYSTEM_NAME} TARGET_OS)
    
    if (TARGET_OS STREQUAL darwin)
        set (CMAKE_MACOSX_RPATH TRUE)
        set (CMAKE_SKIP_BUILD_RPATH FALSE)
    
        # Fix runtime paths on OS X 10.5 and less
        if (CMAKE_SYSTEM_VERSION VERSION_LESS "10.0.0")
            set (CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
        else()
            set (CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
        endif()
    
        set (CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
        set (CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
    
        list (FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir)
    
        if ("${isSystemDir}" STREQUAL "-1")
            set (CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
        endif ("${isSystemDir}" STREQUAL "-1")
    endif()
    

    这个 sn-p 应该用任何 2.8.x 版本修复 CMP0042。

    【讨论】:

    • RPATH 可能会导致安全审核失败。它总是会产生一个发现。在 OS X 上,我们希望看到 install_names。在 Linux 上,我们不希望看到 RPATH。
    • @jww CMake CMP0042 仅适用于 OS X 构建,这就是为什么我建议您只为 OS X 构建修复 RPATH。上面的 sn-p 不会在 Linux 上触及任何东西。
    • RPATH 仍会生成结果。不要使用 rpath 的。这些问题在set(CMAKE_MACOSX_RPATH 0)set(CMAKE_MACOSX_RPATH 0) 的上下文中提出。但是我们已经做出了选择 - set(CMAKE_MACOSX_RPATH 0)。我们没有提及它以避免旷日持久的辩论。
    • @jww 您是否尝试将CMAKE_SKIP_RPATH 变量设置为完全禁用CMake 的RPATH 管理?
    猜你喜欢
    • 1970-01-01
    • 2019-03-20
    • 2020-04-26
    • 2016-06-11
    • 2018-08-10
    • 2013-11-02
    • 2015-09-04
    • 1970-01-01
    相关资源
    最近更新 更多