这可能是一个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
我正在尝试创建一个执行以下操作的cmake文件:
允许mylib
依赖external
中发现的第三方库中的目标,而无需使用add_subdirectory
,因为它们实际上不是子目录,这是一种不好的做法。
允许example_that_uses_mylib
个依赖于mylib
目标的可执行文件,而无需将其添加为子目录。
在看到this project谁的顶级命令执行此操作之前,我不确定如何执行此操作:
add_subdirectory(lib/foo)
add_subdirectory(src/bar)
add_subdirectory(src/baz)
然后bar和baz CMakeLists.txt
执行以下操作:
#Bar
find_package(foo 0.1.2 CONFIG REQUIRED)
#Baz
find_package(bar CONFIG REQUIRED)
这让我觉得我可以对我的库做同样的事情。我不能
最初,单个顶级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)
当我决定将事物拆分成原来的样子时,我做到了(同样有效):
#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中遇到错误
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
?
答案 0 :(得分:1)
另一个项目如何能够以这种方式利用
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)
实际上忽略其配置文件。< / p>
这在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)
,但是可选:一个人可以直接使用{{1 }}或foo
目标,而没有任何foo::foo
。
答案 1 :(得分:0)
您引用的示例项目可以执行以下操作:
#Bar
find_package(foo 0.1.2 CONFIG REQUIRED)
#Baz
find_package(bar CONFIG REQUIRED)
因为两个子项目lib/foo
和src/bar
都有CMakeLists.txt
个文件
包含生成CMake软件包配置文件的CMake代码
如果指定了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)
成功,因为依赖项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
...
现在具有明显的含义。要修复它,您需要填写缺少的内容
external/notmylib_a/CMakeLists.txt
中的CMake代码生成notmylib_a-config.cmake
。