[SystemZ][z/OS] Add ASCII and 32-bit variants for libc++.
authorZibi Sarbinowski <zibi@ca.ibm.com>
Mon, 3 Oct 2022 21:41:58 +0000 (16:41 -0500)
committerZibi Sarbinowski <zibi@ca.ibm.com>
Mon, 3 Oct 2022 22:24:02 +0000 (17:24 -0500)
This patch enables libc++ build as shared library in all combinations of ASCII/EBCDIC and 32-bit/64-bit variants. In particular it introduces:

  # ASCII version of libc++ named as libc++_a.so
  # Script to rename DLL name inside the generated side deck
  # Various names for dataset members where DLL libraries and their side decks will reside
  # Add the following options:

   - LIBCXX_SHARED_OUTPUT_NAME
   - LIBCXX_ADDITIONAL_COMPILE_FLAGS
   - LIBCXX_ADDITIONAL_LIBRARIES
   - LIBCXXABI_ADDITIONAL_COMPILE_FLAGS
   - LIBCXXABI_ADDITIONAL_LIBRARIES

**Background and rational of this patch**

The linker on z/OS creates a list of exported symbols in a file called side deck. The list contains the symbol name as well as the name of the DLL which implements the symbol. The name of the DLL depends on what is specified in the -o command line option. If it points to a USS file, than the DLL name in the side deck will be the USS file name. If it points to a member of a dataset then the DLL name in the side deck is the member name.

If CMake could deal with z/OS datasets we could use -o that points to a dataset member name, but this does not seem to work so we have to produce a USS file as the DLL and then copy the content of the produced side deck to a dataset as well as rename the USS file name in the side deck to a dataset member name that corresponds to that DLL.

Reviewed By: muiez, SeanP, ldionne, #libc, #libc_abi

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

libcxx/CMakeLists.txt
libcxx/cmake/caches/s390x-ibm-zos-ascii.cmake [new file with mode: 0644]
libcxx/cmake/caches/s390x-ibm-zos.cmake [new file with mode: 0644]
libcxx/cmake/caches/s390x32-ibm-zos-ascii.cmake [new file with mode: 0644]
libcxx/cmake/caches/s390x32-ibm-zos.cmake [new file with mode: 0644]
libcxx/docs/BuildingLibcxx.rst
libcxx/src/CMakeLists.txt
libcxx/utils/zos_rename_dll_side_deck.sh [new file with mode: 0755]
libcxxabi/CMakeLists.txt
libcxxabi/src/CMakeLists.txt

index a515615..d1acb2c 100644 (file)
@@ -407,6 +407,9 @@ set(LIBCXX_INSTALL_INCLUDE_DIR "${CMAKE_INSTALL_INCLUDEDIR}/c++/v1" CACHE PATH
 set(LIBCXX_INSTALL_RUNTIME_DIR "${CMAKE_INSTALL_BINDIR}" CACHE PATH
     "Path where built libc++ runtime libraries should be installed.")
 
+set(LIBCXX_SHARED_OUTPUT_NAME "c++" CACHE STRING
+    "Output name for the shared libc++ runtime library.")
+
 if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE)
   set(LIBCXX_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE})
   set(LIBCXX_GENERATED_INCLUDE_DIR "${LLVM_BINARY_DIR}/include/c++/v1")
@@ -449,6 +452,10 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${LIBCXX_LIBRARY_DIR})
 set(LIBCXX_COMPILE_FLAGS "")
 set(LIBCXX_LINK_FLAGS "")
 set(LIBCXX_LIBRARIES "")
+set(LIBCXX_ADDITIONAL_COMPILE_FLAGS "" CACHE STRING
+    "Additional Compile only flags which can be provided in cache")
+set(LIBCXX_ADDITIONAL_LIBRARIES "" CACHE STRING
+    "Additional libraries libc++ is linked to which can be provided in cache")
 
 # Include macros for adding and removing libc++ flags.
 include(HandleLibcxxFlags)
