aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Albert <danalbert@google.com>2018-10-02 05:31:58 +0000
committerDan Albert <danalbert@google.com>2018-10-02 05:38:24 +0000
commitc93d87ee5a193bc2a8ba40809415602083f3cf90 (patch)
treebd2bb27bf894743c08e463f80492e285a92aa92a
parentd3091ab582c75c9bc5522497695204254c2be60b (diff)
downloadndk-c93d87ee5a193bc2a8ba40809415602083f3cf90.tar.gz
Revert "Refactor the build/install module interface."
This reverts commit e1db8f930120fc3e712f9c306819f6a3b4153f89. Reason for revert: Broke the Windows build Change-Id: I05510d5669b35d227f54a36bb6aae611507eec81
-rwxr-xr-xcheckbuild.py352
-rw-r--r--ndk/builds.py139
-rw-r--r--ndk/paths.py7
3 files changed, 238 insertions, 260 deletions
diff --git a/checkbuild.py b/checkbuild.py
index 057ac5be0..7c2818230 100755
--- a/checkbuild.py
+++ b/checkbuild.py
@@ -225,7 +225,6 @@ class Clang(ndk.builds.Module):
@property
def notices(self):
- # TODO: Why every host?
return [
os.path.join(self.get_prebuilt_path('darwin'), 'NOTICE'),
os.path.join(self.get_prebuilt_path('linux'), 'NOTICE'),
@@ -233,10 +232,7 @@ class Clang(ndk.builds.Module):
os.path.join(self.get_prebuilt_path('windows64'), 'NOTICE'),
]
- def get_prebuilt_path(self, host=None):
- if host is None:
- host = self.host
-
+ def get_prebuilt_path(self, host):
# The 32-bit Windows Clang is a part of the 64-bit Clang package in
# prebuilts/clang.
if host == 'windows':
@@ -247,24 +243,26 @@ class Clang(ndk.builds.Module):
platform_host_tag = host + '-x86'
rel_prebuilt_path = 'prebuilts/clang/host/{}'.format(platform_host_tag)
- prebuilt_path = ndk.paths.android_path(rel_prebuilt_path, self.version)
+ prebuilt_path = os.path.join(build_support.android_path(),
+ rel_prebuilt_path, self.version)
if not os.path.isdir(prebuilt_path):
raise RuntimeError(
'Could not find prebuilt LLVM at {}'.format(prebuilt_path))
return prebuilt_path
- def build(self):
+ def build(self, _build_dir, _dist_dir, _args):
pass
- def install(self):
- install_path = self.get_install_path()
+ def install(self, out_dir, _dist_dir, args):
+ prebuilt_path = self.get_prebuilt_path(args.system)
+ install_path = self.get_install_path(out_dir, args.system)
install_parent = os.path.dirname(install_path)
if os.path.exists(install_path):
shutil.rmtree(install_path)
if not os.path.exists(install_parent):
os.makedirs(install_parent)
- shutil.copytree(self.get_prebuilt_path(), install_path)
+ shutil.copytree(prebuilt_path, install_path)
# clang-4053586 was patched in the prebuilts directory to add the
# libc++ includes. These are almost certainly a different revision than
@@ -275,7 +273,7 @@ class Clang(ndk.builds.Module):
cxx_includes_path = os.path.join(install_path, 'include')
shutil.rmtree(cxx_includes_path)
- if self.host in ('darwin', 'linux'):
+ if args.system in ('darwin', 'linux'):
# The Linux and Darwin toolchains have Python compiler wrappers
# that currently do nothing. We don't have these for Windows and we
# want to make sure Windows behavior is consistent with the other
@@ -298,13 +296,13 @@ class Clang(ndk.builds.Module):
#
# Note that lld is experimental in the NDK. It is not the default for
# any architecture and has received only minimal testing in the NDK.
- bin_ext = '.exe' if self.host.startswith('windows') else ''
+ bin_ext = '.exe' if args.system.startswith('windows') else ''
os.remove(os.path.join(install_path, 'bin/ld64.lld' + bin_ext))
os.remove(os.path.join(install_path, 'bin/lld' + bin_ext))
os.remove(os.path.join(install_path, 'bin/lld-link' + bin_ext))
- libdir_name = 'lib' if self.host == 'windows' else 'lib64'
- if self.host.startswith('windows'):
+ libdir_name = 'lib' if args.system == 'windows' else 'lib64'
+ if args.system.startswith('windows'):
# The toolchain prebuilts have LLVMgold.dll in the bin directory
# rather than the lib directory that will actually be searched.
bin_dir = os.path.join(install_path, 'bin')
@@ -320,7 +318,7 @@ class Clang(ndk.builds.Module):
install_clanglib = os.path.join(install_path, libdir_name, 'clang')
linux_prebuilt_path = self.get_prebuilt_path('linux')
- if self.host != 'linux':
+ if args.system != 'linux':
# We don't build target binaries as part of the Darwin or Windows
# build. These toolchains need to get these from the Linux
# prebuilts.
@@ -354,7 +352,7 @@ class Clang(ndk.builds.Module):
# Also remove the other libraries that we installed, but they were only
# installed on Linux.
- if self.host == 'linux':
+ if args.system == 'linux':
shutil.rmtree(os.path.join(install_path, 'runtimes_ndk_cxx'))
@@ -468,11 +466,6 @@ class Binutils(ndk.builds.Module):
path = 'toolchains/{toolchain}-4.9/prebuilt/{host}'
notice_group = ndk.builds.NoticeGroup.TOOLCHAIN
- # TODO: Move GCC wrapper generation to Clang?
- deps = {
- 'clang',
- }
-
@property
def notices(self):
notices = []
@@ -482,40 +475,44 @@ class Binutils(ndk.builds.Module):
notices.append(os.path.join(prebuilt_path, 'NOTICE'))
return notices
- def build(self):
+ def build(self, _build_dir, _dist_dir, _args):
pass
- def install(self):
- for arch in self.arches:
- self.install_arch(arch)
+ def install(self, out_dir, _dist_dir, args):
+ arches = build_support.ALL_ARCHITECTURES
+ if args.arch is not None:
+ arches = [args.arch]
+
+ for arch in arches:
+ self.install_arch(out_dir, args.system, arch)
- def install_arch(self, arch):
- install_path = self.get_install_path(arch=arch)
- toolchain_path = get_binutils_prebuilt_path(self.host, arch)
+ def install_arch(self, out_dir, host, arch):
+ install_path = self.get_install_path(out_dir, host, arch)
+ toolchain_path = get_binutils_prebuilt_path(host, arch)
ndk.builds.install_directory(toolchain_path, install_path)
- self.install_mock_gcc(install_path, arch)
+ self.install_mock_gcc(out_dir, install_path, host, arch)
# We still need libgcc/libatomic. Copy them from the old GCC prebuilts.
for subarch in get_subarches(arch):
- install_libgcc(install_path, self.host, arch, subarch)
- install_libatomic(install_path, self.host, arch, subarch)
+ install_libgcc(install_path, host, arch, subarch)
+ install_libatomic(install_path, host, arch, subarch)
# We don't actually want this, but Clang won't recognize a
# -gcc-toolchain without it.
- install_gcc_crtbegin(install_path, self.host, arch, subarch)
+ install_gcc_crtbegin(install_path, host, arch, subarch)
# Copy the LLVMgold plugin into the binutils plugin directory so ar can
# use it.
- if self.host == 'linux':
+ if host == 'linux':
so = '.so'
- elif self.host == 'darwin':
+ elif host == 'darwin':
so = '.dylib'
else:
so = '.dll'
- is_win = self.host.startswith('windows')
- libdir_name = 'lib' if self.host == 'windows' else 'lib64'
- host_tag = ndk.hosts.host_to_tag(self.host)
+ is_win = host.startswith('windows')
+ libdir_name = 'lib' if host == 'windows' else 'lib64'
+ host_tag = build_support.host_to_tag(host)
clang_prebuilts = build_support.android_path(
'prebuilts/ndk/current/toolchains', host_tag, 'llvm')
clang_bin = os.path.join(clang_prebuilts, 'bin')
@@ -532,7 +529,7 @@ class Binutils(ndk.builds.Module):
if not is_win:
libcxx_1 = os.path.join(
- clang_libs, versioned_so(self.host, 'libc++', '1'))
+ clang_libs, versioned_so(host, 'libc++', '1'))
# The rpath on LLVMgold.so is ../lib64, so we have to install to
# lib/lib64 to have it be in the right place :(
@@ -543,18 +540,18 @@ class Binutils(ndk.builds.Module):
libwinpthread = os.path.join(clang_bin, 'libwinpthread-1.dll')
shutil.copy2(libwinpthread, bfd_plugins)
- def install_mock_gcc(self, install_path, arch):
+ def install_mock_gcc(self, out_dir, install_path, host, arch):
"""Installs gcc scripts that invoke clang.
These are provided to ease porting to new NDKs for projects that are
not actually sensitive to changes in compiler, just changes to compiler
install path.
"""
- is_win = self.host.startswith('windows')
+ is_win = host.startswith('windows')
exe = '.exe' if is_win else ''
cmd = '.cmd' if is_win else ''
clang_install_path = os.path.relpath(
- self.get_dep('clang').get_install_path(),
+ Clang().get_install_path(out_dir, host, arch),
os.path.join(install_path, 'bin'))
shortcuts = {'gcc': 'clang', 'g++': 'clang++'}
@@ -638,15 +635,14 @@ class HostTools(ndk.builds.Module):
ndk.paths.ndk_path('sources/host-tools/toolbox/NOTICE'),
]
- def build(self):
- build_args = ndk.builds.common_build_args(self.out_dir, self.dist_dir,
- self.host)
+ def build(self, build_dir, dist_dir, args):
+ build_args = ndk.builds.common_build_args(build_dir, dist_dir, args)
print('Building make...')
ndk.builds.invoke_external_build(
'ndk/sources/host-tools/make-3.81/build.py', build_args)
- if self.host in ('windows', 'windows64'):
+ if args.system in ('windows', 'windows64'):
print('Building toolbox...')
ndk.builds.invoke_external_build(
'ndk/sources/host-tools/toolbox/build.py', build_args)
@@ -661,8 +657,8 @@ class HostTools(ndk.builds.Module):
print('Building YASM...')
ndk.builds.invoke_external_build('toolchain/yasm/build.py', build_args)
- def install(self):
- install_dir = self.get_install_path()
+ def install(self, out_dir, _dist_dir, args):
+ install_dir = self.get_install_path(out_dir, args.system)
try:
os.makedirs(install_dir)
@@ -685,15 +681,15 @@ class HostTools(ndk.builds.Module):
'ndk-which',
]
- if self.host in ('windows', 'windows64'):
+ if args.system in ('windows', 'windows64'):
packages.append('toolbox')
files.append('ndk-gdb.cmd')
- host_tag = build_support.host_to_tag(self.host)
+ host_tag = build_support.host_to_tag(args.system)
package_names = [p + '-' + host_tag + '.tar.bz2' for p in packages]
for package_name in package_names:
- package_path = os.path.join(self.out_dir, package_name)
+ package_path = os.path.join(out_dir, package_name)
subprocess.check_call(
['tar', 'xf', package_path, '-C', install_dir,
'--strip-components=1'])
@@ -728,10 +724,10 @@ class NdkDepends(ndk.builds.InvokeExternalBuildModule):
script = 'ndk/sources/host-tools/ndk-depends/build.py'
notice = ndk.paths.ndk_path('sources/host-tools/ndk-depends/NOTICE')
- def install(self):
- src = os.path.join(self.out_dir, self.name)
- install_dir = self.get_install_path()
- install_exe(src, install_dir, self.name, self.host)
+ def install(self, out_dir, _dist_dir, args):
+ src = os.path.join(out_dir, self.name)
+ install_dir = self.get_install_path(out_dir, args.system)
+ install_exe(src, install_dir, self.name, args.system)
class NdkStack(ndk.builds.InvokeExternalBuildModule):
@@ -740,10 +736,10 @@ class NdkStack(ndk.builds.InvokeExternalBuildModule):
script = 'ndk/sources/host-tools/ndk-stack/build.py'
notice = ndk.paths.ndk_path('sources/host-tools/ndk-stack/NOTICE')
- def install(self):
- src = os.path.join(self.out_dir, self.name)
- install_dir = self.get_install_path()
- install_exe(src, install_dir, self.name, self.host)
+ def install(self, out_dir, _dist_dir, args):
+ src = os.path.join(out_dir, self.name)
+ install_dir = self.get_install_path(out_dir, args.system)
+ install_exe(src, install_dir, self.name, args.system)
class GdbServer(ndk.builds.InvokeBuildModule):
@@ -755,10 +751,10 @@ class GdbServer(ndk.builds.InvokeBuildModule):
arch_specific = True
split_build_by_arch = True
- def install(self):
- src_dir = os.path.join(self.out_dir, self.name, self.build_arch,
- 'install')
- install_path = self.get_install_path()
+ def install(self, out_dir, dist_dir, args):
+ src_dir = os.path.join(out_dir, self.name, self.build_arch, 'install')
+ install_path = self.get_install_path(
+ out_dir, args.system, self.build_arch)
if os.path.exists(install_path):
shutil.rmtree(install_path)
shutil.copytree(src_dir, install_path)
@@ -803,28 +799,34 @@ class Libcxx(ndk.builds.Module):
'ndk-build-shortcut',
}
- libcxx_path = ndk.paths.android_path('external/libcxx')
+ def __init__(self):
+ super(Libcxx, self).__init__()
+ self.abis = None
+ self.obj_out = None
+ self.lib_out = None
+ self.libcxx_path = ndk.paths.android_path('external/libcxx')
- @property
- def obj_out(self):
- return os.path.join(self.out_dir, 'libcxx/obj')
+ def set_abis(self, arch):
+ if arch is None:
+ self.abis = ndk.abis.ALL_ABIS
+ else:
+ self.abis = ndk.abis.arch_to_abis(arch)
- @property
- def lib_out(self):
- return os.path.join(self.out_dir, 'libcxx/libs')
+ def build(self, build_dir, _dist_dir, args):
+ # The build directory passed to us is for the target OS, which may not
+ # be our host OS (Windows is cross compiled from Linux). We need to use
+ # an NDK matching our host OS.
+ host_build_dir = os.path.join(
+ os.path.dirname(build_dir), ndk.hosts.get_default_host())
+ ndk_path = ndk.paths.get_install_path(host_build_dir)
- @property
- def abis(self):
- abis = []
- for arch in self.arches:
- abis.extend(ndk.abis.arch_to_abis(arch))
- return abis
-
- def build(self):
- ndk_build = os.path.join(
- self.get_dep('ndk-build').get_build_host_install(), 'ndk-build')
+ ndk_build = os.path.join(ndk_path, 'build/ndk-build')
bionic_path = ndk.paths.android_path('bionic')
+ self.obj_out = os.path.join(build_dir, 'libcxx/obj')
+ self.lib_out = os.path.join(build_dir, 'libcxx/libs')
+ self.set_abis(args.arch)
+
android_mk = os.path.join(self.libcxx_path, 'Android.mk')
application_mk = os.path.join(self.libcxx_path, 'Application.mk')
@@ -854,8 +856,9 @@ class Libcxx(ndk.builds.Module):
print('Running: ' + ' '.join([pipes.quote(arg) for arg in build_cmd]))
subprocess.check_call(build_cmd)
- def install(self):
- install_root = self.get_install_path()
+ def install(self, out_dir, dist_dir, args):
+ ndk_path = ndk.paths.get_install_path(out_dir)
+ install_root = os.path.join(ndk_path, self.path)
if os.path.exists(install_root):
shutil.rmtree(install_root)
@@ -1071,8 +1074,8 @@ class Platforms(ndk.builds.Module):
if name.startswith('crtbegin'):
self.check_elf_note(dst_path)
- def build(self):
- build_dir = os.path.join(self.out_dir, self.path)
+ def build(self, build_dir, _dist_dir, args):
+ build_dir = os.path.join(build_dir, self.path)
if os.path.exists(build_dir):
shutil.rmtree(build_dir)
@@ -1085,12 +1088,12 @@ class Platforms(ndk.builds.Module):
arch_name = 'arch-{}'.format(arch)
dst_dir = os.path.join(build_dir, platform, arch_name)
os.makedirs(dst_dir)
- self.build_crt_objects(dst_dir, api, arch,
- self.context.build_number)
+ self.build_crt_objects(dst_dir, api, arch, args.build_number)
- def install(self):
- build_dir = os.path.join(self.out_dir, self.path)
- install_dir = self.get_install_path()
+ def install(self, out_dir, dist_dir, args):
+ build_dir = os.path.join(out_dir, self.path)
+ install_dir = os.path.join(
+ ndk.paths.get_install_path(out_dir), self.path)
if os.path.exists(install_dir):
shutil.rmtree(install_dir)
@@ -1159,7 +1162,7 @@ class LibShaderc(ndk.builds.Module):
os.path.join(shaderc_dir, 'third_party', 'LICENSE.spirv-tools'),
]
- def build(self):
+ def build(self, _build_dir, dist_dir, _args):
copies = [
{
'source_dir': os.path.join(self.src, 'shaderc'),
@@ -1245,8 +1248,7 @@ class LibShaderc(ndk.builds.Module):
else:
print(source_dir, ':', dest_dir, ":", f, "SKIPPED")
- build_support.make_package('libshaderc', shaderc_path,
- self.dist_dir)
+ build_support.make_package('libshaderc', shaderc_path, dist_dir)
finally:
shutil.rmtree(temp_dir)
@@ -1280,13 +1282,13 @@ class Sysroot(ndk.builds.Module):
path = 'sysroot'
notice = ndk.paths.android_path('prebuilts/ndk/platform/sysroot/NOTICE')
- def build(self):
+ def build(self, _out_dir, dist_dir, args):
temp_dir = tempfile.mkdtemp()
try:
path = build_support.android_path('prebuilts/ndk/platform/sysroot')
install_path = os.path.join(temp_dir, 'sysroot')
shutil.copytree(path, install_path)
- if self.host != 'linux':
+ if args.system != 'linux':
# linux/netfilter has some headers with names that differ only
# by case, which can't be extracted to a case-insensitive
# filesystem, which are the defaults for Darwin and Windows :(
@@ -1316,7 +1318,7 @@ class Sysroot(ndk.builds.Module):
minor = ndk.config.hotfix
beta = ndk.config.beta
canary = '1' if ndk.config.canary else '0'
- build = self.context.build_number
+ build = args.build_number
if build == 'dev':
build = '0'
@@ -1364,7 +1366,7 @@ class Sysroot(ndk.builds.Module):
build=build,
canary=canary)))
- build_support.make_package('sysroot', install_path, self.dist_dir)
+ build_support.make_package('sysroot', install_path, dist_dir)
finally:
shutil.rmtree(temp_dir)
@@ -1477,17 +1479,17 @@ class BaseToolchain(ndk.builds.Module):
return (Binutils().notices + Clang().notices + Platforms().notices +
Sysroot().notices + SystemStl().notices)
- def build(self):
+ def build(self, _out_dir, _dist_dir, _args):
pass
- def install(self):
- install_dir = self.get_install_path()
- clang_dir = self.get_dep('clang').get_install_path()
- libandroid_support_dir = self.get_dep(
- 'libandroid_support').get_install_path()
- platforms_dir = self.get_dep('platforms').get_install_path()
- sysroot_dir = self.get_dep('sysroot').get_install_path()
- system_stl_dir = self.get_dep('system-stl').get_install_path()
+ def install(self, out_dir, dist_dir, args):
+ install_dir = self.get_install_path(out_dir, args.system)
+ clang_dir = Clang().get_install_path(out_dir, args.system)
+ libandroid_support_dir = LibAndroidSupport().get_install_path(
+ out_dir, args.system)
+ platforms_dir = Platforms().get_install_path(out_dir, args.system)
+ sysroot_dir = Sysroot().get_install_path(out_dir, args.system)
+ system_stl_dir = SystemStl().get_install_path(out_dir, args.system)
if os.path.exists(install_dir):
shutil.rmtree(install_dir)
@@ -1495,16 +1497,21 @@ class BaseToolchain(ndk.builds.Module):
copy_tree(clang_dir, install_dir)
copy_tree(sysroot_dir, os.path.join(install_dir, 'sysroot'))
- for arch in self.arches:
- binutils_dir = self.get_dep('binutils').get_install_path(arch=arch)
+ arches = build_support.ALL_ARCHITECTURES
+ if args.arch is not None:
+ arches = [args.arch]
+
+ for arch in arches:
+ binutils_dir = Binutils().get_install_path(out_dir, args.system,
+ arch)
copy_tree(binutils_dir, install_dir)
- for api in self.get_dep('platforms').get_apis():
+ for api in Platforms().get_apis():
if api in Platforms.skip_apis:
continue
platform = 'android-{}'.format(api)
- for arch in self.get_dep('platforms').get_arches(api):
+ for arch in Platforms().get_arches(api):
triple = ndk.abis.arch_to_triple(arch)
arch_name = 'arch-{}'.format(arch)
lib_dir = 'lib64' if arch == 'x86_64' else 'lib'
@@ -1518,7 +1525,7 @@ class BaseToolchain(ndk.builds.Module):
write_clang_wrapper(
os.path.join(install_dir, 'bin'), api, triple,
- self.host.startswith('windows'))
+ args.system.startswith('windows'))
# Clang searches for libstdc++ headers at $GCC_PATH/../include/c++. It
# maybe be worth adding a search for the same path within the usual
@@ -1550,7 +1557,7 @@ class Vulkan(ndk.builds.Module):
notice = ndk.paths.android_path(
'external/vulkan-validation-layers/LICENSE.txt')
- def build(self):
+ def build(self, build_dir, dist_dir, args):
print('Constructing Vulkan validation layer source...')
vulkan_root_dir = ndk.paths.android_path(
'external/vulkan-validation-layers')
@@ -1582,11 +1589,11 @@ class Vulkan(ndk.builds.Module):
"linux",
"windows")
- base_vulkan_path = os.path.join(self.out_dir, 'vulkan')
+ base_vulkan_path = os.path.join(build_dir, 'vulkan')
vulkan_path = os.path.join(base_vulkan_path, 'src')
for properties in copies:
source_dir = properties['source_dir']
- dest_dir = os.path.join(self.out_dir, properties['dest_dir'])
+ dest_dir = os.path.join(build_dir, properties['dest_dir'])
for d in properties['dirs']:
src = os.path.join(source_dir, d)
dst = os.path.join(dest_dir, d)
@@ -1620,10 +1627,15 @@ class Vulkan(ndk.builds.Module):
subprocess.check_call(build_cmd)
print('Generation finished')
+ build_args = ndk.builds.common_build_args(build_dir, dist_dir, args)
+ if args.arch is not None:
+ build_args.append('--arch={}'.format(args.arch))
+ build_args.append('--no-symbols')
+
# TODO: Verify source packaged properly
print('Packaging Vulkan source...')
- src = os.path.join(self.out_dir, 'vulkan')
- build_support.make_package('vulkan', src, self.dist_dir)
+ src = os.path.join(build_dir, 'vulkan')
+ build_support.make_package('vulkan', src, dist_dir)
print('Packaging Vulkan source finished')
@@ -1641,7 +1653,6 @@ class Toolchain(ndk.builds.Module):
'base-toolchain',
'libc++',
'libc++abi',
- 'platforms',
}
@property
@@ -1649,13 +1660,17 @@ class Toolchain(ndk.builds.Module):
return (Libcxx().notices + Libcxxabi().notices +
LibAndroidSupport().notices)
- def build(self):
+ def build(self, _out_dir, _dist_dir, _args):
pass
- def install(self):
- install_dir = self.get_install_path()
- libcxx_dir = self.get_dep('libc++').get_install_path()
- libcxxabi_dir = self.get_dep('libc++abi').get_install_path()
+ def install(self, out_dir, dist_dir, args):
+ install_dir = self.get_install_path(out_dir, args.system)
+ libcxx_dir = Libcxx().get_install_path(out_dir, args.system)
+ libcxxabi_dir = Libcxxabi().get_install_path(out_dir, args.system)
+
+ arches = build_support.ALL_ARCHITECTURES
+ if args.arch is not None:
+ arches = [args.arch]
libcxx_hdr_dir = os.path.join(install_dir, 'sysroot/usr/include/c++')
os.makedirs(libcxx_hdr_dir)
@@ -1666,7 +1681,7 @@ class Toolchain(ndk.builds.Module):
libcxxabi_inc_src = os.path.join(libcxxabi_dir, 'include')
copy_tree(libcxxabi_inc_src, libcxx_inc_dst)
- for arch in self.arches:
+ for arch in arches:
# We need to replace libgcc with linker scripts that also use
# libunwind on arm32. We already get libgcc from copying binutils,
# but re-install it so we get the linker scripts.
@@ -1675,7 +1690,7 @@ class Toolchain(ndk.builds.Module):
# libunwind isn't available until libc++ has been built.
for subarch in get_subarches(arch):
install_libgcc(
- install_dir, self.host, arch, subarch, new_layout=True)
+ install_dir, args.system, arch, subarch, new_layout=True)
triple = ndk.abis.arch_to_triple(arch)
abi, = ndk.abis.arch_to_abis(arch)
@@ -1695,11 +1710,11 @@ class Toolchain(ndk.builds.Module):
for lib in libs:
shutil.copy2(os.path.join(libcxx_lib_dir, lib), sysroot_dst)
- for api in self.get_dep('platforms').get_apis():
+ for api in Platforms().get_apis():
if api in Platforms.skip_apis:
continue
- for arch in self.get_dep('platforms').get_arches(api):
+ for arch in Platforms().get_arches(api):
triple = ndk.abis.arch_to_triple(arch)
dst_dir = os.path.join(install_dir, 'sysroot/usr/lib', triple,
str(api))
@@ -1810,9 +1825,9 @@ class NdkBuild(ndk.builds.PackageModule):
src = ndk.paths.ndk_path('build')
notice = ndk.paths.ndk_path('NOTICE')
- def install(self):
- super(NdkBuild, self).install()
- install_path = self.get_install_path()
+ def install(self, out_dir, dist_dir, args):
+ super(NdkBuild, self).install(out_dir, dist_dir, args)
+ install_path = self.get_install_path(out_dir, args.system)
abis_json = os.path.join(Meta.path, 'abis.json')
generate_language_specific_metadata(
@@ -1853,17 +1868,17 @@ class SimplePerf(ndk.builds.Module):
path = 'simpleperf'
notice = ndk.paths.android_path('prebuilts/simpleperf/NOTICE')
- def build(self):
+ def build(self, build_dir, dist_dir, args):
print('Building simpleperf...')
- install_dir = os.path.join(self.out_dir, 'simpleperf')
+ install_dir = os.path.join(build_dir, 'simpleperf')
if os.path.exists(install_dir):
shutil.rmtree(install_dir)
os.makedirs(install_dir)
simpleperf_path = ndk.paths.android_path('prebuilts/simpleperf')
dirs = ['doc', 'inferno', 'bin/android']
- is_win = self.host.startswith('windows')
- host_bin_dir = 'windows' if is_win else self.host
+ is_win = args.system.startswith('windows')
+ host_bin_dir = 'windows' if is_win else args.system
dirs.append(os.path.join('bin/', host_bin_dir))
for d in dirs:
shutil.copytree(os.path.join(simpleperf_path, d),
@@ -1883,7 +1898,7 @@ class SimplePerf(ndk.builds.Module):
shutil.copy2(os.path.join(simpleperf_path, item), install_dir)
shutil.copy2(os.path.join(simpleperf_path, 'ChangeLog'), install_dir)
- build_support.make_package('simpleperf', install_dir, self.dist_dir)
+ build_support.make_package('simpleperf', install_dir, dist_dir)
class RenderscriptLibs(ndk.builds.PackageModule):
@@ -1970,12 +1985,13 @@ class CanaryReadme(ndk.builds.Module):
path = 'README.canary'
no_notice = True
- def build(self):
+ def build(self, _out_dir, _dist_dir, _args):
pass
- def install(self):
+ def install(self, out_dir, _dist_dir, _args):
if ndk.config.canary:
- canary_path = self.get_install_path()
+ extract_dir = ndk.paths.get_install_path(out_dir)
+ canary_path = os.path.join(extract_dir, self.path)
with open(canary_path, 'w') as canary_file:
canary_file.write(CANARY_TEXT)
@@ -1999,13 +2015,14 @@ class SourceProperties(ndk.builds.Module):
path = 'source.properties'
no_notice = True
- def build(self):
+ def build(self, _out_dir, _dist_dir, _args):
pass
- def install(self):
- path = self.get_install_path()
+ def install(self, out_dir, _dist_dir, args):
+ install_dir = ndk.paths.get_install_path(out_dir)
+ path = os.path.join(install_dir, self.path)
with open(path, 'w') as source_properties:
- build = self.context.build_number
+ build = args.build_number
if build == 'dev':
build = '0'
version = '{}.{}.{}'.format(
@@ -2055,30 +2072,30 @@ def create_notice_file(path, for_group):
output_file.write(os.linesep.join(sorted(list(licenses))))
-def launch_build(worker, module, log_dir):
- result = do_build(worker, module, log_dir)
+def launch_build(worker, module, out_dir, dist_dir, args, log_dir):
+ result = do_build(worker, module, out_dir, dist_dir, args, log_dir)
if not result:
return result, module
- do_install(worker, module)
+ do_install(worker, module, out_dir, dist_dir, args)
return True, module
-def do_build(worker, module, log_dir):
+def do_build(worker, module, out_dir, dist_dir, args, log_dir):
with open(module.log_path(log_dir), 'w') as log_file:
os.dup2(log_file.fileno(), sys.stdout.fileno())
os.dup2(log_file.fileno(), sys.stderr.fileno())
try:
worker.status = 'Building {}...'.format(module)
- module.build()
+ module.build(out_dir, dist_dir, args)
return True
except Exception: # pylint: disable=broad-except
traceback.print_exc()
return False
-def do_install(worker, module):
+def do_install(worker, module, out_dir, dist_dir, args):
worker.status = 'Installing {}...'.format(module)
- module.install()
+ module.install(out_dir, dist_dir, args)
def split_module_by_arch(module, arches):
@@ -2297,7 +2314,8 @@ def log_build_failure(log_path, dist_dir):
error_log.write(contents)
-def launch_buildable(deps, workqueue, log_dir, skip_deps, skip_modules):
+def launch_buildable(deps, workqueue, out_dir, dist_dir, log_dir, args,
+ skip_modules):
# If args.skip_deps is true, we could get into a case where we just
# dequeued the only module that was still building and the only
# items in get_buildable() are modules that will be skipped.
@@ -2309,13 +2327,14 @@ def launch_buildable(deps, workqueue, log_dir, skip_deps, skip_modules):
# modules before we complete the loop.
while deps.buildable_modules:
for module in deps.get_buildable():
- if skip_deps and module in skip_modules:
+ if args.skip_deps and module in skip_modules:
deps.complete(module)
continue
- workqueue.add_task(launch_build, module, log_dir)
+ workqueue.add_task(
+ launch_build, module, out_dir, dist_dir, args, log_dir)
-def wait_for_build(deps, workqueue, dist_dir, log_dir, skip_deps,
+def wait_for_build(deps, workqueue, out_dir, dist_dir, log_dir, args,
skip_modules):
console = ndk.ansi.get_console()
ui = ndk.ui.get_build_progress_ui(console, workqueue)
@@ -2334,8 +2353,9 @@ def wait_for_build(deps, workqueue, dist_dir, log_dir, skip_deps,
print('Build succeeded: {}'.format(module))
deps.complete(module)
- launch_buildable(deps, workqueue, log_dir, skip_deps,
- skip_modules)
+ launch_buildable(
+ deps, workqueue, out_dir, dist_dir, log_dir, args,
+ skip_modules)
ui.draw()
ui.clear()
@@ -2343,30 +2363,23 @@ def wait_for_build(deps, workqueue, dist_dir, log_dir, skip_deps,
def build_ndk(modules, deps_only, out_dir, dist_dir, args):
- arches = build_support.ALL_ARCHITECTURES
- if args.arch is not None:
- arches = [args.arch]
-
- build_context = ndk.builds.BuildContext(
- out_dir, dist_dir, ALL_MODULES, args.system, arches, args.build_number)
-
- for module in modules:
- module.context = build_context
+ out_dir = os.path.join(out_dir, args.system)
+ deps = ndk.deps.DependencyManager(modules)
log_dir = os.path.join(dist_dir, 'logs')
if not os.path.exists(log_dir):
os.makedirs(log_dir)
- ndk_dir = ndk.paths.get_install_path(out_dir, args.system)
- if not os.path.exists(ndk_dir):
- os.makedirs(ndk_dir)
-
- deps = ndk.deps.DependencyManager(modules)
workqueue = ndk.workqueue.WorkQueue(args.jobs)
try:
- launch_buildable(deps, workqueue, log_dir, args.skip_deps, deps_only)
+ ndk_dir = ndk.paths.get_install_path(out_dir)
+ if not os.path.exists(ndk_dir):
+ os.makedirs(ndk_dir)
+
+ launch_buildable(
+ deps, workqueue, out_dir, dist_dir, log_dir, args, deps_only)
wait_for_build(
- deps, workqueue, dist_dir, log_dir, args.skip_deps, deps_only)
+ deps, workqueue, out_dir, dist_dir, log_dir, args, deps_only)
if deps.get_buildable():
raise RuntimeError(
@@ -2398,7 +2411,8 @@ def build_ndk_for_cross_compile(out_dir, arches, args):
def create_ndk_symlink(out_dir):
- this_host_ndk = ndk.paths.get_install_path()
+ this_host_out = os.path.join(out_dir, ndk.hosts.get_default_host())
+ this_host_ndk = ndk.paths.get_install_path(this_host_out)
ndk_symlink = os.path.join(out_dir, os.path.basename(this_host_ndk))
if not os.path.exists(ndk_symlink):
os.symlink(this_host_ndk, ndk_symlink)
diff --git a/ndk/builds.py b/ndk/builds.py
index c805b97ee..743dd6389 100644
--- a/ndk/builds.py
+++ b/ndk/builds.py
@@ -44,16 +44,6 @@ class NoticeGroup(object):
TOOLCHAIN = 2
-class BuildContext(object):
- def __init__(self, out_dir, dist_dir, modules, host, arches, build_number):
- self.out_dir = out_dir
- self.dist_dir = dist_dir
- self.modules = {m.name: m for m in modules}
- self.host = host
- self.arches = arches
- self.build_number = build_number
-
-
class Module(object):
name = None
path = None
@@ -87,7 +77,6 @@ class Module(object):
build_arch = None
def __init__(self):
- self.context = None
if self.notice is None:
self.notice = self.default_notice_path()
self.validate()
@@ -126,55 +115,30 @@ class Module(object):
raise self.validate_error(
'notice file {} does not exist'.format(notice))
- def get_dep(self, name):
- if name not in self.deps:
- raise KeyError
- return self.context.modules[name]
-
- def get_build_host_install(self, arch=None):
- return self.get_install_path(ndk.hosts.get_default_host(), arch)
-
- @property
- def out_dir(self):
- return self.context.out_dir
-
- @property
- def dist_dir(self):
- return self.context.dist_dir
-
- @property
- def host(self):
- return self.context.host
-
- @property
- def arches(self):
- return self.context.arches
-
- def build(self):
+ def build(self, build_dir, dist_dir, args):
raise NotImplementedError
- def install(self):
+ def install(self, out_dir, dist_dir, args):
+ arches = ndk.abis.ALL_ARCHITECTURES
+ if args.arch is not None:
+ arches = [args.arch]
package_installs = ndk.packaging.expand_packages(
- self.name, self.path, self.host, self.arches)
+ self.name, self.path, args.system, arches)
- install_base = ndk.paths.get_install_path(self.out_dir,
- self.host)
+ install_base = ndk.paths.get_install_path(out_dir)
for package_name, package_install in package_installs:
install_path = os.path.join(install_base, package_install)
- package = os.path.join(self.context.dist_dir, package_name)
+ package = os.path.join(dist_dir, package_name)
if os.path.exists(install_path):
shutil.rmtree(install_path)
ndk.packaging.extract_zip(package, install_path)
- def get_install_paths(self, host, arches):
+ def get_install_paths(self, build_dir, host, arches):
install_subdirs = ndk.packaging.expand_paths(self.path, host, arches)
- install_base = ndk.paths.get_install_path(self.out_dir, host)
+ install_base = ndk.paths.get_install_path(build_dir)
return [os.path.join(install_base, d) for d in install_subdirs]
- def get_install_path(self, host=None, arch=None):
- if host is None:
- host = self.host
-
+ def get_install_path(self, build_dir, host, arch=None):
arch_dependent = False
if ndk.packaging.package_varies_by(self.path, 'abi'):
arch_dependent = True
@@ -188,13 +152,11 @@ class Module(object):
arches = None
if arch is not None:
arches = [arch]
- elif self.build_arch is not None:
- arches = [self.build_arch]
elif arch_dependent:
raise ValueError(
'get_install_path for {} requires valid arch'.format(arch))
- install_subdirs = self.get_install_paths(host, arches)
+ install_subdirs = self.get_install_paths(build_dir, host, arches)
if len(install_subdirs) != 1:
raise RuntimeError(
@@ -252,12 +214,12 @@ class PackageModule(Module):
raise self.validate_error(
'PackageModule cannot vary by triple')
- def build(self):
+ def build(self, _build_dir, _dist_dir, _args):
pass
- def install(self):
- install_paths = self.get_install_paths(self.host,
- ndk.abis.ALL_ARCHITECTURES)
+ def install(self, out_dir, _dist_dir, args):
+ install_paths = self.get_install_paths(
+ out_dir, args.system, ndk.abis.ALL_ARCHITECTURES)
assert len(install_paths) == 1
install_path = install_paths[0]
install_directory(self.src, install_path)
@@ -269,24 +231,22 @@ class InvokeExternalBuildModule(Module):
script = None
arch_specific = False
- def build(self):
- build_args = common_build_args(self.out_dir, self.dist_dir, self.host)
+ def build(self, build_dir, dist_dir, args):
+ build_args = common_build_args(build_dir, dist_dir, args)
if self.split_build_by_arch:
build_args.append('--arch={}'.format(self.build_arch))
- elif self.arch_specific and len(self.arches) == 1:
- build_args.append('--arch={}'.format(self.arches[0]))
- elif self.arches == ndk.abis.ALL_ARCHITECTURES:
- pass
- else:
- raise NotImplementedError(
- 'Module {} can only build all architectures or none'.format(
- self.name))
+ elif self.arch_specific and args.arch is not None:
+ build_args.append('--arch={}'.format(args.arch))
+ build_args.extend(self.additional_args(args))
script = self.get_script_path()
invoke_external_build(script, build_args)
def get_script_path(self):
return ndk.paths.android_path(self.script)
+ def additional_args(self, _args): # pylint: disable=no-self-use
+ return []
+
class InvokeBuildModule(InvokeExternalBuildModule):
def get_script_path(self):
@@ -299,11 +259,15 @@ class FileModule(Module):
# Used for things like the readme and the changelog. No notice needed.
no_notice = True
- def build(self):
+ def build(self, _build_dir, _dist_dir, _args):
pass
- def install(self):
- shutil.copy2(self.src, self.get_install_path())
+ def install(self, out_dir, dist_dir, args):
+ install_base = ndk.paths.get_install_path(out_dir)
+ install_path = os.path.join(install_base, self.path)
+ if os.path.exists(install_path):
+ os.remove(install_path)
+ shutil.copy2(self.src, install_path)
class ScriptShortcutModule(Module):
@@ -332,32 +296,35 @@ class ScriptShortcutModule(Module):
raise self.validate_error(
'ScriptShortcutModule requires windows_ext')
- def build(self):
+ def build(self, _build_dir, _dist_dir, _args):
pass
- def install(self):
- if self.host.startswith('windows'):
- self.make_cmd_helper()
+ def install(self, out_dir, dist_dir, args):
+ if args.system.startswith('windows'):
+ self.make_cmd_helper(out_dir, args.system)
else:
- self.make_sh_helper()
+ self.make_sh_helper(out_dir, args.system)
- def make_cmd_helper(self):
- script = self.get_script_path()
+ def make_cmd_helper(self, out_dir, system):
+ script = self.get_script_path(system)
full_path = ntpath.join(
'%~dp0', ntpath.normpath(script) + self.windows_ext)
- install_path = self.get_install_path() + '.cmd'
+ install_base = ndk.paths.get_install_path(out_dir)
+ install_path = os.path.join(install_base, self.path) + '.cmd'
with open(os.path.join(install_path), 'w') as helper:
helper.writelines([
'@echo off\n',
full_path + ' %*\n',
])
- def make_sh_helper(self):
- script = self.get_script_path()
- full_path = os.path.join('$DIR', script)
+ def make_sh_helper(self, out_dir, system):
+ script = self.get_script_path(system)
+
+ install_base = ndk.paths.get_install_path(out_dir)
+ install_path = os.path.join(install_base, self.path)
- install_path = self.get_install_path()
+ full_path = os.path.join('$DIR', script)
with open(install_path, 'w') as helper:
helper.writelines([
'#!/bin/sh\n',
@@ -368,9 +335,9 @@ class ScriptShortcutModule(Module):
os.chmod(install_path,
mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
- def get_script_path(self):
+ def get_script_path(self, system):
scripts = ndk.packaging.expand_paths(
- self.script, self.host, ndk.abis.ALL_ARCHITECTURES)
+ self.script, system, ndk.abis.ALL_ARCHITECTURES)
assert len(scripts) == 1
return scripts[0]
@@ -380,12 +347,12 @@ class PythonPackage(Module):
# Assume there's a NOTICE file in the same directory as the setup.py.
return os.path.join(os.path.dirname(self.path), 'NOTICE')
- def build(self):
+ def build(self, build_dir, _dist_dir, _args):
cwd = os.path.dirname(self.path)
subprocess.check_call(
- ['python', self.path, 'sdist', '-d', self.out_dir], cwd=cwd)
+ ['python', self.path, 'sdist', '-d', build_dir], cwd=cwd)
- def install(self):
+ def install(self, _out_dir, _dist_dir, _args):
pass
@@ -404,11 +371,11 @@ def invoke_external_build(script, args=None):
_invoke_build(ndk.paths.android_path(script), args)
-def common_build_args(out_dir, dist_dir, host):
+def common_build_args(out_dir, dist_dir, args):
return [
'--out-dir={}'.format(out_dir),
'--dist-dir={}'.format(dist_dir),
- '--host={}'.format(host),
+ '--host={}'.format(args.system),
]
diff --git a/ndk/paths.py b/ndk/paths.py
index e2349235a..cd7251a85 100644
--- a/ndk/paths.py
+++ b/ndk/paths.py
@@ -85,7 +85,7 @@ def path_in_out(dirname, out_dir=None):
return os.path.join(out_dir, dirname)
-def get_install_path(out_dir=None, host=None):
+def get_install_path(out_dir=None):
"""Returns the built NDK install path.
Note that the path returned might not actually contain the NDK. The NDK may
@@ -98,15 +98,12 @@ def get_install_path(out_dir=None, host=None):
Args:
out_dir: Optional base out directory. Inferred from $OUT_DIR if not
supplied.
- host: Returns the install path for th given host.
Returns:
Directory that the built NDK should be installed to.
"""
- if host is None:
- host = ndk.hosts.get_default_host()
release_name = 'android-ndk-{}'.format(ndk.config.release)
- return path_in_out(os.path.join(host, release_name), out_dir)
+ return path_in_out(release_name, out_dir)
@contextlib.contextmanager