aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build/cmake/android.toolchain.cmake18
-rw-r--r--build/core/build-binary.mk20
-rw-r--r--docs/BuildSystemMaintainers.md56
-rw-r--r--docs/changelogs/Changelog-r22.md20
-rwxr-xr-xndk/checkbuild.py46
-rw-r--r--ndk/test/test_devices.py2
-rw-r--r--ndk/testing/standalone_toolchain.py13
-rw-r--r--ndk/toolchains.py2
8 files changed, 128 insertions, 49 deletions
diff --git a/build/cmake/android.toolchain.cmake b/build/cmake/android.toolchain.cmake
index 48a29bd74..1f6302bb2 100644
--- a/build/cmake/android.toolchain.cmake
+++ b/build/cmake/android.toolchain.cmake
@@ -342,8 +342,12 @@ set(ANDROID_COMPILER_FLAGS_RELEASE)
set(ANDROID_LINKER_FLAGS)
set(ANDROID_LINKER_FLAGS_EXE)
-if(ANDROID_LD STREQUAL lld)
- list(APPEND ANDROID_LINKER_FLAGS -fuse-ld=lld)
+if(ANDROID_LD STREQUAL deprecated)
+ if(ANDROID_ABI STREQUAL arm64-v8a)
+ list(APPEND ANDROID_LINKER_FLAGS -fuse-ld=bfd)
+ else()
+ list(APPEND ANDROID_LINKER_FLAGS -fuse-ld=gold)
+ endif()
endif()
# Don't re-export libgcc symbols in every binary.
@@ -468,12 +472,12 @@ list(APPEND ANDROID_COMPILER_FLAGS
# default hash ("fast").
#
# Note that because we cannot see the user's flags, we can't detect this very
-# accurately. Users that explicitly use -fuse-ld=lld instead of ANDROID_LD will
-# not be able to debug.
-if(ANDROID_LD STREQUAL lld)
- list(APPEND ANDROID_LINKER_FLAGS -Wl,--build-id=sha1)
-else()
+# accurately. Users that explicitly use -fuse-ld=bfd instead of ANDROID_LD will
+# have broken builds.
+if(ANDROID_LD STREQUAL deprecated)
list(APPEND ANDROID_LINKER_FLAGS -Wl,--build-id)
+else()
+ list(APPEND ANDROID_LINKER_FLAGS -Wl,--build-id=sha1)
endif()
list(APPEND ANDROID_LINKER_FLAGS -Wl,--fatal-warnings)
diff --git a/build/core/build-binary.mk b/build/core/build-binary.mk
index 7aaba38e2..bab405240 100644
--- a/build/core/build-binary.mk
+++ b/build/core/build-binary.mk
@@ -496,23 +496,25 @@ CLEAN_OBJS_DIRS += $(LOCAL_OBJS_DIR)
#
linker_ldflags :=
-using_lld := false
-ifeq ($(APP_LD),lld)
- linker_ldflags := -fuse-ld=lld
- using_lld := true
+using_lld := true
+ifeq ($(APP_LD),deprecated)
+ ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
+ linker_ldflags := -fuse-ld=bfd
+ else
+ linker_ldflags := -fuse-ld=gold
+ endif
+ using_lld := false
endif
combined_ldflags := $(TARGET_LDFLAGS) $(NDK_APP_LDFLAGS) $(LOCAL_LDFLAGS)
ndk_fuse_ld_flags := $(filter -fuse-ld=%,$(combined_ldflags))
ndk_used_linker := $(lastword $(ndk_fuse_ld_flags))
ifeq ($(ndk_used_linker),-fuse-ld=lld)
+ # In case the user has set APP_LD=deprecated but also enabled it for a
+ # specific module.
using_lld := true
else
- # In case the user has set APP_LD=lld but also disabled it for a specific
- # module.
- ifneq ($(ndk_used_linker),)
- using_lld := false
- endif
+ using_lld := false
endif
# https://github.com/android/ndk/issues/885
diff --git a/docs/BuildSystemMaintainers.md b/docs/BuildSystemMaintainers.md
index 922d84405..b2b057ce4 100644
--- a/docs/BuildSystemMaintainers.md
+++ b/docs/BuildSystemMaintainers.md
@@ -21,14 +21,16 @@ executables and scripts will differ.
## Introduction
-The NDK uses [Clang] as its C/C++ compiler and [Binutils] for linking,
-archiving, and object file manipulation. Binutils provides both BFD and gold for
-linking. LLVM's [LLD] is also included for testing. AOSP uses LLD by default for
-most projects and the NDK is expected to move to it in the future.
+The NDK predominantly uses [LLVM] tools for building C/C++ code. These include
+[Clang] for compilation, [LLD] for linking, and other [LLVM tools] as well as
+some parts of [Binutils] for other tasks. Binutils will soon be entirely
+replaced by its LLVM equivalents within the NDK, but it remains available during
+the transition.
[Binutils]: https://www.gnu.org/software/binutils
[Clang]: https://clang.llvm.org/
[LLD]: https://lld.llvm.org/
+[LLVM tools]: https://llvm.org/docs/CommandGuide/
### Architectures
[Architectures]: #architectures
@@ -198,23 +200,29 @@ Versions] sections.
## Linkers
-Gold is used by default for most architectures, but BFD is used for AArch64 as
-Gold emits broken debug information for that architecture (see [Issue 70838247]
-for more details).
+LLD is the default linker.
+
+Gold is the fallback linker for most architectures, but BFD is used for AArch64
+as Gold emits broken debug information for that architecture (see [Issue
+70838247] for more details).
+
+The linker used by Clang can be selected with the `-fuse-ld=<linker>` argument,
+passed during linking. For example, to use gold instead of LLD, pass
+`-fuse-ld=gold` when linking. No argument is required to use LLD.
+
+The default linkers are installed to
+`<NDK>/toolchains/llvm/prebuilt/<host-tag>/bin/<triple>-ld` and
+`<NDK>/toolchains/llvm/prebuilt/<host-tag>/<triple>/bin/ld`. BFD and gold are
+installed as `ld.bfd` or `ld.gold` in the same locations. The triple-prefixed
+executables in the common bin directory should be preferred to the
+triple-specific bin directory because the triple-specific directory will be
+removed when binutils is removed from the NDK.
Note: It is usually not necessary to invoke the linkers directly since Clang
will do so automatically. Clang will also automatically link CRT objects and
default libraries and set up other target-specific options, so it is generally
better to use Clang for linking.
-The default linkers are installed to
-`<NDK>/toolchains/llvm/prebuilt/<host-tag>/bin/<triple>-ld` and
-`<NDK>/toolchains/llvm/prebuilt/<host-tag>/<triple>/bin/ld`. To use BFD or gold
-explicitly, use `ld.bfd` or `ld.gold` from the same locations. `ld.lld` is not
-installed to the triple directory and is not triple-prefixed, but rather is only
-installed as `<NDK>/toolchains/llvm/prebuilt/<host-tag>/bin/ld.lld` because the
-one binary supports all ABIs.
-
Warning: Using LLD with GNU `strip` or `objcopy` breaks RelRO. LLVM `strip` and
`objcopy` must be used with LLD. See [Issue 843] and the [Binutils] section of
this document for more information.
@@ -236,16 +244,24 @@ but are not limited to:
* readelf
* strip
-For some of these tools, LLVM equivalents are available. They typically have the
+For each of these tools, LLVM equivalents are available. They typically have the
same name but are prefixed with `llvm-`. For example, `llvm-strip` is used
instead of `<triple>-strip` or the `strip` binary from the triple-specific
directory.
+Note that binutils `as` is used by Clang if the `-fno-integrated-as` argument is
+used.
+
Android is moving away from GNU Binutils in favor of LLVM tools. This is a work
-in progress, but it is likely that a future release of the NDK will deprecate
-and eventually remove GNU Binutils. For now, ensure that your build system works
-with `llvm-strip` and `llvm-objcopy` as they are required when using LLD ([Issue
-843]).
+in progress, but it is likely that binutils will be deprecated in the next
+release of the NDK and removed in the late 2020 LTS release.
+
+At present, the only binutils tool still used by the NDK's build systems is
+`ar`. There may be some issues using `llvm-ar` as a drop in replacement for `ar`
+on Darwin that are still being investigated. See [Issue 1209] for more
+information.
+
+[Issue 1209]: https://github.com/android/ndk/issues/1209
## Sysroot
diff --git a/docs/changelogs/Changelog-r22.md b/docs/changelogs/Changelog-r22.md
index 0b102a579..bdeb8f04f 100644
--- a/docs/changelogs/Changelog-r22.md
+++ b/docs/changelogs/Changelog-r22.md
@@ -9,16 +9,14 @@ For Android Studio issues, follow the docs on the [Android Studio site].
## Announcements
-* [LLD](https://lld.llvm.org/) is now available for testing. AOSP has switched
- to using LLD by default and the NDK will follow (timeline unknown). Test LLD
- in your app by passing `-fuse-ld=lld` when linking. Note that [Issue 843]
- will affect builds using LLD with binutils strip and objcopy as opposed to
- llvm-strip and llvm-objcopy.
+* [LLD](https://lld.llvm.org/) is now the default linker. Gold and BFD will
+ likely be removed in the next LTS release (Q3-Q4 2020). See the Changes
+ section below for more information.
* [Issue 843]: Build system maintainers should begin testing with LLVM's
binutils. Android has switched to using these by default (with the exception
of llvm-ar, as we're still investigating some issues on macOS), and GNU
- binutils will be removed in a future release.
+ binutils will likely be removed in the next LTS release (Q3-Q4 2020).
## Changes
@@ -38,6 +36,16 @@ For Android Studio issues, follow the docs on the [Android Studio site].
r19, file a bug with your build system maintainer. See the [Build System
Maintainers Guide] for information on using the NDK in your own build system.
+* LLD is now used by default. If your build is not yet compatible with LLD, you
+ can continue using the deprecated linkers, set `APP_LD=deprecated` for
+ ndk-build, `ANDROID_LD=deprecated` for CMake, or use an explicit
+ `-fuse-ld=gold` or `-fuse-ld=bfd` in your custom build system. If you
+ encounter issues be sure to file a bug, because this will not be an option in
+ a subsequent release.
+
+ Note that [Issue 843] will affect builds using LLD with binutils strip and
+ objcopy as opposed to llvm-strip and llvm-objcopy.
+
[Build System Maintainers Guide]: https://android.googlesource.com/platform/ndk/+/master/docs/BuildSystemMaintainers.md
## Known Issues
diff --git a/ndk/checkbuild.py b/ndk/checkbuild.py
index 6a1e82830..eaf7f1c80 100755
--- a/ndk/checkbuild.py
+++ b/ndk/checkbuild.py
@@ -1956,6 +1956,52 @@ class BaseToolchain(ndk.builds.Module):
binutils_dir = self.get_dep('binutils').get_install_path(arch=arch)
copy_tree(binutils_dir, install_dir)
+ # Replace the default ld executable with lld.
+ triple = ndk.abis.arch_to_triple(arch)
+ bin_dir = Path(install_dir) / 'bin'
+ arch_bin_dir = Path(install_dir) / triple / 'bin'
+
+ bin_ld = bin_dir / f'{triple}-ld{exe}'
+ arch_ld = arch_bin_dir / f'ld{exe}'
+ lld = bin_dir / f'ld.lld{exe}'
+
+ bin_ld.unlink()
+ shutil.copyfile(lld, bin_ld)
+ shutil.copystat(lld, bin_ld)
+
+ arch_ld.unlink()
+ shutil.copyfile(lld, arch_ld)
+ shutil.copystat(lld, arch_ld)
+
+ # LLD isn't really meant to be moved, so it doesn't have an RPATH
+ # for the arch-specific directory. Ideally we wouldn't copy to this
+ # directory at all, but Clang only searches the arch-specific
+ # directory, so if we don't have this it'll wrongly fall back to
+ # /usr/bin/ld.
+ #
+ # We'll fix Clang before we remove the directory entirely when we
+ # remove binutils, but for now just copy the dependent libraries
+ # with it.
+ if not self.host.is_windows:
+ src_lib64 = bin_dir.parent / 'lib64'
+ dst_lib64 = arch_bin_dir.parent / 'lib64'
+ # The directory already exists for LP64 ABIs, but not for LP32
+ # ABIs.
+ dst_lib64.mkdir(exist_ok=True)
+
+ libcxx = versioned_so(self.host, 'libc++', '1')
+ shutil.copyfile(src_lib64 / libcxx, dst_lib64 / libcxx)
+ shutil.copystat(src_lib64 / libcxx, dst_lib64 / libcxx)
+
+ libcxxabi = versioned_so(self.host, 'libc++', '1')
+ shutil.copyfile(src_lib64 / libcxxabi, dst_lib64 / libcxxabi)
+ shutil.copystat(src_lib64 / libcxxabi, dst_lib64 / libcxxabi)
+ else:
+ src = bin_dir / 'libwinpthread-1.dll'
+ dest = arch_bin_dir / 'libwinpthread-1.dll'
+ shutil.copyfile(src, dest)
+ shutil.copystat(src, dest)
+
platforms = self.get_dep('platforms')
assert isinstance(platforms, Platforms)
for api in platforms.get_apis():
diff --git a/ndk/test/test_devices.py b/ndk/test/test_devices.py
index f953d830f..164d5176e 100644
--- a/ndk/test/test_devices.py
+++ b/ndk/test/test_devices.py
@@ -43,7 +43,7 @@ class MockDevice(ndk.test.devices.Device):
class TestBuildConfiguration(ndk.test.spec.BuildConfiguration):
def __init__(self, abi: Abi, api: Optional[int]):
# Linker option is irrelevant for determining device compatibility.
- super().__init__(abi, api, LinkerOption.Default)
+ super().__init__(abi, api, LinkerOption.Lld)
class DeviceTest(unittest.TestCase):
diff --git a/ndk/testing/standalone_toolchain.py b/ndk/testing/standalone_toolchain.py
index 6708d52ee..6461287e5 100644
--- a/ndk/testing/standalone_toolchain.py
+++ b/ndk/testing/standalone_toolchain.py
@@ -68,14 +68,17 @@ def make_standalone_toolchain(ndk_path: str, arch: str, api: int,
def test_standalone_toolchain(install_dir: str, test_source: str,
- flags: List[str],
- linker: LinkerOption) -> Tuple[bool, str]:
+ flags: List[str], linker: LinkerOption,
+ abi: ndk.abis.Abi) -> Tuple[bool, str]:
compiler_name = 'clang++'
compiler = os.path.join(install_dir, 'bin', compiler_name)
cmd = [compiler, test_source, '-Wl,--no-undefined', '-Wl,--fatal-warnings']
- if linker == LinkerOption.Lld:
- cmd.append('-fuse-ld=lld')
+ if linker == LinkerOption.Deprecated:
+ if abi == ndk.abis.Abi('arm64-v8a'):
+ cmd.append('-fuse-ld=bfd')
+ else:
+ cmd.append('-fuse-ld=gold')
cmd += flags
if os.name == 'nt':
# The Windows equivalent of exec doesn't know file associations so it
@@ -97,6 +100,6 @@ def run_test(ndk_path: str, abi: ndk.abis.Abi, api: int, linker: LinkerOption,
if not success:
return success, out
return test_standalone_toolchain(install_dir, test_source, flags,
- linker)
+ linker, abi)
finally:
shutil.rmtree(install_dir)
diff --git a/ndk/toolchains.py b/ndk/toolchains.py
index 669f2527d..c1e949746 100644
--- a/ndk/toolchains.py
+++ b/ndk/toolchains.py
@@ -35,7 +35,7 @@ HOST_TRIPLE_MAP = {
@enum.unique
class LinkerOption(enum.Enum):
- Default = 'default'
+ Deprecated = 'deprecated'
Lld = 'lld'