@@ -457,9 +464,6 @@ include(HandleLibcxxFlags)
 # These flags get added to CMAKE_CXX_FLAGS and CMAKE_C_FLAGS so that
 # 'config-ix' use them during feature checks. It also adds them to both
 # 'LIBCXX_COMPILE_FLAGS' and 'LIBCXX_LINK_FLAGS'
-if(ZOS)
-  add_target_flags_if_supported("-fzos-le-char-mode=ebcdic")
-endif()
 
 if (${CMAKE_SYSTEM_NAME} MATCHES "AIX")
   add_target_flags_if_supported("-mdefault-visibility-export-mapping=explicit")
@@ -563,6 +567,7 @@ function(cxx_add_basic_build_flags target)
       target_compile_definitions(${target} PRIVATE -D_LIBCPP_LINK_RT_LIB)
     endif()
   endif()
+  target_compile_options(${target} PUBLIC "${LIBCXX_ADDITIONAL_COMPILE_FLAGS}")
 endfunction()
 
 # Warning flags ===============================================================
@@ -799,6 +804,7 @@ function(cxx_link_system_libraries target)
   if (ANDROID AND ANDROID_PLATFORM_LEVEL LESS 21)
     target_link_libraries(${target} PUBLIC android_support)
   endif()
+  target_link_libraries(${target} PUBLIC "${LIBCXX_ADDITIONAL_LIBRARIES}")
 endfunction()
 
 # Windows-related flags =======================================================
