From e434fc0dde8c6b11df8c4d68c2758c3b5d69a97f Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Thu, 4 Feb 2021 12:28:31 -0800 Subject: [PATCH] gn build: Support cross-compiling libunwind for Android. - Usual cross-compilation fix: s/target_/current_/g - Define _LIBUNWIND_IS_NATIVE_ONLY to enable unwinding past functions with return pointer authentication. - Android needs two libunwind static libraries: one with symbols exported and one without. These both need to be in the same build tree so the libunwind_hermetic_static_library configuration option doesn't help here. Replace it with build rules that build both libraries. - Install the libraries in the location that Android expects them to be. Differential Revision: https://reviews.llvm.org/D96563 --- llvm/utils/gn/secondary/libunwind/BUILD.gn | 15 +++- .../utils/gn/secondary/libunwind/src/BUILD.gn | 80 ++++++++++++------- 2 files changed, 67 insertions(+), 28 deletions(-) diff --git a/llvm/utils/gn/secondary/libunwind/BUILD.gn b/llvm/utils/gn/secondary/libunwind/BUILD.gn index 07c3cf0da5210..f66246dc7703e 100644 --- a/llvm/utils/gn/secondary/libunwind/BUILD.gn +++ b/llvm/utils/gn/secondary/libunwind/BUILD.gn @@ -1,3 +1,16 @@ +import("//llvm/utils/gn/build/toolchain/compiler.gni") + +supported_toolchains = [ "//llvm/utils/gn/build/toolchain:stage2_unix" ] +if (android_ndk_path != "") { + supported_toolchains += [ + "//llvm/utils/gn/build/toolchain:stage2_android_aarch64", + "//llvm/utils/gn/build/toolchain:stage2_android_arm", + ] +} + group("libunwind") { - deps = [ "//libunwind/src(//llvm/utils/gn/build/toolchain:stage2_unix)" ] + deps = [] + foreach(toolchain, supported_toolchains) { + deps += [ "//libunwind/src($toolchain)" ] + } } diff --git a/llvm/utils/gn/secondary/libunwind/src/BUILD.gn b/llvm/utils/gn/secondary/libunwind/src/BUILD.gn index 6c91b7a5a462c..1eb5fadae298a 100644 --- a/llvm/utils/gn/secondary/libunwind/src/BUILD.gn +++ b/llvm/utils/gn/secondary/libunwind/src/BUILD.gn @@ -1,4 +1,5 @@ import("//clang/runtimes.gni") +import("//compiler-rt/target.gni") declare_args() { # Build libunwind as a shared library. @@ -6,16 +7,13 @@ declare_args() { # Build libunwind as a static library. libunwind_enable_static = true - - # Do not export any symbols from the static library. - libunwind_hermetic_static_library = true } unwind_headers = [ "../include/libunwind.h", "../include/unwind.h", ] -if (target_os == "mac") { +if (current_os == "mac") { unwind_headers += [ # Make `gn format` not collapse this, for sync_source_lists_from_cmake.py. "../include/mach-o/compact_unwind_encoding.h", @@ -44,25 +42,39 @@ unwind_sources = [ "libunwind.cpp", "libunwind_ext.h", ] -if (target_os == "mac") { +if (current_os == "mac") { unwind_sources += [ "Unwind_AppleExtras.cpp" ] } +if (current_os == "android") { + if (current_cpu == "arm64") { + unwind_output_dir = "$crt_current_out_dir/aarch64" + } else if (current_cpu == "arm") { + unwind_output_dir = "$crt_current_out_dir/arm" + } +} else { + unwind_output_dir = runtimes_dir +} + config("unwind_config") { cflags = [] cflags_c = [ "-std=c99" ] cflags_cc = [ "-fno-rtti" ] + defines = [ "_LIBUNWIND_IS_NATIVE_ONLY" ] include_dirs = [ "//libunwind/include" ] - if (target_os == "mac") { + if (current_os == "mac") { cflags += [ "-U__STRICT_ANSI__" ] } + if (current_os == "android") { + defines += [ "_LIBUNWIND_USE_DLADDR=0" ] + } } if (libunwind_enable_shared) { shared_library("unwind_shared") { - output_dir = runtimes_dir + output_dir = unwind_output_dir output_name = "unwind" - if (target_os == "linux" || target_os == "mac") { + if (current_os == "linux" || current_os == "mac") { cflags = [ "-fPIC" ] ldflags = [ "-nostdlib++" ] libs = [ @@ -70,7 +82,7 @@ if (libunwind_enable_shared) { "pthread", ] } - if (target_os == "mac") { + if (current_os == "mac") { ldflags += [ "-compatibility_version 1", "-install_name /usr/lib/libunwind.1.dylib", @@ -88,24 +100,35 @@ if (libunwind_enable_shared) { } if (libunwind_enable_static) { - static_library("unwind_static") { - output_dir = runtimes_dir - output_name = "unwind" - complete_static_lib = true - configs -= [ "//llvm/utils/gn/build:thin_archive" ] - sources = unwind_sources - public = unwind_headers - if (libunwind_hermetic_static_library) { - cflags = [ "-fvisibility=hidden" ] - cflags_cc = [ "-fvisibility-global-new-delete-hidden" ] - defines = [ "_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS" ] + template("libunwind_static_library") { + static_library(target_name) { + output_dir = unwind_output_dir + output_name = invoker.output_name + complete_static_lib = true + configs -= [ "//llvm/utils/gn/build:thin_archive" ] + sources = unwind_sources + public = unwind_headers + if (!invoker.export) { + cflags = [ "-fvisibility=hidden" ] + cflags_cc = [ "-fvisibility-global-new-delete-hidden" ] + defines = [ "_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS" ] + } + deps = [ "//compiler-rt/lib/builtins" ] + configs += [ ":unwind_config" ] + configs -= [ + "//llvm/utils/gn/build:no_exceptions", + "//llvm/utils/gn/build:no_rtti", + ] } - deps = [ "//compiler-rt/lib/builtins" ] - configs += [ ":unwind_config" ] - configs -= [ - "//llvm/utils/gn/build:no_exceptions", - "//llvm/utils/gn/build:no_rtti", - ] + } + + libunwind_static_library("unwind_static_exported") { + output_name = "unwind-exported" + export = true + } + libunwind_static_library("unwind_static") { + output_name = "unwind" + export = false } } @@ -115,6 +138,9 @@ group("src") { deps += [ ":unwind_shared" ] } if (libunwind_enable_static) { - deps += [ ":unwind_static" ] + deps += [ + ":unwind_static", + ":unwind_static_exported", + ] } }