CMake find_package指定版本范围0.3.3...<0.5.0不兼容0.4.6的问题排查
0.3.3...<0.5.0不匹配0.4.6版本? 这个问题不是CMake版本范围语法的问题,而是出在你依赖的mypkg软件包自身的版本配置文件逻辑上。让我们拆解一下原因和解决办法:
问题根源:软件包的版本兼容性检查逻辑过于严格
你提供的mypkg-config-version.cmake文件是用CMake的write_basic_package_version_file()生成的,从注释和代码逻辑能看出,它采用了SameMinorVersion的兼容性模式——也就是说,只有当请求的版本和当前包的主版本+次版本完全一致时,才会被认为兼容。
而在处理版本范围(比如你写的0.3.3...<0.5.0)时,这个配置文件的逻辑有个硬限制:
if (NOT (PACKAGE_FIND_VERSION_MIN_MAJOR STREQUAL CVF_VERSION_MAJOR AND PACKAGE_FIND_VERSION_MIN_MINOR STREQUAL CVF_VERSION_MINOR) OR ...) set(PACKAGE_VERSION_COMPATIBLE FALSE)
它要求范围的最小端点的主版本和次版本必须和当前包的版本完全匹配。你的当前包版本是0.4.6(主版本0,次版本4),但范围的最小端点是0.3.3(次版本3),两者的次版本不一致,所以直接被判定为不兼容,哪怕0.4.6确实在0.3.3...<0.5.0的范围内。
解决办法
你有几个可选的修复方向:
1. 修改软件包的版本配置生成逻辑(推荐)
如果有权限修改mypkg的CMake配置,把生成版本文件的兼容性模式改成SameMajorVersion或者AnyNewerVersion:
write_basic_package_version_file( mypkg-config-version.cmake VERSION ${PROJECT_VERSION} COMPATIBILITY SameMajorVersion # 允许同主版本下的所有更高次版本 )
SameMajorVersion模式会认可同主版本(这里是0)下,所有大于等于请求版本的包,这样0.4.6自然会被0.3.3...<0.5.0的范围接受。
2. 调整你的版本范围请求
如果无法修改mypkg,可以把你的find_package范围调整为和当前包次版本一致的区间:
find_package(mypkg 0.4.0...<0.5.0 REQUIRED)
这样范围的最小端点次版本是4,和0.4.6的次版本匹配,就能通过配置文件的检查。
3. 放弃范围语法,手动添加版本检查
改用基础的版本请求,然后自己判断版本上限:
find_package(mypkg 0.3.3 REQUIRED) if(mypkg_VERSION VERSION_GREATER_EQUAL 0.5.0) message(FATAL_ERROR "mypkg version must be less than 0.5.0 (found ${mypkg_VERSION})") endif()
这种方式绕开了软件包配置文件的严格检查,自己控制版本范围逻辑。
内容的提问来源于stack exchange,提问作者einpoklum

