@@ -108,9 +108,25 @@ function audit(prefix::Prefix; io=STDERR,
108
108
info (io, msg)
109
109
end
110
110
111
- # Look at every non-default dynamic link
112
- libs = filter_default_linkages ( find_libraries (oh), oh)
111
+ # Look at every dynamic link, and see if we should do anything about that link...
112
+ libs = find_libraries (oh)
113
113
for libname in keys (libs)
114
+ if should_ignore_lib (libname, oh)
115
+ if verbose
116
+ info (io, " Ignoring system library $(libname) " )
117
+ end
118
+ continue
119
+ end
120
+
121
+ # If this is a default dynamic link, then just rewrite to use rpath and call it good.
122
+ if is_default_lib (libname, oh)
123
+ relink_to_rpath (prefix, platform, path (oh), libs[libname])
124
+ if verbose
125
+ info (io, " Rpathify'ing default library $(libname) " )
126
+ end
127
+ continue
128
+ end
129
+
114
130
if ! isfile (libs[libname])
115
131
# If we couldn't resolve this library, let's try autofixing,
116
132
# if we're allowed to by the user
@@ -250,18 +266,9 @@ function collapse_symlinks(files::Vector{String})
250
266
return filter (predicate, files)
251
267
end
252
268
253
- """
254
- filter_default_linkages(libs::Dict, oh::ObjectHandle)
255
-
256
- Given libraries obtained through `ObjectFile.find_libraries()`, filter out
257
- libraries that are "default" libraries and should be available on any system.
258
- """
259
- function filter_default_linkages (libs:: Dict , oh:: ObjectHandle )
260
- return Dict (k => libs[k] for k in keys (libs) if ! should_ignore_lib (k, oh))
261
- end
262
-
269
+ # These are libraries we should straight-up ignore, like libsystem on OSX
263
270
function should_ignore_lib (lib, :: ELFHandle )
264
- default_libs = [
271
+ ignore_libs = [
265
272
" libc.so.6" ,
266
273
# libgcc Linux and FreeBSD style
267
274
" libgcc_s.1.so" ,
@@ -270,32 +277,59 @@ function should_ignore_lib(lib, ::ELFHandle)
270
277
" libgfortran.so.3" ,
271
278
" libgfortran.so.4" ,
272
279
]
273
- return lowercase (basename (lib)) in default_libs
280
+ return lowercase (basename (lib)) in ignore_libs
274
281
end
275
-
276
282
function should_ignore_lib (lib, :: MachOHandle )
277
- default_libs = [
283
+ ignore_libs = [
278
284
" libsystem.b.dylib" ,
279
- " libgcc_s.1.dylib" ,
280
- " libgfortran.3.dylib" ,
281
- " libgfortran.4.dylib" ,
282
- " libquadmath.0.dylib" ,
283
285
]
284
- return lowercase (basename (lib)) in default_libs
286
+ return lowercase (basename (lib)) in ignore_libs
285
287
end
286
-
287
288
function should_ignore_lib (lib, :: COFFHandle )
288
- default_libs = [
289
+ ignore_libs = [
289
290
" msvcrt.dll" ,
290
291
" kernel32.dll" ,
291
292
" user32.dll" ,
292
293
" libgcc_s_sjlj-1.dll" ,
293
294
" libgfortran-3.dll" ,
294
295
" libgfortran-4.dll" ,
295
296
]
297
+ return lowercase (basename (lib)) in ignore_libs
298
+ end
299
+
300
+ # Determine whether a library is a "default" library or not, if it is we need
301
+ # to map it to `@rpath/$libname` on OSX.
302
+ is_default_lib (lib, oh) = false
303
+ function is_default_lib (lib, :: MachOHandle )
304
+ default_libs = [
305
+ " libgcc_s.1.dylib" ,
306
+ " libgfortran.3.dylib" ,
307
+ " libgfortran.4.dylib" ,
308
+ " libquadmath.0.dylib" ,
309
+ ]
296
310
return lowercase (basename (lib)) in default_libs
297
311
end
298
312
313
+ function relink_to_rpath (prefix:: Prefix , platform:: Platform , path:: AbstractString ,
314
+ old_libpath:: AbstractString ; verbose:: Bool = false )
315
+ ur = UserNSRunner (prefix. path; cwd= " /workspace/" , platform= platform, verbose= true )
316
+ rel_path = relpath (path, prefix. path)
317
+ libname = basename (old_libpath)
318
+ relink_cmd = ` `
319
+
320
+ if Compat. Sys. isapple (platform)
321
+ install_name_tool = " /opt/x86_64-apple-darwin14/bin/install_name_tool"
322
+ relink_cmd = ` $install_name_tool -change $(old_libpath) @rpath/$(libname) $(rel_path) `
323
+ elseif Compat. Sys. islinux (platform)
324
+ patchelf = " /usr/local/bin/patchelf"
325
+ relink_cmd = ` $patchelf --replace-needed $(old_libpath) \$ ORIGIN/$(libname) $(rel_path) `
326
+ end
327
+
328
+ # Create a new linkage that looks like $ORIGIN/../lib, or similar
329
+ logpath = joinpath (logdir (prefix), " relink_to_rpath_$(libname) .log" )
330
+ run (ur, relink_cmd, logpath; verbose= verbose)
331
+ end
332
+
299
333
"""
300
334
update_linkage(prefix::Prefix, platform::Platform, path::AbstractString,
301
335
old_libpath, new_libpath; verbose::Bool = false)
0 commit comments