如何通过CMake在同一位置安装多版本库并指定版本调用?
需求说明
希望通过CMake在同一位置(如默认系统前缀路径)安装同一库的多个版本,实现find_package(Package 1.0.0 REQUIRED)这样的调用方式。
- 为何不直接设置路径?
- 因为我不擅长记忆各类路径、编译选项等内容,认为这应该是CMake中
find_package命令的职责。
- 因为我不擅长记忆各类路径、编译选项等内容,认为这应该是CMake中
现存问题
find_package的版本参数只是一个普通参数,会被传递至包的*VersionConfig.cmake文件进行版本校验,若该文件不存在,CMake会将其视为错误。因此无法在同一位置安装不同版本的库。
最简CMake配置
file(WRITE Library.H "void Function();") file(WRITE Library.C "void Function() {}") add_library(Library SHARED Library.H Library.C) target_include_directories(Library PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}> $<INSTALL_INTERFACE:include/Library> ) set_target_properties(Library PROPERTIES VERSION 1.0.0) install(TARGETS Library EXPORT LibraryConfig) install(FILES Library.H DESTINATION include/Library) install(EXPORT LibraryConfig DESTINATION lib/cmake/Library) include(CMakePackageConfigHelpers) write_basic_package_version_file( ${PROJECT_BINARY_DIR}/LibraryConfigVersion.cmake VERSION 1.0.0 COMPATIBILITY SameMajorVersion ) install( FILES ${PROJECT_BINARY_DIR}/LibraryConfigVersion.cmake DESTINATION lib/cmake/Library )
可行方案尝试
我尝试将版本号以${PROJECT_NAME}-${PROJECT_VERSION}的形式附加到目标名称中:
- 修改导出名称:
install(TARGETS Library EXPORT Library-1.0.0Config) install( EXPORT Library-1.0.0Config DESTINATION lib/cmake/Library-1.0.0Config )
- 修改包含目录的
INSTALL_INTERFACE:
target_include_directories(Library PUBLIC $<INSTALL_INTERFACE:include/Library-1.0.0> )
- 修改目标的
OUTPUT_NAME属性:
set_target_properties(Library PROPERTIES OUTPUT_NAME Library-1.0.0 )
最终配置如下:
file(WRITE Library.H "void Function();") file(WRITE Library.C "void Function() {}") add_library(Library SHARED Library.H Library.C) target_include_directories(Library PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}> $<INSTALL_INTERFACE:include/Library-1.0.0> ) set_target_properties(Library PROPERTIES OUTPUT_NAME Library-1.0.0) install(TARGETS Library EXPORT Library-1.0.0Config) install(FILES Library.H DESTINATION include/Library-1.0.0) install(EXPORT Library-1.0.0Config DESTINATION lib/cmake/Library-1.0.0)
但该方案存在局限:调用时必须指定带版本号的目标名,即find_package(Target-1.0.0 REQUIRED),无法实现最初期望的调用方式。
内容的提问来源于stack exchange,提问作者Ghasem Ramezani
相关产品推荐
相关产品推荐

