首页 > 解决方案 > 我应该在 PackageConfig.cmake 中修改 CMAKE_MODULE_PATH

问题描述

我正在为我的项目编写一个带有导出目标的 MyPackageConfig 文件,以便其他项目可以轻松找到 MyPackage 及其依赖项。它看起来像这样:

include(CMakeFindDependencyMacro)

find_dependency(LIB1_WITHOUT_CMAKE_CONFIG)
find_dependency(LIB2_WITH_CMAKE_CONFIG)

include (Some/Install/Dir/MyPackageTargets.cmake)

我想知道在 find_dependency 调用之前将以下行添加到 MyPackageConfig.cmake 是否明智

# Find target dependencies
# Allows packages linking with MyPackage to use the find modules that
# MyPackage used to find it's dependencies. Since this path is appended to
# the existing module path, the calling package's module path will take
# precedence

list(APPEND CMAKE_MODULE_PATH @CMAKE_INSTALL_PREFIX@/lib/cmake/MyPackage/modules)

# Allows packages linking with MyPackage to find MyPacakge's dependencies if
# they don't already have them. Since this path (or these paths) are
# appended to the existing prefix path, the calling package's prefix
# path will take precedence

list(APPEND CMAKE_PREFIX_PATH @CMAKE_PREFIX_PATH@)

find_dependency(LIB1_WITHOUT_CMAKE_CONFIG)
find_dependency(LIB2_WITH_CMAKE_CONFIG)

好主意?不?

对我的理由的更长解释:

  1. 使用 MyPackage 的 YourPackage 如何找到 LIB1?

    (一世)。您可以编写自己的 FindLIB1.cmake 但这是重复劳动

    (二)。我可以将我的 FindLIB1.cmake 与 MyPackageConfig.cmake 一起安装在 Modules 目录中。但是你必须在你的模块路径中包含这个路径。

    find_dependency(LIB1_WITHOUT_CMAKE_CONFIG)我的建议:在修改模块路径之前添加一行,如下所示:

  list(APPEND CMAKE_MODULE_PATH  @CMAKE_INSTALL_PREFIX@/lib/cmake/mstk/modules)

这将确保如果你有一个 FindLIB1.cmake,它将被使用,但如果你没有我的,它将被找到并使用。

  1. 你怎么知道 LIB1 和 LIB2 驻留在哪里(包括 LIB2 的 Config 文件)?

    通过添加行

 list(APPEND CMAKE_PREFIX_PATH @CMAKE_PREFIX_PATH@)

我告诉你的包我在哪里搜索并找到了我的依赖项(但前提是你在指定的 CMAKE_PREFIX_PATH 中还没有它们)

标签: cmake

解决方案


是的,您可以更改变量,例如CMAKE_MODULE_PATHCMAKE_PREFIX_PATH出于配置脚本的目的。

任何“好”项目都应该准备好 prepend/appending CMAKE_PREFIX_PATH,因为这个变量通常可以由用户设置(当 call 时cmake)。至于CMAKE_MODULE_PATH,不同目录中的模块名称很少发生冲突。

一些提示:

  1. 您可以在脚本末尾恢复变量。这样您在更改变量时不会影响调用代码:

    # Store old value of the variable
    set(old_CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH})
    # Change variable, use it, ...
    # ...
    # Restore the variable at the end
    set(CMAKE_MODULE_PATH ${old_CMAKE_MODULE_PATH})
    

    但是请注意,find_dependency如果未找到(内部)包,则从脚本返回,因此在这种情况下不会触发恢复变量。但通常find_package()是用REQUIRED关键字调用的,所以找不到内包是致命的。

  2. CMAKE_PREFIX_PATH您可以设置仅影响特定查找脚本而不影响其他变量的其他变量,而不是进行更改。例如,许多查找脚本使用XXX_ROOT变量来提示位置。

    对于查找配置脚本本身,您可以使用PATHSHINTS选项find_package()

    # Was:
    #- list(APPEND CMAKE_PREFIX_PATH @CMAKE_PREFIX_PATH@)
    #- find_dependency(LIB2_WITH_CMAKE_CONFIG)
    # Replace with:
    find_dependency(LIB2_WITH_CMAKE_CONFIG
        PATHS @CMAKE_PREFIX_PATH@ # Where to find config script
        NO_DEFAULT_PATH # Do not search other places
    )
    

推荐阅读