Merge topic 'aix-no-export-all'

afcd9fe669 AIX: Add an option to disable automatic exports from shared libraries
67f30811ce AIX: Improve name of internal symbol export list file
0ffd54f094 AIX: Add ExportImportList option to skip the object files
0dcfb63cb9 AIX: Revise ExportImportList to build output more incrementally

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !4308
This commit is contained in:
Brad King 2020-02-03 16:31:54 +00:00 committed by Kitware Robot
commit 999a8663c5
24 changed files with 126 additions and 22 deletions

View File

@ -104,6 +104,7 @@ Properties on Targets
:maxdepth: 1
/prop_tgt/ADDITIONAL_CLEAN_FILES
/prop_tgt/AIX_EXPORT_ALL_SYMBOLS
/prop_tgt/ALIASED_TARGET
/prop_tgt/ANDROID_ANT_ADDITIONAL_OPTIONS
/prop_tgt/ANDROID_API

View File

@ -323,6 +323,7 @@ Variables that Control the Build
.. toctree::
:maxdepth: 1
/variable/CMAKE_AIX_EXPORT_ALL_SYMBOLS
/variable/CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS
/variable/CMAKE_ANDROID_API
/variable/CMAKE_ANDROID_API_MIN

View File

@ -0,0 +1,12 @@
AIX_EXPORT_ALL_SYMBOLS
----------------------
On AIX, CMake automatically exports all symbols from shared libraries, and
from executables with the :prop_tgt:`ENABLE_EXPORTS` target property set.
Explicitly disable this boolean property to suppress the behavior and
export no symbols by default. In this case it is expected that the project
will use other means to export some symbols.
This property is initialized by the value of
the :variable:`CMAKE_AIX_EXPORT_ALL_SYMBOLS` variable if it is set
when a target is created.

View File

@ -0,0 +1,7 @@
aix-no-export-all
-----------------
* The :prop_tgt:`AIX_EXPORT_ALL_SYMBOLS` target property and associated
:variable:`CMAKE_AIX_EXPORT_ALL_SYMBOLS` variable were created to
optionally explicitly disbale automatic export of symbols from shared
libraries on AIX.

View File

@ -0,0 +1,6 @@
CMAKE_AIX_EXPORT_ALL_SYMBOLS
----------------------------
Default value for :prop_tgt:`AIX_EXPORT_ALL_SYMBOLS` target property.
This variable is used to initialize the property on each target as it is
created.

View File

