You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
317 lines
9.3 KiB
317 lines
9.3 KiB
#!/usr/bin/env python
|
|
#
|
|
# Copyright (C) 2015 The Android Open Source Project
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
#
|
|
|
|
import argparse
|
|
import multiprocessing
|
|
import os
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
import time
|
|
|
|
from subprocess import PIPE, STDOUT
|
|
|
|
def install_file(file_name, src_dir, dst_dir):
|
|
src_file = os.path.join(src_dir, file_name)
|
|
dst_file = os.path.join(dst_dir, file_name)
|
|
|
|
print('Copying {} to {}...'.format(src_file, dst_file))
|
|
if os.path.isdir(src_file):
|
|
_install_dir(src_file, dst_file)
|
|
elif os.path.islink(src_file):
|
|
_install_symlink(src_file, dst_file)
|
|
else:
|
|
_install_file(src_file, dst_file)
|
|
|
|
|
|
def _install_dir(src_dir, dst_dir):
|
|
parent_dir = os.path.normpath(os.path.join(dst_dir, '..'))
|
|
if not os.path.exists(parent_dir):
|
|
os.makedirs(parent_dir)
|
|
shutil.copytree(src_dir, dst_dir, symlinks=True)
|
|
|
|
|
|
def _install_symlink(src_file, dst_file):
|
|
dirname = os.path.dirname(dst_file)
|
|
if not os.path.exists(dirname):
|
|
os.makedirs(dirname)
|
|
link_target = os.readlink(src_file)
|
|
os.symlink(link_target, dst_file)
|
|
|
|
|
|
def _install_file(src_file, dst_file):
|
|
dirname = os.path.dirname(dst_file)
|
|
if not os.path.exists(dirname):
|
|
os.makedirs(dirname)
|
|
# copy2 is just copy followed by copystat (preserves file metadata).
|
|
shutil.copy2(src_file, dst_file)
|
|
|
|
THIS_DIR = os.path.realpath(os.path.dirname(__file__))
|
|
|
|
ALL_ARCHITECTURES = (
|
|
'arm',
|
|
'arm64',
|
|
'x86',
|
|
'x86_64',
|
|
)
|
|
|
|
# According to vk_platform.h, armeabi is not supported for Vulkan
|
|
# so remove it from the abis list.
|
|
ALL_ABIS = (
|
|
'armeabi-v7a',
|
|
'arm64-v8a',
|
|
'x86',
|
|
'x86_64',
|
|
)
|
|
|
|
def jobs_arg():
|
|
return '-j{}'.format(multiprocessing.cpu_count() * 2)
|
|
|
|
def arch_to_abis(arch):
|
|
return {
|
|
'arm': ['armeabi-v7a'],
|
|
'arm64': ['arm64-v8a'],
|
|
'x86': ['x86'],
|
|
'x86_64': ['x86_64'],
|
|
}[arch]
|
|
|
|
class ArgParser(argparse.ArgumentParser):
|
|
def __init__(self):
|
|
super(ArgParser, self).__init__()
|
|
|
|
self.add_argument(
|
|
'--out-dir', help='Directory to place temporary build files.',
|
|
type=os.path.realpath, default=os.path.join(THIS_DIR, 'out'))
|
|
|
|
self.add_argument(
|
|
'--arch', choices=ALL_ARCHITECTURES,
|
|
help='Architectures to build. Builds all if not present.')
|
|
|
|
self.add_argument('--installdir', dest='installdir', required=True,
|
|
help='Installation directory. Required.')
|
|
|
|
# The default for --dist-dir has to be handled after parsing all
|
|
# arguments because the default is derived from --out-dir. This is
|
|
# handled in run().
|
|
self.add_argument(
|
|
'--dist-dir', help='Directory to place the packaged artifact.',
|
|
type=os.path.realpath)
|
|
|
|
|
|
def main():
|
|
print('THIS_DIR: %s' % THIS_DIR)
|
|
parser = ArgParser()
|
|
args = parser.parse_args()
|
|
|
|
arches = ALL_ARCHITECTURES
|
|
if args.arch is not None:
|
|
arches = [args.arch]
|
|
|
|
# Make paths absolute, and ensure directories exist.
|
|
installdir = os.path.abspath(args.installdir)
|
|
|
|
abis = []
|
|
for arch in arches:
|
|
abis.extend(arch_to_abis(arch))
|
|
|
|
shaderc_path = installdir + '/shaderc/android_test'
|
|
print('shaderc_path = %s' % shaderc_path)
|
|
|
|
ndk_dir = os.path.join(THIS_DIR, '../../../prebuilts/toolchain')
|
|
|
|
ndk_build = os.path.join(ndk_dir, 'ndk-build')
|
|
platforms_root = os.path.join(ndk_dir, 'platforms')
|
|
toolchains_root = os.path.join(ndk_dir, 'toolchains')
|
|
build_dir = installdir
|
|
|
|
print('installdir: %s' % installdir)
|
|
print('ndk_dir: %s' % ndk_dir)
|
|
print('ndk_build: %s' % ndk_build)
|
|
print('platforms_root: %s' % platforms_root)
|
|
|
|
compiler = 'clang'
|
|
stl = 'c++_static'
|
|
obj_out = os.path.join(THIS_DIR, stl, 'obj')
|
|
lib_out = os.path.join(THIS_DIR, 'jniLibs')
|
|
|
|
print('obj_out: %s' % obj_out)
|
|
print('lib_out: %s' % lib_out)
|
|
|
|
print('Constructing shaderc build tree...')
|
|
shaderc_root_dir = os.path.join(THIS_DIR, '../../shaderc')
|
|
|
|
print('Pulling in vulkan headers and layers...')
|
|
vulkan_root_dir = os.path.join(THIS_DIR, '../../vulkan-validation-layers')
|
|
vulkan_headers_root_dir = os.path.join(THIS_DIR, '../../vulkan-headers')
|
|
|
|
copies = [
|
|
{
|
|
'source_dir': os.path.join(shaderc_root_dir, 'shaderc'),
|
|
'dest_dir': 'third_party/shaderc',
|
|
'files': [
|
|
'Android.mk', 'libshaderc/Android.mk',
|
|
'libshaderc_util/Android.mk',
|
|
'third_party/Android.mk',
|
|
'utils/update_build_version.py',
|
|
'CHANGES',
|
|
],
|
|
'dirs': [
|
|
'libshaderc/include', 'libshaderc/src',
|
|
'libshaderc_util/include', 'libshaderc_util/src',
|
|
'android_test'
|
|
],
|
|
},
|
|
{
|
|
'source_dir': os.path.join(shaderc_root_dir, 'spirv-tools'),
|
|
'dest_dir': 'third_party/shaderc/third_party/spirv-tools',
|
|
'files': [
|
|
'utils/generate_grammar_tables.py',
|
|
'utils/generate_language_headers.py',
|
|
'utils/generate_registry_tables.py',
|
|
'utils/update_build_version.py',
|
|
'Android.mk',
|
|
'CHANGES',
|
|
],
|
|
'dirs': ['include', 'source'],
|
|
},
|
|
{
|
|
'source_dir': os.path.join(shaderc_root_dir, 'spirv-headers'),
|
|
'dest_dir':
|
|
'third_party/shaderc/third_party/spirv-tools/external/spirv-headers',
|
|
'dirs': ['include',],
|
|
'files': [
|
|
'include/spirv/1.0/spirv.py',
|
|
'include/spirv/1.1/spirv.py',
|
|
'include/spirv/1.2/spirv.py',
|
|
],
|
|
},
|
|
{
|
|
'source_dir': os.path.join(shaderc_root_dir, 'glslang'),
|
|
'dest_dir': 'third_party/shaderc/third_party/glslang',
|
|
'files': ['glslang/OSDependent/osinclude.h',
|
|
'Android.mk',
|
|
# Build version info is generated frmo the CHANGES.md file.
|
|
'CHANGES.md',
|
|
'build_info.h.tmpl',
|
|
'build_info.py',
|
|
],
|
|
'dirs': [
|
|
'SPIRV',
|
|
'OGLCompilersDLL',
|
|
'glslang/GenericCodeGen',
|
|
'hlsl',
|
|
'glslang/HLSL',
|
|
'glslang/Include',
|
|
'glslang/MachineIndependent',
|
|
'glslang/OSDependent/Unix',
|
|
'glslang/Public',
|
|
],
|
|
},
|
|
{
|
|
'source_dir': vulkan_root_dir,
|
|
'dest_dir': 'vulkan/src',
|
|
'files': [
|
|
],
|
|
'dirs': [
|
|
'layers', 'scripts', 'build-android'
|
|
],
|
|
},
|
|
|
|
{
|
|
'source_dir': vulkan_headers_root_dir,
|
|
'dest_dir': 'vulkan/src',
|
|
'files': [
|
|
],
|
|
'dirs': [
|
|
'include', 'registry'
|
|
],
|
|
},
|
|
]
|
|
|
|
default_ignore_patterns = shutil.ignore_patterns(
|
|
"*CMakeLists.txt",
|
|
"*test.h",
|
|
"*test.cc")
|
|
|
|
for properties in copies:
|
|
source_dir = properties['source_dir']
|
|
dest_dir = os.path.join(installdir, properties['dest_dir'])
|
|
for d in properties['dirs']:
|
|
src = os.path.join(source_dir, d)
|
|
dst = os.path.join(dest_dir, d)
|
|
print(src, " -> ", dst)
|
|
shutil.copytree(src, dst,
|
|
ignore=default_ignore_patterns)
|
|
for f in properties['files']:
|
|
print(source_dir, ':', dest_dir, ":", f)
|
|
# Only copy if the source file exists. That way
|
|
# we can update this script in anticipation of
|
|
# source files yet-to-come.
|
|
if os.path.exists(os.path.join(source_dir, f)):
|
|
install_file(f, source_dir, dest_dir)
|
|
else:
|
|
print(source_dir, ':', dest_dir, ":", f, "SKIPPED")
|
|
|
|
print('Constructing Vulkan validation layer source...')
|
|
|
|
build_cmd = [
|
|
'bash', ndk_build, '-C', build_dir + '/vulkan/src/build-android',
|
|
jobs_arg(),
|
|
'APP_ABI=' + ' '.join(abis),
|
|
# Use the prebuilt platforms and toolchains.
|
|
'NDK_PLATFORMS_ROOT=' + platforms_root,
|
|
'NDK_TOOLCHAINS_ROOT=' + toolchains_root,
|
|
'NDK_MODULE_PATH=' + installdir,
|
|
'GNUSTL_PREFIX=',
|
|
'APP_STL=' + stl,
|
|
'NDK_TOOLCHAIN_VERSION=' + compiler,
|
|
|
|
# Tell ndk-build where to put the results
|
|
'NDK_OUT=' + obj_out,
|
|
'NDK_LIBS_OUT=' + lib_out,
|
|
]
|
|
|
|
print('Building Vulkan validation layers for ABIs:' +
|
|
' {}'.format(', '.join(abis)) + "...")
|
|
print(' '.join(build_cmd))
|
|
|
|
subprocess.check_call(build_cmd)
|
|
|
|
print('Finished building Vulkan validation layers')
|
|
out_package = os.path.join(installdir, 'vulkan_validation_layers.zip')
|
|
os.chdir(lib_out)
|
|
build_cmd = [
|
|
'zip', '-9qr', out_package, "."
|
|
]
|
|
|
|
print('Packaging Vulkan validation layers')
|
|
subprocess.check_call(build_cmd)
|
|
print('Finished Packaging Vulkan validation layers')
|
|
|
|
for properties in copies:
|
|
dest_dir = os.path.join(installdir, properties['dest_dir'])
|
|
for d in properties['dirs']:
|
|
dst = os.path.join(dest_dir, d)
|
|
print('Remove: %s' % dst)
|
|
shutil.rmtree(dst)
|
|
|
|
return 0
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|