Home | History | Annotate | Download | only in build-android
      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