Skip to content

Commit d05c93d

Browse files
janvorlidanmoseley
authored andcommitted
Port Fix ICU load on OpenSUSE Tumbleweed to 2.1 (dotnet#19861)
For some reason, OpenSUSE Tumbleweed has decided to prefix the version number in the SO name of the ICU libraries by "suse". That prevents our ICU version detection code from working. This change adds scanning for SO names that contain that prefix too.
1 parent a25682c commit d05c93d

File tree

1 file changed

+36
-25
lines changed

1 file changed

+36
-25
lines changed

src/corefx/System.Globalization.Native/icushim.cpp

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,15 @@ FOR_ALL_ICU_FUNCTIONS
1919
static void* libicuuc = nullptr;
2020
static void* libicui18n = nullptr;
2121

22-
// .x.x.x, considering the max number of decimal digits for each component
23-
static const int MaxICUVersionStringLength = 33;
22+
#define VERSION_PREFIX_NONE ""
23+
#define VERSION_PREFIX_SUSE "suse"
24+
25+
// .[suse]x.x.x, considering the max number of decimal digits for each component
26+
static const int MaxICUVersionStringLength = sizeof(VERSION_PREFIX_SUSE) + 33;
2427

2528
#ifdef __APPLE__
2629

27-
bool FindICULibs(char* symbolName, char* symbolVersion)
30+
bool FindICULibs(const char* versionPrefix, char* symbolName, char* symbolVersion)
2831
{
2932
#ifndef OSX_ICU_LIBRARY_PATH
3033
static_assert(false, "The ICU Library path is not defined");
@@ -63,11 +66,11 @@ static const int MaxSubICUVersion = 5;
6366
// 1. Only majorVer is not equal to -1 => result is baseFileName.majorver
6467
// 2. Only majorVer and minorVer are not equal to -1 => result is baseFileName.majorver.minorVer
6568
// 3. All components are not equal to -1 => result is baseFileName.majorver.minorVer.subver
66-
void GetVersionedLibFileName(const char* baseFileName, int majorVer, int minorVer, int subVer, char* result)
69+
void GetVersionedLibFileName(const char* baseFileName, int majorVer, int minorVer, int subVer, const char* versionPrefix, char* result)
6770
{
6871
assert(majorVer != -1);
6972

70-
int nameLen = sprintf(result, "%s.%d", baseFileName, majorVer);
73+
int nameLen = sprintf(result, "%s.%s%d", baseFileName, versionPrefix, majorVer);
7174

7275
if (minorVer != -1)
7376
{
@@ -110,16 +113,16 @@ bool FindSymbolVersion(int majorVer, int minorVer, int subVer, char* symbolName,
110113
}
111114

112115
// Try to open the necessary ICU libraries
113-
bool OpenICULibraries(int majorVer, int minorVer, int subVer, char* symbolName, char* symbolVersion)
116+
bool OpenICULibraries(int majorVer, int minorVer, int subVer, const char* versionPrefix, char* symbolName, char* symbolVersion)
114117
{
115118
char libicuucName[64];
116119
char libicui18nName[64];
117120

118121
static_assert(sizeof("libicuuc.so") + MaxICUVersionStringLength <= sizeof(libicuucName), "The libicuucName is too small");
119-
GetVersionedLibFileName("libicuuc.so", majorVer, minorVer, subVer, libicuucName);
122+
GetVersionedLibFileName("libicuuc.so", majorVer, minorVer, subVer, versionPrefix, libicuucName);
120123

121124
static_assert(sizeof("libicui18n.so") + MaxICUVersionStringLength <= sizeof(libicui18nName), "The libicui18nName is too small");
122-
GetVersionedLibFileName("libicui18n.so", majorVer, minorVer, subVer, libicui18nName);
125+
GetVersionedLibFileName("libicui18n.so", majorVer, minorVer, subVer, versionPrefix, libicui18nName);
123126

124127
libicuuc = dlopen(libicuucName, RTLD_LAZY);
125128
if (libicuuc != nullptr)
@@ -142,7 +145,7 @@ bool OpenICULibraries(int majorVer, int minorVer, int subVer, char* symbolName,
142145
// environment variable.
143146
// The format of the string in this variable is majorVer[.minorVer[.subVer]] (the brackets
144147
// indicate optional parts).
145-
bool FindLibUsingOverride(char* symbolName, char* symbolVersion)
148+
bool FindLibUsingOverride(const char* versionPrefix, char* symbolName, char* symbolVersion)
146149
{
147150
char* versionOverride = getenv("CLR_ICU_VERSION_OVERRIDE");
148151
if (versionOverride != nullptr)
@@ -154,7 +157,7 @@ bool FindLibUsingOverride(char* symbolName, char* symbolVersion)
154157
int matches = sscanf(versionOverride, "%d.%d.%d", &first, &second, &third);
155158
if (matches > 0)
156159
{
157-
if (OpenICULibraries(first, second, third, symbolName, symbolVersion))
160+
if (OpenICULibraries(first, second, third, versionPrefix, symbolName, symbolVersion))
158161
{
159162
return true;
160163
}
@@ -165,21 +168,21 @@ bool FindLibUsingOverride(char* symbolName, char* symbolVersion)
165168
}
166169

167170
// Search for library files with names including the major version.
168-
bool FindLibWithMajorVersion(char* symbolName, char* symbolVersion)
171+
bool FindLibWithMajorVersion(const char* versionPrefix, char* symbolName, char* symbolVersion)
169172
{
170173
// ICU packaging documentation (http://userguide.icu-project.org/packaging)
171174
// describes applications link against the major (e.g. libicuuc.so.54).
172175

173176
// Select the version of ICU present at build time.
174-
if (OpenICULibraries(MinICUVersion, -1, -1, symbolName, symbolVersion))
177+
if (OpenICULibraries(MinICUVersion, -1, -1, versionPrefix, symbolName, symbolVersion))
175178
{
176179
return true;
177180
}
178181

179182
// Select the highest supported version of ICU present on the local machine
180183
for (int i = MaxICUVersion; i > MinICUVersion; i--)
181184
{
182-
if (OpenICULibraries(i, -1, -1, symbolName, symbolVersion))
185+
if (OpenICULibraries(i, -1, -1, versionPrefix, symbolName, symbolVersion))
183186
{
184187
return true;
185188
}
@@ -190,13 +193,13 @@ bool FindLibWithMajorVersion(char* symbolName, char* symbolVersion)
190193

191194
// Select the highest supported version of ICU present on the local machine
192195
// Search for library files with names including the major and minor version.
193-
bool FindLibWithMajorMinorVersion(char* symbolName, char* symbolVersion)
196+
bool FindLibWithMajorMinorVersion(const char* versionPrefix, char* symbolName, char* symbolVersion)
194197
{
195198
for (int i = MaxICUVersion; i >= MinICUVersion; i--)
196199
{
197200
for (int j = MaxMinorICUVersion; j >= MinMinorICUVersion; j--)
198201
{
199-
if (OpenICULibraries(i, j, -1, symbolName, symbolVersion))
202+
if (OpenICULibraries(i, j, -1, versionPrefix, symbolName, symbolVersion))
200203
{
201204
return true;
202205
}
@@ -208,15 +211,15 @@ bool FindLibWithMajorMinorVersion(char* symbolName, char* symbolVersion)
208211

209212
// Select the highest supported version of ICU present on the local machine
210213
// Search for library files with names including the major, minor and sub version.
211-
bool FindLibWithMajorMinorSubVersion(char* symbolName, char* symbolVersion)
214+
bool FindLibWithMajorMinorSubVersion(const char* versionPrefix, char* symbolName, char* symbolVersion)
212215
{
213216
for (int i = MaxICUVersion; i >= MinICUVersion; i--)
214217
{
215218
for (int j = MaxMinorICUVersion; j >= MinMinorICUVersion; j--)
216219
{
217220
for (int k = MaxSubICUVersion; k >= MinSubICUVersion; k--)
218221
{
219-
if (OpenICULibraries(i, j, k, symbolName, symbolVersion))
222+
if (OpenICULibraries(i, j, k, versionPrefix, symbolName, symbolVersion))
220223
{
221224
return true;
222225
}
@@ -227,12 +230,13 @@ bool FindLibWithMajorMinorSubVersion(char* symbolName, char* symbolVersion)
227230
return false;
228231
}
229232

230-
bool FindICULibs(char* symbolName, char* symbolVersion)
233+
234+
bool FindICULibs(const char* versionPrefix, char* symbolName, char* symbolVersion)
231235
{
232-
return FindLibUsingOverride(symbolName, symbolVersion) ||
233-
FindLibWithMajorVersion(symbolName, symbolVersion) ||
234-
FindLibWithMajorMinorVersion(symbolName, symbolVersion) ||
235-
FindLibWithMajorMinorSubVersion(symbolName, symbolVersion);
236+
return FindLibUsingOverride(versionPrefix, symbolName, symbolVersion) ||
237+
FindLibWithMajorVersion(versionPrefix, symbolName, symbolVersion) ||
238+
FindLibWithMajorMinorVersion(versionPrefix, symbolName, symbolVersion) ||
239+
FindLibWithMajorMinorSubVersion(versionPrefix, symbolName, symbolVersion);
236240
}
237241

238242
#endif // __APPLE__
@@ -246,8 +250,15 @@ extern "C" int32_t GlobalizationNative_LoadICU()
246250
char symbolName[128];
247251
char symbolVersion[MaxICUVersionStringLength + 1] = "";
248252

249-
if (!FindICULibs(symbolName, symbolVersion))
250-
return 0;
253+
if (!FindICULibs(VERSION_PREFIX_NONE, symbolName, symbolVersion))
254+
{
255+
#ifndef __APPLE__
256+
if (!FindICULibs(VERSION_PREFIX_SUSE, symbolName, symbolVersion))
257+
#endif
258+
{
259+
return 0;
260+
}
261+
}
251262

252263
// Get pointers to all the ICU functions that are needed
253264
#define PER_FUNCTION_BLOCK(fn, lib) \
@@ -290,4 +301,4 @@ void ShutdownICUShim()
290301
dlclose(libicui18n);
291302
libicui18n = nullptr;
292303
}
293-
}
304+
}

0 commit comments

Comments
 (0)