Skip to content
This repository was archived by the owner on Jul 18, 2019. It is now read-only.

Commit 848310f

Browse files
committed
Allow Linux users to build Android even if Python 2 is their default Python
After this commit, users who have the `python` executable as Python 2 can do simply: cd android/ ./build-all.py ./build.py Previously, the following would fail: python3 build-all.py since build-all.py did subcalls to `python build.py`. Remove install-all.py as it is redundant with `build-all.py -deploy`, instead of fixing it as well. Introduce argparse since we are separating argument parsing out of the `main()` function. Tested in Ubuntu 16.04, behaviour should be unchanged for Windows.
1 parent 542be43 commit 848310f

File tree

6 files changed

+160
-157
lines changed

6 files changed

+160
-157
lines changed

android/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ This will build all apks and puts them into the **bin** folder.
3939
#### Build and deploy
4040

4141
```
42-
install-all.py
42+
build-all.py -deploy
4343
```
4444

4545
This will build all apks and deploys them to the currently attached android device.

android/build-all.py

100644100755
+10-9
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
# Build all examples
2-
# Pass -deploy to also install on connected device
1+
#!/usr/bin/env python3
2+
3+
import argparse
34
import subprocess
45
import sys
56

7+
import build
8+
69
EXAMPLES = [
710
"bloom",
811
"computecullandlod",
@@ -64,18 +67,16 @@
6467

6568
CURR_INDEX = 0
6669

67-
BUILD_ARGUMENTS = ""
68-
for arg in sys.argv[1:]:
69-
if arg == "-deploy":
70-
BUILD_ARGUMENTS += "-deploy"
71-
if arg == "-validation":
72-
BUILD_ARGUMENTS += "-validation"
70+
parser = argparse.ArgumentParser()
71+
parser.add_argument('-deploy', default=False, action='store_true', help="install examples on device")
72+
parser.add_argument('-validation', default=False, action='store_true')
73+
args = parser.parse_args()
7374

7475
print("Building all examples...")
7576

7677
for example in EXAMPLES:
7778
print(COLOR_GREEN + "Building %s (%d/%d)" % (example, CURR_INDEX, len(EXAMPLES)) + COLOR_END)
78-
if subprocess.call(("python build.py %s %s" % (example, BUILD_ARGUMENTS)).split(' ')) != 0:
79+
if not build.main(example, args.deploy, args.validation):
7980
print("Error during build process for %s" % example)
8081
sys.exit(-1)
8182
CURR_INDEX += 1

android/build.py

100644100755
+143-132
Original file line numberDiff line numberDiff line change
@@ -1,142 +1,153 @@
1-
# Single example build and deploy script
1+
#!/usr/bin/env python3
2+
23
import os
34
import subprocess
45
import sys
56
import shutil
67
import glob
78
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:
7567
# Use a define to force validation in code
7668
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)
12469

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
133125
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)

android/install-all.py

-13
This file was deleted.

android/uninstall-all.py

100644100755
+3-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#!/usr/bin/env python3
2+
13
# Remove all examples from connected device(s)
24
import subprocess
35
import sys
@@ -64,4 +66,4 @@
6466
print("Uninstalling %s (%d/%d)" % (app, CURR_INDEX, len(APP_NAMES)))
6567
subprocess.call("adb uninstall %s" % (app))
6668
CURR_INDEX += 1
67-
69+

download_assets.py

100644100755
+3-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#!/usr/bin/env python3
2+
13
import sys
24
from urllib.request import urlretrieve
35
from zipfile import ZipFile
@@ -26,4 +28,4 @@ def reporthook(blocknum, blocksize, totalsize):
2628

2729
zip = ZipFile(ASSET_PACK_FILE_NAME, 'r')
2830
zip.extractall("./")
29-
zip.close()
31+
zip.close()

0 commit comments

Comments
 (0)