Metadata-Version: 2.4
Name: apkforge
Version: 1.3.0
Summary: Gradle-free Android build system: aapt2, javac/kotlinc, D8/R8 and a pure-Python APK and AAB signer
Author: Gnana Sagar
License-Expression: Apache-2.0
Project-URL: Homepage, https://github.com/invarq/apkforge
Project-URL: Source, https://github.com/invarq/apkforge
Project-URL: Issues, https://github.com/invarq/apkforge/issues
Project-URL: Changelog, https://github.com/invarq/apkforge/blob/main/CHANGELOG.md
Keywords: android,apk,aab,app-bundle,build-tool,gradle-alternative,aapt2,d8,r8,kotlin,apk-signing,react-native
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development :: Build Tools
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE
Dynamic: license-file

# apkforge

Build Android apps without Gradle, Android Studio or the SDK Manager. apkforge is a Python tool (standard library only, no dependencies) that drives aapt2, javac/kotlinc
and D8/R8 directly, signs APKs and Android App Bundles with its own pure-Python signature engine, and downloads a pinned toolchain the first time it needs one.

**Status: 1.3.0, alpha.** It builds real projects, but it is not a drop-in Gradle replacement: see "What does not work yet" below.

## Install

    pip install apkforge-1.3.0-py3-none-any.whl     # a wheel from a release
    python3 apkforge-1.3.0.pyz --help               # or the single-file build: nothing to install

`pip install apkforge` and `uvx apkforge` work once the package is on PyPI. It needs Python 3.9 or newer and has no Python dependencies.

## Quick start

    apkforge new myapp --package com.acme.myapp     # a project that builds as-is (API 36, minSdk 24)
    apkforge build myapp                            # debug APK, checked after the build -> myapp/build/outputs/
    apkforge run myapp                              # build, install over adb, start it (--logcat follows its log)

    apkforge keygen myapp                           # release keystore and "signing" section (the password is printed once)
    apkforge build myapp --release --aab            # signed APK and an Android App Bundle; what Google Play will object to is printed
    apkforge verify myapp/build/outputs/*.aab       # JSON report on stdout; --play fails on what Google Play refuses
    apkforge test-bundle myapp [--install]          # bundletool's universal APK of the bundle, signed and checked

`apkforge --help` lists the rest, among them `import-gradle` (write `apkforge.json` from an existing Gradle project), `vendor` (offline builds) and `doctor`.

## Java

apkforge needs a Java runtime, because the tools it drives are Java programs: D8/R8, kotlinc and bundletool. It looks for `java` in `JAVA_HOME`, then on `PATH`, then in the
JDK it downloaded itself (`~/.apkforge/toolchain/jdk`). When there is none it downloads a Temurin 21 JDK there, without root, the first time one is needed or when you run
`apkforge doctor`. With `--offline` nothing is downloaded and the error says so. A bare machine, such as a plain Docker image, therefore needs only Python and network access.

## What `doctor` provisions

`apkforge doctor` downloads and checks what a build needs: aapt2, D8/R8, an android.jar (API 35), a JDK when the machine has none, and with `--bundletool` bundletool for
App Bundles. Builds fetch the android.jar of the project's `compileSdk` as well. Everything lives in `~/.apkforge` (set `APKFORGE_HOME` to move it). A download is checked
against the SHA-256 pins in `pins.json` or the checksum its publisher ships, and is otherwise recorded on first use; `--offline` forbids downloads.

## What does not work yet

- Hilt: its Gradle plugin rewrites the base class of `@AndroidEntryPoint` classes in bytecode, and apkforge has no such step.
- Product flavors and flavor dimensions.
- `google-services.json` processing and Crashlytics build steps.
- RenderScript.
- ECDSA signing keys (RSA only).

`apkforge import-gradle` warns about these when it meets them. Not tested yet: `test-bundle --install` on a real device (only against a stand-in adb), and whether Google Play
accepts a bundle (`docs/design/D2-aab-change-note.md`). apkforge is developed and tested on Linux.

## Development

    python3 -m unittest discover -s tests           # under a minute with the toolchain installed

The tests that build demo apps skip themselves until the toolchain is there: run `apkforge doctor --bundletool`, then build any app once (`apkforge new /tmp/demo`,
`apkforge build /tmp/demo`) so that the API 36 android.jar is downloaded.

    python3 tools/build_pyz.py . dist/apkforge-1.3.0.pyz        # the single-file build (carries LICENSE and NOTICE)
    python3 -m pip install build && python3 -m build            # wheel and sdist into dist/
    tools/bare_env.sh setup fresh && tools/bare_env.sh run fresh python3 -m apkforge doctor     # a machine with no Java

The version is written in `apkforge/util.py` (`VERSION`, and `BUILD` for a pre-release label such as `rc1`, empty for a release) and in `pyproject.toml`;
`tests/test_packaging.py` fails when the two differ.

## License

Apache License 2.0. See `LICENSE` and `NOTICE`. Copyright 2026 Gnana Sagar.
