Skip to content

Commit

Permalink
update build script and docs
Browse files Browse the repository at this point in the history
- no build android native libraries if no --arch specified
- add --android-skip-aar to skip building aar
- remove desktop libraries before copy to prevent editor crash
- add prebuilt instructions
- update docs around build.py
  • Loading branch information
j20001970 committed May 16, 2024
1 parent ba2bd3f commit 75e10f5
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 59 deletions.
8 changes: 3 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
# GDMP
GDMP is a [Godot Engine](https://godotengine.org) 3.3+ plugin for utilizing [MediaPipe](https://developers.google.com/mediapipe) framework and solutions.

**NOTICE:** This branch is for Godot 4.x (GDExtension) and later.

- For Godot 3.x (GDNative) version, please refer to `3.x` branch.

## Getting Started
We are still working on precompiled libraries!
1. Download pre-built libraries from releases.
2. Extract `addons` to Godot project's root directory.
3. Open Godot project, go to `Project Settings...` and enable `GDMP` plugin under `Plugins` tab.

## Demo
Please check out [GDMP Demo](https://github.com/j20001970/GDMP-demo) to see how the plugin work.
Expand Down
63 changes: 35 additions & 28 deletions build.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from argparse import ArgumentParser, Namespace
from collections.abc import Callable
from functools import partial
from os import makedirs, path
from os import makedirs, path, remove
from shutil import copyfile, rmtree, which
from subprocess import run

Expand Down Expand Up @@ -57,32 +57,37 @@ def bazel_build(args: list[str]) -> Callable:
return partial(run, cmd, cwd=MEDIAPIPE_DIR, check=True)


def build_android(
build_type: str, build_args: list[str], abi_list: list[str]
) -> list[Callable]:
def build_android(args: Namespace, build_args: list[str]) -> list[Callable]:
build_type: str = args.type
arch: str = args.arch
skip_aar: bool = args.android_skip_aar
cmds = []
if not path.exists(ANDROID_PROJECT):
print("Error: android project does not exist.")
sys.exit(-1)
src = path.join(MEDIAPIPE_DIR, "bazel-bin/GDMP/android/libGDMP.so")
jni_dir = path.join(ANDROID_PROJECT, "src/main/jniLibs")
if path.exists(jni_dir):
cmds.append(partial(rmtree, jni_dir))
for abi in abi_list:
src_opencv = path.join(
MEDIAPIPE_DIR,
"bazel-mediapipe/external/android_opencv/sdk/native/libs",
abi,
"libopencv_java3.so",
)
dst_dir = path.join(jni_dir, abi)
dst = path.join(dst_dir, path.basename(src))
dst_opencv = path.join(dst_dir, path.basename(src_opencv))
build_args = [arg.format(abi=abi) for arg in build_args]
cmds.append(bazel_build(build_args))
cmds.append(partial(makedirs, dst_dir, exist_ok=True))
cmds.append(partial(copyfile, src, dst))
cmds.append(partial(copyfile, src_opencv, dst_opencv))
if arch:
jni_dir = path.join(ANDROID_PROJECT, "src/main/jniLibs")
if path.exists(jni_dir):
cmds.append(partial(rmtree, jni_dir))
abi_list = arch.split(",")
for abi in abi_list:
src_opencv = path.join(
MEDIAPIPE_DIR,
"bazel-mediapipe/external/android_opencv/sdk/native/libs",
abi,
"libopencv_java3.so",
)
dst_dir = path.join(jni_dir, abi)
dst = path.join(dst_dir, path.basename(src))
dst_opencv = path.join(dst_dir, path.basename(src_opencv))
build_args = [arg.format(abi=abi) for arg in build_args]
cmds.append(bazel_build(build_args))
cmds.append(partial(makedirs, dst_dir, exist_ok=True))
cmds.append(partial(copyfile, src, dst))
cmds.append(partial(copyfile, src_opencv, dst_opencv))
if skip_aar:
return cmds
gradlew_exec = path.join(ANDROID_PROJECT, "gradlew")
gradle_build = [gradlew_exec, "clean", f"assemble{build_type.capitalize()}"]
cmds.append(partial(run, gradle_build, cwd=ANDROID_PROJECT, check=True))
Expand All @@ -104,13 +109,10 @@ def get_build_cmds(args: Namespace) -> list[Callable]:
else:
build_args.extend(TARGET_ARGS[target])
if target == "android":
if arch is None:
arch = platform.machine().lower()
abi_list = arch.split(",")
build_args.extend(["--cpu={abi}", TARGETS[target]])
cmds.extend(build_android(build_type, build_args, abi_list))
cmds.extend(build_android(args, build_args))
return cmds
elif target == "ios" and arch != None:
elif target == "ios" and arch:
build_args.append(f"--ios_multi_cpus={arch}")
build_args.append(TARGETS[target])
cmd = bazel_build(build_args)
Expand All @@ -137,6 +139,8 @@ def copy_desktop(args: Namespace):
filename = path.basename(src).split(".")
filename = ".".join([filename[0], desktop_platform, filename[-1]])
dst = path.join(output, filename)
if path.exists(dst):
remove(dst)
copyfile(src, dst)
if desktop_platform == "windows":
opencv_lib = glob.glob(path.join(desktop_output, "opencv_world*.dll"))
Expand Down Expand Up @@ -173,8 +177,11 @@ def copy_output(args: Namespace):
parser.add_argument(
"--type", choices=["debug", "release"], default="debug", help="build type"
)
parser.add_argument("--arch", help="library architecture")
parser.add_argument("--arch", default="", help="library architecture")
parser.add_argument("--output", help="build output directory")
parser.add_argument(
"--android-skip-aar", help="skip building aar for android", action="store_true"
)
args = parser.parse_args()
cmds = get_build_cmds(args)
for cmd in cmds:
Expand Down
43 changes: 17 additions & 26 deletions docs/BUILDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@ Example:
4. Copy `addons` to your Godot project's root directory.
5. (Optional) Add calculator dependencies in `GDMP/GDMP.bzl` if you have additional calculators to compile into GDMP.

## General Build Instructions
`build.py` is a wrapper script that invoke Bazel build commands in `mediapipe` workspace to build GDMP libraries.

Common usage:

```
./build.py [target] --type [debug/release] --output [output-dir]
```
Run `build.py --help` to see all options.

## Building for Android
**Windows users**: Cross-compiling Android library on Windows is currently not supported, please set up WSL or Linux VM before proceed to the instructions below.

Expand All @@ -23,38 +33,27 @@ Example:
You will also need to uncomment `android_sdk_repository` and `android_ndk_repository` that setup script added eariler at the end of `mediapipe/WORKSPACE`

Refer to [MediaPipe docs](https://developers.google.com/mediapipe/framework/getting_started/android#prerequisite) for more details.
2. Build GDMP native libraries. For example, run:
2. Build Android libraries. For example, run:

```
build.py android --arch arm64-v8a
```

to build library for `arm64-v8a` architecture, you might want to build libGDMP.so for multiple architectures before building GDMP aar.
3. Build GDMP aar with Android Studio or Gradle using the `android` project, then copy the debug or release variant of aar library located in `android/build/outputs/aar` to your Godot project's `addons/GDMP/libs`
to build library for `arm64-v8a` architecture, you can pass comma-separated list to build multiple architectures.
If `--arch` is omitted, building native libraries will be skipped, and procceed to build Android AAR directly.
You can use `--android-skip-aar` to skip building Android AAR.

## Building for iOS
1. Install [Xcode](https://developer.apple.com/xcode), then switch to installed Xcode by using `xcode-select`
2. Run:

```
build.py ios
```

to build iOS library, then extract the content of `mediapipe/bazel-bin/GDMP/ios/GDMP.zip` to your Godot project's `addons/GDMP/libs`
2. Run `build.py ios` to build iOS library

Bazel should build GDMP for your Mac's CPU architecture by default, if you would like to build multiple architectures, append `--arch x86_64,arm64` to the build command to build both x86_64 and arm64 architectures for example.

## Building for Linux
**Flatpak environment**: If you intend to distribute the library, you might want to use an environment isolated from host before you proceed. You can use `scripts/flatpak_env.sh` to enable Flatpak environment.

1. Install OpenCV and FFmpeg, then modify `mediapipe/third_party/opencv_linux.BUILD` to make OpenCV visible to Bazel.
2. Run:

```
build.py desktop
```

to build desktop library, then copy `mediapipe/bazel-bin/GDMP/desktop/libGDMP.so` to your Godot project's `addons/GDMP/libs/x86_64`
2. Run `build.py desktop` to build desktop library.

## Building for Windows
1. Install MSVC compiler and Windows SDK, then setting `BAZEL_VC` environment variable pointing to your VC installation.
Expand All @@ -68,12 +67,4 @@ Example:
- Modify `OPENCV_VERSION` in `mediapipe/third_party/opencv_windows.BUILD` if OpenCV version is not `3.4.10`

Refer to [MediaPipe documentation](https://developers.google.com/mediapipe/framework/getting_started/install#installing_on_windows) for more details.
4. Run:

```
build.py desktop
```

to build desktop library, then copy `mediapipe/bazel-bin/GDMP/desktop/GDMP.dll` to your Godot project's `addons/GDMP/libs/x86_64`

(Optional) also copy `opencv_world3410.dll` to the project and add it as GDNative library dependencies if OpenCV is used in calculators.
4. Run `build.py desktop` to build desktop library.

0 comments on commit 75e10f5

Please sign in to comment.