diff --git a/libcxx/cmake/caches/s390x-ibm-zos-ascii.cmake b/libcxx/cmake/caches/s390x-ibm-zos-ascii.cmake
new file mode 100644 (file)
index 0000000..95b7cbe
--- /dev/null
@@ -0,0 +1,22 @@
+# Common
+set(CMAKE_BUILD_TYPE Release CACHE STRING "")
+
+set(LIBCXX_ENABLE_ABI_LINKER_SCRIPT OFF CACHE BOOL "")
+set(LIBCXX_ENABLE_SHARED ON CACHE BOOL "")
+set(LIBCXX_ENABLE_STATIC OFF CACHE BOOL "")
+set(LIBCXX_INCLUDE_TESTS OFF CACHE BOOL "")
+set(LIBCXX_INSTALL_HEADERS OFF CACHE BOOL "")
+set(LIBCXX_INCLUDE_BENCHMARKS OFF CACHE BOOL "")
+
+set(LIBCXXABI_ENABLE_SHARED OFF CACHE BOOL "")
+set(LIBCXXABI_ENABLE_STATIC OFF CACHE BOOL "")
+set(LIBCXXABI_INCLUDE_TESTS OFF CACHE BOOL "")
+
+# Target Specific
+set(LIBCXX_DLL_NAME CRTEQCXS CACHE STRING "")
+set(LIBCXX_SHARED_OUTPUT_NAME "c++_a" CACHE STRING
+    "Output name for the shared libc++ runtime library.")
+set(LIBCXX_CXX_ABI system-libcxxabi CACHE STRING "")
+
+set(LIBCXX_ADDITIONAL_COMPILE_FLAGS "-fzos-le-char-mode=ascii" CACHE STRING "")
+set(LIBCXX_ADDITIONAL_LIBRARIES "-L../s390x-ibm-zos/lib -Wl,../s390x-ibm-zos/lib/libunwind.x" CACHE STRING "")
diff --git a/libcxx/cmake/caches/s390x-ibm-zos.cmake b/libcxx/cmake/caches/s390x-ibm-zos.cmake
new file mode 100644 (file)
index 0000000..3eaed3e
--- /dev/null
@@ -0,0 +1,17 @@
+set(CMAKE_BUILD_TYPE Release CACHE STRING "")
+
+# Common
+set(LIBCXX_ENABLE_ABI_LINKER_SCRIPT OFF CACHE BOOL "")
+set(LIBCXX_ENABLE_SHARED ON CACHE BOOL "")
+set(LIBCXX_ENABLE_STATIC OFF CACHE BOOL "")
+set(LIBCXX_INCLUDE_TESTS ON CACHE BOOL "")
+
+set(LIBCXXABI_ENABLE_SHARED ON CACHE BOOL "")
+set(LIBCXXABI_ENABLE_STATIC OFF CACHE BOOL "")
+set(LIBCXXABI_INCLUDE_TESTS ON CACHE BOOL "")
+
+# Target Specific
+set(LIBCXX_DLL_NAME CRTEQCXE CACHE STRING "")
+
+set(LIBCXXABI_DLL_NAME CRTEQCXA CACHE STRING "")
+set(LIBCXXABI_ADDITIONAL_LIBRARIES "-Wl,lib/libunwind.x" CACHE STRING "")
diff --git a/libcxx/cmake/caches/s390x32-ibm-zos-ascii.cmake b/libcxx/cmake/caches/s390x32-ibm-zos-ascii.cmake
new file mode 100644 (file)
index 0000000..9ee03e1
--- /dev/null
@@ -0,0 +1,22 @@
+# Common
+set(CMAKE_BUILD_TYPE Release CACHE STRING "")
+
+set(LIBCXX_ENABLE_ABI_LINKER_SCRIPT OFF CACHE BOOL "")
+set(LIBCXX_ENABLE_SHARED ON CACHE BOOL "")
+set(LIBCXX_ENABLE_STATIC OFF CACHE BOOL "")
+set(LIBCXX_INCLUDE_TESTS OFF CACHE BOOL "")
+set(LIBCXX_INSTALL_HEADERS OFF CACHE BOOL "")
+set(LIBCXX_INCLUDE_BENCHMARKS OFF CACHE BOOL "")
+
+set(LIBCXXABI_ENABLE_SHARED OFF CACHE BOOL "")
+set(LIBCXXABI_ENABLE_STATIC OFF CACHE BOOL "")
+set(LIBCXXABI_INCLUDE_TESTS OFF CACHE BOOL "")
+
+# Target Specific
+set(LIBCXX_DLL_NAME CRTEHCXS CACHE STRING "")
+set(LIBCXX_SHARED_OUTPUT_NAME "c++_a" CACHE STRING
+    "Output name for the shared libc++ runtime library.")
+set(LIBCXX_CXX_ABI system-libcxxabi CACHE STRING "")
+
+set(LIBCXX_ADDITIONAL_COMPILE_FLAGS "-fzos-le-char-mode=ascii" CACHE STRING "")
+set(LIBCXX_ADDITIONAL_LIBRARIES "-L../s390x32-ibm-zos/lib -Wl,../s390x32-ibm-zos/lib/libunwind.x" CACHE STRING "")
diff --git a/libcxx/cmake/caches/s390x32-ibm-zos.cmake b/libcxx/cmake/caches/s390x32-ibm-zos.cmake
new file mode 100644 (file)
index 0000000..3e57e0a
--- /dev/null
@@ -0,0 +1,18 @@
+# Common
+set(CMAKE_BUILD_TYPE Release CACHE STRING "")
+
+set(LIBCXX_ENABLE_ABI_LINKER_SCRIPT OFF CACHE BOOL "")
+set(LIBCXX_ENABLE_SHARED ON CACHE BOOL "")
+set(LIBCXX_ENABLE_STATIC OFF CACHE BOOL "")
+set(LIBCXX_INCLUDE_TESTS ON CACHE BOOL "")
+
+set(LIBCXXABI_ENABLE_SHARED ON CACHE BOOL "")
+set(LIBCXXABI_ENABLE_STATIC OFF CACHE BOOL "")
+set(LIBCXXABI_INCLUDE_TESTS ON CACHE BOOL "")
+
+# Target Specific
+set(LIBCXX_DLL_NAME CRTEHCXE CACHE STRING "")
+
+set(LIBCXXABI_DLL_NAME CRTEHCXA CACHE STRING "")
+
+set(LIBCXXABI_ADDITIONAL_LIBRARIES "-Wl,lib/libunwind.x" CACHE STRING "")
index 80a105c..59c695e 100644 (file)
@@ -286,6 +286,24 @@ libc++ specific options
   Path where target-specific libc++ headers should be installed. If a relative
   path, relative to ``CMAKE_INSTALL_PREFIX``.
 
