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

whn*_*whn 3 c++ build cmake static-libraries target

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

背景


我有以下项目结构:

-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
Run Code Online (Sandbox Code Playgroud)

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

  • 允许mylib依赖于 3rd 方库中的目标而不external使用,add_subdirectory因为它们实际上不是子目录,这是不好的做法。

  • 允许example_that_uses_mylib依赖于mylib目标的可执行文件而不将其添加为子目录。

在我看到这个项目的顶级 cmake 这样做之前,我不确定如何做到这一点:

add_subdirectory(lib/foo)
add_subdirectory(src/bar)
add_subdirectory(src/baz)
Run Code Online (Sandbox Code Playgroud)

和 bar 和 bazCMakeLists.txt这样做:

#Bar
find_package(foo 0.1.2 CONFIG REQUIRED)

#Baz
find_package(bar CONFIG REQUIRED)
Run Code Online (Sandbox Code Playgroud)

这让我觉得我可以用我的图书馆做同样的事情。我不能。

最初,单个顶级 CMakeLists.txt 构建了所有目标,我想摆脱这一点,并使用 add_subdirectories 拆分构建,从mylib.

问题


最初我的顶级 CMakeLists.txt 看起来很像这样(以前有效):

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)
Run Code Online (Sandbox Code Playgroud)

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

#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)
Run Code Online (Sandbox Code Playgroud)

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

#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)
Run Code Online (Sandbox Code Playgroud)

我在 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

  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.
Run Code Online (Sandbox Code Playgroud)

另一个项目是如何find_package以这种方式利用的?

Tsy*_*rev 5

另一个项目是如何find_package以这种方式利用的?

其他foo项目的配置文件有以下几行

if(NOT TARGET foo::foo)
    include("${foo_CMAKE_DIR}/foo-targets.cmake")
endif()
Run Code Online (Sandbox Code Playgroud)

也就是说,当foo包含在add_subdirectory方法中并创建foo::foo目标时,find_package(foo)实际上会忽略其配置文件。

这在foo 的 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)
Run Code Online (Sandbox Code Playgroud)

换句话说,对于foo包含在add_subdirectory方法中的给定包, usingfind_package(foo)是可能的,但可选的:可以直接使用foofoo::foo针对没有任何find_package().