当前位置: 首页 > news >正文

android-ndk开发(2): macOS 安装 ndk

android-ndk开发(2): macOS 安装 ndk

2025/05/05

1. 概要

对于 android-ndk 在 r23 之前的版本,官方提供了 .zip 文件, 解压即安装。

对于 android-ndk 在 r23 以及之后的版本, 官方只提供了 .dmg 文件, 不能简单的解压完成安装。

2. ndk >= r23, macOS 怎么安装 ?

android ndk 从 r23 开始, 不再提供 macOS 平台的 .zip 安装包(如android-ndk-r22b-darwin-x86_64.zip), 只提供 .dmg 格式的安装包。链接 [1] 可以确认。这导致无法像 Windows 和 Linux 一样, 解压 .zip 就完成 ndk 的安装。

以 android-ndk-r27c-darwin.dmg 为例, 双击后显示两个文件: AndroidNDK12479018.app 和 source.properties。 双击 AndroidNDK12479018.app 后感觉完成了安装, 但在 /Application, /Library, ~/Application, ~/Library 4个目录找不到安装的内容。

手动解压 AndroidNDK12479018.app,里面的 NDK 目录是工具链, CodeSign 这玩意儿暂时不知道用处,感觉就是故意使绊子。

为了一劳永逸解决 macOS 上 ndk >= r23 版本的安装, 上述过程写为 Python 脚本。基本思路是:挂载 .dmg -> 找到 .app 文件 -> 找 NDK 目录 -> 拷贝到目标目录。

import subprocess
import shutil
import os
import timedef mount_and_copy(dmg_path, target_dir):target_dir = os.path.expanduser(target_dir)try:print(f"⏳ 正在挂载 {dmg_path}...")mount_result = subprocess.run(["hdiutil", "attach", "-nobrowse", dmg_path],capture_output=True,text=True,check=True)# 解析挂载路径mount_path = Nonefor line in mount_result.stdout.splitlines():if "/Volumes" in line:mount_path = line.split("\t")[-1].strip()breakif not mount_path:raise FileNotFoundError("无法定位挂载点")time.sleep(2)  # 等待文件系统稳定# 动态查找AndroidNDK*.appapp_files = [f for f in os.listdir(mount_path)if f.startswith("AndroidNDK") and f.endswith(".app")]# e.g. AndroidNDK12479018.app for android-ndk-r27cif not app_files:available = "\n".join(os.listdir(mount_path))raise FileNotFoundError(f"未找到AndroidNDK*.app文件,当前卷内容:\n{available}")app_path = os.path.join(mount_path, app_files[0])print(f"  定位到应用包:{app_path}")# 验证NDK路径ndk_source = os.path.join(app_path, "Contents", "NDK")if not os.path.exists(ndk_source):raise FileNotFoundError(f"NDK目录不存在:{ndk_source}")# 准备目标目录os.makedirs(target_dir, exist_ok=True)print(f"  目标目录:{target_dir}")# 执行复制(保留元数据)print("⚙️ 开始复制NDK文件...")shutil.copytree(ndk_source,target_dir,dirs_exist_ok=True,copy_function=shutil.copy2)# 卸载镜像print("⏳ 正在卸载...")subprocess.run(["hdiutil", "detach", mount_path], check=True)print(f"  安装完成!路径:{target_dir}")except subprocess.CalledProcessError as e:print(f"❌ 命令执行失败:{e.stderr}")if 'mount_path' in locals() and os.path.exists(mount_path):print(f"⚠️ 尝试手动卸载:hdiutil detach {mount_path}")except Exception as e:print(f"❌ 错误:{str(e)}")if __name__ == "__main__":dmg_path = os.path.join(os.getcwd(), "android-ndk-r27c-darwin.dmg")mount_and_copy(dmg_path, "/Users/zz/soft/toolchains/android-ndk-r27c")

References

  • https://github.com/android/ndk/wiki/Unsupported-Downloads

相关文章:

  • C++竞赛指南
  • Pinocchio导入URDF关节为continuous的问题及详细解释
  • 第二章-猜数游戏
  • 【bazel】bazel简介及简单使用
  • Qt实现网页内嵌
  • UDP协议(特点与应用场景)
  • cudaMalloc函数说明
  • 无人机 | 无人机设计概述
  • 某信服EDR3.5.30.ISO安装测试(一)
  • 【Java项目脚手架系列】第二篇:JavaWeb项目脚手架
  • 数据库MySQL学习——day9(聚合函数与分组数据)
  • 机器学习中常见搜索算法
  • Java基础学完,继续深耕(0505)Linux 常用命令
  • Python学习之路(七)-绘画and动画
  • 【Linux】linux入门——基本指令
  • 人工智能数学基础(十)—— 图论
  • 一个电商场景串联23种设计模式:创建型、结构型和行为型
  • Paramiko 核心类关系图解析
  • 新型深度神经网络架构:ENet模型
  • 健康养生:从生活点滴启航
  • “五一”假期出入境人数达1089.6万人次,同比增长28.7%
  • 越老越妖的库里,成了火箭季后赛里一晃十年的噩梦
  • 无畏契约新王诞生:属于电竞世界的凯泽斯劳滕奇迹
  • 几天洗一次头发最好?终于有答案了...
  • 阿根廷发生5.6级地震,震源深度30公里
  • 美国季度GDP时隔三年再现负增长,特朗普政府关税政策对美国经济负面影响或将持续