这可能是一个问题,所以这是我的情况。
我有以下项目结构:
-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
,因为它们实际上不是子目录,这是不好的做法。我不确定如何做到这一点,直到我看到顶级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)
?
另一个项目如何以这种方式利用
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_subdirectory
或find_package(foo)
目标而不使用任何foo
。
您引用的示例项目能够:
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
...
。