Windows: enable gold threading, copy libwinpthread-1.dll
Copy libwinpthread-1.dll alongside the binutils executables on Windows.
The install_winpthreads function is copied from llvm_android:
https://android.googlesource.com/toolchain/llvm_android/+/bd22d9779676661ae9571972dcd744c42c70ffd0/build.py#1063
Most C++ MinGW programs need libpthread, because even libstdc++'s
"operator new" pulls in EH code, which calls into libpthread. Currently,
the ld.gold.exe and dwp.exe binaries need libwinpthread-1.dll, which is
not generally in the PATH, so the binaries don't run.
Previously, the Android GCC build of binutils linked ld.gold.exe and
dwp.exe with -static, which selected the static libpthread.a. Packaging
libwinpthread-1.dll alongside the binaries ensures that ld.gold.exe and
the LLVMgold plugin use the same copy of the winpthreads runtime, which
might be important.
Test: ./toolchain/binutils/build.py --arch arm64 --host win64
Test: ./toolchain/binutils/build.py --arch arm64 --host win
Test: ./toolchain/binutils/build.py --arch arm64 --host linux
Test: ./toolchain/binutils/build.py --arch x86 --host win64
Bug: none
Change-Id: I5fc2d38b67c72fa4760be1c2688ef88479759160
diff --git a/build.py b/build.py
index 4a4f098..f22e821 100755
--- a/build.py
+++ b/build.py
@@ -60,6 +60,12 @@
os.chdir(path)
+def install_file(src, dst):
+ """shutil.copy2 with logging."""
+ logger().info('copy %s %s', src, dst)
+ shutil.copy2(src, dst)
+
+
def check_call(cmd, *args, **kwargs):
"""subprocess.check_call with logging."""
logger().info('check_call %s', subprocess.list2cmdline(cmd))
@@ -84,6 +90,7 @@
'--host={}'.format(configure_host),
'--enable-initfini-array',
'--enable-plugins',
+ '--enable-threads',
'--disable-nls',
'--with-sysroot={}'.format(sysroot),
'--prefix={}'.format(install_dir),
@@ -97,12 +104,6 @@
# https://issuetracker.google.com/70838247
configure_args.append('--enable-gold=default')
- if not is_windows:
- # Multithreaded linking is implemented with pthreads, which we
- # historically couldn't use on Windows.
- # TODO: Try enabling this now that we have winpthreads in mingw.
- configure_args.append('--enable-threads')
-
env = {}
m32 = False
@@ -158,10 +159,31 @@
check_call(['make', '-j', str(jobs)])
-def install(jobs):
+def install_winpthreads(is_windows32, install_dir):
+ """Installs the winpthreads runtime to the Windows bin directory."""
+ lib_name = 'libwinpthread-1.dll'
+ mingw_dir = ndk.paths.android_path(
+ 'prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8',
+ 'x86_64-w64-mingw32')
+ # Yes, this indeed may be found in bin/ because the executables are the
+ # 64-bit version by default.
+ pthread_dir = 'lib32' if is_windows32 else 'bin'
+ lib_path = os.path.join(mingw_dir, pthread_dir, lib_name)
+
+ lib_install = os.path.join(install_dir, 'bin', lib_name)
+ install_file(lib_path, lib_install)
+
+
+def install(jobs, arch, host, install_dir):
"""Installs binutils."""
check_call(['make', 'install-strip', '-j', str(jobs)])
+ if host in ('win', 'win64'):
+ arch_install_dir = os.path.join(
+ install_dir, ndk.abis.arch_to_triple(arch))
+ install_winpthreads(host == 'win', install_dir)
+ install_winpthreads(host == 'win', arch_install_dir)
+
def dist(dist_dir, base_dir, package_name):
"""Packages binutils for distribution."""
@@ -237,7 +259,7 @@
install_timer = ndk.timer.Timer()
with install_timer:
- install(args.jobs)
+ install(args.jobs, args.arch, args.host, install_dir)
finally:
chdir(orig_dir)