CMake构建时将编译生成的SPIR-V着色器复制到APK的assets目录
规范解决CMake将SPIR-V着色器打包进APK的方案
以下是几种比手动复制更规范的实现方式:
方案1:用CMake目标属性直接指定Asset目录
CMake针对Android平台提供了ANDROID_ASSETS_DIR属性,只需为你的Native库目标设置该属性,就能让CMake自动把指定目录下的SPIR-V文件打包进APK的assets中。
假设你的SPIR-V着色器生成在${CMAKE_CURRENT_BINARY_DIR}/shaders目录,Native库目标名为native_lib,在CMakeLists.txt中添加:
set_target_properties(native_lib PROPERTIES ANDROID_ASSETS_DIR "${CMAKE_CURRENT_BINARY_DIR}/shaders" )
CMake会自动处理该目录下的所有文件,无需额外复制操作。
方案2:自定义复制命令+目标
如果需要更灵活的控制(比如只复制特定文件),可以用add_custom_command和add_custom_target将生成的SPIR-V文件复制到Gradle默认识别的asset目录(通常是src/main/assets):
# 配置路径:替换成你的SPIR-V生成文件和目标asset目录 set(SPIRV_INPUT "${CMAKE_CURRENT_BINARY_DIR}/my_shader.spv") set(ASSET_OUTPUT_DIR "${CMAKE_SOURCE_DIR}/src/main/assets/shaders") # 提前创建目标目录,避免复制失败 file(MAKE_DIRECTORY ${ASSET_OUTPUT_DIR}) # 定义复制命令,依赖SPIR-V文件的生成步骤 add_custom_command( OUTPUT "${ASSET_OUTPUT_DIR}/my_shader.spv" COMMAND ${CMAKE_COMMAND} -E copy "${SPIRV_INPUT}" "${ASSET_OUTPUT_DIR}/my_shader.spv" DEPENDS ${SPIRV_INPUT} COMMENT "Copying SPIR-V shader to assets" ) # 创建自定义目标,确保构建时执行复制 add_custom_target(copy_spirv ALL DEPENDS "${ASSET_OUTPUT_DIR}/my_shader.spv" ) # 让Native库依赖这个复制目标,保证着色器复制完成后再编译库 add_dependencies(native_lib copy_spirv)
方案3:Gradle配合CMake输出路径
如果使用AGP 7.0及以上版本,也可以在模块的build.gradle中配置asset源目录,直接包含CMake生成SPIR-V的路径:
android { sourceSets { main { // 替换成你的CMake生成SPIR-V的实际路径,${targetArch}会自动匹配架构 assets.srcDirs += "${buildDir}/cmake/${variant.name}/obj/${targetArch}/shaders" } } }
这种方式无需修改CMakeLists.txt,只需确保SPIR-V文件生成到对应路径即可。
关键注意点
- 所有方案都要通过
DEPENDS(CMake)或依赖顺序(Gradle)确保SPIR-V文件生成完成后再执行复制/打包操作,避免出现空文件或缺失。 - 多架构构建时,注意路径中的架构变量,保证每个架构的着色器都能被正确处理。
内容的提问来源于stack exchange,提问作者Dennis M
相关产品推荐
相关产品推荐

