Merge changes Ice859e8e,I44915dcd
* changes:
Add typing info and documentation to ndk.builds.
Provide type annotations for ndk.paths.
diff --git a/bootstrap/__init__.py b/bootstrap/__init__.py
new file mode 100644
index 0000000..27e707d
--- /dev/null
+++ b/bootstrap/__init__.py
@@ -0,0 +1,231 @@
+#
+# Copyright (C) 2018 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.
+#
+"""Tools for bootstrapping Python 3."""
+import datetime
+import logging
+import multiprocessing
+import os
+import pipes
+import shutil
+import subprocess
+import sys
+import timeit
+
+
+THIS_DIR = os.path.realpath(os.path.dirname(__file__))
+
+
+def logger():
+ """Returns the module level logger."""
+ return logging.getLogger(__name__)
+
+
+def android_path(*args):
+ """Returns the absolute path rooted within the top level source tree."""
+ return os.path.normpath(os.path.join(THIS_DIR, '../..', *args))
+
+
+def _get_dir_from_env(default, env_var):
+ """Returns the path to a directory specified by the environment.
+
+ If the environment variable is not set, the default will be used. The
+ directory is created if it does not exist.
+
+ Args:
+ default: The path used if the environment variable is not set.
+ env_var: The environment variable that contains the path, if any.
+
+ Returns:
+ The absolute path to the directory.
+ """
+ path = os.path.realpath(os.getenv(env_var, default))
+ if not os.path.isdir(path):
+ os.makedirs(path)
+ return path
+
+
+def get_out_dir():
+ """Returns the out directory."""
+ return _get_dir_from_env(android_path('out'), 'OUT_DIR')
+
+
+def get_dist_dir():
+ """Returns the distribution directory.
+
+ The contents of the distribution directory are archived on the build
+ servers. Suitable for build logs and final artifacts.
+ """
+ return _get_dir_from_env(os.path.join(get_out_dir(), 'dist'), 'DIST_DIR')
+
+
+def path_in_out(dirname):
+ """Returns a path within the out directory."
+
+ Args:
+ dirname: Name of the directory.
+
+ Returns:
+ Absolute path within the out directory.
+ """
+ return os.path.join(get_out_dir(), dirname)
+
+
+def log_failure_and_exit(output):
+ """Logs the bootstrapping failure and exits.
+
+ Args:
+ output: Output of the failed command.
+ """
+ log_path = os.path.join(get_dist_dir(), 'logs/build_error.log')
+ with open(log_path, 'w') as error_log:
+ error_log.write('Bootstrapping failed!\n')
+ error_log.write(output)
+
+ logger().error(output)
+ sys.exit('Bootstrapping failed!')
+
+
+def check_output(cmd):
+ """Logged version of subprocess.check_output.
+
+ stderr is automatically forwarded to stdout.
+
+ Args:
+ cmd: argv style argument list for the process to be run.
+
+ Returns:
+ Output
+ """
+ logger().debug('Runnning: %s', ' '.join([pipes.quote(a) for a in cmd]))
+ return subprocess.check_output(cmd, stderr=subprocess.STDOUT)
+
+
+def build_python(install_dir, build_dir):
+ """Builds and installs Python to the given directory.
+
+ Args:
+ install_dir: Install path for the built Python distribution.
+ build_dir: Directory to use for building Python.
+ """
+ logger().info('Bootstrapping Python...')
+
+ if os.path.exists(build_dir):
+ shutil.rmtree(build_dir)
+ os.makedirs(build_dir)
+
+ old_cwd = os.getcwd()
+ try:
+ os.chdir(build_dir)
+
+ python_src = android_path('external/python/cpython3')
+ check_output([
+ os.path.join(python_src, 'configure'),
+ '--prefix=' + install_dir,
+
+ # This enables PGO and requires running all the Python tests to
+ # generate those profiles. If we end up repackaging this Python to
+ # ship in the NDK we should do this, but for now it makes
+ # bootstrapping take a lot longer and we don't need the perforance
+ # since our build time is dominated by non-Python code anyway.
+ # '--enable-optimizations',
+ ])
+
+ check_output([
+ 'make',
+ '-j',
+ str(multiprocessing.cpu_count()),
+ 'install',
+ ])
+ except subprocess.CalledProcessError as ex:
+ log_failure_and_exit(ex.output)
+ finally:
+ os.chdir(old_cwd)
+
+
+class Timer(object): # pylint: disable=useless-object-inheritance
+ """Execution timer.
+
+ Can be used explicitly with stop/start, but preferably is used as a context
+ manager:
+
+ >>> timer = Timer()
+ >>> with timer:
+ >>> do_something()
+ >>> print('do_something() took {}'.format(timer.duration))
+ """
+ def __init__(self):
+ self.start_time = None
+ self.end_time = None
+ self.duration = None
+
+ def start(self):
+ """Start the timer."""
+ self.start_time = timeit.default_timer()
+
+ def finish(self):
+ """Stop the timer."""
+ self.end_time = timeit.default_timer()
+
+ # Not interested in partial seconds at this scale.
+ seconds = int(self.end_time - self.start_time)
+ self.duration = datetime.timedelta(seconds=seconds)
+
+ def __enter__(self):
+ self.start()
+
+ def __exit__(self, _exc_type, _exc_value, _traceback):
+ self.finish()
+
+
+def do_bootstrap(install_dir):
+ """Helper function for bootstrapping.
+
+ Builds and installs Python 3 if necessary, but does not modify the
+ environment.
+
+ Args:
+ install_dir: Directory in which to install Python 3.
+
+ Returns:
+ Python 3 install directory.
+ """
+ build_dir = path_in_out('bootstrap-build')
+
+ bootstrap_completed_file = path_in_out('.bootstrapped')
+ if os.path.exists(bootstrap_completed_file):
+ return
+
+ timer = Timer()
+ with timer:
+ build_python(install_dir, build_dir)
+ # TODO: Install any desired site-packages?
+ logger().info('Bootstrapping completed in %s', timer.duration)
+
+ with open(bootstrap_completed_file, 'w'):
+ pass
+
+
+def bootstrap():
+ """Creates a bootstrap Python 3 environment.
+
+ Builds and installs Python 3 for use on the current host. After execution,
+ the directory containing the python3 binary will be the first element in
+ the PATH.
+ """
+ install_dir = path_in_out('bootstrap')
+ do_bootstrap(install_dir)
+ bootstrap_bin = os.path.join(install_dir, 'bin')
+ os.environ['PATH'] = os.pathsep.join([bootstrap_bin, os.environ['PATH']])
diff --git a/build/cmake/android.toolchain.cmake b/build/cmake/android.toolchain.cmake
index 1b03647..f568453 100644
--- a/build/cmake/android.toolchain.cmake
+++ b/build/cmake/android.toolchain.cmake
@@ -407,10 +407,10 @@
set(CMAKE_CXX_COMPILER_ID_RUN TRUE)
set(CMAKE_C_COMPILER_ID Clang)
set(CMAKE_CXX_COMPILER_ID Clang)
-set(CMAKE_C_COMPILER_VERSION 7.0)
-set(CMAKE_CXX_COMPILER_VERSION 7.0)
+set(CMAKE_C_COMPILER_VERSION 8.0)
+set(CMAKE_CXX_COMPILER_VERSION 8.0)
set(CMAKE_C_STANDARD_COMPUTED_DEFAULT 11)
-set(CMAKE_CXX_STANDARD_COMPUTED_DEFAULT 98)
+set(CMAKE_CXX_STANDARD_COMPUTED_DEFAULT 14)
set(CMAKE_C_COMPILER_TARGET ${ANDROID_LLVM_TRIPLE})
set(CMAKE_CXX_COMPILER_TARGET ${ANDROID_LLVM_TRIPLE})
set(CMAKE_ASM_COMPILER_TARGET ${ANDROID_LLVM_TRIPLE})
@@ -466,7 +466,6 @@
# STL specific flags.
if(ANDROID_STL MATCHES "^c\\+\\+_")
- list(APPEND ANDROID_COMPILER_FLAGS_CXX "-std=c++11")
if(ANDROID_ABI MATCHES "^armeabi")
list(APPEND ANDROID_LINKER_FLAGS "-Wl,--exclude-libs,libunwind.a")
endif()
diff --git a/build/tools/make_standalone_toolchain.py b/build/tools/make_standalone_toolchain.py
index 3978d6b..0849cdc 100755
--- a/build/tools/make_standalone_toolchain.py
+++ b/build/tools/make_standalone_toolchain.py
@@ -121,7 +121,7 @@
arch = 'armv7a' # Target armv7, not armv5.
target = '-'.join([arch, 'none', os_name, env])
- flags = '-target {}{} -stdlib=libc++'.format(target, api)
+ flags = '-target {}{}'.format(target, api)
# We only need mstackrealign to fix issues on 32-bit x86 pre-24. After 24,
# this consumes an extra register unnecessarily, which can cause issues for
@@ -130,6 +130,8 @@
if arch == 'i686' and api < 24:
flags += ' -mstackrealign'
+ cxx_flags = flags + ' -stdlib=libc++'
+
clang_path = os.path.join(install_dir, 'bin/clang')
with open(clang_path, 'w') as clang:
clang.write(textwrap.dedent("""\
@@ -155,7 +157,7 @@
# target/triple already spelled out.
`dirname $0`/clang{version}++ "$@"
fi
- """.format(version=version_number, flags=flags)))
+ """.format(version=version_number, flags=cxx_flags)))
mode = os.stat(clangpp_path).st_mode
os.chmod(clangpp_path, mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
@@ -167,6 +169,7 @@
if windows:
for pp_suffix in ('', '++'):
+ is_cpp = pp_suffix == '++'
exe_name = 'clang{}{}.exe'.format(version_number, pp_suffix)
clangbat_text = textwrap.dedent("""\
@echo off
@@ -191,7 +194,7 @@
exit /b
:done
- """.format(exe=exe_name, flags=flags))
+ """.format(exe=exe_name, flags=cxx_flags if is_cpp else flags))
for triple_prefix in ('', triple + '-'):
clangbat_path = os.path.join(
diff --git a/build/tools/prebuilt-common.sh b/build/tools/prebuilt-common.sh
index 5d57227..b3c6a01 100644
--- a/build/tools/prebuilt-common.sh
+++ b/build/tools/prebuilt-common.sh
@@ -1247,7 +1247,7 @@
{
local NAME DIR BINPREFIX
local SYSTEM=${1:-$(get_prebuilt_host_tag)}
- local VERSION=r339409b
+ local VERSION=r344140b
SYSTEM=${SYSTEM%_64} # Trim _64 suffix. We only have one LLVM.
BINPREFIX=$ANDROID_BUILD_TOP/prebuilts/clang/host/$SYSTEM/clang-$VERSION/bin
echo "$BINPREFIX"
diff --git a/checkbuild.py b/checkbuild.py
index 25b29c0..da676df 100755
--- a/checkbuild.py
+++ b/checkbuild.py
@@ -20,214 +20,17 @@
allowing this script to bootstrap our build with a specific version of Python.
"""
import argparse
-import datetime
import logging
-import multiprocessing
import os
-import pipes
-import shutil
import subprocess
import sys
-import timeit
+
+from bootstrap import bootstrap
THIS_DIR = os.path.realpath(os.path.dirname(__file__))
-def logger():
- """Returns the module level logger."""
- return logging.getLogger(__name__)
-
-
-def android_path(*args):
- """Returns the absolute path rooted within the top level source tree."""
- return os.path.normpath(os.path.join(THIS_DIR, '..', *args))
-
-
-def ndk_path(*args):
- """Returns the absolute path rooted within the NDK source tree."""
- return android_path('ndk', *args)
-
-
-def _get_dir_from_env(default, env_var):
- """Returns the path to a directory specified by the environment.
-
- If the environment variable is not set, the default will be used. The
- directory is created if it does not exist.
-
- Args:
- default: The path used if the environment variable is not set.
- env_var: The environment variable that contains the path, if any.
-
- Returns:
- The absolute path to the directory.
- """
- path = os.path.realpath(os.getenv(env_var, default))
- if not os.path.isdir(path):
- os.makedirs(path)
- return path
-
-
-def get_out_dir():
- """Returns the out directory."""
- return _get_dir_from_env(android_path('out'), 'OUT_DIR')
-
-
-def get_dist_dir():
- """Returns the distribution directory.
-
- The contents of the distribution directory are archived on the build
- servers. Suitable for build logs and final artifacts.
- """
- return _get_dir_from_env(os.path.join(get_out_dir(), 'dist'), 'DIST_DIR')
-
-
-def path_in_out(dirname):
- """Returns a path within the out directory."
-
- Args:
- dirname: Name of the directory.
-
- Returns:
- Absolute path within the out directory.
- """
- return os.path.join(get_out_dir(), dirname)
-
-
-def log_failure_and_exit(output):
- """Logs the bootstrapping failure and exits.
-
- Args:
- output: Output of the failed command.
- """
- log_path = os.path.join(get_dist_dir(), 'logs/build_error.log')
- with open(log_path, 'w') as error_log:
- error_log.write('Bootstrapping failed!\n')
- error_log.write(output)
-
- logger().error(output)
- sys.exit('Bootstrapping failed!')
-
-
-def check_output(cmd):
- """Logged version of subprocess.check_output.
-
- stderr is automatically forwarded to stdout.
-
- Args:
- cmd: argv style argument list for the process to be run.
-
- Returns:
- Output
- """
- logger().debug('Runnning: %s', ' '.join([pipes.quote(a) for a in cmd]))
- return subprocess.check_output(cmd, stderr=subprocess.STDOUT)
-
-
-def build_python(install_dir, build_dir):
- """Builds and installs Python to the given directory.
-
- Args:
- install_dir: Install path for the built Python distribution.
- build_dir: Directory to use for building Python.
- """
- logger().info('Bootstrapping Python...')
-
- if os.path.exists(build_dir):
- shutil.rmtree(build_dir)
- os.makedirs(build_dir)
-
- old_cwd = os.getcwd()
- try:
- os.chdir(build_dir)
-
- python_src = android_path('external/python/cpython3')
- check_output([
- os.path.join(python_src, 'configure'),
- '--prefix=' + install_dir,
-
- # This enables PGO and requires running all the Python tests to
- # generate those profiles. If we end up repackaging this Python to
- # ship in the NDK we should do this, but for now it makes
- # bootstrapping take a lot longer and we don't need the perforance
- # since our build time is dominated by non-Python code anyway.
- # '--enable-optimizations',
- ])
-
- check_output([
- 'make',
- '-j',
- str(multiprocessing.cpu_count()),
- 'install',
- ])
- except subprocess.CalledProcessError as ex:
- log_failure_and_exit(ex.output)
- finally:
- os.chdir(old_cwd)
-
-
-class Timer(object): # pylint: disable=useless-object-inheritance
- """Execution timer.
-
- Can be used explicitly with stop/start, but preferably is used as a context
- manager:
-
- >>> timer = Timer()
- >>> with timer:
- >>> do_something()
- >>> print('do_something() took {}'.format(timer.duration))
- """
- def __init__(self):
- self.start_time = None
- self.end_time = None
- self.duration = None
-
- def start(self):
- """Start the timer."""
- self.start_time = timeit.default_timer()
-
- def finish(self):
- """Stop the timer."""
- self.end_time = timeit.default_timer()
-
- # Not interested in partial seconds at this scale.
- seconds = int(self.end_time - self.start_time)
- self.duration = datetime.timedelta(seconds=seconds)
-
- def __enter__(self):
- self.start()
-
- def __exit__(self, _exc_type, _exc_value, _traceback):
- self.finish()
-
-
-def bootstrap():
- """Bootstraps the NDK's build.
-
- Builds the Python distribution needed for building the NDK.
-
- Returns:
- Install directory for the built Python distribution.
- """
- install_dir = path_in_out('bootstrap')
- build_dir = path_in_out('bootstrap-build')
-
- bootstrap_completed_file = path_in_out('.bootstrapped')
- if os.path.exists(bootstrap_completed_file):
- return install_dir
-
- timer = Timer()
- with timer:
- build_python(install_dir, build_dir)
- # TODO: Install any desired site-packages?
- logger().info('Bootstrapping completed in %s', timer.duration)
-
- with open(bootstrap_completed_file, 'w'):
- pass
-
- return install_dir
-
-
def parse_args():
"""Parses and returns command line arguments."""
parser = argparse.ArgumentParser()
@@ -253,11 +56,9 @@
else:
logging.basicConfig(level=logging.INFO)
- python_install = bootstrap()
- bootstrap_bin = os.path.join(python_install, 'bin')
- os.environ['PATH'] = os.pathsep.join([bootstrap_bin, os.environ['PATH']])
- subprocess.check_call(['python3', ndk_path('do_checkbuild.py')] +
- sys.argv[1:])
+ bootstrap()
+ subprocess.check_call(
+ ['python3', os.path.join(THIS_DIR, 'do_checkbuild.py')] + sys.argv[1:])
if __name__ == '__main__':
diff --git a/docs/changelogs/Changelog-r19.md b/docs/changelogs/Changelog-r19.md
index 98c754e..d4a5e2e 100644
--- a/docs/changelogs/Changelog-r19.md
+++ b/docs/changelogs/Changelog-r19.md
@@ -54,6 +54,7 @@
-------
* Updated Clang to r339409.
+ * C++ compilation now defaults to C++14.
* [Issue 780]: A complete NDK toolchain is now installed to the Clang
directory. See the announcements section for more information.
* ndk-build no longer removes artifacts from `NDK_LIBS_OUT` for ABIs not
diff --git a/docs/changelogs/Changelog-r20.md b/docs/changelogs/Changelog-r20.md
index a9a0db4..6b95c4f 100644
--- a/docs/changelogs/Changelog-r20.md
+++ b/docs/changelogs/Changelog-r20.md
@@ -20,6 +20,8 @@
## Changes
+ * Updated Clang to r344140.
+
## Known Issues
* This is not intended to be a comprehensive list of all outstanding bugs.
diff --git a/ndk/checkbuild.py b/ndk/checkbuild.py
index a44e029..4444006 100755
--- a/ndk/checkbuild.py
+++ b/ndk/checkbuild.py
@@ -227,7 +227,7 @@
class Clang(ndk.builds.Module):
name = 'clang'
path = 'toolchains/llvm/prebuilt/{host}'
- version = 'clang-r339409b'
+ version = 'clang-r344140b'
notice_group = ndk.builds.NoticeGroup.TOOLCHAIN
@property