如何正确使用FetchContent_Declare()并链接库?附报错排查
问题解决:FetchContent 获取Khronos库的报错与链接目标确认
一、解决glslang克隆报错
你遇到的报错:
Performing download step (git clone) for 'glslang--populate'
Cloning into 'glslang--src'...
fatal: invalid reference: master
CMake Error at glslang--subbuild/glslang--populate-prefix/tmp/glslang--populate-gitclone.cmake:61 (message):
Failed to checkout tag: 'master'
报错原因
- 未定义
glslang_VERSION变量:代码中使用${glslang_VERSION}作为GIT_TAG,但没有提前赋值,CMake将空值解析为默认的'master',而glslang仓库当前默认分支是main,且直接用分支名做GIT_TAG不是稳定做法(推荐用具体版本tag)。 - 未正确导入glslang子项目:仅调用
FetchContent_Populate但未执行add_subdirectory,导致glslang的CMake目标不会被注册到项目中,后续链接会失败。
修正后的glslang配置
# 定义glslang稳定版本tag,可根据需求替换为最新版本 set(glslang_VERSION "13.0.0") FetchContent_Declare( glslang GIT_REPOSITORY https://github.com/KhronosGroup/glslang.git GIT_TAG ${glslang_VERSION} GIT_SHALLOW TRUE SYSTEM ) # 用FetchContent_MakeAvailable自动处理下载、解压、添加子目录,无需手动判断POPULATED状态 FetchContent_MakeAvailable(glslang)
二、确认target_link_libraries可用的库名称
库的链接目标名不是FetchContent_Declare中定义的名称(比如你写的glslang-${glslang_VERSION}),而是子项目自身CMakeLists.txt中通过add_library定义的目标名,部分库会用add_library(别名::别名 ALIAS 真实目标名)创建命名空间别名。
三个库的可用目标说明
- glslang:子项目定义了
glslang、glslang-default-resource-limits、SPIRV等目标,同时提供glslang::glslang这类命名空间别名,你当前写的链接目标是正确的。 - SPIRV-Cross:子项目定义了
spirv-cross-core、spirv-cross-glsl、spirv-cross-hlsl等目标,你写的链接目标正确。 - SPIRV-Tools:子项目定义了
SPIRV-Tools(动态库)、SPIRV-Tools-static(静态库)、SPIRV-Tools-opt等目标,你写的链接目标正确。
确认目标名的方法
- 查看子项目CMakeLists.txt:进入下载后的子项目源码目录,搜索
add_library或ALIAS关键字,直接找到定义的目标名。 - CMake命令行查看:运行CMake配置后,执行
cmake --build . --target help,输出列表包含所有可链接的目标。 - CMake调试输出:在你的CMakeLists.txt中添加调试代码,打印所有已注册的目标:
get_cmake_property(all_targets BUILDSYSTEM_TARGETS) message("All available targets: ${all_targets}")
修正后的完整CMakeLists.txt示例
cmake_minimum_required(VERSION 3.28) project(foo) include(FetchContent) # glslang配置 set(glslang_VERSION "13.0.0") FetchContent_Declare( glslang GIT_REPOSITORY https://github.com/KhronosGroup/glslang.git GIT_TAG ${glslang_VERSION} GIT_SHALLOW TRUE SYSTEM ) FetchContent_MakeAvailable(glslang) # SPIRV-Cross配置 set(spirv_cross_VERSION "vulkan-sdk-1.3.290.0") FetchContent_Declare( spirv_cross GIT_REPOSITORY https://github.com/KhronosGroup/SPIRV-Cross.git GIT_TAG ${spirv_cross_VERSION} GIT_SHALLOW TRUE PATCH_COMMAND git apply ${CMAKE_CURRENT_SOURCE_DIR}/patches/spirv-cross-${spirv_cross_VERSION}.diff UPDATE_DISCONNECTED 1 SYSTEM ) FetchContent_MakeAvailable(spirv_cross) # SPIRV-Tools配置 FetchContent_Declare( spirv_tools GIT_REPOSITORY https://github.com/KhronosGroup/SPIRV-Tools.git # 指定稳定版本tag,避免拉取最新代码导致兼容性问题 GIT_TAG v2024.1 GIT_SHALLOW TRUE ) FetchContent_MakeAvailable(spirv_tools) add_library(${PROJECT_NAME} SHARED ${CMAKE_SOURCE_DIR}/src/main.cpp) # 无需手动添加include目录,子项目目标已通过target_include_directories设置依赖包含路径 target_link_libraries( ${PROJECT_NAME} PRIVATE glslang::glslang glslang::glslang-default-resource-limits glslang::SPIRV spirv-cross-core spirv-cross-glsl SPIRV-Tools-static SPIRV-Tools-opt )
内容的提问来源于stack exchange,提问作者Fox1942
相关产品推荐
相关产品推荐