+.. option:: LIBCXX_SHARED_OUTPUT_NAME:STRING
+
+  **Default**: ``c++``
+
+  Output name for the shared libc++ runtime library.
+
+.. option:: LIBCXX_ADDITIONAL_COMPILE_FLAGS:STRING
+
+  **Default**: ``""``
+
+  Additional Compile only flags which can be provided in cache.
+
+.. option:: LIBCXX_ADDITIONAL_LIBRARIES:STRING
+
+  **Default**: ``""``
+
+  Additional libraries libc++ is linked to which can be provided in cache.
+
 
 .. _ABI Library Specific Options:
 
@@ -329,6 +347,18 @@ ABI Library Specific Options
   Build and use the LLVM unwinder. Note: This option can only be used when
   libc++abi is the C++ ABI library used.
 
+.. option:: LIBCXXABI_ADDITIONAL_COMPILE_FLAGS:STRING
+
+  **Default**: ``""``
+
+  Additional Compile only flags which can be provided in cache.
+
+.. option:: LIBCXXABI_ADDITIONAL_LIBRARIES:STRING
+
+  **Default**: ``""``
+
+  Additional libraries libc++abi is linked to which can be provided in cache.
+
 
 libc++ Feature Options
 ----------------------
index 9abf548..189ba67 100644 (file)
@@ -204,7 +204,7 @@ if (LIBCXX_ENABLE_SHARED)
     PROPERTIES
       COMPILE_FLAGS "${LIBCXX_COMPILE_FLAGS}"
       LINK_FLAGS    "${LIBCXX_LINK_FLAGS}"
-      OUTPUT_NAME   "c++"
+      OUTPUT_NAME   "${LIBCXX_SHARED_OUTPUT_NAME}"
       VERSION       "${LIBCXX_LIBRARY_VERSION}"
       SOVERSION     "${LIBCXX_ABI_VERSION}"
       DEFINE_SYMBOL ""
@@ -212,6 +212,16 @@ if (LIBCXX_ENABLE_SHARED)
   cxx_add_common_build_flags(cxx_shared)
   cxx_set_common_defines(cxx_shared)
 
+  if(ZOS)
+    add_custom_command(TARGET cxx_shared POST_BUILD
+      COMMAND
+        ${LIBCXX_SOURCE_DIR}/utils/zos_rename_dll_side_deck.sh
+        $<TARGET_LINKER_FILE_NAME:cxx_shared> $<TARGET_FILE_NAME:cxx_shared> "${LIBCXX_DLL_NAME}"
+      COMMENT "Rename dll name inside the side deck file"
+      WORKING_DIRECTORY $<TARGET_FILE_DIR:cxx_shared>
+    )
+  endif()
+
   # Link against libc++abi
   if (LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY)
     target_link_libraries(cxx_shared PRIVATE libcxx-abi-shared-objects)
