Skip to content

Commit ed35d3d

Browse files
committed
Support even more paths.
It turns out that the path to the runtime might also include the architecture as well as the platform. So we need to search <root>/lib/swift/<platform> <root>/lib/swift/<platform>/<arch> <root>/lib/swift <root>/lib/swift/<arch> <root>/bin/ <root>/bin/<arch> <root> in that order. Hopefully this now covers all the possibilities. rdar://103071801
1 parent 1529320 commit ed35d3d

File tree

2 files changed

+107
-81
lines changed

2 files changed

+107
-81
lines changed

stdlib/cmake/modules/AddSwiftStdlib.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ function(_add_target_variant_c_compile_flags)
159159
list(APPEND result
160160
"-DSWIFT_RUNTIME"
161161
"-DSWIFT_LIB_SUBDIR=\"${SWIFT_SDK_${CFLAGS_SDK}_LIB_SUBDIR}\""
162+
"-DSWIFT_ARCH=\"${CFLAGS_ARCH}\""
162163
)
163164

164165
if ("${CFLAGS_ARCH}" STREQUAL "arm64" OR

stdlib/public/runtime/Paths.cpp

Lines changed: 106 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ void _swift_initRuntimePath(void *);
5050
void _swift_initRootPath(void *);
5151
const char *_swift_getDefaultRootPath();
5252
char *_swift_getAuxExePathIn(const char *path, const char *name);
53+
const char *_swift_tryAuxExePath(const char *name, const char *path, ...);
5354

5455
bool _swift_isPathSep(char ch) {
5556
#ifdef _WIN32
@@ -134,22 +135,31 @@ _swift_getDefaultRootPath()
134135
// +-------------- ptr - 10
135136
ptr -= 10;
136137
} else {
137-
// We *might* be in a <platform> directory, so scan backwards for that too
138+
// We *might* be in a <platform> or <platform>/<arch> directory, so scan
139+
// backwards for that too
140+
bool found = false;
138141
const char *platform = ptr;
139-
while (platform > runtimePath && !_swift_isPathSep(*--platform));
140142

141-
if (_swift_lookingAtLibSwift(platform, runtimePath)) {
143+
for (unsigned n = 0; n < 2; ++n) {
144+
while (platform > runtimePath && !_swift_isPathSep(*--platform));
142145

143-
// When we get here, we have:
144-
//
145-
// /some/path/to/some/thing/lib/swift/macosx/libswiftCore.dylib
146-
// ^ ^ ^
147-
// | | +---- ptr
148-
// | +----------- platform
149-
// +--------------------- platform - 10
146+
if (_swift_lookingAtLibSwift(platform, runtimePath)) {
150147

151-
ptr = platform - 10;
152-
} else {
148+
// When we get here, we have:
149+
//
150+
// /some/path/to/some/thing/lib/swift/macosx/libswiftCore.dylib
151+
// ^ ^ ^
152+
// | | +---- ptr
153+
// | +----------- platform
154+
// +--------------------- platform - 10
155+
156+
ptr = platform - 10;
157+
found = true;
158+
break;
159+
}
160+
}
161+
162+
if (!found) {
153163
// We *might* also be in a bin directory, for instance on Windows, so
154164
// check if we should remove that also.
155165
if (_swift_lookingAtBin(ptr, runtimePath)) {
@@ -178,13 +188,15 @@ _swift_getDefaultRootPath()
178188

179189
// Join paths together
180190
char *
181-
_swift_joinPaths(const char *path, ...)
191+
_swift_joinPathsV(const char *path, va_list val)
182192
{
183-
va_list val;
193+
va_list val2;
184194
size_t baseLen = 0;
185195
size_t totalLen = 0;
186196
const char *pathSeg;
187197

198+
va_copy(val2, val);
199+
188200
baseLen = std::strlen(path);
189201
while (baseLen && _swift_isPathSep(path[baseLen - 1]))
190202
--baseLen;
@@ -194,15 +206,13 @@ _swift_joinPaths(const char *path, ...)
194206
else
195207
totalLen = baseLen;
196208

197-
va_start(val, path);
198-
while ((pathSeg = va_arg(val, const char *))) {
209+
while ((pathSeg = va_arg(val2, const char *))) {
199210
size_t len = std::strlen(pathSeg);
200211
while (len && _swift_isPathSep(pathSeg[len - 1]))
201212
--len;
202213
if (len)
203214
totalLen += 1 + len;
204215
}
205-
va_end(val);
206216

207217
char *buffer = static_cast<char *>(std::malloc(totalLen + 1));
208218
char *ptr = buffer;
@@ -214,7 +224,6 @@ _swift_joinPaths(const char *path, ...)
214224
ptr += baseLen;
215225
}
216226

217-
va_start(val, path);
218227
while ((pathSeg = va_arg(val, const char *))) {
219228
size_t len = std::strlen(pathSeg);
220229
while (len && _swift_isPathSep(pathSeg[len - 1]))
@@ -230,6 +239,19 @@ _swift_joinPaths(const char *path, ...)
230239
return buffer;
231240
}
232241

242+
char *
243+
_swift_joinPaths(const char *path, ...)
244+
{
245+
va_list val;
246+
char *result;
247+
248+
va_start(val, path);
249+
result = _swift_joinPathsV(path, val);
250+
va_end(val);
251+
252+
return result;
253+
}
254+
233255
void
234256
_swift_initRootPath(void *)
235257
{
@@ -340,81 +362,58 @@ swift_getAuxiliaryExecutablePath(const char *name)
340362
const char *rootPath = swift_getRootPath();
341363

342364
const char *platformName = SWIFT_LIB_SUBDIR;
365+
const char *archName = SWIFT_ARCH;
343366

344367
// <rootPath>/libexec/swift/<platformName>
345-
{
346-
char *libexecPlatPath = _swift_joinPaths(rootPath,
347-
"libexec" PATHSEP_STR "swift",
348-
platformName, nullptr);
349-
350-
// If it exists, look there
351-
if (_swift_exists(libexecPlatPath)) {
352-
char *result = _swift_getAuxExePathIn(libexecPlatPath, name);
353-
354-
if (_swift_exists(result)) {
355-
std::free(libexecPlatPath);
356-
357-
return result;
358-
}
359-
360-
std::free(result);
361-
}
362-
368+
if (const char *result = _swift_tryAuxExePath(name,
369+
rootPath,
370+
"libexec", "swift",
371+
platformName, nullptr)) {
372+
return result;
373+
}
363374

364-
std::free(libexecPlatPath);
375+
// <rootPath>/libexec/swift/<platformName>/<arch>
376+
if (const char *result = _swift_tryAuxExePath(name,
377+
rootPath,
378+
"libexec", "swift",
379+
platformName,
380+
archName, nullptr)) {
381+
return result;
365382
}
366383

367384
// <rootPath>/libexec/swift
368-
{
369-
char *libexecPath = _swift_joinPaths(rootPath,
370-
"libexec" PATHSEP_STR "swift",
371-
nullptr);
372-
373-
// If it exists, look there
374-
if (_swift_exists(libexecPath)) {
375-
char *result = _swift_getAuxExePathIn(libexecPath, name);
376-
377-
if (_swift_exists(result)) {
378-
std::free(libexecPath);
379-
380-
return result;
381-
}
382-
383-
std::free(result);
384-
}
385+
if (const char *result = _swift_tryAuxExePath(name,
386+
rootPath,
387+
"libexec", "swift",
388+
nullptr)) {
389+
return result;
390+
}
385391

386-
std::free(libexecPath);
392+
// <rootPath>/libexec/swift/<arch>
393+
if (const char *result = _swift_tryAuxExePath(name,
394+
rootPath,
395+
"libexec", "swift",
396+
archName, nullptr)) {
397+
return result;
387398
}
388399

389400
// <rootPath>/bin
390-
{
391-
char *binPath = _swift_joinPaths(rootPath, "bin", nullptr);
392-
393-
// If bin exists, look there
394-
if (_swift_exists(binPath)) {
395-
char *result = _swift_getAuxExePathIn(binPath, name);
396-
397-
if (_swift_exists(result)) {
398-
std::free(binPath);
399-
400-
return result;
401-
}
402-
403-
std::free(result);
404-
}
405-
406-
std::free(binPath);
401+
if (const char *result = _swift_tryAuxExePath(name,
402+
rootPath,
403+
"bin", nullptr)) {
404+
return result;
407405
}
408406

409-
// Otherwise, look in the root itself
410-
char *result = _swift_getAuxExePathIn(rootPath, name);
411-
412-
if (_swift_exists(result))
407+
// <rootPath>/bin/<arch>
408+
if (const char *result = _swift_tryAuxExePath(name,
409+
rootPath,
410+
"bin",
411+
archName, nullptr)) {
413412
return result;
413+
}
414414

415-
std::free(result);
416-
417-
return nullptr;
415+
// Otherwise, look in the root itself
416+
return _swift_tryAuxExePath(name, rootPath, nullptr);
418417
}
419418

420419
namespace {
@@ -444,6 +443,32 @@ _swift_getAuxExePathIn(const char *path, const char *name)
444443
return fullPath;
445444
}
446445

446+
const char *
447+
_swift_tryAuxExePath(const char *name, const char *path, ...)
448+
{
449+
va_list val;
450+
char *fullPath;
451+
va_start(val, path);
452+
fullPath = _swift_joinPathsV(path, val);
453+
va_end(val);
454+
455+
if (_swift_exists(fullPath)) {
456+
char *result = _swift_getAuxExePathIn(fullPath, name);
457+
458+
if (_swift_exists(result)) {
459+
std::free(fullPath);
460+
461+
return result;
462+
}
463+
464+
std::free(result);
465+
}
466+
467+
std::free(fullPath);
468+
469+
return nullptr;
470+
}
471+
447472
#if !defined(_WIN32) || defined(__CYGWIN__)
448473
void
449474
_swift_initRuntimePath(void *) {
@@ -494,7 +519,7 @@ _swift_initRuntimePath(void *) {
494519

495520
std::free(lpFilename);
496521

497-
runtimePath = swift::win32::copyUTF8FromWide(lpWin32Filename);
522+
runtimePath = _swift_win32_copyUTF8FromWide(lpWin32Filename);
498523
if (!runtimePath) {
499524
swift::fatalError(/* flags = */ 0,
500525
"Unable to convert Swift runtime path to UTF-8: %lx, %d\n",
@@ -519,7 +544,7 @@ bool _swift_exists(const char *path)
519544
struct stat st;
520545
return stat(path, &st) == 0;
521546
#else
522-
wchar_t *wszPath = swift::win32::copyWideFromUTF8(path);
547+
wchar_t *wszPath = _swift_win32_copyWideFromUTF8(path);
523548
bool result = GetFileAttributesW(wszPath) != INVALID_FILE_ATTRIBUTES;
524549
free(wszPath);
525550
return result;

0 commit comments

Comments
 (0)