mirror of
https://github.com/opencv/opencv.git
synced 2026-07-29 15:23:05 +04:00
Merge pull request #24456 from alexlyulkov:al/aar
Added scripts for creating an AAR package and a local Maven repository with OpenCV library #24456 Added scripts for creating an AAR package and a local Maven repository with OpenCV library. The build_java_shared_aar.py script creates AAR with Java + C++ shared libraries. The build_static_aar.py script creates AAR with static C++ libraries. The scripts use an Android project template. The project is almost a default Android AAR library project with empty Java code and one empty C++ library. Only build.gradle.template and CMakeLists.txt.template files contain significant changes. See README.md for more information.
This commit is contained in:
Executable
+156
@@ -0,0 +1,156 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import argparse
|
||||
from os import path
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import string
|
||||
import subprocess
|
||||
|
||||
|
||||
COPY_FROM_SDK_TO_ANDROID_PROJECT = [
|
||||
["sdk/native/jni/include", "OpenCV/src/main/cpp/include"],
|
||||
["sdk/java/src/org", "OpenCV/src/main/java/org"],
|
||||
["sdk/java/res", "OpenCV/src/main/res"]
|
||||
]
|
||||
|
||||
COPY_FROM_SDK_TO_APK = [
|
||||
["sdk/native/libs/<ABI>/lib<LIB_NAME>.so", "jni/<ABI>/lib<LIB_NAME>.so"],
|
||||
["sdk/native/libs/<ABI>/lib<LIB_NAME>.so", "prefab/modules/<LIB_NAME>/libs/android.<ABI>/lib<LIB_NAME>.so"],
|
||||
]
|
||||
|
||||
ANDROID_PROJECT_TEMPLATE_DIR = path.join(path.dirname(__file__), "aar-template")
|
||||
TEMP_DIR = "build_java_shared"
|
||||
ANDROID_PROJECT_DIR = path.join(TEMP_DIR, "AndroidProject")
|
||||
COMPILED_AAR_PATH_1 = path.join(ANDROID_PROJECT_DIR, "OpenCV/build/outputs/aar/OpenCV-release.aar") # original package name
|
||||
COMPILED_AAR_PATH_2 = path.join(ANDROID_PROJECT_DIR, "OpenCV/build/outputs/aar/opencv-release.aar") # lower case package name
|
||||
AAR_UNZIPPED_DIR = path.join(TEMP_DIR, "aar_unzipped")
|
||||
FINAL_AAR_PATH_TEMPLATE = "outputs/opencv_java_shared_<OPENCV_VERSION>.aar"
|
||||
FINAL_REPO_PATH = "outputs/maven_repo"
|
||||
MAVEN_PACKAGE_NAME = "opencv"
|
||||
|
||||
def fill_template(src_path, dst_path, args_dict):
|
||||
with open(src_path, "r") as f:
|
||||
template_text = f.read()
|
||||
template = string.Template(template_text)
|
||||
text = template.safe_substitute(args_dict)
|
||||
with open(dst_path, "w") as f:
|
||||
f.write(text)
|
||||
|
||||
def get_opencv_version(opencv_sdk_path):
|
||||
version_hpp_path = path.join(opencv_sdk_path, "sdk/native/jni/include/opencv2/core/version.hpp")
|
||||
with open(version_hpp_path, "rt") as f:
|
||||
data = f.read()
|
||||
major = re.search(r'^#define\W+CV_VERSION_MAJOR\W+(\d+)$', data, re.MULTILINE).group(1)
|
||||
minor = re.search(r'^#define\W+CV_VERSION_MINOR\W+(\d+)$', data, re.MULTILINE).group(1)
|
||||
revision = re.search(r'^#define\W+CV_VERSION_REVISION\W+(\d+)$', data, re.MULTILINE).group(1)
|
||||
return "%(major)s.%(minor)s.%(revision)s" % locals()
|
||||
|
||||
def get_compiled_aar_path(path1, path2):
|
||||
if path.exists(path1):
|
||||
return path1
|
||||
elif path.exists(path2):
|
||||
return path2
|
||||
else:
|
||||
raise Exception("Can't find compiled AAR path in [" + path1 + ", " + path2 + "]")
|
||||
|
||||
def cleanup(paths_to_remove):
|
||||
exists = False
|
||||
for p in paths_to_remove:
|
||||
if path.exists(p):
|
||||
exists = True
|
||||
if path.isdir(p):
|
||||
shutil.rmtree(p)
|
||||
else:
|
||||
os.remove(p)
|
||||
print("Removed", p)
|
||||
if not exists:
|
||||
print("Nothing to remove")
|
||||
|
||||
def main(args):
|
||||
opencv_version = get_opencv_version(args.opencv_sdk_path)
|
||||
abis = os.listdir(path.join(args.opencv_sdk_path, "sdk/native/libs"))
|
||||
lib_name = "opencv_java" + opencv_version.split(".")[0]
|
||||
final_aar_path = FINAL_AAR_PATH_TEMPLATE.replace("<OPENCV_VERSION>", opencv_version)
|
||||
|
||||
print("Removing data from previous runs...")
|
||||
cleanup([TEMP_DIR, final_aar_path, path.join(FINAL_REPO_PATH, "org/opencv", MAVEN_PACKAGE_NAME)])
|
||||
|
||||
print("Preparing Android project...")
|
||||
# ANDROID_PROJECT_TEMPLATE_DIR contains an Android project template that creates AAR
|
||||
shutil.copytree(ANDROID_PROJECT_TEMPLATE_DIR, ANDROID_PROJECT_DIR)
|
||||
|
||||
# Configuring the Android project to Java + shared C++ lib version
|
||||
shutil.rmtree(path.join(ANDROID_PROJECT_DIR, "OpenCV/src/main/cpp/include"))
|
||||
|
||||
fill_template(path.join(ANDROID_PROJECT_DIR, "OpenCV/build.gradle.template"),
|
||||
path.join(ANDROID_PROJECT_DIR, "OpenCV/build.gradle"),
|
||||
{"LIB_NAME": lib_name,
|
||||
"LIB_TYPE": "c++_shared",
|
||||
"PACKAGE_NAME": MAVEN_PACKAGE_NAME,
|
||||
"OPENCV_VERSION": opencv_version,
|
||||
"COMPILE_SDK": args.android_compile_sdk,
|
||||
"MIN_SDK": args.android_min_sdk,
|
||||
"TARGET_SDK": args.android_target_sdk,
|
||||
"ABI_FILTERS": ", ".join(['"' + x + '"' for x in abis]),
|
||||
"JAVA_VERSION": args.java_version,
|
||||
})
|
||||
fill_template(path.join(ANDROID_PROJECT_DIR, "OpenCV/src/main/cpp/CMakeLists.txt.template"),
|
||||
path.join(ANDROID_PROJECT_DIR, "OpenCV/src/main/cpp/CMakeLists.txt"),
|
||||
{"LIB_NAME": lib_name, "LIB_TYPE": "SHARED"})
|
||||
|
||||
# Copying Java code and C++ public headers from SDK to the Android project
|
||||
for src, dst in COPY_FROM_SDK_TO_ANDROID_PROJECT:
|
||||
shutil.copytree(path.join(args.opencv_sdk_path, src),
|
||||
path.join(ANDROID_PROJECT_DIR, dst))
|
||||
|
||||
print("Running gradle assembleRelease...")
|
||||
# Running gradle to build the Android project
|
||||
subprocess.run(["./gradlew", "assembleRelease"],
|
||||
shell=False,
|
||||
cwd=ANDROID_PROJECT_DIR,
|
||||
check=True)
|
||||
|
||||
print("Adding libs to AAR...")
|
||||
# The created AAR package doesn't contain C++ shared libs.
|
||||
# We need to add them manually.
|
||||
# AAR package is just a zip archive.
|
||||
complied_aar_path = get_compiled_aar_path(COMPILED_AAR_PATH_1, COMPILED_AAR_PATH_2) # two possible paths
|
||||
shutil.unpack_archive(complied_aar_path, AAR_UNZIPPED_DIR, "zip")
|
||||
|
||||
for abi in abis:
|
||||
for src, dst in COPY_FROM_SDK_TO_APK:
|
||||
src = src.replace("<ABI>", abi).replace("<LIB_NAME>", lib_name)
|
||||
dst = dst.replace("<ABI>", abi).replace("<LIB_NAME>", lib_name)
|
||||
shutil.copy(path.join(args.opencv_sdk_path, src),
|
||||
path.join(AAR_UNZIPPED_DIR, dst))
|
||||
|
||||
# Creating final AAR zip archive
|
||||
os.makedirs("outputs", exist_ok=True)
|
||||
shutil.make_archive(final_aar_path, "zip", AAR_UNZIPPED_DIR, ".")
|
||||
os.rename(final_aar_path + ".zip", final_aar_path)
|
||||
|
||||
print("Creating local maven repo...")
|
||||
|
||||
shutil.copy(final_aar_path, path.join(ANDROID_PROJECT_DIR, "OpenCV/opencv-release.aar"))
|
||||
subprocess.run(["./gradlew", "publishReleasePublicationToMyrepoRepository"],
|
||||
shell=False,
|
||||
cwd=ANDROID_PROJECT_DIR,
|
||||
check=True)
|
||||
|
||||
os.makedirs(path.join(FINAL_REPO_PATH, "org/opencv"), exist_ok=True)
|
||||
shutil.move(path.join(ANDROID_PROJECT_DIR, "OpenCV/build/repo/org/opencv", MAVEN_PACKAGE_NAME),
|
||||
path.join(FINAL_REPO_PATH, "org/opencv", MAVEN_PACKAGE_NAME))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Builds AAR with Java and shared C++ libs from OpenCV SDK")
|
||||
parser.add_argument('opencv_sdk_path')
|
||||
parser.add_argument('--android_compile_sdk', default="26")
|
||||
parser.add_argument('--android_min_sdk', default="21")
|
||||
parser.add_argument('--android_target_sdk', default="26")
|
||||
parser.add_argument('--java_version', default="1_8")
|
||||
args = parser.parse_args()
|
||||
|
||||
main(args)
|
||||
Reference in New Issue
Block a user