Android Studio CMake构建对象文件路径超Windows限制的方案咨询
修正NDK专属构建暂存目录配置
全局配置的buildDir仅接管Java/Kotlin编译、打包阶段的输出路径,AGP默认会把CMake的配置缓存、临时探测文件存储在源码根目录下的.externalNativeBuild文件夹,这是修改全局buildDir后路径依然超长的核心原因。
直接在模块级build.gradle(包含NDK构建的对应模块)的android配置块中,通过buildStagingDirectory把NDK专属暂存目录指向极短的浅层路径,示例配置:
android { externalNativeBuild { cmake { // 直接指向根盘下的极短路径,无多余层级 buildStagingDirectory = "C:/nb" path = "src/main/cpp/CMakeLists.txt" } } }
该配置会将原本藏在源码深层目录下的CMake临时探测目录、编译中间路径全部迁移到C:/nb这类总长度仅个位数的位置,从根源砍掉长路径的冗余长度。
让CMAKE_OBJECT_PATH_MAX配置实际生效
在业务层CMakeLists.txt中设置set(CMAKE_OBJECT_PATH_MAX 9999)无法生效,是因为该变量必须在调用project()命令前完成设置,而业务层CMakeLists的加载时机是AGP生成的顶层CMake入口执行完project()命令后,配置根本无法触发生效逻辑。
可通过两种方式让配置生效:
- 在模块build.gradle的CMake参数中传入变量设置:
android { defaultConfig { externalNativeBuild { cmake { arguments "-DCMAKE_OBJECT_PATH_MAX=1024" } } } } - 配置完成后,删除所有已存在的CMake缓存(包括源码目录下残留的
.externalNativeBuild文件夹),重新触发配置流程,CMake将不再抛出250字符路径上限的警告。
利用NTFS 8.3短路径映射压缩路径长度
无需调整Gradle/CMake配置,直接利用Windows原生短路径机制将深层项目目录映射为极短路径,不需要移动任何文件:
- 以管理员身份打开命令提示符,查看项目所在磁盘的8.3短路径生成状态:
fsutil 8dot3name query C: - 如果状态为禁用,执行命令开启:
fsutil 8dot3name set C: 0 - 查看项目目录对应的短路径,系统会自动生成类似
C:/Users/ccj/WORK~1/MY-PRO~1的短路径,路径总长度通常可压缩至原长度的1/3以内:dir /x C:/Users/ccj/work/ - 直接使用生成的短路径作为项目根目录打开Android Studio或执行构建,无需修改任何项目配置即可大幅缩短构建路径总长度。
压缩CMake生成的超长对象文件路径
编译阶段的核心报错来源是:CMake对构建目录外的源文件,会自动将文件绝对路径转为带盘符的全拼接路径(即报错中看到的C_/Users/ccj/work/...格式),再将该拼接后的长路径作为对象文件的存储子目录,相当于把整个源码路径的长度在构建目录下重复生成了一份,进一步拉长总路径长度。
可通过两个配置砍掉这部分冗余:
- 在CMake参数中加入
-DCMAKE_USE_RELATIVE_PATHS=ON,让CMake生成对象文件路径时,尽可能使用短相对路径而非全拼的盘符绝对路径 - 配置
target_include_directories时使用相对路径引用公共源码根目录,避免CMake自动拼接全绝对路径生成超长的子目录名
此前几类常规方案不生效的核心原因:
- 移动项目到用户根目录的操作,仅缩短了项目根目录的前置长度,没有砍掉CMake生成的、把全源码路径重复拼接为对象文件路径的冗余长度,缩短的长度远不足以抵消生成路径的增量
- 业务层CMakeLists中设置
CMAKE_OBJECT_PATH_MAX的操作,因配置加载时序晚于CMake的project()初始化阶段,无法覆盖默认的250字符上限校验逻辑- 系统注册表开启长路径的操作,因CMake、Ninja的程序应用清单未声明长路径支持,系统级开关对这类传统编译工具不生效
内容的提问来源于stack exchange,提问作者CCJ

