summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2019-07-12 16:55:55 (GMT)
committerBrad King <brad.king@kitware.com>2019-07-15 17:27:16 (GMT)
commit9f5c2040bfd41a2c87624cec3d9504cf477c9fc3 (patch)
tree9c3b008604781f25b8a43938c584d6a5627e8f90
parent0f150b69d3a01c3c5b4a96d10334eb2703ba237f (diff)
downloadCMake-9f5c2040bfd41a2c87624cec3d9504cf477c9fc3.zip
CMake-9f5c2040bfd41a2c87624cec3d9504cf477c9fc3.tar.gz
CMake-9f5c2040bfd41a2c87624cec3d9504cf477c9fc3.tar.bz2
AIX: Explicitly compute executable exports for both XL and GNU
On AIX, symbols in executables must be exported in order to be visible to modules (plugins) they load via `dlopen`. Prior to policy `CMP0065`, CMake linked all executables with flags to export symbols, but the NEW behavior for that policy is to do so only for executables that have the `ENABLE_EXPORTS` target property set. In both cases, CMake has always used the AIX linker option `-bexpall` option to export symbols from executables. This has worked fairly well with the XL compiler, but with the GNU compiler it works only for C ABI symbols. The reason is that `-bexpall` does not export symbols starting in `_` but the GNU C++ ABI mangles all symbols with a leading `_`. Therefore we have only supported C ABI plugins with the GNU compiler on AIX. Some projects have tried to work around this by replacing `-bexpall` with `-bexpfull`, but the latter often exports symbols that we do not want exported. Avoid using `-bexpall` for executables by instead using by our own internal `ExportImportList` script to compute symbol export lists from the object files to be linked into an executable. Pass the explicitly computed export list to the AIX linker's `-bE:...` option. We already do this for shared object exports. Issue: #19163
-rw-r--r--Modules/Platform/AIX-GNU.cmake6
-rw-r--r--Modules/Platform/AIX-XL.cmake6
-rw-r--r--Source/cmGeneratorTarget.cxx7
-rw-r--r--Source/cmLocalGenerator.cxx12
-rw-r--r--Source/cmTarget.cxx11
-rw-r--r--Source/cmTarget.h3
-rw-r--r--Tests/RunCMake/CMP0065/RunCMakeTest.cmake7
-rw-r--r--Tests/RunCMake/CMakeLists.txt2
8 files changed, 45 insertions, 9 deletions
diff --git a/Modules/Platform/AIX-GNU.cmake b/Modules/Platform/AIX-GNU.cmake
index beb928b..cec71a1 100644
--- a/Modules/Platform/AIX-GNU.cmake
+++ b/Modules/Platform/AIX-GNU.cmake
@@ -18,7 +18,7 @@ macro(__aix_compiler_gnu lang)
set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG "-Wl,-blibpath:")
set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG_SEP ":")
string(APPEND CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS " -Wl,-G,-bnoipath")
- set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-Wl,-bexpall")
+ set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-Wl,-bexpall") # CMP0065 old behavior
set(CMAKE_${lang}_USE_IMPLICIT_LINK_DIRECTORIES_IN_RUNTIME_PATH 1)
set(CMAKE_${lang}_LINK_FLAGS "-Wl,-bnoipath")
@@ -32,4 +32,8 @@ macro(__aix_compiler_gnu lang)
"\"${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>"
)
+
+ set(CMAKE_${lang}_LINK_EXECUTABLE_WITH_EXPORTS
+ "\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <OBJECT_DIR>/objects.exp <OBJECTS>"
+ "<CMAKE_${lang}_COMPILER> <FLAGS> <CMAKE_${lang}_LINK_FLAGS> -Wl,-bE:<OBJECT_DIR>/objects.exp <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
endmacro()
diff --git a/Modules/Platform/AIX-XL.cmake b/Modules/Platform/AIX-XL.cmake
index 569edf7..52292bd 100644
--- a/Modules/Platform/AIX-XL.cmake
+++ b/Modules/Platform/AIX-XL.cmake
@@ -18,7 +18,7 @@ macro(__aix_compiler_xl lang)
set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG "-Wl,-blibpath:")
set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG_SEP ":")
set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-G -Wl,-bnoipath") # -shared
- set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-Wl,-bexpall")
+ set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-Wl,-bexpall") # CMP0065 old behavior
set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS " ")
set(CMAKE_SHARED_MODULE_${lang}_FLAGS " ")
@@ -30,4 +30,8 @@ macro(__aix_compiler_xl lang)
"\"${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>"
)
+
+ set(CMAKE_${lang}_LINK_EXECUTABLE_WITH_EXPORTS
+ "\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <OBJECT_DIR>/objects.exp <OBJECTS>"
+ "<CMAKE_${lang}_COMPILER> <FLAGS> <CMAKE_${lang}_LINK_FLAGS> -Wl,-bE:<OBJECT_DIR>/objects.exp <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
endmacro()
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index c807f6d..a2c0503 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -2754,6 +2754,13 @@ std::string cmGeneratorTarget::GetCreateRuleVariable(
case cmStateEnums::MODULE_LIBRARY:
return "CMAKE_" + lang + "_CREATE_SHARED_MODULE";
case cmStateEnums::EXECUTABLE:
+ if (this->IsExecutableWithExports()) {
+ std::string linkExeWithExports =
+ "CMAKE_" + lang + "_LINK_EXECUTABLE_WITH_EXPORTS";
+ if (this->Makefile->IsDefinitionSet(linkExeWithExports)) {
+ return linkExeWithExports;
+ }
+ }
return "CMAKE_" + lang + "_LINK_EXECUTABLE";
default:
break;
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 0f730c9..4ffd6e0 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -1515,8 +1515,10 @@ std::string cmLocalGenerator::GetLinkLibsCMP0065(
}
CM_FALLTHROUGH;
case cmPolicies::OLD:
- // OLD behavior is to always add the flags
- add_shlib_flags = true;
+ // OLD behavior is to always add the flags, except on AIX where
+ // we compute symbol exports if ENABLE_EXPORTS is on.
+ add_shlib_flags =
+ !(tgt.Target->IsAIX() && tgt.GetPropertyAsBool("ENABLE_EXPORTS"));
break;
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
@@ -1525,8 +1527,10 @@ std::string cmLocalGenerator::GetLinkLibsCMP0065(
cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0065));
CM_FALLTHROUGH;
case cmPolicies::NEW:
- // NEW behavior is to only add the flags if ENABLE_EXPORTS is on
- add_shlib_flags = tgt.GetPropertyAsBool("ENABLE_EXPORTS");
+ // NEW behavior is to only add the flags if ENABLE_EXPORTS is on,
+ // except on AIX where we compute symbol exports.
+ add_shlib_flags =
+ !tgt.Target->IsAIX() && tgt.GetPropertyAsBool("ENABLE_EXPORTS");
break;
}
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 773487e..9290d27 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -171,6 +171,7 @@ public:
bool IsGeneratorProvided;
bool HaveInstallRule;
bool IsDLLPlatform;
+ bool IsAIX;
bool IsAndroid;
bool IsImportedTarget;
bool ImportedGloballyVisible;
@@ -219,6 +220,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
impl->IsGeneratorProvided = false;
impl->HaveInstallRule = false;
impl->IsDLLPlatform = false;
+ impl->IsAIX = false;
impl->IsAndroid = false;
impl->IsImportedTarget =
(vis == VisibilityImported || vis == VisibilityImportedGlobally);
@@ -229,6 +231,10 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
impl->IsDLLPlatform =
!impl->Makefile->GetSafeDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX").empty();
+ // Check whether we are targeting AIX.
+ impl->IsAIX =
+ (impl->Makefile->GetSafeDefinition("CMAKE_SYSTEM_NAME") == "AIX");
+
// Check whether we are targeting an Android platform.
impl->IsAndroid =
(impl->Makefile->GetSafeDefinition("CMAKE_SYSTEM_NAME") == "Android");
@@ -1664,6 +1670,11 @@ bool cmTarget::IsDLLPlatform() const
return impl->IsDLLPlatform;
}
+bool cmTarget::IsAIX() const
+{
+ return impl->IsAIX;
+}
+
bool cmTarget::IsImported() const
{
return impl->IsImportedTarget;
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index d9e87b8..a808bb4 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -180,6 +180,9 @@ public:
//! Return whether or not the target is for a DLL platform.
bool IsDLLPlatform() const;
+ //! Return whether or not we are targeting AIX.
+ bool IsAIX() const;
+
bool IsImported() const;
bool IsImportedGloballyVisible() const;
diff --git a/Tests/RunCMake/CMP0065/RunCMakeTest.cmake b/Tests/RunCMake/CMP0065/RunCMakeTest.cmake
index 254a4ec..e86b50e 100644
--- a/Tests/RunCMake/CMP0065/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CMP0065/RunCMakeTest.cmake
@@ -1,8 +1,11 @@
include(RunCMake)
run_cmake(OLDBad1)
-run_cmake(OLDBad2)
-run_cmake(NEWBad)
+if(NOT CMAKE_SYSTEM_NAME STREQUAL "AIX")
+ # Tests with ENABLE_EXPORTS ON. For AIX we do not use the flags at all.
+ run_cmake(OLDBad2)
+ run_cmake(NEWBad)
+endif()
run_cmake(NEWGood)
run_cmake(WARN-OFF)
run_cmake(WARN-ON)
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 735ad5f..c952b1a 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -120,7 +120,7 @@ add_RunCMake_test(CMP0081)
# CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS variable, which both the VS and Xcode
# generators ignore. The policy will have no effect on those generators.
if(NOT CMAKE_GENERATOR MATCHES "Visual Studio|Xcode")
- add_RunCMake_test(CMP0065)
+ add_RunCMake_test(CMP0065 -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME})
endif()
if(CMAKE_GENERATOR MATCHES "Make")
add_RunCMake_test(Make -DMAKE_IS_GNU=${MAKE_IS_GNU})