# gradle2bp **Repository Path**: violetshalei/gradle2bp ## Basic Information - **Project Name**: gradle2bp - **Description**: 将 Android Gradle 项目的 Maven 依赖自动转换为 AOSP / Soong 构建系统使用的 `Android.bp` 配置。 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-20 - **Last Updated**: 2026-09-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # gradle2bp 将 Android Gradle 项目的 Maven 依赖自动转换为 AOSP / Soong 构建系统使用的 `Android.bp` 配置。 ## 背景 Android 向 Soong (`Android.bp`) 迁移时,Gradle 声明的依赖无法直接使用,需要手动: 1. 定位 Gradle 中的依赖声明(`build.gradle.kts` + `libs.versions.toml`); 2. 解析 BOM 和传递依赖,得到完整的 artifact 列表; 3. 逐个从 Maven 仓库下载 AAR / JAR; 4. 为每个 artifact 写一个独立的 `Android.bp`,必要时解压 AAR 取 `AndroidManifest.xml`; 5. 从 manifest 读取 `minSdkVersion` 填到 bp 里。 6. 识别 AOSP 已经预设好的依赖(kotlin 标准库、kotlinx 协程/序列化、androidx prebuilts 等),直接引用内置 module 名而不重复下载。 本工具把这些步骤串起来,一条命令生成可用的结果。 ## 功能 | 阶段 | 做什么 | |------|--------| | 解析 | 从 `libs.versions.toml` 提取版本和库定义,从 `app/build.gradle.kts` 提取实际使用的别名 | | BOM 解析 | 识别 `androidx-compose-bom` 等 BOM,从 POM 里把被 BOM 托管但没写版本号的依赖补上版本 | | 传递依赖 | 递归下载每个 artifact 的 POM,自动收集间接依赖 | | AOSP 预设排除 | 跳过 kotlin / kotlinx 系列 + androidx prebuilts 已覆盖的依赖,bp 里直接引用 AOSP module 名 | | 下载 | 多线程并发下载 AAR / JAR,阿里云国内镜像加速;已存在则跳过 | | Manifest 提取 | 从 AAR 中提取 `AndroidManifest.xml` 到同级 `manifest/` 目录 | | bp 生成 | 为每个依赖生成独立目录下的 `Android.bp`(`android_library_import` / `java_import`);同时输出一份汇总的 `deps.bp` 方便人工浏览;**命名对齐 AOSP 规范**(group 里的 `.` 替换为 `_`) | ## 输出目录结构 所有产物都放在扫描根目录下的 `.out/`: ``` /.out/ ├── logs/ # 本次运行的日志 ├── third_party/ # 下载的 artifact + 生成的 per-dir Android.bp │ └── androidx/activity/activity/1.8.0/ │ ├── activity-1.8.0.aar │ ├── Android.bp │ └── manifest/ │ └── AndroidManifest.xml └── androidbp/ └── deps.bp # 全量模块汇总(便于参考 / diff) ``` ## 使用 ### 安装依赖 ```bash pip3 install -r requirements.txt ``` ### 交互式运行(默认) 不带参数直接执行,会列出候选目录让你选: ```bash python3 main.py ``` ### 指定扫描目录 ```bash python3 main.py -p /path/to/your/android/project ``` ### 指定输出目录(可选) ```bash python3 main.py -p /path/to/project -o /tmp/my_out ``` ### 指定 AOSP prebuilts 路径 如果你的 AOSP 源码树不在默认位置,可以直接命令行传入: ```bash python3 main.py -p /path/to/project \ -a /path/to/aosp/prebuilts/sdk/current/androidx/m2repository ``` ## 配置文件(可选,推荐) 在目标 Android 项目根目录下放一个 `.gradle2bp.conf`,可以固定 AOSP prebuilts 路径,不用每次命令行传入。 文件格式是标准 INI: ```ini [paths] aosp_prebuilts_dir = /home/yourname/aosp/prebuilts/sdk/current/androidx/m2repository ``` ### 路径解析优先级 从高到低依次尝试,命中即停止: 1. 命令行 `-a` 显式指定 2. 配置文件 `.gradle2bp.conf` 的 `[paths] aosp_prebuilts_dir` 3. **自动探测**:从项目目录开始一路向上找 `prebuilts/sdk/current/androidx/m2repository`(在 AOSP 树里的项目自动命中) 如果三者都不存在,所有 androidx 依赖都会被下载。 ### 配置文件搜索位置 工具会在以下位置按顺序查找 `.gradle2bp.conf`: - `-c` 显式指定的路径 - 扫描目标项目根目录 - 当前工作目录 - 用户主目录 `~/` ## AOSP 预设依赖映射 工具内置了一张映射表,识别后直接使用 AOSP 已有 module 名,跳过下载: | Gradle coord | AOSP module 名 | |-------------|---------------| | `org.jetbrains.kotlin:kotlin-stdlib` | `kotlin-stdlib` | | `org.jetbrains.kotlin:kotlin-stdlib-jdk7` | `kotlin-stdlib-jdk7` | | `org.jetbrains.kotlin:kotlin-stdlib-jdk8` | `kotlin-stdlib-jdk8` | | `org.jetbrains.kotlinx:kotlinx-coroutines-android` | `kotlinx-coroutines-android` | | `org.jetbrains.kotlinx:atomicfu` | `kotlinx_atomicfu` | | `org.jetbrains:annotations` | `kotlin-annotations` | | `androidx.core:core` | `androidx.core_core` | | `androidx.activity:activity` | `androidx.activity_activity` | | ... | ... | 后两行这种格式是从 AOSP prebuilts 里自动扫描出来的(`group.artifact` → `group_artifact`),不需要手动维护。 ## 生成的 Android.bp 示例 每个依赖一个目录下的 `Android.bp`: ```bp android_library_import { name: "androidx.test_runner", aars: ["runner-1.5.2.aar"], min_sdk_version: "14", manifest: "manifest/AndroidManifest.xml", static_libs: [ "androidx.annotation_annotation", "androidx.test_monitor", "junit_junit", ], } ``` 纯 JAR 依赖生成 `java_import`: ```bp java_import { name: "com.google.guava_listenablefuture", jars: ["listenablefuture-1.0.jar"], } ``` 注意: - `name` 里的 `.` 全部替换为 `_`,**与 AOSP 规范完全对齐**,可以直接在其他 bp 里引用 - `min_sdk_version` 是**字符串**,从 AAR 内 `AndroidManifest.xml` 的 `uses-sdk` 读取 - `static_libs` 里混合了本地生成模块(如 `androidx.annotation_annotation`)和 AOSP 预设模块(如 `kotlin-stdlib`),统一用 bp module 名 ## 如何查看依赖对应关系 `deps.bp`(`/.out/androidbp/deps.bp`)是一张**总览清单**,上半部分是被跳过的 AOSP 预设依赖,下半部分是实际下载生成的模块。完整结构如下: ```bp // Auto-generated by gradle2bp // DO NOT EDIT MANUALLY // ---- AOSP preset deps (skipped, use built-in modules) ---- // org.jetbrains.kotlin:kotlin-stdlib // → AOSP module: "kotlin-stdlib" // org.jetbrains.kotlin:kotlin-stdlib-jdk7 // → AOSP module: "kotlin-stdlib-jdk7" // org.jetbrains.kotlinx:kotlinx-coroutines-android // → AOSP module: "kotlinx-coroutines-android" // org.jetbrains:annotations // → AOSP module: "kotlin-annotations" // androidx.core:core // → AOSP module: "androidx.core_core" // androidx.activity:activity // → AOSP module: "androidx.activity_activity" // ... // --------------------------------------------------------- aar_import { name: "androidx.test_runner", aars: ["runner-1.5.2.aar"], min_sdk_version: "14", manifest: "manifest/AndroidManifest.xml", static_libs: [ "androidx.annotation_annotation", "kotlin-stdlib", // ← 这里直接引用 AOSP 预设 module 名 ], } java_import { name: "com.google.guava_listenablefuture", jars: ["listenablefuture-1.0.jar"], } ``` ### 查 gradle coord → bp module 名 - **如果被跳过了**(AOSP 预设):直接在 deps.bp 顶部注释里搜 gradle coord,下一行就是对应的 AOSP module 名 - **如果实际生成了**:在 deps.bp 的 import block 里搜 `name:` 字段,就是最终的 bp module 名 ### 查 bp module 名 → 原始 gradle coord - 从 bp 的 `name` 反推:把最后一个 `_` 换成 `:`,前面的 `_` 换回 `.` (粗略规则,大部分 androidx 和三方库能对上) - 精确查:翻日志文件 `.out/logs/`,里面 Stage 3~8 会打印每个依赖的完整 coord - 最直接:grep 下载目录 `.out/third_party/`,路径本身就是 `group/artifact/version/` 结构 ```bash # 例子:bp module 名 → 下载目录 → gradle coord grep -r 'name: "androidx.test_runner"' .out/third_party/*/Android.bp # → 命中 .out/third_party/androidx/test/runner/1.5.2/Android.bp # → 原始 coord: androidx.test:runner:1.5.2 ``` ## 命令行参数速查 ``` -p, --project-dir Android 项目根目录(必须) -o, --output-dir 输出目录,默认 /.out -a, --aosp-prebuilts-dir AOSP prebuilts m2repository 路径 -c, --config 配置文件路径,默认搜索 .gradle2bp.conf ``` ## 目录结构 ``` gradle2bp/ ├── main.py # 入口,串联各阶段 ├── config.py # 集中配置 + 命令行解析 + manifest minSdk 解析 + AOSP prebuilts 扫描 ├── parser.py # TOML 与 build.gradle.kts 解析 ├── resolver.py # BOM 版本解析 + 传递依赖 POM 解析 ├── downloader.py # 多线程下载 + 进度条 ├── extractor.py # AAR 中提取 AndroidManifest.xml ├── generator.py # Android.bp 生成(命名对齐 AOSP 规范) ├── logger.py # 统一日志 └── requirements.txt # requests ```