[libunwind] Support building hermetic static library

This is useful when the static libunwind library is being linked into
shared libraries that may be used in with other shared libraries that
use different unwinder. We want to avoid avoid exporting libunwind
symbols in those cases. This achieved by a new CMake option which can be
enabled by libunwind vendors as needed.

The same CMake option has already been added to libc++ and libc++abi in
D55404 and D56026.

Differential Revision: https://reviews.llvm.org/D57107

git-svn-id: https://llvm.org/svn/llvm-project/libunwind/trunk@352559 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 46e7ce1..41b990f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -168,6 +168,9 @@
   message(FATAL_ERROR "LIBUNWIND_BUILD_32_BITS=ON is not supported on this platform.")
 endif()
 
+option(LIBUNWIND_HERMETIC_STATIC_LIBRARY
+  "Do not export any symbols from the static library." OFF)
+
 #===============================================================================
 # Configure System
 #===============================================================================
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index f7523f8..080e8c5 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -105,17 +105,44 @@
 set_property(SOURCE ${LIBUNWIND_C_SOURCES}
              APPEND_STRING PROPERTY COMPILE_FLAGS " ${LIBUNWIND_C_FLAGS}")
 
-# Add a object library that contains the compiled source files.
-add_library(unwind_objects OBJECT ${LIBUNWIND_SOURCES} ${LIBUNWIND_HEADERS})
+macro(unwind_object_library name)
+  cmake_parse_arguments(ARGS "" "" "DEFINES;FLAGS" ${ARGN})
 
-set_target_properties(unwind_objects
-                      PROPERTIES
-                        COMPILE_FLAGS "${LIBUNWIND_COMPILE_FLAGS}"
-                        POSITION_INDEPENDENT_CODE ON)
+# Add a object library that contains the compiled source files.
+  add_library(${name} OBJECT ${LIBUNWIND_SOURCES} ${LIBUNWIND_HEADERS})
+
+  if(ARGS_DEFINES)
+    target_compile_definitions(${name} PRIVATE ${ARGS_DEFINES})
+  endif()
+
+  set_target_properties(${name}
+                        PROPERTIES
+                          COMPILE_FLAGS "${LIBUNWIND_COMPILE_FLAGS}"
+                          POSITION_INDEPENDENT_CODE ON)
+
+  if(ARGS_FLAGS)
+    target_compile_options(${name} PRIVATE ${ARGS_FLAGS})
+  endif()
+endmacro()
+
+if(LIBUNWIND_HERMETIC_STATIC_LIBRARY)
+  append_flags_if_supported(UNWIND_STATIC_OBJECTS_FLAGS -fvisibility=hidden)
+  append_flags_if_supported(UNWIND_STATIC_OBJECTS_FLAGS -fvisibility-global-new-delete-hidden)
+  unwind_object_library(unwind_static_objects
+    DEFINES _LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS
+    FLAGS ${UNWIND_STATIC_OBJECTS_FLAGS})
+  unwind_object_library(unwind_shared_objects)
+  set(unwind_static_sources $<TARGET_OBJECTS:unwind_static_objects>)
+  set(unwind_shared_sources $<TARGET_OBJECTS:unwind_shared_objects>)
+else()
+  unwind_object_library(unwind_objects)
+  set(unwind_static_sources $<TARGET_OBJECTS:unwind_objects>)
+  set(unwind_shared_sources $<TARGET_OBJECTS:unwind_objects>)
+endif()
 
 # Build the shared library.
 if (LIBUNWIND_ENABLE_SHARED)
-  add_library(unwind_shared SHARED $<TARGET_OBJECTS:unwind_objects>)
+  add_library(unwind_shared SHARED ${unwind_shared_sources})
   if(COMMAND llvm_setup_rpath)
     llvm_setup_rpath(unwind_shared)
   endif()
@@ -134,7 +161,7 @@
 
 # Build the static library.
 if (LIBUNWIND_ENABLE_STATIC)
-  add_library(unwind_static STATIC $<TARGET_OBJECTS:unwind_objects>)
+  add_library(unwind_static STATIC ${unwind_static_sources})
   target_link_libraries(unwind_static ${libraries})
   set_target_properties(unwind_static
                         PROPERTIES