Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 845da03

Browse files
tmdsjanvorli
authored andcommitted
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
1 parent 0f97a82 commit 845da03

File tree

1 file changed

+61
-62
lines changed

1 file changed

+61
-62
lines changed

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

Lines changed: 61 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,38 @@ void GetVersionedLibFileName(const char* baseFileName, int majorVer, int minorVe
7979
}
8080
}
8181

82+
bool FindSymbolVersion(int majorVer, int minorVer, int subVer, char* symbolName, char* symbolVersion)
83+
{
84+
// Find out the format of the version string added to each symbol
85+
// First try just the unversioned symbol
86+
if (dlsym(libicuuc, "u_strlen") == nullptr)
87+
{
88+
// Now try just the _majorVer added
89+
sprintf(symbolVersion, "_%d", majorVer);
90+
sprintf(symbolName, "u_strlen%s", symbolVersion);
91+
if ((dlsym(libicuuc, symbolName) == nullptr) && (minorVer != -1))
92+
{
93+
// Now try the _majorVer_minorVer added
94+
sprintf(symbolVersion, "_%d_%d", majorVer, minorVer);
95+
sprintf(symbolName, "u_strlen%s", symbolVersion);
96+
if ((dlsym(libicuuc, symbolName) == nullptr) && (subVer != -1))
97+
{
98+
// Finally, try the _majorVer_minorVer_subVer added
99+
sprintf(symbolVersion, "_%d_%d_%d", majorVer, minorVer, subVer);
100+
sprintf(symbolName, "u_strlen%s", symbolVersion);
101+
if (dlsym(libicuuc, symbolName) == nullptr)
102+
{
103+
return false;
104+
}
105+
}
106+
}
107+
}
108+
109+
return true;
110+
}
111+
82112
// Try to open the necessary ICU libraries
83-
bool OpenICULibraries(int majorVer, int minorVer, int subVer)
113+
bool OpenICULibraries(int majorVer, int minorVer, int subVer, char* symbolName, char* symbolVersion)
84114
{
85115
char libicuucName[64];
86116
char libicui18nName[64];
@@ -94,7 +124,10 @@ bool OpenICULibraries(int majorVer, int minorVer, int subVer)
94124
libicuuc = dlopen(libicuucName, RTLD_LAZY);
95125
if (libicuuc != nullptr)
96126
{
97-
libicui18n = dlopen(libicui18nName, RTLD_LAZY);
127+
if (FindSymbolVersion(majorVer, minorVer, subVer, symbolName, symbolVersion))
128+
{
129+
libicui18n = dlopen(libicui18nName, RTLD_LAZY);
130+
}
98131
if (libicui18n == nullptr)
99132
{
100133
dlclose(libicuuc);
@@ -109,7 +142,7 @@ bool OpenICULibraries(int majorVer, int minorVer, int subVer)
109142
// environment variable.
110143
// The format of the string in this variable is majorVer[.minorVer[.subVer]] (the brackets
111144
// indicate optional parts).
112-
bool FindLibUsingOverride(int* majorVer, int* minorVer, int* subVer)
145+
bool FindLibUsingOverride(char* symbolName, char* symbolVersion)
113146
{
114147
char* versionOverride = getenv("CLR_ICU_VERSION_OVERRIDE");
115148
if (versionOverride != nullptr)
@@ -121,11 +154,8 @@ bool FindLibUsingOverride(int* majorVer, int* minorVer, int* subVer)
121154
int matches = sscanf(versionOverride, "%d.%d.%d", &first, &second, &third);
122155
if (matches > 0)
123156
{
124-
if (OpenICULibraries(first, second, third))
157+
if (OpenICULibraries(first, second, third, symbolName, symbolVersion))
125158
{
126-
*majorVer = first;
127-
*minorVer = second;
128-
*subVer = third;
129159
return true;
130160
}
131161
}
@@ -134,15 +164,23 @@ bool FindLibUsingOverride(int* majorVer, int* minorVer, int* subVer)
134164
return false;
135165
}
136166

137-
// Select the highest supported version of ICU present on the local machine
138167
// Search for library files with names including the major version.
139-
bool FindLibWithMajorVersion(int* majorVer)
168+
bool FindLibWithMajorVersion(char* symbolName, char* symbolVersion)
140169
{
141-
for (int i = MaxICUVersion; i >= MinICUVersion; i--)
170+
// ICU packaging documentation (http://userguide.icu-project.org/packaging)
171+
// describes applications link against the major (e.g. libicuuc.so.54).
172+
173+
// Select the version of ICU present at build time.
174+
if (OpenICULibraries(MinICUVersion, -1, -1, symbolName, symbolVersion))
142175
{
143-
if (OpenICULibraries(i, -1, -1))
176+
return true;
177+
}
178+
179+
// Select the highest supported version of ICU present on the local machine
180+
for (int i = MaxICUVersion; i > MinICUVersion; i--)
181+
{
182+
if (OpenICULibraries(i, -1, -1, symbolName, symbolVersion))
144183
{
145-
*majorVer = i;
146184
return true;
147185
}
148186
}
@@ -152,16 +190,14 @@ bool FindLibWithMajorVersion(int* majorVer)
152190

153191
// Select the highest supported version of ICU present on the local machine
154192
// Search for library files with names including the major and minor version.
155-
bool FindLibWithMajorMinorVersion(int* majorVer, int* minorVer)
193+
bool FindLibWithMajorMinorVersion(char* symbolName, char* symbolVersion)
156194
{
157195
for (int i = MaxICUVersion; i >= MinICUVersion; i--)
158196
{
159197
for (int j = MaxMinorICUVersion; j >= MinMinorICUVersion; j--)
160198
{
161-
if (OpenICULibraries(i, j, -1))
199+
if (OpenICULibraries(i, j, -1, symbolName, symbolVersion))
162200
{
163-
*majorVer = i;
164-
*minorVer = j;
165201
return true;
166202
}
167203
}
@@ -172,19 +208,16 @@ bool FindLibWithMajorMinorVersion(int* majorVer, int* minorVer)
172208

173209
// Select the highest supported version of ICU present on the local machine
174210
// Search for library files with names including the major, minor and sub version.
175-
bool FindLibWithMajorMinorSubVersion(int* majorVer, int* minorVer, int* subVer)
211+
bool FindLibWithMajorMinorSubVersion(char* symbolName, char* symbolVersion)
176212
{
177213
for (int i = MaxICUVersion; i >= MinICUVersion; i--)
178214
{
179215
for (int j = MaxMinorICUVersion; j >= MinMinorICUVersion; j--)
180216
{
181217
for (int k = MaxSubICUVersion; k >= MinSubICUVersion; k--)
182218
{
183-
if (OpenICULibraries(i, j, k))
219+
if (OpenICULibraries(i, j, k, symbolName, symbolVersion))
184220
{
185-
*majorVer = i;
186-
*minorVer = j;
187-
*subVer = k;
188221
return true;
189222
}
190223
}
@@ -196,46 +229,10 @@ bool FindLibWithMajorMinorSubVersion(int* majorVer, int* minorVer, int* subVer)
196229

197230
bool FindICULibs(char* symbolName, char* symbolVersion)
198231
{
199-
int majorVer = -1;
200-
int minorVer = -1;
201-
int subVer = -1;
202-
203-
if (!FindLibUsingOverride(&majorVer, &minorVer, &subVer) &&
204-
!FindLibWithMajorMinorVersion(&majorVer, &minorVer) &&
205-
!FindLibWithMajorMinorSubVersion(&majorVer, &minorVer, &subVer) &&
206-
// This is a fallback for the rare case when there are only lib files with major version
207-
!FindLibWithMajorVersion(&majorVer))
208-
{
209-
// No usable ICU version found
210-
return false;
211-
}
212-
// Find out the format of the version string added to each symbol
213-
// First try just the unversioned symbol
214-
if (dlsym(libicuuc, "u_strlen") == nullptr)
215-
{
216-
// Now try just the _majorVer added
217-
sprintf(symbolVersion, "_%d", majorVer);
218-
sprintf(symbolName, "u_strlen%s", symbolVersion);
219-
if ((dlsym(libicuuc, symbolName) == nullptr) && (minorVer != -1))
220-
{
221-
// Now try the _majorVer_minorVer added
222-
sprintf(symbolVersion, "_%d_%d", majorVer, minorVer);
223-
sprintf(symbolName, "u_strlen%s", symbolVersion);
224-
if ((dlsym(libicuuc, symbolName) == nullptr) && (subVer != -1))
225-
{
226-
// Finally, try the _majorVer_minorVer_subVer added
227-
sprintf(symbolVersion, "_%d_%d_%d", majorVer, minorVer, subVer);
228-
sprintf(symbolName, "u_strlen%s", symbolVersion);
229-
if (dlsym(libicuuc, symbolName) == nullptr)
230-
{
231-
return false;
232-
}
233-
}
234-
}
235-
}
236-
237-
return true;
238-
232+
return FindLibUsingOverride(symbolName, symbolVersion) ||
233+
FindLibWithMajorVersion(symbolName, symbolVersion) ||
234+
FindLibWithMajorMinorVersion(symbolName, symbolVersion) ||
235+
FindLibWithMajorMinorSubVersion(symbolName, symbolVersion);
239236
}
240237

241238
#endif // __APPLE__
@@ -285,10 +282,12 @@ void ShutdownICUShim()
285282
if (libicuuc != nullptr)
286283
{
287284
dlclose(libicuuc);
285+
libicuuc = nullptr;
288286
}
289287

290288
if (libicui18n != nullptr)
291289
{
292290
dlclose(libicui18n);
291+
libicui18n = nullptr;
293292
}
294-
}
293+
}

0 commit comments

Comments
 (0)