如何在从顶级add_subdirectory添加的包上使用find_package?

问题描述 投票:1回答:2

这可能是一个问题,所以这是我的情况。

背景


我有以下项目结构:

-project
    -examples
        -example_that_uses_mylib_1
            * CMakeLists.txt
            * main.cpp
        -example_that_uses_mylib_2
            * CMakeLists.txt
            * main.cpp
    -external
        -notmylib_a
            * CMakeLists.txt
            * ... (other stuff)
        -notmylib_b
            * CMakeLists.txt
            * ... (other stuff)
    -src
        -mylib_stuff
            * file1.cpp
            * file1.h
        *CMakeLists.txt
    CMakeLists.txt

我正在尝试制作一个执行以下操作的cmake文件:

  • 允许mylib依赖于在external中找到的第三方库中的目标而不使用add_subdirectory,因为它们实际上不是子目录,这是不好的做法。
  • 允许依赖qazxsw poi目标的qazxsw poi可执行文件而不将其添加为子目录。

我不确定如何做到这一点,直到我看到顶级cmake的example_that_uses_mylib这样做:

mylib

和bar和baz this project这样做:

add_subdirectory(lib/foo)
add_subdirectory(src/bar)
add_subdirectory(src/baz)

这让我觉得我可以对我的库做同样的事情。我不能。

最初单个顶级CMakeLists.txt构建了所有目标,我想远离这个,并从CMakeLists.txt开始用add_subdirectories拆分构建。

问题


最初我的顶级CMakeLists.txt看起来很像这个(以前工作过):

#Bar
find_package(foo 0.1.2 CONFIG REQUIRED)

#Baz
find_package(bar CONFIG REQUIRED)

当我决定将事情分开时,我做了这个(这也有效):

mylib

然后,为了跟随另一个项目,我决定这样做:

add_subdirectory(external/notmylib_a)
add_library(mylib STATIC src/mylib_stuff/file1.cpp)
target_include_directories(mylib PUBLIC src/)
target_link_libraries(mylib PRIVATE notmylib_a::notmylib_a)

我在CMAKE中遇到错误

#CMakeLists.txt
add_subdirectory(external/notmylib_a)


#src/CMakeLists.txt
add_library(mylib STATIC src/mylib_stuff/file1.cpp)
target_include_directories(mylib PUBLIC src/)
target_link_libraries(mylib PRIVATE notmylib_a::notmylib_a)

另一个项目如何以这种方式利用#CMakeLists.txt add_subdirectory(external/notmylib_a) #src/CMakeLists.txt find_package(notmylib_a CONFIG REQUIRED) #NEW LINE!! add_library(mylib STATIC src/mylib_stuff/file1.cpp) target_include_directories(mylib PUBLIC src/) target_link_libraries(mylib PRIVATE notmylib_a::notmylib_a)

c++ build cmake static-libraries target
2个回答
1
投票

另一个项目如何以这种方式利用CMake Error at src/CMakeLists.txt:25 (find_package): Could not find a package configuration file provided by "notmylib_a" with any of the following names: notmylib_aConfig.cmake notmylib_a-config.cmake Add the installation prefix of "notmylib_a" to CMAKE_PREFIX_PATH or set "notmylib_a_DIR" to a directory containing one of the above files. If "notmylib_a" provides a separate development package or SDK, be sure it has been installed.

其他find_package项目find_package的配置文件:

foo

也就是说,当has these lines包含if(NOT TARGET foo::foo) include("${foo_CMAKE_DIR}/foo-targets.cmake") endif() 方法并创建foo目标时,add_subdirectory实际上忽略了它的配置文件。

这在foo::foo中注明:

find_package(foo)

换句话说,使用foo's CMakeLists.txt方法包含的给定# We also add an alias definition so that we shadown # the export namespace when using add_subdirectory() instead. add_library(foo::foo ALIAS foo) 包,使用foo是可能的,但是可选:可以直接使用add_subdirectoryfind_package(foo)目标而不使用任何foo


0
投票

您引用的示例项目能够:

foo::foo

因为两个子项目find_package()#Bar find_package(foo 0.1.2 CONFIG REQUIRED) #Baz find_package(bar CONFIG REQUIRED) 都有lib/foo文件,其中包含生成CMake包配置文件的CMake代码,当src/bar模式被指定时,CMakeLists.txt将搜索该文件,发现这将构成find_package命令的成功。

例如,在CONFIG,此类代码包括:

find_package

因此,当运行lib/foo/CMakeLists.txt生成项目构建文件时,包配置文件是生成的文件之一,如下所示:

include(CMakePackageConfigHelpers)
...
set(PROJECT_CONFIG_FILE         "${PROJECT_BINARY_DIR}/foo-config.cmake")
...
configure_package_config_file(cmake/foo-config.cmake.in
        ${PROJECT_CONFIG_FILE}
        INSTALL_DESTINATION ${INSTALL_CONFIG_DIR})

这两个cmake文件分别是$ git clone https://github.com/sunsided/cmake.git ... $ cd cmake/ $ mkdir build $ cd build $ cmake .. ... $ find -name '*-config.cmake' ./lib/foo/foo-config.cmake ./src/bar/bar-config.cmake *-config.cmake的包配置文件。 lib/foo的文档描述了src/bar将发现它们的(复杂)搜索算法。对于子项目find_package CONFIG mode

find_package

能够找到src/bar,因为在运行时,已经生成了依赖项find_package(foo 0.1.2 CONFIG REQUIRED) 的构建文件。同样对于子项目lib/foo/foo-config.cmake

lib/foo

之所以成功,是因为已经生成了依赖关系src/baz的构建文件。

您尝试以相同方式使用find_package(bar CONFIG REQUIRED) 时收到的CMake错误:

src/bar

现在有一个明显的意义。要修复它,您需要填写find_package中缺少的CMake代码以生成CMake Error at src/CMakeLists.txt:25 (find_package): Could not find a package configuration file provided by "notmylib_a" with any of the following names: notmylib_aConfig.cmake notmylib_a-config.cmake ...

© www.soinside.com 2019 - 2024. All rights reserved.