Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/source/using-executorch-android.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ published to Maven Central and S3. Users can also build the AAR from source.

The AAR artifact contains the Java library for users to integrate with their Java/Kotlin application code, as well as the corresponding JNI library (.so file), which is loaded by the Java code during initialization.

- [Java library](https://github.com/pytorch/executorch/tree/main/extension/android/executorch_android/src/main/java/org/pytorch/executorch)
- [Java library](https://github.com/pytorch/executorch/tree/main/extension/java/src/main/java/org/pytorch/executorch) <!-- @lint-ignore (path exists only after this PR lands) -->
- [Java API Reference (Javadoc)](https://pytorch.org/executorch/main/javadoc/index.html)
- JNI contains the JNI binding for the corresponding Java code, and ExecuTorch native library, including
- Core ExecuTorch runtime libraries
Expand Down
33 changes: 18 additions & 15 deletions extension/android/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,27 @@ load("@fbsource//tools/build_defs/android:fb_android_library.bzl", "fb_android_l

oncall("executorch")

# NOTE: the platform-neutral sources live in the shared source directory

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nits: The maintenance note says shared sources must be listed in a matching Buck target, but the shared ASR sources are not listed here. Is ASR intentionally Gradle-only, or should the comment/targets be updated to reflect the actual contract?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct — ASR is intentionally Gradle-only, matching the pre-move state (the ASR sources were not in any Buck target before this PR either). The BUCK header and extension/java/README.md now state this explicitly for ASR and the Android-only ImageProcessor, so the contract is documented rather than implied. Happy to add an executorch_asr target in a follow-up if an internal build needs it.

# extension/java/src/main/java and are consumed here as filegroup labels
# exported from extension/java/BUCK, so the Android targets keep their
# historical names, ownership, and attributes (required_for_source_only_abi,
# pure_kotlin, deps) while compiling the exact same classes as before the
# move. Log.kt is the Android-backed implementation of the
# org.pytorch.executorch.Log facade that the shared sources reference.
#
# MAINTENANCE: both Gradle (java.srcDirs glob) and the filegroups in
# extension/java/BUCK (glob) pick up new shared sources automatically, so no
# per-file lists need updating. The ASR and image-processing sources are
# intentionally Gradle-only (as before this change); add Buck targets for them
# when an internal build needs them.

non_fbcode_target(_kind = fb_android_library,
name = "executorch",
warnings_as_errors = False,
required_for_source_only_abi = True,
srcs = [
"executorch_android/src/main/java/org/pytorch/executorch/BackendOptionsMap.kt",
"executorch_android/src/main/java/org/pytorch/executorch/DType.kt",
"executorch_android/src/main/java/org/pytorch/executorch/EValue.kt",
"executorch_android/src/main/java/org/pytorch/executorch/ExecuTorchRuntime.kt",
"executorch_android/src/main/java/org/pytorch/executorch/ExecutorchRuntimeException.kt",
"executorch_android/src/main/java/org/pytorch/executorch/MethodMetadata.kt",
"executorch_android/src/main/java/org/pytorch/executorch/Module.kt",
"executorch_android/src/main/java/org/pytorch/executorch/Tensor.kt",
"executorch_android/src/main/java/org/pytorch/executorch/annotations/Experimental.kt",
"executorch_android/src/main/java/org/pytorch/executorch/Log.kt",
"//xplat/executorch/extension/java:core_sources",
],
autoglob = False,
language = "KOTLIN",
Expand All @@ -34,8 +41,7 @@ non_fbcode_target(_kind = fb_android_library,
name = "executorch_training",
warnings_as_errors = False,
srcs = [
"executorch_android/src/main/java/org/pytorch/executorch/training/SGD.kt",
"executorch_android/src/main/java/org/pytorch/executorch/training/TrainingModule.kt",
"//xplat/executorch/extension/java:training_sources",
],
autoglob = False,
language = "KOTLIN",
Expand All @@ -50,10 +56,7 @@ non_fbcode_target(_kind = fb_android_library,
name = "executorch_llama",
warnings_as_errors = False,
srcs = [
"executorch_android/src/main/java/org/pytorch/executorch/extension/llm/LlmCallback.kt",
"executorch_android/src/main/java/org/pytorch/executorch/extension/llm/LlmGenerationConfig.kt",
"executorch_android/src/main/java/org/pytorch/executorch/extension/llm/LlmModule.kt",
"executorch_android/src/main/java/org/pytorch/executorch/extension/llm/LlmModuleConfig.kt",
"//xplat/executorch/extension/java:llm_sources",
],
autoglob = False,
language = "KOTLIN",
Expand Down
7 changes: 7 additions & 0 deletions extension/android/executorch_android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ plugins {

spotless {
kotlin {
// Scoped to this module's sources only: Spotless refuses targets
// outside the project directory ("All target files must be within
// the project dir"), so the shared sources in extension/java cannot
// be listed here. They are kept ktfmt-clean per extension/java/README.md.
target '**/*.kt'
ktfmt()
}
Expand Down Expand Up @@ -46,6 +50,9 @@ android {
sourceSets {
main {
jniLibs.srcDirs = ['../../../cmake-out-android-so/']
// Platform-neutral API sources shared with the desktop JVM artifact.
// They are compiled directly into this AAR, keeping it self-contained.
java.srcDirs += ['../../java/src/main/java']
}
androidTest {
resources.srcDirs += ['src/androidTest/resources']
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/

package org.pytorch.executorch

/**
* Platform logging facade used by the shared sources under extension/java.
*
* <p>The shared sources reference [Log] by simple name (same package, no import), and each platform
* artifact compiles its own implementation:
* <ul>
* <li>Android (this file): delegates to [android.util.Log], so logcat output — tags, priorities,
* and messages — is byte-for-byte identical to logging directly from the caller.
* <li>Desktop JVM (extension/jvm, added separately): a console-backed implementation.
* </ul>
*
* The shared source set itself contains no [Log] definition, so there is exactly one implementation
* per artifact and no duplicate-class collision.
*
* Note: this is public (not `internal`) because the shared sources are compiled by several Buck
* targets (executorch, executorch_llama, executorch_training), and `internal` visibility is scoped
* to a single Kotlin compilation module — a shared source in another target calling [Log] would
* fail to compile. It is nevertheless an implementation detail and not part of the public API.
*/
object Log {
@JvmStatic fun v(tag: String, msg: String): Int = android.util.Log.v(tag, msg)

@JvmStatic fun d(tag: String, msg: String): Int = android.util.Log.d(tag, msg)

@JvmStatic fun i(tag: String, msg: String): Int = android.util.Log.i(tag, msg)

@JvmStatic fun w(tag: String, msg: String): Int = android.util.Log.w(tag, msg)

@JvmStatic fun w(tag: String, msg: String, tr: Throwable): Int = android.util.Log.w(tag, msg, tr)

@JvmStatic fun e(tag: String, msg: String): Int = android.util.Log.e(tag, msg)

@JvmStatic fun e(tag: String, msg: String, tr: Throwable): Int = android.util.Log.e(tag, msg, tr)
}
32 changes: 32 additions & 0 deletions extension/java/BUCK
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
load("@fbcode_macros//build_defs:build_file_migration.bzl", "fbcode_target", "non_fbcode_target")
load("@fbcode_macros//build_defs:native_rules.bzl", "buck_filegroup")

oncall("executorch")

# Shared platform-neutral Java/Kotlin sources, compiled in place by each
# platform artifact (see README.md in this directory). Exported as filegroup
# labels so consuming targets never need parent-relative ("../") source paths,
# and globs so newly added shared sources are picked up automatically.
#
# NOTE: the ASR sources under src/main/java/org/pytorch/executorch/extension/asr
# are intentionally not referenced by any Buck target here; they are built by
# the OSS Gradle AAR only (same as before the shared-source move). Add a
# filegroup + consumer target when an internal Buck build needs them.

fbcode_target(_kind = buck_filegroup,
name = "core_sources",
srcs = glob([
"src/main/java/org/pytorch/executorch/*.kt",
"src/main/java/org/pytorch/executorch/annotations/*.kt",
]),
)

fbcode_target(_kind = buck_filegroup,
name = "training_sources",
srcs = glob(["src/main/java/org/pytorch/executorch/training/*.kt"]),
)

fbcode_target(_kind = buck_filegroup,
name = "llm_sources",
srcs = glob(["src/main/java/org/pytorch/executorch/extension/llm/*.kt"]),
)
48 changes: 48 additions & 0 deletions extension/java/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# ExecuTorch shared Java sources

This directory holds the **platform-neutral** Java/Kotlin API sources
(`Module`, `Tensor`, `EValue`, `DType`, `LlmModule`, `AsrModule`, training,
…) that are shared by every Java-platform artifact.

## How the sources are consumed

These sources are **not** published as their own artifact. Each platform
build compiles them directly into its own, self-contained artifact by
referencing this directory as an additional source root:

- **Android** (`extension/android/executorch_android`) adds
`../../java/src/main/java` via `java.srcDirs`, so the shipping AAR embeds
the same classes it always has — no new transitive dependency, unchanged
bytecode target (Java 11), unchanged manifest.
- **Desktop JVM** (`extension/jvm`, added separately) compiles the same
sources into its own jar.

## Contract for sources in this directory

1. **No platform APIs.** Sources here must not import `android.*`,
`java.awt.*`, or any other platform-specific API. The only permitted
dependencies are the JDK, fbjni, and soloader.
2. **Logging goes through the `org.pytorch.executorch.Log` facade.** The
facade is referenced by simple name (same package, no import) and is
*not* defined in this directory. Each platform artifact compiles exactly
one implementation (Android: backed by `android.util.Log`; desktop:
console-backed), so there is never a duplicate-class collision and each
platform keeps its native logging behavior.
3. **Native library loading stays per-platform.** Shared sources load the
native library through soloader's `NativeLoader`, whose delegate is
configured by the platform runtime, not by a cross-platform mutable
global.

## Adding a source here

Both consumers pick up new files automatically — Gradle
(`extension/android/executorch_android/build.gradle`) globs this directory via
`java.srcDirs`, and the Buck side globs it via the filegroups in
`extension/java/BUCK` (`core_sources`, `training_sources`, `llm_sources`), so
no per-file lists need updating. Keep every file ktfmt-formatted (the Android
module's Spotless cannot target this directory — Spotless requires all target
files to live under the module's project dir).

The ASR (`extension/asr/`) sources and the Android-only `ImageProcessor` are
Gradle/AAR-only today and intentionally have no Buck targets, matching the
pre-move state; add Buck targets for them when an internal build needs them.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

package org.pytorch.executorch

import android.util.Log
import com.facebook.jni.HybridData
import com.facebook.jni.annotations.DoNotStrip
import java.nio.Buffer
Expand Down
Loading