beeware / beeware/briefcase

Android: no first-class way to bundle a local AAR / declare an extra Gradle repository

Open
#2,878 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
3.3k
Forks
549
Avg merge
1d 4h
Merged PRs (30d)
40

Description

### Summary

Briefcase's Android (Gradle) backend can declare **remote** Maven dependencies
(`build_gradle_dependencies`), but there is no first-class, documented way to:

1. declare an **extra/local Gradle repository** (e.g. `flatDir`, `mavenLocal`, or a
custom `maven { url … }`), or
2. bundle and link a **local artifact** — a local `.aar`, a local `.jar`, or a local
Maven artifact built outside the app.

`build_gradle_dependencies` entries resolve only against the repositories hard-coded
in the generated `build.gradle` (`google()`, `mavenCentral()`), and there's no config
key to add another. The app `build.gradle` has `implementation fileTree(dir: 'libs',
include: ['*.jar'])`, but that globs `*.jar` only (not `*.aar`), and there's no
documented way to stage files into `app/libs` (the `build/` tree is regenerated on
`create`/`update`).

The only current workaround is `build_gradle_extra_content` (raw text appended to
`app/build.gradle`) **plus** manually getting the artifact onto disk where a hand-written
`flatDir` repo can find it — i.e. exactly the escape hatch, not a first-class feature.

### Use case

I maintain an app whose alarm engine is a small Kotlin module shipped as a prebuilt
Android **AAR** (it needs `AlarmManager`/foreground-service/boot-receiver behavior that
isn't practical in pure Python). To get it into the Briefcase build today I have to:

```toml
build_gradle_extra_content = """
repositories { flatDir { dirs "${rootProject.projectDir}/../../../../native//build/outputs/aar" } }
"""
build_gradle_dependencies = [
# …androidx deps…
":-release@aar", # positional flatDir match by filename
]
```

This works but is fragile: the `flatDir` repo is injected via raw text, the dependency
is matched positionally by filename, and the relative path has to walk out of the
regenerated build tree. A first-class mechanism would make "bundle a local native
module" a supported, documented story.

### Proposal (seeking direction before a PR)

Smallest-first, Android-first: add a **repository-declaration** capability — e.g. a
`build_gradle_repositories` key (mirroring `build_gradle_dependencies`) that the
template renders into the Gradle `repositories {}` block — since the hard-coded
`google()`/`mavenCentral()` set is the actual blocker. Combined with the existing
`build_gradle_dependencies`, that's enough to reference a local `flatDir`/`mavenLocal`
artifact cleanly.

A fuller option is a per-platform `native_libraries`/`local_libraries` table that
*stages* a project-relative artifact into the build (on every `create`/`update`, since
`build/` is regenerated) and wires it into `dependencies` — but that's more design
surface, so I'd rather confirm the approach first. Note the `fileTree` glob is
`*.jar`-only, so AAR support needs either a `flatDir` repo or `implementation
files('libs/foo.aar')`.

### Prior art / related

- #485 — *Add ability for libraries to declare build-time requirements* (open; the
foundational issue; explicitly cites Android Jetpack libs + an iOS CocoaPod). A
local-artifact/repository feature should align with this.
- #1610 — the merged PR that added `build_gradle_dependencies` (precedent that a
narrow, general key is welcome rather than only the generic escape hatch).
- #1879 — *Allow third-party packages to supplement Briefcase configuration* (open;
same problem space, an alternative “auto-derive config” axis).
- #1861 — *custom build params for macOS Xcode builds* (open; the iOS/macOS side has
no `build_gradle_extra_content`-equivalent today, so a local **XCFramework** is a
separate, larger lift — out of scope here).

### Questions

1. Is a `build_gradle_repositories` key (or an equivalent first-class
local-artifact/repository mechanism) something you'd accept, and is the
`build_gradle_*` family the right place — or do you prefer the #485 “package
declares its own native requirements” model / #1879’s auto-derive approach?
2. For local AAR specifically: would you prefer teaching the template to emit
`files('libs/*.aar')` / broaden the `fileTree` glob, or a declared `flatDir` repo?

Happy to implement once there's a preferred direction (Android-first; iOS XCFramework
as a later, separate effort).

Contributor guide

Open the contributing guide

Research direction

Start with the Android Gradle backend's generated app/build.gradle and the configuration entry points build_gradle_dependencies and build_gradle_extra_content. Compare the existing google()/mavenCentral(), fileTree('libs', '*.jar'), and regeneration behavior against the proposed repository-declaration or local-artifact options. Done means an agreed first-class Android approach and documented acceptance criteria; no implementation path is selected yet.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, kotlin, python
Domain
build-system, mobile-dev
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.