You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用CMake为仅含头文件的INTERFACE库设置版本?

Configuring Version for a Header-Only (INTERFACE) Library in CMake

Great question! This is a common gotcha with INTERFACE libraries in CMake because they don’t represent a binary target—so properties like VERSION and SOVERSION aren’t in their default allowed property list (hence the error you’re seeing). Let’s break down the solutions based on your CMake version:

Option 1: Use CMake 3.24+ (Simplest Approach)

Starting with CMake 3.24, the VERSION and SOVERSION properties were added to the allowed list for INTERFACE targets. You can use set_target_properties just like you would for a regular library:

add_library(MyHeaderOnlyLib INTERFACE)
set_target_properties(MyHeaderOnlyLib PROPERTIES
    VERSION "1.2.3"
    SOVERSION "1"
)

This makes the version properties available to any targets linking against your INTERFACE library, and works seamlessly with CMake’s package configuration system.

Option 2: For CMake < 3.24 (Workarounds)

If you’re stuck on an older CMake version, you’ll need to use alternative methods to expose version information:

Suboption 2a: Expose Version via Compile Definitions

You can directly pass version constants to consuming targets using target_compile_definitions:

add_library(MyHeaderOnlyLib INTERFACE)
target_compile_definitions(MyHeaderOnlyLib INTERFACE
    MY_LIB_VERSION_MAJOR=1
    MY_LIB_VERSION_MINOR=2
    MY_LIB_VERSION_PATCH=3
    MY_LIB_VERSION="1.2.3"
)

Consuming code can then use these preprocessor defines directly.

Suboption 2b: Generate a Version Header File

A cleaner approach is to create a version header using configure_file, which lets you centralize version info and make it accessible via a header:

  1. Create a version.h.in template:
#define MY_LIB_VERSION_MAJOR @MY_LIB_VERSION_MAJOR@
#define MY_LIB_VERSION_MINOR @MY_LIB_VERSION_MINOR@
#define MY_LIB_VERSION_PATCH @MY_LIB_VERSION_PATCH@
#define MY_LIB_VERSION "@MY_LIB_VERSION@"
  1. In your CMakeLists.txt, set the version variables and generate the header:
# Define version constants
set(MY_LIB_VERSION_MAJOR 1)
set(MY_LIB_VERSION_MINOR 2)
set(MY_LIB_VERSION_PATCH 3)
set(MY_LIB_VERSION "${MY_LIB_VERSION_MAJOR}.${MY_LIB_VERSION_MINOR}.${MY_LIB_VERSION_PATCH}")

add_library(MyHeaderOnlyLib INTERFACE)
# Generate the version header
configure_file(version.h.in ${CMAKE_CURRENT_BINARY_DIR}/version.h @ONLY)
# Make the generated header available to consumers
target_include_directories(MyHeaderOnlyLib INTERFACE
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
    $<INSTALL_INTERFACE:include>
)

Consumers can now include <version.h> to access the version info.

Suboption 2c: Support Version Checking for find_package

If you want users to be able to do find_package(MyLib 1.2 REQUIRED), you need to generate a ConfigVersion.cmake file (regardless of CMake version):

include(CMakePackageConfigHelpers)
write_basic_package_version_file(
    ${CMAKE_CURRENT_BINARY_DIR}/MyHeaderOnlyLibConfigVersion.cmake
    VERSION ${MY_LIB_VERSION}
    COMPATIBILITY SameMajorVersion # Or another compatibility rule like SameMinorVersion/AnyNewerVersion
)

# Install the config files so find_package can locate them
install(FILES
    ${CMAKE_CURRENT_BINARY_DIR}/MyHeaderOnlyLibConfigVersion.cmake
    ${CMAKE_CURRENT_SOURCE_DIR}/MyHeaderOnlyLibConfig.cmake
    DESTINATION lib/cmake/MyHeaderOnlyLib
)

# Install your INTERFACE target and exports
install(TARGETS MyHeaderOnlyLib
    EXPORT MyHeaderOnlyLibTargets
    INCLUDES DESTINATION include
)

install(EXPORT MyHeaderOnlyLibTargets
    FILE MyHeaderOnlyLibTargets.cmake
    DESTINATION lib/cmake/MyHeaderOnlyLib
)

This ensures CMake can validate the version when users try to find your library.

内容的提问来源于stack exchange,提问作者user8183713

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:22:08