ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Cocos Creator Android打包NDK版本配置与报错排查实战

Cocos Creator Android打包NDK版本配置与报错排查实战 如果你曾经在 Cocos Creator 里点完构建看着进度条走完结果在 Android Studio 那边弹出一行NDK not configured. Download it with SDK manager. Preferred NDK version is ...那你跟我踩过的是同一个坑。NDK 版本选择与配置这件事看着只是装个工具链实际上牵扯到 Cocos 版本、AGP 版本、CMake 版本、ABI 目标甚至本机 SDK 路径的正反斜杠。这篇文章我想把 Android 打包里关于 NDK 的前因后果一次性说透包括版本怎么选、装哪个版本、在哪配置、报错怎么排查都是我在真实项目里试过、炸过、又修好的经验。先说个结论NDK 不是越新越好也不是随便装一个就能用。很多人在这一步卡住是因为 Cocos 的构建脚本已经在项目里锁定了它期望的 NDK 版本你本机没装那个版本或者装了一个不匹配的版本报错就来了。下面我从打包链路开始拆把这个配置问题彻底讲清楚。1. 先弄清楚 NDK 在 Android 打包里的位置才不会配错方向1.1 一次 Cocos Android 打包实际上经历了什么很多人以为 Cocos Creator 的打包就是 JS/TS 脚本被包进一个壳里其实不是。Cocos 引擎的底层渲染、物理、音频、资源读取这些核心模块大部分是用 C 写的。你点构建的时候Cocos 会先生成一个原生 Android 工程然后由 Gradle 去驱动 CMake 和 NDK把引擎 C 源码交叉编译成.so文件再和 Java/Kotlin 层、资源一起塞进 APK。这里的关键点是NDK 就是给 Android 设备编译 C/C 代码的交叉编译工具链。SDK 负责的是 Java 层编译和 APK 打包NDK 负责 C 层。Cocos 这类引擎型的项目NDK 是刚需不是可选项。所以“NDK not configured”这类报错本质上是构建工程在准备调用 C 编译工具链时发现你本机的环境里没有它认识的 NDK。要么没装要么装的版本不对要么路径没指对。1.2 版本匹配为什么这么严格Cocos 生成的 Android 原生工程里其实已经写死了它期望的 NDK 版本。比如你打开工程里的app/build.gradle经常会看到类似这样的代码android { ndkVersion 21.4.7075529 }这行代码是什么意思它的意思是这个工程编译时请使用版本号为21.4.7075529的 NDK。如果你机器上已经装了 NDK但装的是25.2.9519653那 Gradle 不会默默替你换一个版本而是直接报错。这是很多新手的困惑来源明明我装了 NDK为什么还说我 not configured因为你装的版本和工程要求的版本不是同一个。NDK 版本与引擎之间的绑定关系很强引擎自带的第三方预编译库、CMake 脚本、STL 实现都是按特定 NDK 行为编写的。换个大版本轻则工具链参数不兼容重则编译不过甚至生成出来的.so在真机上跑不起来。1.3 配置入口太多反而容易乱NDK 相关的配置入口至少有四五个Cocos Creator 偏好设置里的路径、构建面板里的路径、local.properties文件里的ndk.dir、原生工程里的ndkVersion、还有系统环境变量。热词里出现的一堆ndk配置、local.properties、android sdk官网下载都跟这些入口有关。这几个入口不是同一层级的东西。Android Studio 新版已经不再推荐用local.properties里的ndk.dir指定 NDK而是强烈建议使用 side-by-side 的 NDK 版本目录配合工程里的ndkVersion字段来锁定版本。Cocos Creator 里的路径设置主要作用是在生成原生工程时告诉构建流程去哪个 SDK 下找 NDK。理解了这个分层关系后面配置就不会手忙脚乱生成工程阶段看 Cocos Creator 的路径设置编译阶段看ndkVersion和本机已安装的 NDK 目录。提示NDK 不是你装得越多越好关键是让项目锁定到它期望的那一版。同一台电脑上装多个版本很正常重要的是每个项目都能准确找到自己那一份。2. NDK 版本到底怎么选先看项目别先下载2.1 最权威的版本来源其实是报错信息当你拿到一个 Cocos Creator 项目尤其是别人发给你的、或者从仓库里 clone 下来的工程第一件事不是打开浏览器搜“Cocos NDK 推荐版本”而是先看报错和构建脚本。报错信息里往往直接写着 Gradle 期望的版本。比如开头说的那行NDK not configured. Download it with SDK manager. Preferred NDK version is 21.4.7075529.这里21.4.7075529就是工程锁定的版本。你只需要安装这个精确版本问题大概率就解决了。如果工程还没有构建过没有报错可以参考那就去原生工程里找app/build.gradle里的ndkVersionlocal.properties里的sdk.dirgradle/wrapper/gradle-wrapper.properties里的 Gradle 版本build.gradle的 dependencies 里 Android Gradle Plugin 版本这些信息拼在一起基本能判断出项目期望的环境。与其网上找一堆“万能配置”不如把工程自己的配置读明白。2.2 不同 Cocos Creator 版本的常用 NDK 组合参考我下面列出来的组合来自我做过的一些项目以及在社区里看到过的稳定搭配。注意一点这只是一个参考不是绝对真理。Cocos 官方文档在不同版本里给出的建议有变化而且项目里第三库、插件也会影响实际版本需求。Cocos Creator 版本常见 Gradle 版本常见 AGP 版本常见 NDK 版本备注2.4.x5.1.13.4.0r21e21.4.7075529老项目常见JDK 8 较稳3.6.x7.57.0.4r21e 或 r23c新工程如果报错优先装 r21e3.8.x7.67.4.2r21e 或 r23c部分项目用 r25b 也能过但没必要时别冒险4.0.x较新版本8.x8.xr23c 或更高需看构建面板默认值有一个很常见的现象同一个 Cocos 版本A 项目用 r21eB 项目用 r23c都跑得好好的。这不是玄学而是因为这两个项目的第三方原生库不一样。只要工程里没有写死ndkVersionGradle 会用默认版本所以看起来好像“什么版本都能用”。但如果另一个项目写死了版本你机器上没装立马爆错。21.4.7075529这个长数字是 Google 的 NDK 版本代号对应社区常说的 r21e。23.2.8568313对应 r23c。建议你用长数字精确安装不要只按“r21e”这个名字去猜因为 NDK 还有个旧版安装目录不带版本号非常容易搞混。2.3 不要无脑装最新版 NDKNDK 从 r23 开始移除了 GCCr25 以后对最低系统版本、C 标准库的支持行为也有变化。如果你的 Cocos 版本比较老还在用 Android.mk 或者依赖旧版编译链的一些特性直接上最新 NDK 会出现一堆编译错误比如找不到libgcc、stlport相关的头文件或者莫名其妙的链接错误。我见过一个真实情况某 2.4.x 项目开发者装了当时最新的 NDK r26 之后CMake 阶段一直报clang: error: no such file or directory排查了很久最后发现就是 NDK 版本太新工具链行为变化导致 CMake 配置阶段生成的参数失效。把 NDK 换回 r21e 后一次通过。注意遇到编译报错时如果最近刚升级过 NDK第一反应应该是“退回项目需要的版本”而不是去翻 CMake 脚本改参数。除非你有非常明确的升级理由否则不要动工具链版本。3. 配置实操全流程从安装 NDK 到项目跑通3.1 用 Android Studio 的 SDK Manager 安装指定版本这是最直观、最不容易出错的方式。前提是你已经装好了 Android Studio并且至少打开过一次让它生成了默认 SDK 目录。操作步骤打开 Android Studio在欢迎页或主界面进入 SDK Manager。切到 SDK Tools 标签页。找到 NDK (Side by side)如果列表里没有勾选右下角的 Show Package Details。展开后你会看到一堆版本找到工程需要的那个精确版本号比如21.4.7075529。同时确认 CMake 版本一般建议装3.22.1如果工程里指定了其他版本按需勾选。点 Apply等下载安装完成。安装完成后NDK 会出现在 SDK 目录的ndk/21.4.7075529文件夹下。这个文件夹里有一个source.properties文件用来标识 NDK 的版本。3.2 命令行安装适合远程开发机和不想开 IDE 的人如果你懒得开 Android Studio或者是在一台没有图形界面的构建机上操作可以直接用sdkmanager命令行安装。首先要找到sdkmanager的位置。新版 Android SDK 通过cmdline-tools管理路径一般是你的SDK目录/cmdline-tools/latest/bin/sdkmanager先列出可用的 NDK 版本sdkmanager --list | grep ndk会看到一大堆带版本号的条目例如ndk;21.4.7075529 ndk;23.2.8568313 ndk;25.2.9519653安装指定版本sdkmanager --install ndk;21.4.7075529 cmake;3.22.1安装结束后可以用下面命令确认目录存在ls 你的SDK目录/ndk/输出里应该有你刚安装的版本文件夹。如果之前装过其他版本会并列存在。3.3 在 Cocos Creator 里把 NDK 路径指对Cocos Creator 版本不同设置入口的位置略有差异。Cocos Creator 3.x菜单栏打开 偏好设置 - 外部程序。在 Native 环境分类里找到 NDK 路径。直接选择你的SDK目录/ndk/21.4.7075529注意选到具体版本目录而不是ndk外层目录。SDK 路径也同步检查一下确保指向根目录比如D:\Android\Sdk。Cocos Creator 2.x在构建发布面板中拉到 Android 配置区。填写 NDK 路径同样要填到具体版本目录。有些 2.x 版本还支持环境变量方式设置ANDROID_NDK_ROOT指向 NDK 目录实测也能生效。设置完成后重新构建一次项目。如果这一步没配好后期打开原生工程时会直接出现找不到 NDK 的提示。提示NDK 路径千万别选到旧版那种不带版本号的目录。旧版 NDK 目录结构不同AGP 在读取source.properties时会失败报错和你没装 NDK 是一样的。3.4 用 local.properties 和 ndkVersion 锁住版本Cocos 构建生成的 Android 工程里通常会带一个local.properties文件内容是本地 SDK 路径sdk.dirD\:\\Android\\Sdk有些老教程会教你在里面加一行ndk.dirD\:\\Android\\Sdk\\ndk\\21.4.7075529这里要提醒一下新版 AGP 对这个字段是 deprecated 状态虽然很多版本还能读但已经不稳定了。更可靠的锁定方式是在app/build.gradle里显式声明ndkVersionandroid { compileSdkVersion 33 ndkVersion 21.4.7075529 }这样设置之后Gradle 会在本机已安装的 side-by-side NDK 里查找精确匹配的版本。如果没找到会报出我们熟悉的NDK not configured... Preferred NDK version is 21.4.7075529看到这个报错就知道缺哪个版本了。3.5 环境变量的作用有限但可以辅助定位老项目里偶尔会用到ANDROID_NDK_HOME或ANDROID_NDK_ROOT环境变量Cocos 2.x 时代有些构建流程依赖这个。新版 Cocos 和 AGP 的对环境变量的依赖已经很低了主要看 SDK Manager 安装的 side-by-side 目录。如果你的构建流程非要环境变量可以在系统变量里加ANDROID_NDK_ROOTD:\Android\Sdk\ndk\21.4.7075529 ANDROID_SDK_ROOTD:\Android\Sdk但要注意环境变量的优先级比较迷有时候设置了反而会和工程的ndkVersion打架。我个人的建议是环境变量作为一种辅助手段能不动尽量不动重点把 SDK Manager 安装和工程ndkVersion对齐。4. 打包阶段的关键参数与一手经验4.1 ABI 选择和包体大小直接相关NDK 编译的产物是.so但 Android 设备有不同的 CPU 架构也就是 ABI。Cocos 构建面板里一般会让你选择目标平台常见的四个armeabi-v7a兼容绝大多数老手机arm64-v8a现在的主流机型x86老模拟器常用x86_64新版模拟器和部分平板每勾选一个 ABINDK 就要完整编译一遍引擎源码构建时间和最终 APK 体积都会成倍增加。我见过一个项目为了“保险”四个 ABI 全勾最终 APK 直接 300 多 MB。实际上现在真机基本都是arm64-v8a老的armeabi-v7a可以给需要兼容低端机的项目留一个x86系列只在你经常用模拟器调试时才有必要选。这里有个常见的反直觉点如果你的项目依赖了某个第三方原生库而这个库只提供了armeabi-v7a的.so那你就不能只勾arm64-v8a否则真机上会报找不到 so 文件。反过来只提供arm64-v8a的老库反而很少见。所以 ABI 选择不完全是个人的喜好问题还得看依赖库给不给面子。4.2 Gradle 内存配置影响打包稳定性NDK 编译 C 的耗时本来就长如果你本机内存只有 8GB还要边开编辑器边打包Gradle 很容易因为内存不足直接卡死或报 OOM。在原生工程的gradle.properties里默认可能会有几行配置org.gradle.jvmargs-Xmx2048m -XX:MaxMetaspaceSize512m如果项目比较大可以适度调高但要留出系统余量比如 16GB 内存的机器可以设成org.gradle.jvmargs-Xmx4096m -XX:MaxMetaspaceSize1024m-Xmx是 Gradle 进程的最大堆内存并不是设得越大越好。设得比物理内存还大系统会开始疯狂交换内存打包速度反而下降。我个人的经验是最多不超过物理内存的一半同时尽量关闭其他大内存软件。4.3 命令行打包和 CI 场景的注意事项如果你要写脚本批量打渠道包或者接到 CI 流水线上就不能依赖 Android Studio 的图形界面了。Cocos Creator 支持命令行构建常用的参数包括平台、NDK 路径、SDK 路径等。以 Cocos Creator 3.x 为例命令行构建大致长这样cocos build -p android --ndk-path D:/Android/Sdk/ndk/21.4.7075529 --sdk-path D:/Android/Sdk不过实际参数会因为版本不同有差异建议先查一下当前版本的命令行帮助。CI 上最容易忽略的问题是路径格式Windows 下反斜杠转义经常出问题建议统一用正斜杠D:/Android/Sdk。另外CI 环境里不要依赖 Android Studio 的 SDK Manager 的 GUI 安装直接用sdkmanager命令装好 NDK 和 CMake并且把--ndk-path明确传给 Cocos比靠环境变量要稳得多。5. 常见报错与排查技巧实录5.1 经典的“NDK not configured”报错报错完整版通常是NDK not configured. Download it with SDK manager. Preferred NDK version is 21.4.7075529.排查思路按下面顺序做看报错里的 Preferred NDK version 是多少。打开你的 SDK 目录下的ndk文件夹看有没有对应版本。没装就按上面 3.1 或 3.2 的方法装装了但报错还在检查 Cocos Creator 里的 NDK 路径是否精确到版本目录。如果用的是 Android Studio打开工程后重新 Gradle Sync让配置生效。便携老项目还会遇到一种情况local.properties里sdk.dir指向的是别人机器的旧路径比如C:\Users\旧用户名\AppData\Local\Android\Sdk。这会直接导致 AGP 找不到整个 SDK更别说 NDK 了。解决方法是把sdk.dir改成你自己的 SDK 路径或者直接删除local.properties让 Android Studio 自动生成一份。5.2 装了新版本 NDK 后编译报错常见错误有Unsupported NDK version requested或A problem occurred configuring project :app. NDK did not have a source.properties file前者通常是你机器的某个版本不在 AGP 支持范围内后者是路径指到了旧版 NDK 或者不完整的目录。这两种情况处理方式都不建议“硬扛”而是把 NDK 版本切回工程期望的精确版本。如果项目里没有写死ndkVersion你可以先看看app/build.gradle里是不是用了ndkVersion没有的话Gradle 会用最近安装的版本。如果你之前装过 r25后来为了兼容其他项目又装了 r21eGradle 可能会“偷懒”选到 r25导致编译错误。解决办法就是显式写上ndkVersion。5.3 CMake 版本缺失或不对应Cocos 构建生成的工程一般会依赖 CMake。报错类似于CMake 3.22.1 was not found. Install it using SDK manager.这种处理起来最简单打开 SDK Manager在 SDK Tools 里勾选对应的 CMake 版本或者用命令行sdkmanager --install cmake;3.22.1需要注意 CMake 版本和 NDK 版本之间也有兼容关系。高版本 NDK 可能要求 CMake 3.22 以上老版本 NDK 配太新的 CMake 有时也能跑但没必要去踩这个边界按报错提示的版本装就完了。5.4 路径里的中文和空格坑Windows 上打包最常见的一类坑就是路径。SDK 路径、NDK 路径、项目路径任何一个包含中文、空格、特殊符号CMake 在解析路径时都会出现难以理解的报错。比如D:\游戏项目\release\build这类路径轻则文件找不到重则整个构建崩溃。我现在的习惯是Android SDK 保持在纯英文、无空格的路径比如D:\Android\SdkNDK 路径由 SDK 目录自动带出不手动复制到别处Cocos 项目路径也用纯英文比如D:\Projects\MyGame不用桌面路径这个习惯帮我避开了非常多查都查不明白的诡异问题。最后说点个人体会NDK 版本这件事看起来是环境配置但背后是工具链与引擎之间的耦合关系。我踩过最深的坑就是“顺手装了个最新版”结果整个 C 编译阶段持续报错浪费了一整天。后来学乖了拿到任何项目先看报错提示里的 Preferred NDK version再看工程的ndkVersion最后才决定装什么。如果你现在正被某个奇怪的 C 编译错误折磨并且最近改过 NDK 版本我建议你先回到项目原本的版本试试很多时候问题就是这么简单。工具链保持稳定比追逐新版本重要得多。
返回列表