summaryrefslogtreecommitdiff
path: root/src/corefx
diff options
context:
space:
mode:
authorTom Deseyn <tom.deseyn@gmail.com>2017-12-22 13:25:43 +0100
committerJan Vorlicek <janvorli@microsoft.com>2017-12-22 13:25:43 +0100
commit845da035a50199f53ae805840c92845d0a3573c7 (patch)
tree01171c4d17ba3076f86440809744d62c523b0f0b /src/corefx
parent0f97a82d81c32c388fb69a17fe9dd4d21cd2efd2 (diff)
downloadcoreclr-845da035a50199f53ae805840c92845d0a3573c7.tar.gz
coreclr-845da035a50199f53ae805840c92845d0a3573c7.tar.bz2
coreclr-845da035a50199f53ae805840c92845d0a3573c7.zip
icushim: try using the build-time libicu version (#15562)
* icushim: try using the build-time libicu version * Based on ICU packaging doc, use major instead of (major, minor) * Verify we can look-up symbols on the build version * First find Major; add FEATURE_FIXED_ICU_VERSION * Move FindSymbolVersion check in OpenICULibraries * Remove FEATURE_FIXED_ICU_VERSION
Diffstat (limited to 'src/corefx')
-rw-r--r--src/corefx/System.Globalization.Native/icushim.cpp123
1 files changed, 61 insertions, 62 deletions
diff --git a/src/corefx/System.Globalization.Native/icushim.cpp b/src/corefx/System.Globalization.Native/icushim.cpp
index e97896a205..42193ba4d9 100644
--- a/src/corefx/System.Globalization.Native/icushim.cpp
+++ b/src/corefx/System.Globalization.Native/icushim.cpp
@@ -79,8 +79,38 @@ void GetVersionedLibFileName(const char* baseFileName, int majorVer, int minorVe
}
}
+bool FindSymbolVersion(int majorVer, int minorVer, int subVer, char* symbolName, char* symbolVersion)
+{
+ // Find out the format of the version string added to each symbol
+ // First try just the unversioned symbol
+ if (dlsym(libicuuc, "u_strlen") == nullptr)
+ {
+ // Now try just the _majorVer added
+ sprintf(symbolVersion, "_%d", majorVer);
+ sprintf(symbolName, "u_strlen%s", symbolVersion);
+ if ((dlsym(libicuuc, symbolName) == nullptr) && (minorVer != -1))
+ {
+ // Now try the _majorVer_minorVer added
+ sprintf(symbolVersion, "_%d_%d", majorVer, minorVer);
+ sprintf(symbolName, "u_strlen%s", symbolVersion);
+ if ((dlsym(libicuuc, symbolName) == nullptr) && (subVer != -1))
+ {
+ // Finally, try the _majorVer_minorVer_subVer added
+ sprintf(symbolVersion, "_%d_%d_%d", majorVer, minorVer, subVer);
+ sprintf(symbolName, "u_strlen%s", symbolVersion);
+ if (dlsym(libicuuc, symbolName) == nullptr)
+ {
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
// Try to open the necessary ICU libraries
-bool OpenICULibraries(int majorVer, int minorVer, int subVer)
+bool OpenICULibraries(int majorVer, int minorVer, int subVer, char* symbolName, char* symbolVersion)
{
char libicuucName[64];
char libicui18nName[64];
@@ -94,7 +124,10 @@ bool OpenICULibraries(int majorVer, int minorVer, int subVer)
libicuuc = dlopen(libicuucName, RTLD_LAZY);
if (libicuuc != nullptr)
{
- libicui18n = dlopen(libicui18nName, RTLD_LAZY);
+ if (FindSymbolVersion(majorVer, minorVer, subVer, symbolName, symbolVersion))
+ {
+ libicui18n = dlopen(libicui18nName, RTLD_LAZY);
+ }
if (libicui18n == nullptr)
{
dlclose(libicuuc);
@@ -109,7 +142,7 @@ bool OpenICULibraries(int majorVer, int minorVer, int subVer)
// environment variable.
// The format of the string in this variable is majorVer[.minorVer[.subVer]] (the brackets
// indicate optional parts).
-bool FindLibUsingOverride(int* majorVer, int* minorVer, int* subVer)
+bool FindLibUsingOverride(char* symbolName, char* symbolVersion)
{
char* versionOverride = getenv("CLR_ICU_VERSION_OVERRIDE");
if (versionOverride != nullptr)
@@ -121,11 +154,8 @@ bool FindLibUsingOverride(int* majorVer, int* minorVer, int* subVer)
int matches = sscanf(versionOverride, "%d.%d.%d", &first, &second, &third);
if (matches > 0)
{
- if (OpenICULibraries(first, second, third))
+ if (OpenICULibraries(first, second, third, symbolName, symbolVersion))
{
- *majorVer = first;
- *minorVer = second;
- *subVer = third;
return true;
}
}
@@ -134,15 +164,23 @@ bool FindLibUsingOverride(int* majorVer, int* minorVer, int* subVer)
return false;
}
-// Select the highest supported version of ICU present on the local machine
// Search for library files with names including the major version.
-bool FindLibWithMajorVersion(int* majorVer)
+bool FindLibWithMajorVersion(char* symbolName, char* symbolVersion)
{
- for (int i = MaxICUVersion; i >= MinICUVersion; i--)
+ // ICU packaging documentation (http://userguide.icu-project.org/packaging)
+ // describes applications link against the major (e.g. libicuuc.so.54).
+
+ // Select the version of ICU present at build time.
+ if (OpenICULibraries(MinICUVersion, -1, -1, symbolName, symbolVersion))
{
- if (OpenICULibraries(i, -1, -1))
+ return true;
+ }
+
+ // Select the highest supported version of ICU present on the local machine
+ for (int i = MaxICUVersion; i > MinICUVersion; i--)
+ {
+ if (OpenICULibraries(i, -1, -1, symbolName, symbolVersion))
{
- *majorVer = i;
return true;
}
}
@@ -152,16 +190,14 @@ bool FindLibWithMajorVersion(int* majorVer)
// Select the highest supported version of ICU present on the local machine
// Search for library files with names including the major and minor version.
-bool FindLibWithMajorMinorVersion(int* majorVer, int* minorVer)
+bool FindLibWithMajorMinorVersion(char* symbolName, char* symbolVersion)
{
for (int i = MaxICUVersion; i >= MinICUVersion; i--)
{
for (int j = MaxMinorICUVersion; j >= MinMinorICUVersion; j--)
{
- if (OpenICULibraries(i, j, -1))
+ if (OpenICULibraries(i, j, -1, symbolName, symbolVersion))
{
- *majorVer = i;
- *minorVer = j;
return true;
}
}
@@ -172,7 +208,7 @@ bool FindLibWithMajorMinorVersion(int* majorVer, int* minorVer)
// Select the highest supported version of ICU present on the local machine
// Search for library files with names including the major, minor and sub version.
-bool FindLibWithMajorMinorSubVersion(int* majorVer, int* minorVer, int* subVer)
+bool FindLibWithMajorMinorSubVersion(char* symbolName, char* symbolVersion)
{
for (int i = MaxICUVersion; i >= MinICUVersion; i--)
{
@@ -180,11 +216,8 @@ bool FindLibWithMajorMinorSubVersion(int* majorVer, int* minorVer, int* subVer)
{
for (int k = MaxSubICUVersion; k >= MinSubICUVersion; k--)
{
- if (OpenICULibraries(i, j, k))
+ if (OpenICULibraries(i, j, k, symbolName, symbolVersion))
{
- *majorVer = i;
- *minorVer = j;
- *subVer = k;
return true;
}
}
@@ -196,46 +229,10 @@ bool FindLibWithMajorMinorSubVersion(int* majorVer, int* minorVer, int* subVer)
bool FindICULibs(char* symbolName, char* symbolVersion)
{
- int majorVer = -1;
- int minorVer = -1;
- int subVer = -1;
-
- if (!FindLibUsingOverride(&majorVer, &minorVer, &subVer) &&
- !FindLibWithMajorMinorVersion(&majorVer, &minorVer) &&
- !FindLibWithMajorMinorSubVersion(&majorVer, &minorVer, &subVer) &&
- // This is a fallback for the rare case when there are only lib files with major version
- !FindLibWithMajorVersion(&majorVer))
- {
- // No usable ICU version found
- return false;
- }
- // Find out the format of the version string added to each symbol
- // First try just the unversioned symbol
- if (dlsym(libicuuc, "u_strlen") == nullptr)
- {
- // Now try just the _majorVer added
- sprintf(symbolVersion, "_%d", majorVer);
- sprintf(symbolName, "u_strlen%s", symbolVersion);
- if ((dlsym(libicuuc, symbolName) == nullptr) && (minorVer != -1))
- {
- // Now try the _majorVer_minorVer added
- sprintf(symbolVersion, "_%d_%d", majorVer, minorVer);
- sprintf(symbolName, "u_strlen%s", symbolVersion);
- if ((dlsym(libicuuc, symbolName) == nullptr) && (subVer != -1))
- {
- // Finally, try the _majorVer_minorVer_subVer added
- sprintf(symbolVersion, "_%d_%d_%d", majorVer, minorVer, subVer);
- sprintf(symbolName, "u_strlen%s", symbolVersion);
- if (dlsym(libicuuc, symbolName) == nullptr)
- {
- return false;
- }
- }
- }
- }
-
- return true;
-
+ return FindLibUsingOverride(symbolName, symbolVersion) ||
+ FindLibWithMajorVersion(symbolName, symbolVersion) ||
+ FindLibWithMajorMinorVersion(symbolName, symbolVersion) ||
+ FindLibWithMajorMinorSubVersion(symbolName, symbolVersion);
}
#endif // __APPLE__
@@ -285,10 +282,12 @@ void ShutdownICUShim()
if (libicuuc != nullptr)
{
dlclose(libicuuc);
+ libicuuc = nullptr;
}
if (libicui18n != nullptr)
{
dlclose(libicui18n);
+ libicui18n = nullptr;
}
-}
+} \ No newline at end of file