15
15
#include <dlfcn.h>
16
16
#endif
17
17
18
+ #if !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS
19
+
20
+ #if DEPLOYMENT_TARGET_LINUX
21
+ #if __LP64__
22
+ #define _CFBundleFHSArchDirectorySuffix "64"
23
+ #else // !__LP64__
24
+ #define _CFBundleFHSArchDirectorySuffix "32"
25
+ #endif // __LP64__
26
+ #endif // DEPLOYMENT_TARGET_LINUX
27
+
28
+ CONST_STRING_DECL (_kCFBundleFHSDirectory_bin , "bin" );
29
+ CONST_STRING_DECL (_kCFBundleFHSDirectory_sbin , "sbin" );
30
+ CONST_STRING_DECL (_kCFBundleFHSDirectory_lib , "lib" );
31
+ #if DEPLOYMENT_TARGET_LINUX
32
+ CONST_STRING_DECL (_kCFBundleFHSDirectory_libWithArchSuffix , "lib" _CFBundleFHSArchDirectorySuffix );
33
+ #endif
34
+
35
+ #define _CFBundleFHSExecutablesDirectorySuffix CFSTR(".executables")
36
+ #define _CFBundleFHSDirectoryCLiteral_libexec "libexec"
37
+
38
+ #if DEPLOYMENT_TARGET_LINUX
39
+ #define _CFBundleFHSDirectoriesInExecutableSearchOrder \
40
+ _kCFBundleFHSDirectory_bin, \
41
+ _kCFBundleFHSDirectory_sbin, \
42
+ _kCFBundleFHSDirectory_libWithArchSuffix, \
43
+ _kCFBundleFHSDirectory_lib
44
+ #else
45
+ #define _CFBundleFHSDirectoriesInExecutableSearchOrder \
46
+ _kCFBundleFHSDirectory_bin, \
47
+ _kCFBundleFHSDirectory_sbin, \
48
+ _kCFBundleFHSDirectory_lib
49
+ #endif // DEPLOYMENT_TARGET_LINUX
50
+
51
+ #endif // !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS
52
+
18
53
// This is here because on iPhoneOS with the dyld shared cache, we remove binaries from their
19
54
// original locations on disk, so checking whether a binary's path exists is no longer sufficient.
20
55
// For performance reasons, we only call dlopen_preflight() after we've verified that the binary
@@ -38,7 +73,22 @@ static CFURLRef _CFBundleCopyExecutableURLRaw(CFURLRef urlPath, CFStringRef exeN
38
73
CFURLRef executableURL = NULL ;
39
74
if (!urlPath || !exeName ) return NULL ;
40
75
41
- #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
76
+ #if !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS
77
+ if (!executableURL ) {
78
+ executableURL = CFURLCreateWithFileSystemPathRelativeToBase (kCFAllocatorSystemDefault , exeName , kCFURLPOSIXPathStyle , false, urlPath );
79
+ if (!_binaryLoadable (executableURL )) {
80
+ CFRelease (executableURL );
81
+
82
+ CFStringRef sharedLibraryName = CFStringCreateWithFormat (kCFAllocatorSystemDefault , NULL , CFSTR ("%@%@%@" ), _CFBundleFHSSharedLibraryFilenamePrefix , exeName , _CFBundleFHSSharedLibraryFilenameSuffix );
83
+
84
+ executableURL = CFURLCreateWithFileSystemPathRelativeToBase (kCFAllocatorSystemDefault , sharedLibraryName , kCFURLPOSIXPathStyle , false, urlPath );
85
+ if (!_binaryLoadable (executableURL )) {
86
+ CFRelease (executableURL );
87
+ executableURL = NULL ;
88
+ }
89
+ }
90
+ }
91
+ #elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
42
92
const uint8_t * image_suffix = (uint8_t * )__CFgetenvIfNotRestricted ("DYLD_IMAGE_SUFFIX" );
43
93
44
94
if (image_suffix ) {
@@ -152,19 +202,60 @@ static CFURLRef _CFBundleCopyExecutableURLInDirectory2(CFBundleRef bundle, CFURL
152
202
#else
153
203
Boolean doExecSearch = true;
154
204
#endif
205
+
206
+ #if !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS
207
+ if (lookupMainExe && bundle && bundle -> _isFHSInstalledBundle ) {
208
+ // For a FHS installed bundle, the URL points to share/Bundle.resources, and the binary is in:
209
+
210
+ CFURLRef prefix = CFURLCreateCopyDeletingLastPathComponent (kCFAllocatorSystemDefault , url );
211
+
212
+ CFStringRef directories [] = { _CFBundleFHSDirectoriesInExecutableSearchOrder };
213
+ size_t directoriesCount = sizeof (directories ) / sizeof (directories [0 ]);
214
+
215
+ for (size_t i = 0 ; i < directoriesCount ; i ++ ) {
216
+ CFURLRef where = CFURLCreateCopyAppendingPathComponent (kCFAllocatorSystemDefault , prefix , directories [i ], true);
217
+ executableURL = _CFBundleCopyExecutableURLRaw (where , executableName );
218
+ CFRelease (where );
219
+
220
+ if (executableURL ) {
221
+ foundIt = true;
222
+ break ;
223
+ }
224
+ }
225
+
226
+ CFRelease (prefix );
227
+ }
228
+ #endif // !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS
229
+
155
230
// Now, look for the executable inside the bundle.
156
- if (doExecSearch && 0 != version ) {
231
+ if (! foundIt && doExecSearch && 0 != version ) {
157
232
CFURLRef exeDirURL = NULL ;
158
233
234
+ #if !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS
235
+ if (bundle && bundle -> _isFHSInstalledBundle ) {
236
+ CFURLRef withoutExtension = CFURLCreateCopyDeletingPathExtension (kCFAllocatorSystemDefault , url );
237
+ CFStringRef lastPathComponent = CFURLCopyLastPathComponent (withoutExtension );
238
+
239
+ CFURLRef libexec = CFURLCreateWithString (kCFAllocatorSystemDefault , CFSTR ("../../" _CFBundleFHSDirectoryCLiteral_libexec ), url );
240
+
241
+ CFStringRef exeDirName = CFStringCreateWithFormat (kCFAllocatorSystemDefault , NULL , CFSTR ("%@%@" ), lastPathComponent , _CFBundleFHSExecutablesDirectorySuffix );
242
+ exeDirURL = CFURLCreateCopyAppendingPathComponent (kCFAllocatorSystemDefault , libexec , exeDirName , true);
243
+
244
+ CFRelease (withoutExtension );
245
+ CFRelease (lastPathComponent );
246
+ CFRelease (libexec );
247
+ CFRelease (exeDirName );
248
+ } else
249
+ #endif // !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS
159
250
if (1 == version ) {
160
251
exeDirURL = CFURLCreateWithString (kCFAllocatorSystemDefault , _CFBundleExecutablesURLFromBase1 , url );
161
252
} else if (2 == version ) {
162
253
exeDirURL = CFURLCreateWithString (kCFAllocatorSystemDefault , _CFBundleExecutablesURLFromBase2 , url );
163
254
} else {
164
- #if DEPLOYMENT_TARGET_WINDOWS
165
- // On Windows, if the bundle URL is foo.resources, then the executable is at the same level as the .resources directory
255
+ #if DEPLOYMENT_TARGET_WINDOWS || ! DEPLOYMENT_RUNTIME_OBJC
256
+ // On Windows and on targets that support FHS bundles , if the bundle URL is foo.resources, then the executable is at the same level as the .resources directory
166
257
CFStringRef extension = CFURLCopyPathExtension (url );
167
- if (extension && CFEqual (extension , _CFBundleWindowsResourceDirectoryExtension )) {
258
+ if (extension && CFEqual (extension , _CFBundleSiblingResourceDirectoryExtension )) {
168
259
exeDirURL = CFURLCreateCopyDeletingLastPathComponent (kCFAllocatorSystemDefault , url );
169
260
} else {
170
261
exeDirURL = (CFURLRef )CFRetain (url );
@@ -201,7 +292,7 @@ static CFURLRef _CFBundleCopyExecutableURLInDirectory2(CFBundleRef bundle, CFURL
201
292
CFURLRef absURL = CFURLCopyAbsoluteURL (executableURL );
202
293
#if DEPLOYMENT_TARGET_WINDOWS
203
294
executablePath = CFURLCopyFileSystemPath (absURL , kCFURLWindowsPathStyle );
204
- #elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
295
+ #else
205
296
executablePath = CFURLCopyFileSystemPath (absURL , kCFURLPOSIXPathStyle );
206
297
#endif
207
298
CFRelease (absURL );
@@ -232,15 +323,15 @@ static CFURLRef _CFBundleCopyBundleURLForExecutablePath(CFStringRef str) {
232
323
#if DEPLOYMENT_TARGET_WINDOWS
233
324
// Is this a .dll or .exe?
234
325
if (buffLen >= 5 && (_wcsnicmp ((wchar_t * )& (buff [buffLen - 4 ]), L".dll" , 4 ) == 0 || _wcsnicmp ((wchar_t * )& (buff [buffLen - 4 ]), L".exe" , 4 ) == 0 )) {
235
- CFIndex extensionLength = CFStringGetLength (_CFBundleWindowsResourceDirectoryExtension );
326
+ CFIndex extensionLength = CFStringGetLength (_CFBundleSiblingResourceDirectoryExtension );
236
327
buffLen -= 4 ;
237
328
// If this is an _debug, we should strip that before looking for the bundle
238
329
if (buffLen >= 7 && (_wcsnicmp ((wchar_t * )& buff [buffLen - 6 ], L"_debug" , 6 ) == 0 )) buffLen -= 6 ;
239
330
240
331
if (buffLen + 1 + extensionLength < CFMaxPathSize ) {
241
332
buff [buffLen ] = '.' ;
242
333
buffLen ++ ;
243
- CFStringGetCharacters (_CFBundleWindowsResourceDirectoryExtension , CFRangeMake (0 , extensionLength ), buff + buffLen );
334
+ CFStringGetCharacters (_CFBundleSiblingResourceDirectoryExtension , CFRangeMake (0 , extensionLength ), buff + buffLen );
244
335
buffLen += extensionLength ;
245
336
outstr = CFStringCreateWithCharactersNoCopy (kCFAllocatorSystemDefault , buff , buffLen , kCFAllocatorNull );
246
337
url = CFURLCreateWithFileSystemPath (kCFAllocatorSystemDefault , outstr , PLATFORM_PATH_STYLE , true);
0 commit comments