diff options
author | Dan Albert <danalbert@google.com> | 2019-03-08 16:25:32 -0800 |
---|---|---|
committer | Haibo Huang <hhb@google.com> | 2019-08-20 14:59:27 -0700 |
commit | 61f17259c4323dcd18c4fd27a0d174b432e5172a (patch) | |
tree | 58b6f094baed59a20f1cf9b79c6fd3f3158ce479 | |
parent | fe5512b37fbef472db20f4ae237ec8f761d09cfb (diff) | |
download | ndk-61f17259c4323dcd18c4fd27a0d174b432e5172a.tar.gz |
Move GDB out of HostTools.
Test: ./checkbuild.py gdb
Test: ./checkbuild.py --system windows gdb
Test: ./checkbuild.py --system windows64 gdb
Test: cd samples/NdkGdbSample && \
./gradlew installDebug && \
$NDK/ndk-gdb --launch
Bug: http://b/62547070
Change-Id: I4e2472de84f1ca475f9235dc983fb61e261701a9
-rwxr-xr-x | build/tools/build-gdb-stub.sh | 81 | ||||
-rw-r--r-- | ndk/autoconf.py | 17 | ||||
-rwxr-xr-x | ndk/checkbuild.py | 209 | ||||
-rw-r--r-- | sources/host-tools/gdb-stub/gdb-stub.c | 17 |
4 files changed, 213 insertions, 111 deletions
diff --git a/build/tools/build-gdb-stub.sh b/build/tools/build-gdb-stub.sh deleted file mode 100755 index 2dfd6434d..000000000 --- a/build/tools/build-gdb-stub.sh +++ /dev/null @@ -1,81 +0,0 @@ -#!/bin/bash - -NDK_BUILDTOOLS_PATH="$(dirname $0)" -. "$NDK_BUILDTOOLS_PATH/prebuilt-common.sh" -. "$NDK_BUILDTOOLS_PATH/common-build-host-funcs.sh" - -PROGRAM_PARAMETERS="" -PROGRAM_DESCRIPTION="\ -This program is used to build the gdb stub for Windows and replace a -gdb executable with it. Because of the replacing nature of this, I -check to see if there's a gdb-orig.exe there already and if so, 'undo' -the process first by putting it back. Sample usage: - -$0 --gdb-executable-path=\$NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/bin/arm-linux-androideabi-gdb.exe \\ - --python-prefix-dir=\$NDK/prebuilt/windows \\ - --mingw-w64-gcc-path=\$HOME/i686-w64-mingw32/bin/i686-w64-mingw32-gcc -" - -NDK_DIR=$ANDROID_NDK_ROOT - -PYTHON_PREFIX_DIR= -register_var_option "--python-prefix-dir=<path>" PYTHON_PREFIX_DIR "Python prefix directory." - -GDB_EXECUTABLE_PATH= -register_var_option "--gdb-executable-path=<path>" GDB_EXECUTABLE_PATH "GDB executable file to stubify." - -MINGW_W64_GCC= -register_var_option "--mingw-w64-gcc=<program>" MINGW_W64_GCC "MinGW-w64 gcc program to use." - -DEBUG_STUB= -register_var_option "--debug" DEBUG_STUB "Build stub in debug mode." - -extract_parameters "$@" - -if [ -n "$DEBUG_STUB" ]; then - STUB_CFLAGS="-O0 -g -D_DEBUG" -else - STUB_CFLAGS="-O2 -s -DNDEBUG" -fi - -if [ ! -f "$GDB_EXECUTABLE_PATH" ]; then - panic "GDB executable $GDB_EXECUTABLE_PATH doesn't exist!" -fi - -if [ ! -d "$PYTHON_PREFIX_DIR" ]; then - panic "Python prefix dir $PYTHON_PREFIX_DIR doesn't exist!" -fi - -if [ -z "$MINGW_W64_GCC" ]; then - panic "Please specify an existing MinGW-w64 cross compiler with --mingw-w64-gcc=<program>" -fi - -GDB_BIN_DIR=$(cd $(dirname "$GDB_EXECUTABLE_PATH"); pwd) -PYTHON_PREFIX_DIR=$(cd "$PYTHON_PREFIX_DIR"; pwd) -PYTHON_BIN_DIR=${PYTHON_PREFIX_DIR}/bin - -# Sed is used to get doubled up Windows style dir separators. -GDB_TO_PYTHON_REL_DIR=$(relpath "$GDB_BIN_DIR" "$PYTHON_BIN_DIR" | sed -e s./.\\\\\\\\.g) -PYTHONHOME_REL_DIR=$(relpath "$GDB_BIN_DIR" "$PYTHON_PREFIX_DIR" | sed -e s./.\\\\\\\\.g) -dump "GDB_TO_PYTHON_REL_DIR=$GDB_TO_PYTHON_REL_DIR" -dump "PYTHONHOME_REL_DIR=$PYTHONHOME_REL_DIR" - -GDB_EXECUTABLE_ORIG=$(dirname "$GDB_EXECUTABLE_PATH")/$(basename "$GDB_EXECUTABLE_PATH" ".exe")-orig.exe -if [ -f "$GDB_EXECUTABLE_ORIG" ] ; then - echo "Warning : Found an existing gdb-stub called $GDB_EXECUTABLE_ORIG so will un-do a previous run of this script." - cp "$GDB_EXECUTABLE_ORIG" "$GDB_EXECUTABLE_PATH" -fi -cp "$GDB_EXECUTABLE_PATH" "$GDB_EXECUTABLE_ORIG" - -GDB_EXECUTABLE_ORIG_FILENAME=$(basename "$GDB_EXECUTABLE_ORIG") - -# Build the stub in-place of the real gdb. -run $MINGW_W64_GCC $STUB_CFLAGS "$NDK_DIR/sources/host-tools/gdb-stub/gdb-stub.c" \ - -o "$GDB_EXECUTABLE_PATH" \ - -DGDB_TO_PYTHON_REL_DIR=\"$GDB_TO_PYTHON_REL_DIR\" \ - -DPYTHONHOME_REL_DIR=\"$PYTHONHOME_REL_DIR\" \ - -DGDB_EXECUTABLE_ORIG_FILENAME=\"$GDB_EXECUTABLE_ORIG_FILENAME\" - -fail_panic "Can't build gdb stub!" - -dump "GDB Stub done!" diff --git a/ndk/autoconf.py b/ndk/autoconf.py index edd447540..0c9e98895 100644 --- a/ndk/autoconf.py +++ b/ndk/autoconf.py @@ -144,21 +144,14 @@ class AutoconfBuilder: automatically. """ with self.cd(): - build_host_args: List[str] - if self.no_build_or_host: - build_host_args = [] - else: - build_triple = HOST_TRIPLE_MAP[get_default_host()] - host_triple = HOST_TRIPLE_MAP[self.host] - build_host_args = [ - f'--build={build_triple}', - f'--host={host_triple}', - ] - + build_triple = HOST_TRIPLE_MAP[get_default_host()] + host_triple = HOST_TRIPLE_MAP[self.host] configure_args = [ str(self.configure_script), f'--prefix={self.install_directory}', - ] + build_host_args + args + f'--build={build_triple}', + f'--host={host_triple}', + ] + args flags_str = ' '.join(self.toolchain.flags + self.flags) cc = f'{self.toolchain.cc} {flags_str}' diff --git a/ndk/checkbuild.py b/ndk/checkbuild.py index f6dd4011f..b2ef56e89 100755 --- a/ndk/checkbuild.py +++ b/ndk/checkbuild.py @@ -67,6 +67,7 @@ from build.lib import build_support import ndk.abis from ndk.autoconf import AutoconfBuilder import ndk.ansi +import ndk.autoconf import ndk.builds import ndk.config import ndk.deps @@ -603,7 +604,6 @@ class HostTools(ndk.builds.Module): @property def notices(self) -> List[str]: return [ - ndk.paths.android_path('toolchain/gdb/gdb-7.11/COPYING'), ndk.paths.android_path('toolchain/python/Python-2.7.5/LICENSE'), str(self.make_src / 'COPYING'), ndk.paths.ndk_path('sources/host-tools/toolbox/NOTICE'), @@ -646,9 +646,6 @@ class HostTools(ndk.builds.Module): ndk.builds.invoke_external_build( 'toolchain/python/build.py', build_args) - print('Building GDB...') - ndk.builds.invoke_external_build('toolchain/gdb/build.py', build_args) - print('Building YASM...') ndk.builds.invoke_external_build('toolchain/yasm/build.py', build_args) @@ -657,7 +654,6 @@ class HostTools(ndk.builds.Module): ndk.ext.shutil.create_directory(install_dir) packages = [ - 'gdb-multiarch-7.11', 'ndk-python', 'ndk-yasm', ] @@ -1114,6 +1110,208 @@ class Platforms(ndk.builds.Module): 'This file forces git to keep the directory.') +class Gdb(ndk.builds.Module): + """Module for multi-arch host GDB. + + Note that the device side, gdbserver, is a separate module because it needs + to be cross compiled for all four Android ABIs. + """ + + name = 'gdb' + path = 'prebuilt/{host}' + + deps = { + 'host-tools', + } + + GDB_VERSION = '7.11' + + expat_src = ndk.paths.ANDROID_DIR / 'toolchain/expat/expat-2.0.1' + lzma_src = ndk.paths.ANDROID_DIR / 'toolchain/xz' + gdb_src = ndk.paths.ANDROID_DIR / f'toolchain/gdb/gdb-{GDB_VERSION}' + + notice_group = ndk.builds.NoticeGroup.TOOLCHAIN + + _expat_builder: Optional[ndk.autoconf.AutoconfBuilder] = None + _lzma_builder: Optional[ndk.autoconf.AutoconfBuilder] = None + _gdb_builder: Optional[ndk.autoconf.AutoconfBuilder] = None + + @property + def notices(self) -> List[str]: + return [ + str(self.expat_src / 'COPYING'), + str(self.gdb_src / 'COPYING'), + str(self.lzma_src / 'COPYING'), + ] + + @property + def intermediate_out_dir(self) -> Path: + """Path for intermediate outputs of this module.""" + return Path(self.out_dir) / self.host.value / 'gdb' + + @property + def expat_builder(self) -> ndk.autoconf.AutoconfBuilder: + """Returns the lazily initialized expat builder for this module.""" + if self._expat_builder is None: + self._expat_builder = ndk.autoconf.AutoconfBuilder( + self.expat_src / 'configure', + self.intermediate_out_dir / 'expat', self.host) + return self._expat_builder + + @property + def lzma_builder(self) -> ndk.autoconf.AutoconfBuilder: + """Returns the lazily initialized lzma builder for this module.""" + if self._lzma_builder is None: + self._lzma_builder = ndk.autoconf.AutoconfBuilder( + self.lzma_src / 'configure', + self.intermediate_out_dir / 'lzma', + self.host, + add_toolchain_to_path=True) + return self._lzma_builder + + @property + def gdb_builder(self) -> ndk.autoconf.AutoconfBuilder: + """Returns the lazily initialized gdb builder for this module.""" + if self._gdb_builder is None: + self._gdb_builder = ndk.autoconf.AutoconfBuilder( + self.gdb_src / 'configure', + self.intermediate_out_dir / 'gdb', self.host) + return self._gdb_builder + + @property + def gdb_stub_install_path(self) -> Path: + """The gdb stub install path.""" + return self.gdb_builder.install_directory / 'bin/gdb-stub' + + def build_expat(self) -> None: + """Builds the expat dependency.""" + self.expat_builder.build([ + '--disable-shared', + '--enable-static', + ]) + + def build_lzma(self) -> None: + """Builds the liblzma dependency.""" + self.lzma_builder.build([ + '--disable-shared', + '--enable-static', + '--disable-xz', + '--disable-xzdec', + '--disable-lzmadev', + '--disable-scripts', + '--disable-doc', + ]) + + def build_gdb(self) -> None: + """Builds GDB itself.""" + targets = ' '.join(ndk.abis.ALL_TRIPLES) + # TODO: Cleanup Python module so we don't need this explicit path. + python_config = (Path( + self.out_dir) / self.host.value / 'python' / ndk.hosts.host_to_tag( + self.host) / 'install/host-tools/bin/python-config.sh') + configure_args = [ + '--with-expat', + f'--with-libexpat-prefix={self.expat_builder.install_directory}', + f'--with-python={python_config}', + f'--enable-targets={targets}', + '--disable-shared', + '--disable-werror', + '--disable-nls', + '--disable-docs', + '--without-mpc', + '--without-mpfr', + '--without-gmp', + '--without-isl', + '--disable-sim', + '--enable-gdbserver=no', + ] + + configure_args.extend([ + '--with-lzma', + f'--with-liblzma-prefix={self.lzma_builder.install_directory}', + ]) + + self.gdb_builder.build(configure_args) + + def build_gdb_stub(self) -> None: + """Builds a gdb wrapper to setup PYTHONHOME. + + We need to use gdb with the Python it was built against, so we need to + setup PYTHONHOME to point to the NDK's Python, not the host's. + """ + if self.host.is_windows: + # TODO: Does it really need to be an executable? + # It's probably an executable because the original author wanted a + # .exe rather than a .cmd. Not sure how disruptive this change + # would be now. Presumably hardly at all because everyone needs to + # use ndk-gdb for reasonable behavior anyway? + self.build_exe_gdb_stub() + else: + self.build_sh_gdb_stub() + + def build_exe_gdb_stub(self) -> None: + # Don't need to worry about extension here because it'll be renamed on + # install anyway. + gdb_stub_path = self.gdb_builder.install_directory / 'bin/gdb-stub' + stub_src = ndk.paths.NDK_DIR / 'sources/host-tools/gdb-stub/gdb-stub.c' + mingw_path = (ndk.paths.ANDROID_DIR / + 'prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8/bin' + / 'x86_64-w64-mingw32-gcc') + + cmd = [ + str(mingw_path), + '-O2', + '-s', + '-DNDEBUG', + str(stub_src), + '-o', + str(gdb_stub_path), + ] + pp_cmd = ' '.join([pipes.quote(arg) for arg in cmd]) + print('Running: {}'.format(pp_cmd)) + subprocess.run(cmd, check=True) + + def build_sh_gdb_stub(self) -> None: + self.gdb_stub_install_path.write_text( + textwrap.dedent("""\ + #!/bin/bash + GDBDIR=$(cd $(dirname $0) && pwd) + PYTHONHOME="$GDBDIR/.." "$GDBDIR/gdb-orig" "$@" + """)) + self.gdb_stub_install_path.chmod(0o755) + + def build(self) -> None: + """Builds GDB.""" + if self.intermediate_out_dir.exists(): + shutil.rmtree(self.intermediate_out_dir) + + self.build_expat() + self.build_lzma() + self.build_gdb() + self.build_gdb_stub() + + def install(self) -> None: + """Installs GDB.""" + install_dir = Path(self.get_install_path()) + copy_tree( + str(self.gdb_builder.install_directory / 'bin'), + str(install_dir / 'bin')) + gdb_share_dir = self.gdb_builder.install_directory / 'share/gdb' + gdb_share_install_dir = install_dir / 'share/gdb' + if gdb_share_install_dir.exists(): + shutil.rmtree(gdb_share_install_dir) + shutil.copytree(gdb_share_dir, gdb_share_install_dir) + + # gdb is currently gdb(.exe)? and the gdb stub is currently gdb-stub. + # Make them gdb-orig(.exe)? and gdb(.exe)? respectively. + exe_suffix = '.exe' if self.host.is_windows else '' + gdb_exe = install_dir / ('bin/gdb' + exe_suffix) + gdb_exe.rename(install_dir / ('bin/gdb-orig' + exe_suffix)) + + gdb_stub = install_dir / 'bin/gdb-stub' + gdb_stub.rename(install_dir / ('bin/gdb' + exe_suffix)) + + class LibShaderc(ndk.builds.Module): name = 'libshaderc' path = 'sources/third_party/shaderc' @@ -2299,6 +2497,7 @@ ALL_MODULES = [ Changelog(), Clang(), CpuFeatures(), + Gdb(), GdbServer(), Gtest(), HostTools(), diff --git a/sources/host-tools/gdb-stub/gdb-stub.c b/sources/host-tools/gdb-stub/gdb-stub.c index edb76cb33..49c6fc321 100644 --- a/sources/host-tools/gdb-stub/gdb-stub.c +++ b/sources/host-tools/gdb-stub/gdb-stub.c @@ -43,21 +43,12 @@ #define dbg_printf(...) do {} while(0) #endif -// When built for the Android NDK, values are -// passed in on the GCC commandline, and when -// built for mingw-builds, these defaults are -// used. -#ifndef GDB_TO_PYTHON_REL_DIR - #define GDB_TO_PYTHON_REL_DIR "..\\opt\\bin" -#endif +#define GDB_TO_PYTHON_REL_DIR "." -#ifndef GDB_EXECUTABLE_ORIG_FILENAME - #define GDB_EXECUTABLE_ORIG_FILENAME "gdborig.exe" -#endif +#define GDB_EXECUTABLE_ORIG_FILENAME "gdb-orig.exe" -#ifndef PYTHONHOME_REL_DIR - #define PYTHONHOME_REL_DIR "..\\opt" -#endif +// The stub is installed to $PREBUILTS/bin, PYTHONHOME is $PREBUILTS. +#define PYTHONHOME_REL_DIR ".." #define DIE_IF_FALSE(var) \ do { \ |