@ -23,11 +23,11 @@ macro(__aix_compiler_gnu lang)
# 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_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <OBJECT_DIR>/exports.exp <AIX_EXPORTS> <OBJECTS>"
"<CMAKE_${lang}_COMPILER> <CMAKE_SHARED_LIBRARY_${lang}_FLAGS> -Wl,-bE:<OBJECT_DIR>/exports.exp <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>"
)
set(CMAKE_${lang}_LINK_EXECUTABLE_WITH_EXPORTS
"\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <TARGET_IMPLIB> -l . <OBJECTS>"
"\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <TARGET_IMPLIB> -l . <AIX_EXPORTS> <OBJECTS>"
"<CMAKE_${lang}_COMPILER> <FLAGS> <CMAKE_${lang}_LINK_FLAGS> -Wl,-bE:<TARGET_IMPLIB> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
endmacro()

View File

@ -29,12 +29,12 @@ macro(__aix_compiler_xl lang)
# 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_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <OBJECT_DIR>/exports.exp <AIX_EXPORTS>${_OBJECTS}"
"<CMAKE_${lang}_COMPILER> <CMAKE_SHARED_LIBRARY_${lang}_FLAGS> -Wl,-bE:<OBJECT_DIR>/exports.exp <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>"
)
set(CMAKE_${lang}_LINK_EXECUTABLE_WITH_EXPORTS
"\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <TARGET_IMPLIB> -l . <OBJECTS>"
"\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <TARGET_IMPLIB> -l . <AIX_EXPORTS> <OBJECTS>"
"<CMAKE_${lang}_COMPILER> <FLAGS> <CMAKE_${lang}_LINK_FLAGS> -Wl,-bE:<TARGET_IMPLIB> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
unset(_OBJECTS)

View File

@ -5,7 +5,7 @@
# 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> [-l <lib>] [--] <objects>...'
usage='usage: ExportImportList -o <out-file> [-l <lib>] [-n] [--] <objects>...'
die() {
echo "$@" 1>&2; exit 1
@ -14,10 +14,12 @@ die() {
# Process command-line arguments.
out=''
lib=''
no_objects=''
while test "$#" != 0; do
case "$1" in
-l) shift; lib="$1" ;;
-o) shift; out="$1" ;;
-n) no_objects='1' ;;
--) shift; break ;;
-*) die "$usage" ;;
*) break ;;
@ -26,23 +28,28 @@ while test "$#" != 0; do
done
test -n "$out" || die "$usage"
# Collect symbols exported from all object files.
# Build a temporary file that atomically replaces the output later.
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)]
> "$out_tmp"
# Collect symbols exported from all object files.
if test -z "$no_objects"; then
for f in "$@"; do
dump -tov -X 32_64 "$f" |
awk '
BEGIN {
V["EXPORTED"]=" export"
V["PROTECTED"]=" protected"
}
}
'
done > "$out_tmp"
/^\[[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"
fi
# Generate the export/import file.
{

View File

@ -17,6 +17,7 @@
#include "cmSourceFile.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmTarget.h"
cmCommonTargetGenerator::cmCommonTargetGenerator(cmGeneratorTarget* gt)
: GeneratorTarget(gt)
@ -216,6 +217,20 @@ std::string cmCommonTargetGenerator::GetManifests(const std::string& config)
return cmJoin(manifests, " ");
}
std::string cmCommonTargetGenerator::GetAIXExports(std::string const&)
{
std::string aixExports;
if (this->GeneratorTarget->Target->IsAIX()) {
if (const char* exportAll =
this->GeneratorTarget->GetProperty("AIX_EXPORT_ALL_SYMBOLS")) {
if (cmIsOff(exportAll)) {
aixExports = "-n";
}
}
}
return aixExports;
}
void cmCommonTargetGenerator::AppendOSXVerFlag(std::string& flags,
const std::string& lang,
const char* name, bool so)

View File

@ -55,6 +55,7 @@ protected:
std::string GetDefines(const std::string& l, const std::string& config);
std::string GetIncludes(std::string const& l, const std::string& config);
std::string GetManifests(const std::string& config);
std::string GetAIXExports(std::string const& config);
std::vector<std::string> GetLinkedTargetDirectories(
const std::string& config) const;

View File

@ -196,6 +196,8 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule(
this->CreateObjectLists(useLinkScript, false, useResponseFileForObjects,
buildObjs, depends, useWatcomQuote);
std::string const& aixExports = this->GetAIXExports(this->GetConfigName());
cmRulePlaceholderExpander::RuleVariables vars;
std::string objectDir = this->GeneratorTarget->GetSupportDirectory();
@ -219,6 +221,7 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule(
cmOutputConverter::SHELL);
vars.Language = linkLanguage.c_str();
vars.AIXExports = aixExports.c_str();
vars.Objects = buildObjs.c_str();
vars.ObjectDir = objectDir.c_str();
vars.Target = target.c_str();

View File

@ -727,6 +727,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
cmOutputConverter::SHELL);
}
std::string const& aixExports = this->GetAIXExports(this->GetConfigName());
// maybe create .def file from list of objects
this->GenDefFile(real_link_commands);
@ -756,6 +758,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
vars.CMTargetType =
cmState::GetTargetTypeName(this->GeneratorTarget->GetType());
vars.Language = linkLanguage.c_str();
vars.AIXExports = aixExports.c_str();
vars.Objects = buildObjs.c_str();
std::string objectDir = this->GeneratorTarget->GetSupportDirectory();

View File

@ -286,6 +286,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile,
std::string lang = this->TargetLinkLanguage(config);
vars.Language = config.c_str();
vars.AIXExports = "$AIX_EXPORTS";
if (this->TargetLinkLanguage(config) == "Swift") {
vars.SwiftLibraryName = "$SWIFT_LIBRARY_NAME";
@ -955,6 +956,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
vars["LINK_FLAGS"] = globalGen->EncodeLiteral(vars["LINK_FLAGS"]);
vars["MANIFESTS"] = this->GetManifests(config);
vars["AIX_EXPORTS"] = this->GetAIXExports(config);
vars["LINK_PATH"] = frameworkPath + linkPath;
std::string lwyuFlags;

View File

@ -85,6 +85,11 @@ std::string cmRulePlaceholderExpander::ExpandRuleVariable(
return replaceValues.ObjectsQuoted;
}
}
if (replaceValues.AIXExports) {
if (variable == "AIX_EXPORTS") {
return replaceValues.AIXExports;
}
}
if (replaceValues.Defines && variable == "DEFINES") {
return replaceValues.Defines;
}

View File

@ -36,6 +36,7 @@ public:
const char* TargetVersionMajor;
const char* TargetVersionMinor;
const char* Language;
const char* AIXExports;
const char* Objects;
const char* Target;
const char* LinkLibraries;

View File

@ -491,6 +491,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
}
if (impl->TargetType == cmStateEnums::SHARED_LIBRARY ||
impl->TargetType == cmStateEnums::EXECUTABLE) {
initProp("AIX_EXPORT_ALL_SYMBOLS");
initProp("WINDOWS_EXPORT_ALL_SYMBOLS");
}

