CMake:或者在 Debug/Release 中安装一个导出文件?
CMake: Install an export file in Debug/Release alternatively?
以下面的例子为例:
...
add_library(Foo ...)
install(TARGETS Foo EXPORT FooTargets
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
...
)
install(EXPORT FooTargets
FILE lib/cmake/Foo
...
)
运行这个跟
$ mkdir build; cd build
$ cmake -DCMAKE_BUILD_TYPE=Release .. (or in Debug)
$ cmake --build .
$ cmake --install . --prefix my/custom/prefix
这将创建文件:
my/custom/prefix/lib/cmake/Foo/FooTargets.cmake
my/custom/prefix/lib/cmake/Foo/FooTargets-release.cmake (Or debug, respectively)
my/custom/prefix/lib/libFoo.a
根据我从 FooTargets.cmake
文件中设法理解的内容,它包含所有 FooTargets-*.cmake
文件和 includes()
所有文件。
反过来,FooTargets-release.cmake
文件引用了 libFoo.a
文件。
在关于 install
命令的文档中,它说您可以将 CONFIGURATIONS
选项添加到 install TARGETS
命令,因此如果我们更改上面的内容:
install(TARGETS Foo EXPORT FooTargets
CONFIGURATIONS Debug
LIBRARY DESTINATION lib/Debug
ARCHIVE DESTINATION lib/Debug
这将在 my/custom/path/lib/Debug/libFoo.a
中安装 libFoo.a
文件。现在假设我希望将 Release 库安装在 lib/Release
中,将 Debug 库安装在 lib/Debug
中,并且当下游项目使用我的包时,它将拥有正确的库,具体取决于它配置 - 即 - 调试构建将 link 针对调试库,与发布相同。
我认为我能做的是:
install(TARGETS Foo EXPORT FooTargets
CONFIGURATIONS Debug
LIBRARY DESTINATION lib/Debug
ARCHIVE DESTINATION lib/Debug
)
install(TARGETS Foo EXPORT FooTargets
CONFIGURATIONS Release
LIBRARY DESTINATION lib/Release
ARCHIVE DESTINATION lib/Release
)
install(EXPORT FooTargets
DESTINATION lib/cmake/Foo
...
)
而在Debug
中构建时,会生成FooTargets-debug.cmake
,指向lib/Debug/libFoo.a
,而在Release中构建时,FooTargets-release.cmake
] 将生成,指向 lib/Release/libFoo.a
。然后 FooTargets.cmake
将检查正在构建的消费项目使用什么配置,并包含正确的配置。
当我尝试执行上述操作时,我得到:
-- Configuring done
CMake Error: install(EXPORT "FooTargets" ...) includes target "Foo" more than once in the export set.
-- Generating done
CMake Generate step failed. Build files cannot be regenerated correctly.
这应该怎么做?
编辑
我以一种不太直接的方式发现,当我这样构建消费项目时:
$ cmake -DCMAKE_BUILD_TYPE=Debug ..
像这样:
$ cmake -DCMAKE_BUILD_TYPE=Release ..
我link只反对相关图书馆。基本上,它的工作原理是 FooTargets.cmake
文件包含在 FooConfig.cmake
文件中,该文件由 find_package
调用。 FooTargets.cmake
文件是定义导入目标的文件:
add_library(Foo IMPORTED)
此文件然后调用所有 FooTargets-*.cmake
,将相关库添加到某个名为 _IMPORT_CHECK_FILES_FOR_FOO
的列表中。
该文件还做的是:
set_property(TARGET Foo::Foo APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
显然有一些 属性 IMPORTED_CONFIGURATIONS 保存导入的配置。
我想在路上的某个地方,find_package
获取此列表并根据 CMAKE_BUILD_TYPE 变量对其进行过滤,这样 link 只有相关的库。
我仍然不明白的是,如何在(Foo 的)Release 构建时创建 FooTargets-release.cmake
,指向 lib/Release/Foo.a
,对于调试构建。
看来 CMake 已经完成了一半,除非我严重遗漏了什么。
似乎 per-CONFIGURATIONS 安装不容易适应 EXPORT 语义。
但是,在简单的情况下,per-configuration 的特定可以通过在 DESTINATION 中使用 generator expressions 来实现:
install(TARGETS Foo EXPORT FooTargets
LIBRARY DESTINATION lib/$<CONFIG>
ARCHIVE DESTINATION lib/$<CONFIG>
)
install(EXPORT FooTargets
DESTINATION lib/cmake/Foo
...
)
上面的代码会将库安装到 lib/Debug
进行调试配置,并安装到 lib/Release
进行发布配置。
以下面的例子为例:
...
add_library(Foo ...)
install(TARGETS Foo EXPORT FooTargets
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
...
)
install(EXPORT FooTargets
FILE lib/cmake/Foo
...
)
运行这个跟
$ mkdir build; cd build
$ cmake -DCMAKE_BUILD_TYPE=Release .. (or in Debug)
$ cmake --build .
$ cmake --install . --prefix my/custom/prefix
这将创建文件:
my/custom/prefix/lib/cmake/Foo/FooTargets.cmake
my/custom/prefix/lib/cmake/Foo/FooTargets-release.cmake (Or debug, respectively)
my/custom/prefix/lib/libFoo.a
根据我从 FooTargets.cmake
文件中设法理解的内容,它包含所有 FooTargets-*.cmake
文件和 includes()
所有文件。
反过来,FooTargets-release.cmake
文件引用了 libFoo.a
文件。
在关于 install
命令的文档中,它说您可以将 CONFIGURATIONS
选项添加到 install TARGETS
命令,因此如果我们更改上面的内容:
install(TARGETS Foo EXPORT FooTargets
CONFIGURATIONS Debug
LIBRARY DESTINATION lib/Debug
ARCHIVE DESTINATION lib/Debug
这将在 my/custom/path/lib/Debug/libFoo.a
中安装 libFoo.a
文件。现在假设我希望将 Release 库安装在 lib/Release
中,将 Debug 库安装在 lib/Debug
中,并且当下游项目使用我的包时,它将拥有正确的库,具体取决于它配置 - 即 - 调试构建将 link 针对调试库,与发布相同。
我认为我能做的是:
install(TARGETS Foo EXPORT FooTargets
CONFIGURATIONS Debug
LIBRARY DESTINATION lib/Debug
ARCHIVE DESTINATION lib/Debug
)
install(TARGETS Foo EXPORT FooTargets
CONFIGURATIONS Release
LIBRARY DESTINATION lib/Release
ARCHIVE DESTINATION lib/Release
)
install(EXPORT FooTargets
DESTINATION lib/cmake/Foo
...
)
而在Debug
中构建时,会生成FooTargets-debug.cmake
,指向lib/Debug/libFoo.a
,而在Release中构建时,FooTargets-release.cmake
] 将生成,指向 lib/Release/libFoo.a
。然后 FooTargets.cmake
将检查正在构建的消费项目使用什么配置,并包含正确的配置。
当我尝试执行上述操作时,我得到:
-- Configuring done
CMake Error: install(EXPORT "FooTargets" ...) includes target "Foo" more than once in the export set.
-- Generating done
CMake Generate step failed. Build files cannot be regenerated correctly.
这应该怎么做?
编辑
我以一种不太直接的方式发现,当我这样构建消费项目时:
$ cmake -DCMAKE_BUILD_TYPE=Debug ..
像这样:
$ cmake -DCMAKE_BUILD_TYPE=Release ..
我link只反对相关图书馆。基本上,它的工作原理是 FooTargets.cmake
文件包含在 FooConfig.cmake
文件中,该文件由 find_package
调用。 FooTargets.cmake
文件是定义导入目标的文件:
add_library(Foo IMPORTED)
此文件然后调用所有 FooTargets-*.cmake
,将相关库添加到某个名为 _IMPORT_CHECK_FILES_FOR_FOO
的列表中。
该文件还做的是:
set_property(TARGET Foo::Foo APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
显然有一些 属性 IMPORTED_CONFIGURATIONS 保存导入的配置。
我想在路上的某个地方,find_package
获取此列表并根据 CMAKE_BUILD_TYPE 变量对其进行过滤,这样 link 只有相关的库。
我仍然不明白的是,如何在(Foo 的)Release 构建时创建 FooTargets-release.cmake
,指向 lib/Release/Foo.a
,对于调试构建。
看来 CMake 已经完成了一半,除非我严重遗漏了什么。
似乎 per-CONFIGURATIONS 安装不容易适应 EXPORT 语义。
但是,在简单的情况下,per-configuration 的特定可以通过在 DESTINATION 中使用 generator expressions 来实现:
install(TARGETS Foo EXPORT FooTargets
LIBRARY DESTINATION lib/$<CONFIG>
ARCHIVE DESTINATION lib/$<CONFIG>
)
install(EXPORT FooTargets
DESTINATION lib/cmake/Foo
...
)
上面的代码会将库安装到 lib/Debug
进行调试配置,并安装到 lib/Release
进行发布配置。