使用父库安装预构建的静态库依赖项
Install prebuilt static library dependency with the parent library
我的项目结构如下所示:
Parent/
CMakeLists.txt
file.cpp
third_party/
dependency/
CMakeLists.txt
lib/
dependency.lib
请注意 dependency.lib 是一个 precompiled/prebuilt 库:我什至没有它的资源。
当我安装 Parent
时,我希望它像这样进入 dist 文件夹(在之前的树结构中,但为清楚起见省略):
Parent/
dist/
Parent/
include/
bin/
lib/
cmake/
ParentTargets.cmake
Parent.lib
dependency.lib
这里的想法是将生成的库和依赖库都放在一个地方以便于安装。
Parent CMakeLists.txt
的相关部分如下所示(省略了很多内容,例如包含等):
cmake_minimum_required(VERSION 3.22)
project(Parent VERSION 0.1.0 LANGUAGES C CXX)
add_library(Parent)
target_sources(Parent PRIVATE file.cpp)
add_subdirectory("${CMAKE_SOURCE_DIR}/third_party/dependency")
target_link_libraries(Parent PRIVATE dependency)
# Manual copy of dependency.lib to install location
install(DIRECTORY "${CMAKE_SOURCE_DIR}/third_party/dependency/lib/"
DESTINATION lib
FILES_MATCHING
PATTERN "dependency.lib"
)
# Install all targets to ParentTargets export set.
# (omitting install dir variables, components, etc. for clarity)
install(
TARGETS
Parent dependency
EXPORT
ParentTargets
LIBRARY
DESTINATION lib
ARCHIVE
DESTINATION lib
)
# Write ParentTargets export set to targets file directly in install folder
install(EXPORT ParentTargets
FILE ParentTargets.cmake
NAMESPACE Parent::
DESTINATION lib/cmake
)
这就是我对依赖项的 CMakeLists.txt
:
add_library(dependency INTERFACE)
target_link_libraries(dependency
INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/lib/dependency.lib>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/lib/dependency.lib>
)
这几乎是可行的,问题是如果您查看生成的 ParentTargets.cmake
,这就是 CMake 为 dependency
目标生成的内容:
# Create imported target Parent::dependency
add_library(Parent::dependency INTERFACE IMPORTED)
set_target_properties(Parent::dependency PROPERTIES
INTERFACE_LINK_LIBRARIES "E:/absolute/path/Parent/dist/Parent/lib/dependency.lib"
)
...它是我的安装目录的硬编码绝对路径。这不是很好,通常对于构建的库,CMake 会生成类似 ${_IMPORT_PREFIX}/lib/dependency.lib
的路径,这是我想要的,并且对于安装可重定位很重要。
这是我的问题:
- 这样做正确吗?我永远找不到关于如何将依赖静态库与项目一起打包的很好的参考,而且 CMake 似乎并没有太急切地“自行”执行此操作(我什至不得不手动复制 .lib,如您所见) ;
- 如何让 CMake 在那里使用
${_IMPORT_PREFIX}
?我不能只在我的 CMakeLists.txt 上使用它,因为它会在生成期间评估为空字符串,而且我不能像 ${_IMPORT_PREFIX}
那样转义它,因为它仍然将转义版本放在 ParentTargets.cmake...
Is this the right way of doing this? I could never find a good reference on how to package dependency static libraries alongside your project, and CMake doesn't seem to do this "on its own" too eagerly (I even had to manually copy the .lib there as you can see);
我认为你所做的很好。如果是我,我会在主构建和包配置文件中为 dependency.lib
创建并 link 到名为 Parent::ThirdParty::dependency
的 IMPORTED STATIC
目标,并设置其 IMPORTED_LOCATION
属性 每个都合适。
原因是 CMake 将验证您 link 名称中包含 ::
的任何内容都是 CMake 目标。这往往会减少 link 行上的意外情况,并允许您将诸如包含路径之类的内容附加到库中。
How do I get CMake to use ${_IMPORT_PREFIX} there? [...]
您的问题在这里:
$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/lib/dependency.lib>
CMAKE_INSTALL_PREFIX
设置为 E:/absolute/path/Parent/dist/Parent
立即 并且 CMake 没有机会用 ${_IMPORT_PREFIX}
之类的东西替换它。幸运的是,有一个生成器表达式。
$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/lib/dependency.lib>
试试看。
我的项目结构如下所示:
Parent/
CMakeLists.txt
file.cpp
third_party/
dependency/
CMakeLists.txt
lib/
dependency.lib
请注意 dependency.lib 是一个 precompiled/prebuilt 库:我什至没有它的资源。
当我安装 Parent
时,我希望它像这样进入 dist 文件夹(在之前的树结构中,但为清楚起见省略):
Parent/
dist/
Parent/
include/
bin/
lib/
cmake/
ParentTargets.cmake
Parent.lib
dependency.lib
这里的想法是将生成的库和依赖库都放在一个地方以便于安装。
Parent CMakeLists.txt
的相关部分如下所示(省略了很多内容,例如包含等):
cmake_minimum_required(VERSION 3.22)
project(Parent VERSION 0.1.0 LANGUAGES C CXX)
add_library(Parent)
target_sources(Parent PRIVATE file.cpp)
add_subdirectory("${CMAKE_SOURCE_DIR}/third_party/dependency")
target_link_libraries(Parent PRIVATE dependency)
# Manual copy of dependency.lib to install location
install(DIRECTORY "${CMAKE_SOURCE_DIR}/third_party/dependency/lib/"
DESTINATION lib
FILES_MATCHING
PATTERN "dependency.lib"
)
# Install all targets to ParentTargets export set.
# (omitting install dir variables, components, etc. for clarity)
install(
TARGETS
Parent dependency
EXPORT
ParentTargets
LIBRARY
DESTINATION lib
ARCHIVE
DESTINATION lib
)
# Write ParentTargets export set to targets file directly in install folder
install(EXPORT ParentTargets
FILE ParentTargets.cmake
NAMESPACE Parent::
DESTINATION lib/cmake
)
这就是我对依赖项的 CMakeLists.txt
:
add_library(dependency INTERFACE)
target_link_libraries(dependency
INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/lib/dependency.lib>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/lib/dependency.lib>
)
这几乎是可行的,问题是如果您查看生成的 ParentTargets.cmake
,这就是 CMake 为 dependency
目标生成的内容:
# Create imported target Parent::dependency
add_library(Parent::dependency INTERFACE IMPORTED)
set_target_properties(Parent::dependency PROPERTIES
INTERFACE_LINK_LIBRARIES "E:/absolute/path/Parent/dist/Parent/lib/dependency.lib"
)
...它是我的安装目录的硬编码绝对路径。这不是很好,通常对于构建的库,CMake 会生成类似 ${_IMPORT_PREFIX}/lib/dependency.lib
的路径,这是我想要的,并且对于安装可重定位很重要。
这是我的问题:
- 这样做正确吗?我永远找不到关于如何将依赖静态库与项目一起打包的很好的参考,而且 CMake 似乎并没有太急切地“自行”执行此操作(我什至不得不手动复制 .lib,如您所见) ;
- 如何让 CMake 在那里使用
${_IMPORT_PREFIX}
?我不能只在我的 CMakeLists.txt 上使用它,因为它会在生成期间评估为空字符串,而且我不能像${_IMPORT_PREFIX}
那样转义它,因为它仍然将转义版本放在 ParentTargets.cmake...
Is this the right way of doing this? I could never find a good reference on how to package dependency static libraries alongside your project, and CMake doesn't seem to do this "on its own" too eagerly (I even had to manually copy the .lib there as you can see);
我认为你所做的很好。如果是我,我会在主构建和包配置文件中为 dependency.lib
创建并 link 到名为 Parent::ThirdParty::dependency
的 IMPORTED STATIC
目标,并设置其 IMPORTED_LOCATION
属性 每个都合适。
原因是 CMake 将验证您 link 名称中包含 ::
的任何内容都是 CMake 目标。这往往会减少 link 行上的意外情况,并允许您将诸如包含路径之类的内容附加到库中。
How do I get CMake to use ${_IMPORT_PREFIX} there? [...]
您的问题在这里:
$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/lib/dependency.lib>
CMAKE_INSTALL_PREFIX
设置为 E:/absolute/path/Parent/dist/Parent
立即 并且 CMake 没有机会用 ${_IMPORT_PREFIX}
之类的东西替换它。幸运的是,有一个生成器表达式。
$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/lib/dependency.lib>
试试看。