Add support for x32-abi

Detect x32-abi through CMakeCompilerABI infrastruture and use this
information at runtime to determine the correct library paths with
`FIND_LIBRARY_USE_LIBX32_PATHS`.

Fixes: #15994
This commit is contained in:
Steven Newbury
2017-02-27 21:06:51 +00:00
committed by Brad King
parent 06ef23c3e0
commit 462cf25427
13 changed files with 74 additions and 3 deletions

View File

@@ -53,7 +53,8 @@ If the :variable:`CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX` variable is set all
search paths will be tested as normal, with the suffix appended, and with search paths will be tested as normal, with the suffix appended, and with
all matches of ``lib/`` replaced with all matches of ``lib/`` replaced with
``lib${CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX}/``. This variable overrides ``lib${CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX}/``. This variable overrides
the :prop_gbl:`FIND_LIBRARY_USE_LIB32_PATHS` the :prop_gbl:`FIND_LIBRARY_USE_LIB32_PATHS`,
:prop_gbl:`FIND_LIBRARY_USE_LIBX32_PATHS`,
and :prop_gbl:`FIND_LIBRARY_USE_LIB64_PATHS` global properties. and :prop_gbl:`FIND_LIBRARY_USE_LIB64_PATHS` global properties.
If the :prop_gbl:`FIND_LIBRARY_USE_LIB32_PATHS` global property is set If the :prop_gbl:`FIND_LIBRARY_USE_LIB32_PATHS` global property is set
@@ -63,6 +64,13 @@ automatically set for the platforms that are known to need it if at
least one of the languages supported by the :command:`project` command least one of the languages supported by the :command:`project` command
is enabled. is enabled.
If the :prop_gbl:`FIND_LIBRARY_USE_LIBX32_PATHS` global property is set
all search paths will be tested as normal, with ``x32/`` appended, and
with all matches of ``lib/`` replaced with ``libx32/``. This property is
automatically set for the platforms that are known to need it if at
least one of the languages supported by the :command:`project` command
is enabled.
If the :prop_gbl:`FIND_LIBRARY_USE_LIB64_PATHS` global property is set If the :prop_gbl:`FIND_LIBRARY_USE_LIB64_PATHS` global property is set
all search paths will be tested as normal, with ``64/`` appended, and all search paths will be tested as normal, with ``64/`` appended, and
with all matches of ``lib/`` replaced with ``lib64/``. This property is with all matches of ``lib/`` replaced with ``lib64/``. This property is

View File

@@ -26,6 +26,7 @@ Properties of Global Scope
/prop_gbl/ENABLED_LANGUAGES /prop_gbl/ENABLED_LANGUAGES
/prop_gbl/FIND_LIBRARY_USE_LIB32_PATHS /prop_gbl/FIND_LIBRARY_USE_LIB32_PATHS
/prop_gbl/FIND_LIBRARY_USE_LIB64_PATHS /prop_gbl/FIND_LIBRARY_USE_LIB64_PATHS
/prop_gbl/FIND_LIBRARY_USE_LIBX32_PATHS
/prop_gbl/FIND_LIBRARY_USE_OPENBSD_VERSIONING /prop_gbl/FIND_LIBRARY_USE_OPENBSD_VERSIONING
/prop_gbl/GLOBAL_DEPENDS_DEBUG_MODE /prop_gbl/GLOBAL_DEPENDS_DEBUG_MODE
/prop_gbl/GLOBAL_DEPENDS_NO_CYCLES /prop_gbl/GLOBAL_DEPENDS_NO_CYCLES

View File

@@ -0,0 +1,12 @@
FIND_LIBRARY_USE_LIBX32_PATHS
-----------------------------
Whether the :command:`find_library` command should automatically search
``libx32`` directories.
``FIND_LIBRARY_USE_LIBX32_PATHS`` is a boolean specifying whether the
:command:`find_library` command should automatically search the ``libx32``
variant of directories called ``lib`` in the search path when building
x32-abi binaries.
See also the :variable:`CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX` variable.

View File

