【问题标题】:CMake: Convert relative path to absolute path, with build directory as current directoryCMake:将相对路径转换为绝对路径,构建目录为当前目录
【发布时间】:2016-12-25 22:04:40
【问题描述】:

在 CMake 中,您可以使用将相对路径转换为绝对路径

get_filename_component(ABSOLUTE_PATH ${RELATIVE_PATH} ABSOLUTE)

但是,../../other_program/ 等路径是基于源目录(即CMakeLists.txt 文件所在的目录),而不是构建目录(即调用cmake 的目录)。如果您将相对路径作为命令行选项提供,这可能会导致一些混乱。

有没有办法告诉get_filename_component 它应该基于当前二进制目录而不是当前源目录的相对路径?

【问题讨论】:

    标签: cmake


    【解决方案1】:

    来自get_filename_component 的文档(突出显示我)

    get_filename_component(<VAR> <FileName>
                           <COMP> [BASE_DIR <BASE_DIR>]
                           [CACHE])
    

    &lt;VAR&gt; 设置为&lt;FileName&gt; 的绝对路径,其中&lt;COMP&gt; 是以下之一:

    ABSOLUTE = 文件的完整路径 REALPATH = 已解析符号链接的现有文件的完整路径

    如果提供的&lt;FileName&gt; 是相对路径,则相对于给定的基目录&lt;BASE_DIR&gt; 进行评估。 如果未提供基目录,则默认基目录将为CMAKE_CURRENT_SOURCE_DIR .

    返回的路径带有正斜杠并且没有尾随斜杠。如果指定了可选的CACHE 参数,则将结果变量添加到缓存中。

    因此,您使用:

    get_filename_component(buildDirRelFilePath "${myFile}"
                           REALPATH BASE_DIR "${CMAKE_BINARY_DIR}")
    

    要将文件的绝对路径转换为相对路径,您可以使用file command

    file(RELATIVE_PATH <variable> <directory> <file>)
    

    计算从&lt;directory&gt;&lt;file&gt; 的相对路径并将其存储在&lt;variable&gt; 中。

    file(RELATIVE_PATH buildDirRelFilePath "${CMAKE_BINARY_DIR}" "${myFile}")
    

    【讨论】:

    • 是的,此解决方案非常适合 CMake 3.4 及更高版本。对于较旧的 CMake 版本(低至 2.6 版),mike.did 的解决方案是处理它的最佳方式。
    • 请始终使用CMAKE_CURRENT_[BINARY|SOURCE]_DIR 而不仅仅是CMAKE_[BINARY|SOURCE]_DIR 变量。对于试图在更大项目中使用您的库的人来说,后者会搞砸很多事情。
    • 这适用于源代码构建。但是,对于源代码外构建 (cmake -S src -B build),CMAKE_BINARY_DIR 显示的是 build 目录,而不是顶级源目录。源代码外构建应该使用什么?或者更好 - 为两者工作。
    • @ilya1725 答案已经在您上面的 Qix 评论中:使用CMAKE_CURRENT_SOURCE_DIR 获取src(而不是CMAKE_CURRENT_BINARY_DIR 获取build)。
    • 或使用CMAKE_CURRENT_LIST_DIR 作为基础,它会扩展为CMake 文件的目录(您在其中编写的文件)。
    【解决方案2】:
    get_filename_component(MY_RESULT_ABSOLUTE_PATH_VAR
                           "${CMAKE_CURRENT_LIST_DIR}/${MY_RELATIVE_PATH_VAR}"
                           ABSOLUTE)
    

    【讨论】:

    【解决方案3】:

    您可以使用if(IS_ABSOLUTE path) 检查路径是否是绝对路径,以及它是否不是您想要的基本目录。例如,

    if(NOT IS_ABSOLUTE ${p})
        set(p "${CMAKE_CURRENT_BINARY_DIR}/${p}")
    endif()
    

    【讨论】:

      猜你喜欢
      • 2011-02-03
      • 1970-01-01
      • 2017-08-01
      • 2011-11-07
      • 2011-05-02
      相关资源
      最近更新 更多