Skip to content

Commit

Permalink
Disable multithreaded linking for Windows LLD.
Browse files Browse the repository at this point in the history
This only affects ndk-build because CMake can't currently check if it
is using LLD since our toolchain file has finished running by the
time the user can add ldflags.

Not enabling this with standalone toolchains since we can't enable it
for the built in toolchains without recompiling Clang and those are
supposed to match. Will disable in the driver in a follow up if a
workaround is not found.

Test: ./checkbuild.py
Bug: android/ndk#855
Change-Id: I4a24166adce463bea47ca4bf0e97d5375c69f40e
  • Loading branch information
DanAlbert committed Feb 8, 2019
1 parent 5b8d7dd commit 144b244
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 0 deletions.
9 changes: 9 additions & 0 deletions build/core/build-binary.mk
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,15 @@ ifneq ($(filter armeabi%,$(TARGET_ARCH_ABI)),)
my_ldflags += $(TARGET_$(my_link_arm_mode)_LDFLAGS)
endif

# https://github.com/android-ndk/ndk/issues/855
ifeq ($(HOST_OS),windows)
ndk_fuse_ld_flags := $(filter -fuse-ld=%,$(my_ldflags))
ndk_used_linker := $(lastword $(ndk_fuse_ld_flags))
ifeq ($(ndk_used_linker),-fuse-ld=lld)
my_ldflags += -Wl,--no-threads
endif
endif

# When LOCAL_SHORT_COMMANDS is defined to 'true' we are going to write the
# list of all object files and/or static/shared libraries that appear on the
# command line to a file, then use the @<listfile> syntax to invoke it.
Expand Down
6 changes: 6 additions & 0 deletions docs/BuildSystemMaintainers.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,13 @@ 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: Multithreaded linking with LLD may hang on Windows. This feature is on
by default. To workaround this, `-Wl,--no-threads` must be passed to Clang when
using LLD on Windows. See [Issue 855].

[Issue 70838247]: https://issuetracker.google.com/70838247
[Issue 855]: https://github.com/android-ndk/ndk/issues/855

## Sysroot

Expand Down
9 changes: 9 additions & 0 deletions docs/changelogs/Changelog-r19.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ Announcements
r19b
----

* [Issue 855]: ndk-build automatically disables multithreaded linking for LLD
on Windows, where it may hang. It is not possible for the NDK to detect this
situation for CMake, so CMake users and custom build systems must pass
`-Wl,--no-threads` when linking with LLD on Windows.
* [Issue 849]: Fixed unused command line argument warning when using standalone
toolchains to compile C code.
* [Issue 890]: Fixed `CMAKE_FIND_ROOT_PATH`. CMake projects will no longer
Expand Down Expand Up @@ -124,6 +128,10 @@ Known Issues
to not call `dlclose`.
* [Issue 70838247]: Gold emits broken debug information for AArch64. AArch64
still uses BFD by default.
* [Issue 855]: LLD may hang on Windows when using multithreaded linking.
ndk-build will automatically disable multithreaded linking in this situation,
but CMake users and custom build systems should pass `-Wl,--no-threads` when
using LLD on Windows. The other linkers and operating systems are unaffected.
* [Issue 884]: Third-party build systems must pass `-fno-addrsig` to Clang for
compatibility with binutils. ndk-build, CMake, and standalone toolchains
handle this automatically.
Expand All @@ -135,6 +143,7 @@ Known Issues

[Issue 360]: https://github.com/android-ndk/ndk/issues/360
[Issue 70838247]: https://issuetracker.google.com/70838247
[Issue 855]: https://github.com/android-ndk/ndk/issues/855
[Issue 884]: https://github.com/android-ndk/ndk/issues/884
[Issue 888]: https://github.com/android-ndk/ndk/issues/888
[use plugin version 3.1 or newer]: https://developer.android.com/studio/releases/gradle-plugin#updating-plugin
6 changes: 6 additions & 0 deletions tests/build/lld_no_threads/project/jni/Android.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := libfoo
LOCAL_SRC_FILES := foo.cpp
include $(BUILD_SHARED_LIBRARY)
1 change: 1 addition & 0 deletions tests/build/lld_no_threads/project/jni/foo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
void foo() {}
67 changes: 67 additions & 0 deletions tests/build/lld_no_threads/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#
# Copyright (C) 2019 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.
#
"""Check that Windows LLD does not use threads with ndk-build.
https://github.com/android-ndk/ndk/issues/855 reports that this sometimes hangs
on Windows.
"""
import os
import subprocess
import sys


def check_ndk_build(ndk_path, abi, platform, build_flags, use_lld):
"""Checks --no-threads behavior with ndk-build.
If use_lld is used, the test will build the ndk-build project with
APP_LDFLAGS=-fuse-ld=lld to force the project to use lld. In this case, we
expect to see -Wl,--no-threads passed to the linker on Windows.
"""
ndk_build = os.path.join(ndk_path, 'ndk-build')
is_win = sys.platform == 'win32'
if is_win:
ndk_build += '.cmd'
if use_lld:
build_flags.append('APP_LDFLAGS=-fuse-ld=lld')
project_path = 'project'
ndk_args = build_flags + [
'APP_ABI=' + abi,
'APP_PLATFORM=android-{}'.format(platform),
'V=1',
'-B',
]
proc = subprocess.Popen([ndk_build, '-C', project_path] + ndk_args,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
out, _ = proc.communicate()
out = out.decode('utf-8')
if proc.returncode != 0:
return proc.returncode == 0, out

out_words = out.split(' ')
if is_win and use_lld:
result = '-Wl,--no-threads' in out_words
else:
result = '-Wl,--no-threads' not in out_words

return result, out


def run_test(ndk_path, abi, platform, build_flags):
"""Checks --no-threads-behavior."""
result, out = check_ndk_build(ndk_path, abi, platform, build_flags, False)
if not result:
return result, out
return check_ndk_build(ndk_path, abi, platform, build_flags, True)

0 comments on commit 144b244

Please sign in to comment.