diff --git a/android/README.md b/android/README.md index d8ff2b5c..7463ec2b 100644 --- a/android/README.md +++ b/android/README.md @@ -39,7 +39,7 @@ This will build all apks and puts them into the **bin** folder. #### Build and deploy ``` -install-all.py +build-all.py -deploy ``` This will build all apks and deploys them to the currently attached android device. diff --git a/android/build-all.py b/android/build-all.py old mode 100644 new mode 100755 index 2389eb45..aa045553 --- a/android/build-all.py +++ b/android/build-all.py @@ -1,8 +1,11 @@ -# Build all examples -# Pass -deploy to also install on connected device +#!/usr/bin/env python3 + +import argparse import subprocess import sys +import build + EXAMPLES = [ "bloom", "computecullandlod", @@ -64,18 +67,16 @@ COLOR_END = '\033[0m' CURR_INDEX = 0 -BUILD_ARGUMENTS = "" -for arg in sys.argv[1:]: - if arg == "-deploy": - BUILD_ARGUMENTS += "-deploy" - if arg == "-validation": - BUILD_ARGUMENTS += "-validation" +parser = argparse.ArgumentParser() +parser.add_argument('-deploy', default=False, action='store_true', help="install examples on device") +parser.add_argument('-validation', default=False, action='store_true') +args = parser.parse_args() print("Building all examples...") for example in EXAMPLES: print(COLOR_GREEN + "Building %s (%d/%d)" % (example, CURR_INDEX, len(EXAMPLES)) + COLOR_END) - if subprocess.call(("python build.py %s %s" % (example, BUILD_ARGUMENTS)).split(' ')) != 0: + if not build.main(example, args.deploy, args.validation): print("Error during build process for %s" % example) sys.exit(-1) CURR_INDEX += 1 diff --git a/android/build.py b/android/build.py old mode 100644 new mode 100755 index 800fcc33..b8d3ff9f --- a/android/build.py +++ b/android/build.py @@ -1,142 +1,153 @@ -# Single example build and deploy script +#!/usr/bin/env python3 + import os import subprocess import sys import shutil import glob import json +import argparse -# Android SDK version used -SDK_VERSION = "android-23" +def main(project_folder, deploy=False, validation=False): -PROJECT_FOLDER = "" + # Android SDK version used + SDK_VERSION = "android-23" -# Check if python 3, python 2 not supported -if sys.version_info <= (3, 0): - print("Sorry, requires Python 3.x, not Python 2.x") - sys.exit(-1) + # Check if python 3, python 2 not supported + if sys.version_info <= (3, 0): + print("Sorry, requires Python 3.x, not Python 2.x") + return False -# Name/folder of the project to build -if len(sys.argv) > 1: - PROJECT_FOLDER = sys.argv[1] -if not os.path.exists(PROJECT_FOLDER): - print("Please specify a valid project folder to build!") - sys.exit(-1) + # Definitions (apk name, folders, etc.) will be taken from a json definition + if not os.path.isfile(os.path.join(project_folder, "example.json")): + print("Could not find json definition for example %s" % project_folder) + return False -# Definitions (apk name, folders, etc.) will be taken from a json definition -if not os.path.isfile(os.path.join(PROJECT_FOLDER, "example.json")): - print("Could not find json definition for example %s" % PROJECT_FOLDER) - sys.exit(-1) + # Check if a build file is present, if not create one using the android SDK version specified + if not os.path.isfile(os.path.join(project_folder, "build.xml")): + print("Build.xml not present, generating with %s " % SDK_VERSION) + ANDROID_CMD = "android" + if os.name == 'nt': + ANDROID_CMD += ".bat" + if subprocess.call(("%s update project -p ./%s -t %s" % (ANDROID_CMD, project_folder, SDK_VERSION)).split(' ')) != 0: + print("Error: Project update failed!") + return False -# Check if a build file is present, if not create one using the android SDK version specified -if not os.path.isfile(os.path.join(PROJECT_FOLDER, "build.xml")): - print("Build.xml not present, generating with %s " % SDK_VERSION) - ANDROID_CMD = "android" - if os.name == 'nt': - ANDROID_CMD += ".bat" - if subprocess.call(("%s update project -p ./%s -t %s" % (ANDROID_CMD, PROJECT_FOLDER, SDK_VERSION)).split(' ')) != 0: - print("Error: Project update failed!") - sys.exit(-1) + # Load example definition from json file + with open(os.path.join(project_folder, "example.json")) as json_file: + EXAMPLE_JSON = json.load(json_file) -# Load example definition from json file -with open(os.path.join(PROJECT_FOLDER, "example.json")) as json_file: - EXAMPLE_JSON = json.load(json_file) + APK_NAME = EXAMPLE_JSON["apkname"] + SHADER_DIR = EXAMPLE_JSON["directories"]["shaders"] -APK_NAME = EXAMPLE_JSON["apkname"] -SHADER_DIR = EXAMPLE_JSON["directories"]["shaders"] + # Additional + ADDITIONAL_DIRS = [] + ADDITIONAL_FILES = [] + if "assets" in EXAMPLE_JSON and "additional" in EXAMPLE_JSON["assets"]: + ADDITIONAL = EXAMPLE_JSON["assets"]["additional"] + if "directories" in ADDITIONAL: + ADDITIONAL_DIRS = ADDITIONAL["directories"] + if "files" in ADDITIONAL: + ADDITIONAL_FILES = ADDITIONAL["files"] -# Additional -ADDITIONAL_DIRS = [] -ADDITIONAL_FILES = [] -if "assets" in EXAMPLE_JSON and "additional" in EXAMPLE_JSON["assets"]: - ADDITIONAL = EXAMPLE_JSON["assets"]["additional"] - if "directories" in ADDITIONAL: - ADDITIONAL_DIRS = ADDITIONAL["directories"] - if "files" in ADDITIONAL: - ADDITIONAL_FILES = ADDITIONAL["files"] + # Get assets to be copied + ASSETS_MODELS = [] + ASSETS_TEXTURES = [] + if "assets" in EXAMPLE_JSON: + ASSETS = EXAMPLE_JSON["assets"] + if "models" in ASSETS: + ASSETS_MODELS = EXAMPLE_JSON["assets"]["models"] + if "textures" in ASSETS: + ASSETS_TEXTURES = EXAMPLE_JSON["assets"]["textures"] -# Get assets to be copied -ASSETS_MODELS = [] -ASSETS_TEXTURES = [] -if "assets" in EXAMPLE_JSON: - ASSETS = EXAMPLE_JSON["assets"] - if "models" in ASSETS: - ASSETS_MODELS = EXAMPLE_JSON["assets"]["models"] - if "textures" in ASSETS: - ASSETS_TEXTURES = EXAMPLE_JSON["assets"]["textures"] + # Enable validation + BUILD_ARGS = "" -# Enable validation -VALIDATION = False -BUILD_ARGS = "" - -for arg in sys.argv[1:]: - if arg == "-validation": - VALIDATION = True + if validation: # Use a define to force validation in code BUILD_ARGS = "APP_CFLAGS=-D_VALIDATION" - break -# Verify submodules are loaded in external folder -if not os.listdir("../external/glm/") or not os.listdir("../external/gli/"): - print("External submodules not loaded. Clone them using:") - print("\tgit submodule init\n\tgit submodule update") - sys.exit(-1) + # Verify submodules are loaded in external folder + if not os.listdir("../external/glm/") or not os.listdir("../external/gli/"): + print("External submodules not loaded. Clone them using:") + print("\tgit submodule init\n\tgit submodule update") + return False -# Build -os.chdir(PROJECT_FOLDER) + # Build + old_cwd = os.getcwd() + os.chdir(project_folder) -if subprocess.call("ndk-build %s" %BUILD_ARGS, shell=True) == 0: - print("Build successful") + if subprocess.call("ndk-build %s" %BUILD_ARGS, shell=True) == 0: + print("Build successful") - if VALIDATION: - # Copy validation layers - # todo: Currently only arm v7 - print("Validation enabled, copying validation layers...") - os.makedirs("./libs/armeabi-v7a", exist_ok=True) - for file in glob.glob("../layers/armeabi-v7a/*.so"): - print("\t" + file) - shutil.copy(file, "./libs/armeabi-v7a") + if validation: + # Copy validation layers + # todo: Currently only arm v7 + print("Validation enabled, copying validation layers...") + os.makedirs("./libs/armeabi-v7a", exist_ok=True) + for file in glob.glob("../layers/armeabi-v7a/*.so"): + print("\t" + file) + shutil.copy(file, "./libs/armeabi-v7a") - # Create folders - os.makedirs("./assets/shaders/base", exist_ok=True) - os.makedirs("./assets/shaders/%s" % SHADER_DIR, exist_ok=True) - os.makedirs("./assets/models", exist_ok=True) - os.makedirs("./assets/textures", exist_ok=True) - for directory in ADDITIONAL_DIRS: - os.makedirs("./assets/%s" % directory, exist_ok=True) - os.makedirs("./res/drawable", exist_ok=True) + # Create folders + os.makedirs("./assets/shaders/base", exist_ok=True) + os.makedirs("./assets/shaders/%s" % SHADER_DIR, exist_ok=True) + os.makedirs("./assets/models", exist_ok=True) + os.makedirs("./assets/textures", exist_ok=True) + for directory in ADDITIONAL_DIRS: + os.makedirs("./assets/%s" % directory, exist_ok=True) + os.makedirs("./res/drawable", exist_ok=True) - for filename in glob.glob("../../data/shaders/base/*.spv"): - shutil.copy(filename, "./assets/shaders/base") - for filename in glob.glob("../../data/shaders/%s/*.spv" %SHADER_DIR): - shutil.copy(filename, "./assets/shaders/%s" % SHADER_DIR) - for filename in ASSETS_MODELS: - shutil.copy("../../data/models/%s" % filename, "./assets/models") - for filename in ASSETS_TEXTURES: - shutil.copy("../../data/textures/%s" % filename, "./assets/textures") - for filename in ADDITIONAL_FILES: - if "*." in filename: - for fname in glob.glob("../../data/%s" % filename): - locfname = fname.replace("../../data/", "") - shutil.copy(fname, "./assets/%s" % locfname) + for filename in glob.glob("../../data/shaders/base/*.spv"): + shutil.copy(filename, "./assets/shaders/base") + for filename in glob.glob("../../data/shaders/%s/*.spv" %SHADER_DIR): + shutil.copy(filename, "./assets/shaders/%s" % SHADER_DIR) + for filename in ASSETS_MODELS: + shutil.copy("../../data/models/%s" % filename, "./assets/models") + for filename in ASSETS_TEXTURES: + shutil.copy("../../data/textures/%s" % filename, "./assets/textures") + for filename in ADDITIONAL_FILES: + if "*." in filename: + for fname in glob.glob("../../data/%s" % filename): + locfname = fname.replace("../../data/", "") + shutil.copy(fname, "./assets/%s" % locfname) + else: + shutil.copy("../../data/%s" % filename, "./assets/%s" % filename) + + shutil.copy("../../android/images/icon.png", "./res/drawable") + + if subprocess.call("ant debug -Dout.final.file=%s.apk" % APK_NAME, shell=True) == 0: + if deploy and subprocess.call("adb install -r %s.apk" % APK_NAME, shell=True) != 0: + print("Could not deploy to device!") else: - shutil.copy("../../data/%s" % filename, "./assets/%s" % filename) - - shutil.copy("../../android/images/icon.png", "./res/drawable") - - if subprocess.call("ant debug -Dout.final.file=%s.apk" % APK_NAME, shell=True) == 0: - # Deploy to device - for arg in sys.argv[1:]: - if arg == "-deploy": - if subprocess.call("adb install -r %s.apk" % APK_NAME, shell=True) != 0: - print("Could not deploy to device!") + print("Error during build process!") + return False else: - print("Error during build process!") - sys.exit(-1) -else: - print("Error building project!") - sys.exit(-1) + print("Error building project!") + return False -# Copy apk to bin folder -os.makedirs("../bin", exist_ok=True) -shutil.move('%s.apk' % APK_NAME, "../bin/%s.apk" % APK_NAME) + # Copy apk to bin folder + os.makedirs("../bin", exist_ok=True) + shutil.move('%s.apk' % APK_NAME, "../bin/%s.apk" % APK_NAME) + os.chdir(old_cwd) + return True + +class ReadableDir(argparse.Action): + def __call__(self, parser, namespace, values, option_string=None): + if not os.path.isdir(values): + raise argparse.ArgumentTypeError("{0} is not a valid path".format(values)) + if not os.access(values, os.R_OK): + raise argparse.ArgumentTypeError("{0} is not a readable dir".format(values)) + setattr(namespace, self.dest,values) + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description="Build and deploy a single example") + parser.add_argument('-deploy', default=False, action='store_true', help="install example on device") + parser.add_argument('-validation', default=False, action='store_true') + parser.add_argument('project_folder', action=ReadableDir) + try: + args = parser.parse_args() + except SystemExit: + sys.exit(1) + ok = main(args.project_folder, args.deploy, args.validation) + sys.exit(0 if ok else 1) diff --git a/android/install-all.py b/android/install-all.py deleted file mode 100644 index 16c3b1e6..00000000 --- a/android/install-all.py +++ /dev/null @@ -1,13 +0,0 @@ -# Install all examples to connected device(s) -import subprocess -import sys - -answer = input("Install all vulkan examples to attached device, this may take some time! (Y/N)").lower() == 'y' -if answer: - BUILD_ARGUMENTS = "" - for arg in sys.argv[1:]: - if arg == "-validation": - BUILD_ARGUMENTS += "-validation" - if subprocess.call(("python build-all.py -deploy %s" % BUILD_ARGUMENTS).split(' ')) != 0: - print("Error: Not all examples may have been installed!") - sys.exit(-1) diff --git a/android/uninstall-all.py b/android/uninstall-all.py old mode 100644 new mode 100755 index 5b3700a7..62649972 --- a/android/uninstall-all.py +++ b/android/uninstall-all.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python3 + # Remove all examples from connected device(s) import subprocess import sys @@ -64,4 +66,4 @@ if answer: print("Uninstalling %s (%d/%d)" % (app, CURR_INDEX, len(APP_NAMES))) subprocess.call("adb uninstall %s" % (app)) CURR_INDEX += 1 - \ No newline at end of file + diff --git a/download_assets.py b/download_assets.py old mode 100644 new mode 100755 index 9aaf6783..8a9bff77 --- a/download_assets.py +++ b/download_assets.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python3 + import sys from urllib.request import urlretrieve from zipfile import ZipFile @@ -26,4 +28,4 @@ print("Extracting assets") zip = ZipFile(ASSET_PACK_FILE_NAME, 'r') zip.extractall("./") -zip.close() \ No newline at end of file +zip.close()