@@ -9,3 +9,4 @@ This overrides the behavior of related global properties:
* :prop_gbl:`FIND_LIBRARY_USE_LIB32_PATHS` * :prop_gbl:`FIND_LIBRARY_USE_LIB32_PATHS`
* :prop_gbl:`FIND_LIBRARY_USE_LIB64_PATHS` * :prop_gbl:`FIND_LIBRARY_USE_LIB64_PATHS`
* :prop_gbl:`FIND_LIBRARY_USE_LIBX32_PATHS`

View File

@@ -25,6 +25,10 @@ const char info_sizeof_dptr[] = {
#elif defined(__GNU__) && defined(__ELF__) && defined(__ARMEL__) #elif defined(__GNU__) && defined(__ELF__) && defined(__ARMEL__)
#define ABI_ID "ELF ARM" #define ABI_ID "ELF ARM"
#elif defined(__linux__) && defined(__ELF__) && defined(__amd64__) && \
defined(__ILP32__)
#define ABI_ID "ELF X32"
#elif defined(__ELF__) #elif defined(__ELF__)
#define ABI_ID "ELF" #define ABI_ID "ELF"
#endif #endif

View File

@@ -312,6 +312,10 @@ macro(_pkg_check_modules_internal _is_required _is_silent _no_cmake_path _no_cma
if(uselib64 AND CMAKE_SIZEOF_VOID_P EQUAL 8) if(uselib64 AND CMAKE_SIZEOF_VOID_P EQUAL 8)
list(APPEND _lib_dirs "lib64/pkgconfig") list(APPEND _lib_dirs "lib64/pkgconfig")
endif() endif()
get_property(uselibx32 GLOBAL PROPERTY FIND_LIBRARY_USE_LIBX32_PATHS)
if(uselibx32 AND CMAKE_INTERNAL_PLATFORM_ABI STREQUAL "ELF X32")
list(APPEND _lib_dirs "libx32/pkgconfig")
endif()
endif() endif()
endif() endif()
list(APPEND _lib_dirs "lib/pkgconfig") list(APPEND _lib_dirs "lib/pkgconfig")

View File

@@ -86,3 +86,4 @@ list(APPEND CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES
# Enable use of lib32 and lib64 search path variants by default. # Enable use of lib32 and lib64 search path variants by default.
set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB32_PATHS TRUE) set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB32_PATHS TRUE)
set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS TRUE) set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS TRUE)
set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIBX32_PATHS TRUE)

View File

