CMake自定义目标中如何通过通配符获取生成的.a文件路径
问题原因
你之前写的两种方式无法拿到有效路径,核心是执行时机不对:
set(A_FILE ${CMAKE_BINARY_DIR}/*.a)本身不会解析通配符,只会把带*的字面字符串直接赋值给变量,不会做实际的文件匹配。file(GLOB A_FILE ${CMAKE_BINARY_DIR}/*.a)是CMake配置阶段执行的命令,这个阶段还没启动编译构建,.a静态库文件根本没有生成,自然匹配不到有效结果。而你的自定义目标是全构建流程结束后才执行,配置阶段的匹配逻辑早于文件生成时间,必然拿不到结果。
实现方案
要拿到有效路径,必须把通配符匹配逻辑放到构建执行阶段(也就是自定义目标实际运行的时候)执行,不能放在配置阶段,常用两种跨环境可行的写法:
方案1:直接通过执行环境的Shell做通配符匹配
这是最简单的写法,自定义目标的命令执行时文件已经生成,直接调用Shell的原生通配符能力即可匹配,不需要额外写脚本:
add_custom_target(your_custom_target # 依赖静态库构建目标,保证执行顺序正确,等.a生成后再跑后续逻辑 DEPENDS your_static_library_target # 类Unix环境(Linux/macOS/MSYS2)用bash做匹配,可直接把匹配结果存到Shell变量供后续操作使用 COMMAND bash -c "A_FILE=(${CMAKE_BINARY_DIR}/*.a); if [ ${#A_FILE[@]} -eq 0 ]; then echo '未找到.a静态库'; exit 1; fi; echo '匹配到静态库路径:' ${A_FILE[0]}; # 后续对${A_FILE[0]}的操作直接写在后面即可" # 如果是Windows原生CMD/PowerShell环境,替换成对应环境的匹配语法即可,比如PowerShell写法: # COMMAND powershell -Command "$aFile = Get-ChildItem '${CMAKE_BINARY_DIR}/*.a' | Select-Object -First 1; if (-not $aFile) { Write-Error '未找到.a静态库'; exit 1 }; Write-Host '匹配到静态库路径:' $aFile.FullName; # 后续操作基于$aFile.FullName编写" )
注意:如果使用Visual Studio、Xcode、Ninja Multi-Config这类多配置生成器,静态库实际输出路径是
${CMAKE_BINARY_DIR}/$<CONFIG>,要把搜索路径替换成这个生成器表达式对应的路径,避免匹配到其他配置生成的旧文件。
方案2:用CMake脚本模式做跨平台匹配
如果不想依赖不同环境的Shell语法,可以用CMake的脚本执行模式,在构建阶段调用独立CMake脚本做文件匹配,天然跨平台:
- 先在项目目录下写一个独立的匹配脚本
find_static_lib.cmake:# find_static_lib.cmake file(GLOB matched_a_files "${SEARCH_DIR}/*.a") list(LENGTH matched_a_files match_count) if(match_count EQUAL 0) message(FATAL_ERROR "搜索目录${SEARCH_DIR}下未找到.a格式静态库") endif() # 取第一个匹配到的文件,若有多个匹配项可自行调整过滤规则 list(GET matched_a_files 0 a_file_path) message(STATUS "匹配到静态库文件: ${a_file_path}") # 后续需要对静态库执行的操作可直接写在这个脚本里 - 在CMakeLists.txt中给自定义目标添加命令,构建阶段调用这个脚本:
add_custom_target(your_custom_target DEPENDS your_static_library_target # 构建阶段才执行脚本,此时.a文件已经生成 COMMAND ${CMAKE_COMMAND} -DSEARCH_DIR=${CMAKE_BINARY_DIR} -P ${CMAKE_CURRENT_SOURCE_DIR}/find_static_lib.cmake )
注意事项
- 如果构建输出目录下可能存在多个
.a文件,建议缩小匹配范围,比如加项目名前缀匹配${CMAKE_BINARY_DIR}/libyourproject*.a,避免拿到无关的静态库文件。 - 无论用哪种方案,都必须给自定义目标添加对应静态库目标的
DEPENDS依赖,避免构建顺序错乱导致匹配时文件还未生成。
内容的提问来源于stack exchange,提问作者Xershy
相关产品推荐
相关产品推荐

