mirror of
https://github.com/Kitware/CMake.git
synced 2026-02-16 12:11:04 -06:00
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
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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})
|
||||
|
||||
Reference in New Issue
Block a user