|
1 |
| -# Single example build and deploy script |
| 1 | +#!/usr/bin/env python3 |
| 2 | + |
2 | 3 | import os
|
3 | 4 | import subprocess
|
4 | 5 | import sys
|
5 | 6 | import shutil
|
6 | 7 | import glob
|
7 | 8 | import json
|
8 |
| - |
9 |
| -# Android SDK version used |
10 |
| -SDK_VERSION = "android-23" |
11 |
| - |
12 |
| -PROJECT_FOLDER = "" |
13 |
| - |
14 |
| -# Check if python 3, python 2 not supported |
15 |
| -if sys.version_info <= (3, 0): |
16 |
| - print("Sorry, requires Python 3.x, not Python 2.x") |
17 |
| - sys.exit(-1) |
18 |
| - |
19 |
| -# Name/folder of the project to build |
20 |
| -if len(sys.argv) > 1: |
21 |
| - PROJECT_FOLDER = sys.argv[1] |
22 |
| -if not os.path.exists(PROJECT_FOLDER): |
23 |
| - print("Please specify a valid project folder to build!") |
24 |
| - sys.exit(-1) |
25 |
| - |
26 |
| -# Definitions (apk name, folders, etc.) will be taken from a json definition |
27 |
| -if not os.path.isfile(os.path.join(PROJECT_FOLDER, "example.json")): |
28 |
| - print("Could not find json definition for example %s" % PROJECT_FOLDER) |
29 |
| - sys.exit(-1) |
30 |
| - |
31 |
| -# Check if a build file is present, if not create one using the android SDK version specified |
32 |
| -if not os.path.isfile(os.path.join(PROJECT_FOLDER, "build.xml")): |
33 |
| - print("Build.xml not present, generating with %s " % SDK_VERSION) |
34 |
| - ANDROID_CMD = "android" |
35 |
| - if os.name == 'nt': |
36 |
| - ANDROID_CMD += ".bat" |
37 |
| - if subprocess.call(("%s update project -p ./%s -t %s" % (ANDROID_CMD, PROJECT_FOLDER, SDK_VERSION)).split(' ')) != 0: |
38 |
| - print("Error: Project update failed!") |
39 |
| - sys.exit(-1) |
40 |
| - |
41 |
| -# Load example definition from json file |
42 |
| -with open(os.path.join(PROJECT_FOLDER, "example.json")) as json_file: |
43 |
| - EXAMPLE_JSON = json.load(json_file) |
44 |
| - |
45 |
| -APK_NAME = EXAMPLE_JSON["apkname"] |
46 |
| -SHADER_DIR = EXAMPLE_JSON["directories"]["shaders"] |
47 |
| - |
48 |
| -# Additional |
49 |
| -ADDITIONAL_DIRS = [] |
50 |
| -ADDITIONAL_FILES = [] |
51 |
| -if "assets" in EXAMPLE_JSON and "additional" in EXAMPLE_JSON["assets"]: |
52 |
| - ADDITIONAL = EXAMPLE_JSON["assets"]["additional"] |
53 |
| - if "directories" in ADDITIONAL: |
54 |
| - ADDITIONAL_DIRS = ADDITIONAL["directories"] |
55 |
| - if "files" in ADDITIONAL: |
56 |
| - ADDITIONAL_FILES = ADDITIONAL["files"] |
57 |
| - |
58 |
| -# Get assets to be copied |
59 |
| -ASSETS_MODELS = [] |
60 |
| -ASSETS_TEXTURES = [] |
61 |
| -if "assets" in EXAMPLE_JSON: |
62 |
| - ASSETS = EXAMPLE_JSON["assets"] |
63 |
| - if "models" in ASSETS: |
64 |
| - ASSETS_MODELS = EXAMPLE_JSON["assets"]["models"] |
65 |
| - if "textures" in ASSETS: |
66 |
| - ASSETS_TEXTURES = EXAMPLE_JSON["assets"]["textures"] |
67 |
| - |
68 |
| -# Enable validation |
69 |
| -VALIDATION = False |
70 |
| -BUILD_ARGS = "" |
71 |
| - |
72 |
| -for arg in sys.argv[1:]: |
73 |
| - if arg == "-validation": |
74 |
| - VALIDATION = True |
| 9 | +import argparse |
| 10 | + |
| 11 | +def main(project_folder, deploy=False, validation=False): |
| 12 | + |
| 13 | + # Android SDK version used |
| 14 | + SDK_VERSION = "android-23" |
| 15 | + |
| 16 | + # Check if python 3, python 2 not supported |
| 17 | + if sys.version_info <= (3, 0): |
| 18 | + print("Sorry, requires Python 3.x, not Python 2.x") |
| 19 | + return False |
| 20 | + |
| 21 | + # Definitions (apk name, folders, etc.) will be taken from a json definition |
| 22 | + if not os.path.isfile(os.path.join(project_folder, "example.json")): |
| 23 | + print("Could not find json definition for example %s" % project_folder) |
| 24 | + return False |
| 25 | + |
| 26 | + # Check if a build file is present, if not create one using the android SDK version specified |
| 27 | + if not os.path.isfile(os.path.join(project_folder, "build.xml")): |
| 28 | + print("Build.xml not present, generating with %s " % SDK_VERSION) |
| 29 | + ANDROID_CMD = "android" |
| 30 | + if os.name == 'nt': |
| 31 | + ANDROID_CMD += ".bat" |
| 32 | + if subprocess.call(("%s update project -p ./%s -t %s" % (ANDROID_CMD, project_folder, SDK_VERSION)).split(' ')) != 0: |
| 33 | + print("Error: Project update failed!") |
| 34 | + return False |
| 35 | + |
| 36 | + # Load example definition from json file |
| 37 | + with open(os.path.join(project_folder, "example.json")) as json_file: |
| 38 | + EXAMPLE_JSON = json.load(json_file) |
| 39 | + |
| 40 | + APK_NAME = EXAMPLE_JSON["apkname"] |
| 41 | + SHADER_DIR = EXAMPLE_JSON["directories"]["shaders"] |
| 42 | + |
| 43 | + # Additional |
| 44 | + ADDITIONAL_DIRS = [] |
| 45 | + ADDITIONAL_FILES = [] |
| 46 | + if "assets" in EXAMPLE_JSON and "additional" in EXAMPLE_JSON["assets"]: |
| 47 | + ADDITIONAL = EXAMPLE_JSON["assets"]["additional"] |
| 48 | + if "directories" in ADDITIONAL: |
| 49 | + ADDITIONAL_DIRS = ADDITIONAL["directories"] |
| 50 | + if "files" in ADDITIONAL: |
| 51 | + ADDITIONAL_FILES = ADDITIONAL["files"] |
| 52 | + |
| 53 | + # Get assets to be copied |
| 54 | + ASSETS_MODELS = [] |
| 55 | + ASSETS_TEXTURES = [] |
| 56 | + if "assets" in EXAMPLE_JSON: |
| 57 | + ASSETS = EXAMPLE_JSON["assets"] |
| 58 | + if "models" in ASSETS: |
| 59 | + ASSETS_MODELS = EXAMPLE_JSON["assets"]["models"] |
| 60 | + if "textures" in ASSETS: |
| 61 | + ASSETS_TEXTURES = EXAMPLE_JSON["assets"]["textures"] |
| 62 | + |
| 63 | + # Enable validation |
| 64 | + BUILD_ARGS = "" |
| 65 | + |
| 66 | + if validation: |
75 | 67 | # Use a define to force validation in code
|
76 | 68 | BUILD_ARGS = "APP_CFLAGS=-D_VALIDATION"
|
77 |
| - break |
78 |
| - |
79 |
| -# Verify submodules are loaded in external folder |
80 |
| -if not os.listdir("../external/glm/") or not os.listdir("../external/gli/"): |
81 |
| - print("External submodules not loaded. Clone them using:") |
82 |
| - print("\tgit submodule init\n\tgit submodule update") |
83 |
| - sys.exit(-1) |
84 |
| - |
85 |
| -# Build |
86 |
| -os.chdir(PROJECT_FOLDER) |
87 |
| - |
88 |
| -if subprocess.call("ndk-build %s" %BUILD_ARGS, shell=True) == 0: |
89 |
| - print("Build successful") |
90 |
| - |
91 |
| - if VALIDATION: |
92 |
| - # Copy validation layers |
93 |
| - # todo: Currently only arm v7 |
94 |
| - print("Validation enabled, copying validation layers...") |
95 |
| - os.makedirs("./libs/armeabi-v7a", exist_ok=True) |
96 |
| - for file in glob.glob("../layers/armeabi-v7a/*.so"): |
97 |
| - print("\t" + file) |
98 |
| - shutil.copy(file, "./libs/armeabi-v7a") |
99 |
| - |
100 |
| - # Create folders |
101 |
| - os.makedirs("./assets/shaders/base", exist_ok=True) |
102 |
| - os.makedirs("./assets/shaders/%s" % SHADER_DIR, exist_ok=True) |
103 |
| - os.makedirs("./assets/models", exist_ok=True) |
104 |
| - os.makedirs("./assets/textures", exist_ok=True) |
105 |
| - for directory in ADDITIONAL_DIRS: |
106 |
| - os.makedirs("./assets/%s" % directory, exist_ok=True) |
107 |
| - os.makedirs("./res/drawable", exist_ok=True) |
108 |
| - |
109 |
| - for filename in glob.glob("../../data/shaders/base/*.spv"): |
110 |
| - shutil.copy(filename, "./assets/shaders/base") |
111 |
| - for filename in glob.glob("../../data/shaders/%s/*.spv" %SHADER_DIR): |
112 |
| - shutil.copy(filename, "./assets/shaders/%s" % SHADER_DIR) |
113 |
| - for filename in ASSETS_MODELS: |
114 |
| - shutil.copy("../../data/models/%s" % filename, "./assets/models") |
115 |
| - for filename in ASSETS_TEXTURES: |
116 |
| - shutil.copy("../../data/textures/%s" % filename, "./assets/textures") |
117 |
| - for filename in ADDITIONAL_FILES: |
118 |
| - if "*." in filename: |
119 |
| - for fname in glob.glob("../../data/%s" % filename): |
120 |
| - locfname = fname.replace("../../data/", "") |
121 |
| - shutil.copy(fname, "./assets/%s" % locfname) |
122 |
| - else: |
123 |
| - shutil.copy("../../data/%s" % filename, "./assets/%s" % filename) |
124 | 69 |
|
125 |
| - shutil.copy("../../android/images/icon.png", "./res/drawable") |
126 |
| - |
127 |
| - if subprocess.call("ant debug -Dout.final.file=%s.apk" % APK_NAME, shell=True) == 0: |
128 |
| - # Deploy to device |
129 |
| - for arg in sys.argv[1:]: |
130 |
| - if arg == "-deploy": |
131 |
| - if subprocess.call("adb install -r %s.apk" % APK_NAME, shell=True) != 0: |
132 |
| - print("Could not deploy to device!") |
| 70 | + # Verify submodules are loaded in external folder |
| 71 | + if not os.listdir("../external/glm/") or not os.listdir("../external/gli/"): |
| 72 | + print("External submodules not loaded. Clone them using:") |
| 73 | + print("\tgit submodule init\n\tgit submodule update") |
| 74 | + return False |
| 75 | + |
| 76 | + # Build |
| 77 | + old_cwd = os.getcwd() |
| 78 | + os.chdir(project_folder) |
| 79 | + |
| 80 | + if subprocess.call("ndk-build %s" %BUILD_ARGS, shell=True) == 0: |
| 81 | + print("Build successful") |
| 82 | + |
| 83 | + if validation: |
| 84 | + # Copy validation layers |
| 85 | + # todo: Currently only arm v7 |
| 86 | + print("Validation enabled, copying validation layers...") |
| 87 | + os.makedirs("./libs/armeabi-v7a", exist_ok=True) |
| 88 | + for file in glob.glob("../layers/armeabi-v7a/*.so"): |
| 89 | + print("\t" + file) |
| 90 | + shutil.copy(file, "./libs/armeabi-v7a") |
| 91 | + |
| 92 | + # Create folders |
| 93 | + os.makedirs("./assets/shaders/base", exist_ok=True) |
| 94 | + os.makedirs("./assets/shaders/%s" % SHADER_DIR, exist_ok=True) |
| 95 | + os.makedirs("./assets/models", exist_ok=True) |
| 96 | + os.makedirs("./assets/textures", exist_ok=True) |
| 97 | + for directory in ADDITIONAL_DIRS: |
| 98 | + os.makedirs("./assets/%s" % directory, exist_ok=True) |
| 99 | + os.makedirs("./res/drawable", exist_ok=True) |
| 100 | + |
| 101 | + for filename in glob.glob("../../data/shaders/base/*.spv"): |
| 102 | + shutil.copy(filename, "./assets/shaders/base") |
| 103 | + for filename in glob.glob("../../data/shaders/%s/*.spv" %SHADER_DIR): |
| 104 | + shutil.copy(filename, "./assets/shaders/%s" % SHADER_DIR) |
| 105 | + for filename in ASSETS_MODELS: |
| 106 | + shutil.copy("../../data/models/%s" % filename, "./assets/models") |
| 107 | + for filename in ASSETS_TEXTURES: |
| 108 | + shutil.copy("../../data/textures/%s" % filename, "./assets/textures") |
| 109 | + for filename in ADDITIONAL_FILES: |
| 110 | + if "*." in filename: |
| 111 | + for fname in glob.glob("../../data/%s" % filename): |
| 112 | + locfname = fname.replace("../../data/", "") |
| 113 | + shutil.copy(fname, "./assets/%s" % locfname) |
| 114 | + else: |
| 115 | + shutil.copy("../../data/%s" % filename, "./assets/%s" % filename) |
| 116 | + |
| 117 | + shutil.copy("../../android/images/icon.png", "./res/drawable") |
| 118 | + |
| 119 | + if subprocess.call("ant debug -Dout.final.file=%s.apk" % APK_NAME, shell=True) == 0: |
| 120 | + if deploy and subprocess.call("adb install -r %s.apk" % APK_NAME, shell=True) != 0: |
| 121 | + print("Could not deploy to device!") |
| 122 | + else: |
| 123 | + print("Error during build process!") |
| 124 | + return False |
133 | 125 | else:
|
134 |
| - print("Error during build process!") |
135 |
| - sys.exit(-1) |
136 |
| -else: |
137 |
| - print("Error building project!") |
138 |
| - sys.exit(-1) |
139 |
| - |
140 |
| -# Copy apk to bin folder |
141 |
| -os.makedirs("../bin", exist_ok=True) |
142 |
| -shutil.move('%s.apk' % APK_NAME, "../bin/%s.apk" % APK_NAME) |
| 126 | + print("Error building project!") |
| 127 | + return False |
| 128 | + |
| 129 | + # Copy apk to bin folder |
| 130 | + os.makedirs("../bin", exist_ok=True) |
| 131 | + shutil.move('%s.apk' % APK_NAME, "../bin/%s.apk" % APK_NAME) |
| 132 | + os.chdir(old_cwd) |
| 133 | + return True |
| 134 | + |
| 135 | +class ReadableDir(argparse.Action): |
| 136 | + def __call__(self, parser, namespace, values, option_string=None): |
| 137 | + if not os.path.isdir(values): |
| 138 | + raise argparse.ArgumentTypeError("{0} is not a valid path".format(values)) |
| 139 | + if not os.access(values, os.R_OK): |
| 140 | + raise argparse.ArgumentTypeError("{0} is not a readable dir".format(values)) |
| 141 | + setattr(namespace, self.dest,values) |
| 142 | + |
| 143 | +if __name__ == '__main__': |
| 144 | + parser = argparse.ArgumentParser(description="Build and deploy a single example") |
| 145 | + parser.add_argument('-deploy', default=False, action='store_true', help="install example on device") |
| 146 | + parser.add_argument('-validation', default=False, action='store_true') |
| 147 | + parser.add_argument('project_folder', action=ReadableDir) |
| 148 | + try: |
| 149 | + args = parser.parse_args() |
| 150 | + except SystemExit: |
| 151 | + sys.exit(1) |
| 152 | + ok = main(args.project_folder, args.deploy, args.validation) |
| 153 | + sys.exit(0 if ok else 1) |
0 commit comments