1 #!/usr/bin/env python 2 # 3 # Copyright (C) 2015 The Android Open Source Project 4 # 5 # Licensed under the Apache License, Version 2.0 (the "License"); 6 # you may not use this file except in compliance with the License. 7 # You may obtain a copy of the License at 8 # 9 # http://www.apache.org/licenses/LICENSE-2.0 10 # 11 # Unless required by applicable law or agreed to in writing, software 12 # distributed under the License is distributed on an "AS IS" BASIS, 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 # See the License for the specific language governing permissions and 15 # limitations under the License. 16 # 17 18 import argparse 19 import multiprocessing 20 import os 21 import subprocess 22 import sys 23 24 from subprocess import PIPE, STDOUT 25 26 THIS_DIR = os.path.realpath(os.path.dirname(__file__)) 27 28 ALL_ARCHITECTURES = ( 29 'arm', 30 'arm64', 31 'mips', 32 'mips64', 33 'x86', 34 'x86_64', 35 ) 36 37 # According to vk_platform.h, armeabi is not supported for Vulkan 38 # so remove it from the abis list. 39 ALL_ABIS = ( 40 'armeabi-v7a', 41 'arm64-v8a', 42 'mips', 43 'mips64', 44 'x86', 45 'x86_64', 46 ) 47 48 def jobs_arg(): 49 return '-j{}'.format(multiprocessing.cpu_count() * 2) 50 51 def arch_to_abis(arch): 52 return { 53 'arm': ['armeabi-v7a'], 54 'arm64': ['arm64-v8a'], 55 'mips': ['mips'], 56 'mips64': ['mips64'], 57 'x86': ['x86'], 58 'x86_64': ['x86_64'], 59 }[arch] 60 61 class ArgParser(argparse.ArgumentParser): 62 def __init__(self): 63 super(ArgParser, self).__init__() 64 65 self.add_argument( 66 '--out-dir', help='Directory to place temporary build files.', 67 type=os.path.realpath, default=os.path.join(THIS_DIR, 'out')) 68 69 self.add_argument( 70 '--arch', choices=ALL_ARCHITECTURES, 71 help='Architectures to build. Builds all if not present.') 72 73 self.add_argument('--installdir', dest='installdir', required=True, 74 help='Installation directory. Required.') 75 76 # The default for --dist-dir has to be handled after parsing all 77 # arguments because the default is derived from --out-dir. This is 78 # handled in run(). 79 self.add_argument( 80 '--dist-dir', help='Directory to place the packaged artifact.', 81 type=os.path.realpath) 82 83 84 def main(): 85 print('Constructing Vulkan validation layer source...') 86 87 print('THIS_DIR: %s' % THIS_DIR) 88 parser = ArgParser() 89 args = parser.parse_args() 90 91 arches = ALL_ARCHITECTURES 92 if args.arch is not None: 93 arches = [args.arch] 94 95 # ensure directory exists. 96 if not os.path.isdir(args.installdir): 97 os.makedirs(args.installdir) 98 99 # Make paths absolute, and ensure directories exist. 100 installdir = os.path.abspath(args.installdir) 101 102 abis = [] 103 for arch in arches: 104 abis.extend(arch_to_abis(arch)) 105 106 shaderc_dir = THIS_DIR + '/../../shaderc/shaderc/android_test' 107 print('shaderc_dir = %s' % shaderc_dir) 108 109 if os.path.isdir('/buildbot/android-ndk'): 110 ndk_dir = '/buildbot/android-ndk' 111 elif os.path.isdir(os.environ['NDK_PATH']): 112 ndk_dir = os.environ['NDK_PATH']; 113 else: 114 print('Error: No NDK environment found') 115 return 116 117 ndk_build = os.path.join(ndk_dir, 'ndk-build') 118 platforms_root = os.path.join(ndk_dir, 'platforms') 119 toolchains_root = os.path.join(ndk_dir, 'toolchains') 120 build_dir = THIS_DIR 121 122 print('installdir: %s' % installdir) 123 print('ndk_dir: %s' % ndk_dir) 124 print('ndk_build: %s' % ndk_build) 125 print('platforms_root: %s' % platforms_root) 126 127 compiler = 'clang' 128 stl = 'gnustl_static' 129 obj_out = os.path.join(THIS_DIR, stl, 'obj') 130 lib_out = os.path.join(THIS_DIR, 'jniLibs') 131 132 print('obj_out: %s' % obj_out) 133 print('lib_out: %s' % lib_out) 134 135 print('Building shader toolchain...') 136 build_cmd = [ 137 'bash', ndk_build, '-C', shaderc_dir, jobs_arg(), 138 'APP_ABI=' + ' '.join(abis), 139 # Use the prebuilt platforms and toolchains. 140 'NDK_PLATFORMS_ROOT=' + platforms_root, 141 'NDK_TOOLCHAINS_ROOT=' + toolchains_root, 142 'GNUSTL_PREFIX=', 143 144 # Tell ndk-build where all of our makefiles are and where outputs 145 # should go. The defaults in ndk-build are only valid if we have a 146 # typical ndk-build layout with a jni/{Android,Application}.mk. 147 'NDK_PROJECT_PATH=null', 148 'NDK_TOOLCHAIN_VERSION=' + compiler, 149 'APP_BUILD_SCRIPT=' + os.path.join(shaderc_dir, 'jni', 'Android.mk'), 150 'APP_STL=' + stl, 151 'NDK_APPLICATION_MK=' + os.path.join(shaderc_dir, 'jni', 'Application.mk'), 152 'NDK_OUT=' + os.path.join(shaderc_dir, 'obj'), 153 'NDK_LIBS_OUT=' + os.path.join(shaderc_dir, 'jniLibs'), 154 'THIRD_PARTY_PATH=../..', 155 156 # Put armeabi-v7a-hard in its own directory. 157 '_NDK_TESTING_ALL_=yes' 158 ] 159 160 subprocess.check_call(build_cmd) 161 print('Finished shader toolchain build') 162 163 build_cmd = [ 164 'bash', THIS_DIR + '/android-generate.sh' 165 ] 166 print('Generating generated layers...') 167 subprocess.check_call(build_cmd) 168 print('Generation finished') 169 170 171 build_cmd = [ 172 'bash', ndk_build, '-C', build_dir, jobs_arg(), 173 'APP_ABI=' + ' '.join(abis), 174 # Use the prebuilt platforms and toolchains. 175 'NDK_PLATFORMS_ROOT=' + platforms_root, 176 'NDK_TOOLCHAINS_ROOT=' + toolchains_root, 177 'GNUSTL_PREFIX=', 178 179 # Tell ndk-build where all of our makefiles are and where outputs 180 # should go. The defaults in ndk-build are only valid if we have a 181 # typical ndk-build layout with a jni/{Android,Application}.mk. 182 'NDK_PROJECT_PATH=null', 183 'NDK_TOOLCHAIN_VERSION=' + compiler, 184 'APP_BUILD_SCRIPT=' + os.path.join(build_dir, 'jni', 'Android.mk'), 185 'APP_STL=' + stl, 186 'NDK_APPLICATION_MK=' + os.path.join(build_dir, 'jni', 'Application.mk'), 187 'NDK_OUT=' + obj_out, 188 'NDK_LIBS_OUT=' + lib_out, 189 'THIRD_PARTY_PATH=', 190 191 # Put armeabi-v7a-hard in its own directory. 192 '_NDK_TESTING_ALL_=yes' 193 ] 194 195 print('Building Vulkan validation layers for ABIs:' + 196 ' {}'.format(', '.join(abis))) 197 subprocess.check_call(build_cmd) 198 199 print('Finished building Vulkan validation layers') 200 out_package = os.path.join(installdir, 'vulkan_validation_layers.zip') 201 os.chdir(lib_out) 202 build_cmd = [ 203 'zip', '-9qr', out_package, "." 204 ] 205 206 print('Packaging Vulkan validation layers') 207 subprocess.check_call(build_cmd) 208 print('Finished Packaging Vulkan validation layers') 209 210 211 if __name__ == '__main__': 212 main() 213