我正在更新库的(非常旧的)查找模块。所以情况是使用CMake本身的现有共享库。用户可能已经安装了这个地方,包裹寄存处或其他任何地方。
现在他们想要使用它。好方法是
find_package(Foo REQUIRED)
target_link_libraries(MyProject Foo::Foo)
这就是目标。
问题是:一个好的find_package-Config或-Module怎么样才能让这个2-liner工作?它应该满足这两个要求:
cxx_std_11
(CMake 3.8+),cxx_alias_templates
(CMake 3.1+),check_cxx_source_compiles
和C ++设置C ++ 11要求11个代码和旧CMakes的警告)有两种方法可以做到这一点:
Foo::Foo
并正确设置(使用属性),并且还可以为旧的CMake设置FOO_INCLUDE_DIR
和FOO_LIBRARIES
目标。find_path
和find_library
,设置导入的目标即可完成。向前和向后兼容,因此即使找到旧版本也可以。 用法:
用户将(最新的)FindFoo.cmake
复制到其项目中,例如cmake/Modules
并将CMAKE_MODULE_PATH
指向它,或将FindFoo.cmake
复制到某个CMake默认路径。
倾听Daniel Pfeiffer和Modern CMake说If you are the library author, don't make a Find<mypackage>.cmake script!
所以我们导出并安装目标。
这有点乱。需要进行以下更改:
EXPORTS FooTargets
和INCLUDES DESTINATION include
添加到install(TARGETS
(参见Pfeiffer#24),它基本上只定义了一个导出。 (我真的不明白,为什么我要为已经有名字的东西创建一个额外的名字。为什么以下命令不能简单地引用一个目标?)install(EXPORT FooTargets NAMESPACE Foo:: DESTINATION lib/cmake/Foo)
,这会在FooTargets.cmake
中创建<CMAKE_INSTALL_PREFIX>/lib/cmake/Foo
,定义目标Foo::Foo
(希望)所有依赖项FooConfigVersion.cmake
创建write_basic_package_version_file
,根据我的理解,将版本硬编码到该文件FooConfig.cmake
,可以使用find_dependency
搜索Foo所依赖的库并包含FooTargets.cmake
FooConfig.cmake
和FooConfigVersion.cmake
安装到lib/cmake/Foo
target_include_directories
以使用单独的BUILD_INTERFACE
和INSTALL_INTERFACE
路径 用法:
当find_package
被搜索时,FooConfig.cmake
会自动找到FooConfigVersion.cmake
和Foo
。
所以Config-Module应该是首选,但我看到的问题是:
那么我们可以用CMake-Config解决这些需求吗?一个答案应该提供一个解决方案,或者至少是一个有根据的“不可能的”#34;它还应该解决最后概述的问题。
最后注意:如果它不存在,我想这会成为一个不错的维基词条。