1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-10-14 19:08:07 +08:00

AIX: Explicitly compute shared object exports for both XL and GNU

On AIX, symbols in shared objects must be exported in order to be
visible to dependents (similar to Windows).  The AIX linker provides a
`-bE:...` option to specify a file listing symbols to be exported.
Compilers offer some features to help:

* When the XL compiler is invoked with its `-qmkshrobj`/`-G` options for
  creating shared objects (without/with runtime linking), it recognizes
  when no explicit `-bE:...` linker option is specified and runs a
  `CreateExportList` tool provided with the compiler to compute one from
  the object files.  Since commit d468a2c2cb (XL: Avoid copying archives
  into shared libraries that link them, 2011-04-07, v2.8.5~153^2) CMake
  runs `CreateExportList` explicitly to ensure it only looks at the object
  files and not any library files.

* When the GNU compiler is invoked with its `-shared` option for creating
  shared objects, its internal `collect2` tool recognizes when no explicit
  `-bE:...` linker option is specified and computes one itself from the
  object files.  However, it sometimes includes extra symbols such as
  `.__init_aix_libgcc_cxa_atexit`.

Introduce our own internal `ExportImportList` script to compute symbol
export lists from object files.  Use a basic implementation for now: it
can be extended as needed later.  Update our shared library creation
rules to run the script explicitly for both the XL and GNU compilers.

Issue: #19163
This commit is contained in:
Brad King
2019-07-11 20:32:59 -04:00
parent a5bf4e7921
commit 0f150b69d3
3 changed files with 60 additions and 20 deletions

View File

@@ -25,4 +25,11 @@ macro(__aix_compiler_gnu lang)
if(CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 7 OR CMAKE_SYSTEM_VERSION VERSION_LESS 7.1)
unset(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY)
endif()
# Construct the export list ourselves to pass only the object files so
# that we export only the symbols actually provided by the sources.
set(CMAKE_${lang}_CREATE_SHARED_LIBRARY
"\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <OBJECT_DIR>/objects.exp <OBJECTS>"
"<CMAKE_${lang}_COMPILER> <CMAKE_SHARED_LIBRARY_${lang}_FLAGS> -Wl,-bE:<OBJECT_DIR>/objects.exp <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>"
)
endmacro()

View File

@@ -24,25 +24,10 @@ macro(__aix_compiler_xl lang)
set(CMAKE_${lang}_LINK_FLAGS "-Wl,-bnoipath")
# Find the CreateExportList program that comes with this toolchain.
find_program(CMAKE_XL_CreateExportList
NAMES CreateExportList
DOC "IBM XL CreateExportList tool"
# Construct the export list ourselves to pass only the object files so
# that we export only the symbols actually provided by the sources.
set(CMAKE_${lang}_CREATE_SHARED_LIBRARY
"\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <OBJECT_DIR>/objects.exp <OBJECTS>"
"<CMAKE_${lang}_COMPILER> <CMAKE_SHARED_LIBRARY_${lang}_FLAGS> -Wl,-bE:<OBJECT_DIR>/objects.exp <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>"
)
# CMAKE_XL_CreateExportList is part of the AIX XL compilers but not the linux ones.
# If we found the tool, we'll use it to create exports, otherwise stick with the regular
# create shared library compile line.
if (CMAKE_XL_CreateExportList)
# The compiler front-end passes all object files, archive files, and shared
# library files named on the command line to CreateExportList to create a
# list of all symbols to be exported from the shared library. This causes
# all archive members to be copied into the shared library whether they are
# needed or not. Instead we run the tool ourselves to pass only the object
# files so that we export only the symbols actually provided by the sources.
set(CMAKE_${lang}_CREATE_SHARED_LIBRARY
"${CMAKE_XL_CreateExportList} <OBJECT_DIR>/objects.exp <OBJECTS>"
"<CMAKE_${lang}_COMPILER> <CMAKE_SHARED_LIBRARY_${lang}_FLAGS> -Wl,-bE:<OBJECT_DIR>/objects.exp <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>"
)
endif()
endmacro()

View File

@@ -0,0 +1,48 @@
#!/bin/sh
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
# This script is internal to CMake and meant only to be
# invoked by CMake-generated build systems on AIX.
usage='usage: ExportImportList -o <out-file> [--] <objects>...'
die() {
echo "$@" 1>&2; exit 1
}
# Process command-line arguments.
out=''
while test "$#" != 0; do
case "$1" in
-o) shift; out="$1" ;;
--) shift; break ;;
-*) die "$usage" ;;
*) break ;;
esac
shift
done
test -n "$out" || die "$usage"
# Collect symbols exported from all object files.
out_tmp="$out.tmp$$"
trap 'rm -f "$out_tmp"' EXIT INT TERM
for f in "$@"; do
dump -tov -X 32_64 "$f" |
awk '
BEGIN {
V["EXPORTED"]=" export"
V["PROTECTED"]=" protected"
}
/^\[[0-9]+\]\tm +[^ ]+ +\.(text|data|bss) +[^ ]+ +(extern|weak) +(EXPORTED|PROTECTED| ) / {
if (!match($NF,/^(\.|__sinit|__sterm|__[0-9]+__)/)) {
print $NF V[$(NF-1)]
}
}
'
done > "$out_tmp"
# Generate the export/import file.
{
sort -u "$out_tmp"
} > "$out"