@@ -195,8 +195,10 @@ void cmExportInstallFileGenerator::GenerateImportPrefix(std::ostream& os)
<< " \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n"; << " \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n";
if (cmHasLiteralPrefix(absDestS.c_str(), "/lib/") || if (cmHasLiteralPrefix(absDestS.c_str(), "/lib/") ||
cmHasLiteralPrefix(absDestS.c_str(), "/lib64/") || cmHasLiteralPrefix(absDestS.c_str(), "/lib64/") ||
cmHasLiteralPrefix(absDestS.c_str(), "/libx32/") ||
cmHasLiteralPrefix(absDestS.c_str(), "/usr/lib/") || cmHasLiteralPrefix(absDestS.c_str(), "/usr/lib/") ||
cmHasLiteralPrefix(absDestS.c_str(), "/usr/lib64/")) { cmHasLiteralPrefix(absDestS.c_str(), "/usr/lib64/") ||
cmHasLiteralPrefix(absDestS.c_str(), "/usr/libx32/")) {
// Handle "/usr move" symlinks created by some Linux distros. // Handle "/usr move" symlinks created by some Linux distros.
/* clang-format off */ /* clang-format off */
os << os <<

View File

@@ -43,7 +43,8 @@ bool cmFindLibraryCommand::InitialPass(std::vector<std::string> const& argsIn,
return true; return true;
} }
// add custom lib<qual> paths instead of using fixed lib32 or lib64 // add custom lib<qual> paths instead of using fixed lib32, lib64 or
// libx32
if (const char* customLib = this->Makefile->GetDefinition( if (const char* customLib = this->Makefile->GetDefinition(
"CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX")) { "CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX")) {
this->AddArchitecturePaths(customLib); this->AddArchitecturePaths(customLib);
@@ -60,6 +61,12 @@ bool cmFindLibraryCommand::InitialPass(std::vector<std::string> const& argsIn,
"FIND_LIBRARY_USE_LIB64_PATHS")) { "FIND_LIBRARY_USE_LIB64_PATHS")) {
this->AddArchitecturePaths("64"); this->AddArchitecturePaths("64");
} }
// add special 32 bit paths if this is an x32 compile.
else if (this->Makefile->PlatformIsx32() &&
this->Makefile->GetState()->GetGlobalPropertyAsBool(
"FIND_LIBRARY_USE_LIBX32_PATHS")) {
this->AddArchitecturePaths("x32");
}
std::string library = this->FindLibrary(); std::string library = this->FindLibrary();
if (library != "") { if (library != "") {

View File

@@ -92,6 +92,7 @@ cmFindPackageCommand::cmFindPackageCommand()
this->DebugMode = false; this->DebugMode = false;
this->UseLib32Paths = false; this->UseLib32Paths = false;
this->UseLib64Paths = false; this->UseLib64Paths = false;
this->UseLibx32Paths = false;
this->PolicyScope = true; this->PolicyScope = true;
this->VersionMajor = 0; this->VersionMajor = 0;
this->VersionMinor = 0; this->VersionMinor = 0;
@@ -173,6 +174,13 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args,
this->UseLib64Paths = true; this->UseLib64Paths = true;
} }
// Lookup whether libx32 paths should be used.
if (this->Makefile->PlatformIsx32() &&
this->Makefile->GetState()->GetGlobalPropertyAsBool(
"FIND_LIBRARY_USE_LIBX32_PATHS")) {
this->UseLibx32Paths = true;
}
// Check if User Package Registry should be disabled // Check if User Package Registry should be disabled
if (this->Makefile->IsOn("CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY")) { if (this->Makefile->IsOn("CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY")) {
this->NoUserRegistry = true; this->NoUserRegistry = true;
@@ -2002,6 +2010,9 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
if (this->UseLib64Paths) { if (this->UseLib64Paths) {
common.push_back("lib64"); common.push_back("lib64");
} }
if (this->UseLibx32Paths) {
common.push_back("libx32");
}
common.push_back("lib"); common.push_back("lib");
common.push_back("share"); common.push_back("share");

View File

@@ -169,6 +169,7 @@ private:
bool DebugMode; bool DebugMode;
bool UseLib32Paths; bool UseLib32Paths;
bool UseLib64Paths; bool UseLib64Paths;
bool UseLibx32Paths;
bool PolicyScope; bool PolicyScope;
std::string LibraryArchitecture; std::string LibraryArchitecture;
std::vector<std::string> Names; std::vector<std::string> Names;

View File

@@ -2149,6 +2149,12 @@ bool cmMakefile::IsSet(const std::string& name) const
bool cmMakefile::PlatformIs32Bit() const bool cmMakefile::PlatformIs32Bit() const
{ {
if (const char* plat_abi =
this->GetDefinition("CMAKE_INTERNAL_PLATFORM_ABI")) {
if (strcmp(plat_abi, "ELF X32") == 0) {
return false;
}
}
if (const char* sizeof_dptr = this->GetDefinition("CMAKE_SIZEOF_VOID_P")) { if (const char* sizeof_dptr = this->GetDefinition("CMAKE_SIZEOF_VOID_P")) {
return atoi(sizeof_dptr) == 4; return atoi(sizeof_dptr) == 4;
} }
@@ -2163,6 +2169,17 @@ bool cmMakefile::PlatformIs64Bit() const
return false; return false;
} }
bool cmMakefile::PlatformIsx32() const
{
if (const char* plat_abi =
this->GetDefinition("CMAKE_INTERNAL_PLATFORM_ABI")) {
if (strcmp(plat_abi, "ELF X32") == 0) {
return true;
}
}
return false;
}
bool cmMakefile::PlatformIsAppleIos() const bool cmMakefile::PlatformIsAppleIos() const
{ {
std::string sdkRoot; std::string sdkRoot;

View File

@@ -436,6 +436,8 @@ public:
/** Return whether the target platform is 64-bit. */ /** Return whether the target platform is 64-bit. */
bool PlatformIs64Bit() const; bool PlatformIs64Bit() const;
/** Return whether the target platform is x32. */
bool PlatformIsx32() const;
/** Return whether the target platform is Apple iOS. */ /** Return whether the target platform is Apple iOS. */
bool PlatformIsAppleIos() const; bool PlatformIsAppleIos() const;