View File

@ -0,0 +1 @@
[^0]

View File

@ -0,0 +1 @@
ERROR: Undefined symbol: .AIXNotExported

View File

@ -0,0 +1,7 @@
enable_language(C)
set(CMAKE_AIX_EXPORT_ALL_SYMBOLS OFF)
add_library(AIXExportExplicitLib SHARED AIXExportExplicitLib.c)
add_executable(AIXExportExplicitMain AIXExportExplicitMain.c)
target_link_options(AIXExportExplicitLib PRIVATE LINKER:-bE:${CMAKE_CURRENT_SOURCE_DIR}/AIXExportExplicitLib.exp)
target_link_libraries(AIXExportExplicitMain PRIVATE AIXExportExplicitLib)

View File

@ -0,0 +1,8 @@
int AIXNotExported(void)
{
return 0;
}
int AIXExportedSymbol(void)
{
return 0;
}

View File

@ -0,0 +1 @@
AIXExportedSymbol

View File

@ -0,0 +1,7 @@
extern int AIXNotExported(void);
extern int AIXExportedSymbol(void);
int main(void)
{
return AIXNotExported() + AIXExportedSymbol();
}

View File

@ -55,3 +55,14 @@ if(EXPORTS)
message(SEND_ERROR "\"${EXPORTS_DEF}\" has been updated.")
endif()
endif()
function(run_AIXExportExplicit)
set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/AIXExpotExplicit-build")
run_cmake(AIXExportExplicit)
set(RunCMake_TEST_NO_CLEAN 1)
set(RunCMake_TEST_OUTPUT_MERGE TRUE)
run_cmake_command(AIXExportExplicit-build ${CMAKE_COMMAND} --build . --config Debug)
endfunction()
if(CMAKE_SYSTEM_NAME STREQUAL "AIX")
run_AIXExportExplicit()
endif()

View File

@ -614,7 +614,10 @@ endif()
add_RunCMake_test_group(CPack "${cpack_tests}")
# add a test to make sure symbols are exported from a shared library
# for MSVC compilers CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS property is used
add_RunCMake_test(AutoExportDll -DCMAKE_CXX_COMPILER_ID=${CMAKE_CXX_COMPILER_ID})
add_RunCMake_test(AutoExportDll
-DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}
-DCMAKE_CXX_COMPILER_ID=${CMAKE_CXX_COMPILER_ID}
)
add_RunCMake_test(AndroidMK)