diff --git a/libcxx/utils/zos_rename_dll_side_deck.sh b/libcxx/utils/zos_rename_dll_side_deck.sh
new file mode 100755 (executable)
index 0000000..adab79f
--- /dev/null
@@ -0,0 +1,57 @@
+#!/usr/bin/env bash
+#
+# Script to rename DLL name within side deck.
+#
+
+# Stops execution if a command or pipeline has an error.
+set -e
+
+sidedeck=$1
+old_dll_name=$2
+new_dll_name=$3
+
+function error() {
+  printf "ERROR: %s\n" "$*"
+  exit 1
+}
+
+function usage() {
+cat <<EOF
+Usage: $(basename $0) <side deck file> <old dll name> <new dll name>:
+          [-h|--help] Display this help and exit.
+EOF
+}
+
+rename_dll_name_inside_side_deck() {
+
+if [[ -z "$sidedeck" || -z "$old_dll_name" || -z "$new_dll_name" ]]; then
+  usage
+  error "All 3 parameters must be specified."
+fi
+
+[[ -f "$sidedeck" ]] || error "The '$sidedeck' file must exists."
+
+old_len=${#old_dll_name}
+new_len=${#new_dll_name}
+
+if (( $new_len > $old_len )); then
+  error "New DLL name $new_dll_name must have $old_len characters or less."
+fi
+
+if ((padding_len=$old_len-$new_len )); then
+  pad=$(printf "%*s" $padding_len "")
+fi
+
+# Touch the temp. file and set the tag to 1047 first so the redirecting statement
+# will write in 1047 and not 819 encoding.
+touch $sidedeck.tmp; chtag -tc1047 $sidedeck.tmp
+sed "/ IMPORT /s/'$old_dll_name/$pad'$new_dll_name/g" $sidedeck > $sidedeck.tmp
+mv $sidedeck.tmp $sidedeck
+}
+
+function main() {
+  rename_dll_name_inside_side_deck
+}
+
+main "$@"
+
index b8326d0..903c659 100644 (file)
@@ -228,6 +228,10 @@ set(LIBCXXABI_CXX_FLAGS "")
 set(LIBCXXABI_COMPILE_FLAGS "")
 set(LIBCXXABI_LINK_FLAGS "")
 set(LIBCXXABI_LIBRARIES "")
+set(LIBCXXABI_ADDITIONAL_COMPILE_FLAGS "" CACHE STRING
+    "Additional Compile only flags which can be provided in cache")
+set(LIBCXXABI_ADDITIONAL_LIBRARIES "" CACHE STRING
+    "Additional libraries libc++abi is linked to which can be provided in cache")
 
 # Include macros for adding and removing libc++abi flags.
 include(HandleLibcxxabiFlags)
@@ -245,6 +249,8 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "AIX")
   add_target_flags_if_supported("-mdefault-visibility-export-mapping=explicit")
   set(CMAKE_AIX_EXPORT_ALL_SYMBOLS OFF)
 endif()
+add_compile_flags("${LIBCXXABI_ADDITIONAL_COMPILE_FLAGS}")
+add_library_flags("${LIBCXXABI_ADDITIONAL_LIBRARIES}")
 
 # Configure compiler. Must happen after setting the target flags.
 include(config-ix)
index 248acc6..a8cd222 100644 (file)
@@ -191,6 +191,17 @@ if (LIBCXXABI_ENABLE_SHARED)
       SOVERSION "1"
       VERSION "${LIBCXXABI_LIBRARY_VERSION}"
   )
+
+  if (ZOS)
+    add_custom_command(TARGET cxxabi_shared POST_BUILD
+      COMMAND
+        ${LIBCXXABI_LIBCXX_PATH}/utils/zos_rename_dll_side_deck.sh
+        $<TARGET_LINKER_FILE_NAME:cxxabi_shared> $<TARGET_FILE_NAME:cxxabi_shared> "${LIBCXXABI_DLL_NAME}"
+      COMMENT "Rename dll name inside the side deck file"
+      WORKING_DIRECTORY $<TARGET_FILE_DIR:cxxabi_shared>
+    )
+  endif ()
+
   target_link_libraries(cxxabi_shared
     PUBLIC cxxabi_shared_objects
     PRIVATE ${LIBCXXABI_SHARED_LIBRARIES} ${LIBCXXABI_LIBRARIES})