Skip to content

Commit

Permalink
Automatically relink libgfortran to @rpath/libgfortran on OSX. (J…
Browse files Browse the repository at this point in the history
  • Loading branch information
staticfloat committed Feb 15, 2018
1 parent 35f4e9f commit 96871ea
Showing 1 changed file with 57 additions and 23 deletions.
80 changes: 57 additions & 23 deletions src/Auditor.jl
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,25 @@ function audit(prefix::Prefix; io=STDERR,
info(io, msg)
end

# Look at every non-default dynamic link
libs = filter_default_linkages(find_libraries(oh), oh)
# Look at every dynamic link, and see if we should do anything about that link...
libs = find_libraries(oh)
for libname in keys(libs)
if should_ignore_lib(libname, oh)
if verbose
info(io, "Ignoring system library $(libname)")
end
continue
end

# If this is a default dynamic link, then just rewrite to use rpath and call it good.
if is_default_lib(libname, oh)
relink_to_rpath(prefix, platform, path(oh), libs[libname])
if verbose
info(io, "Rpathify'ing default library $(libname)")
end
continue
end

if !isfile(libs[libname])
# If we couldn't resolve this library, let's try autofixing,
# if we're allowed to by the user
Expand Down Expand Up @@ -250,18 +266,9 @@ function collapse_symlinks(files::Vector{String})
return filter(predicate, files)
end

"""
filter_default_linkages(libs::Dict, oh::ObjectHandle)
Given libraries obtained through `ObjectFile.find_libraries()`, filter out
libraries that are "default" libraries and should be available on any system.
"""
function filter_default_linkages(libs::Dict, oh::ObjectHandle)
return Dict(k => libs[k] for k in keys(libs) if !should_ignore_lib(k, oh))
end

# These are libraries we should straight-up ignore, like libsystem on OSX
function should_ignore_lib(lib, ::ELFHandle)
default_libs = [
ignore_libs = [
"libc.so.6",
# libgcc Linux and FreeBSD style
"libgcc_s.1.so",
Expand All @@ -270,32 +277,59 @@ function should_ignore_lib(lib, ::ELFHandle)
"libgfortran.so.3",
"libgfortran.so.4",
]
return lowercase(basename(lib)) in default_libs
return lowercase(basename(lib)) in ignore_libs
end

function should_ignore_lib(lib, ::MachOHandle)
default_libs = [
ignore_libs = [
"libsystem.b.dylib",
"libgcc_s.1.dylib",
"libgfortran.3.dylib",
"libgfortran.4.dylib",
"libquadmath.0.dylib",
]
return lowercase(basename(lib)) in default_libs
return lowercase(basename(lib)) in ignore_libs
end

function should_ignore_lib(lib, ::COFFHandle)
default_libs = [
ignore_libs = [
"msvcrt.dll",
"kernel32.dll",
"user32.dll",
"libgcc_s_sjlj-1.dll",
"libgfortran-3.dll",
"libgfortran-4.dll",
]
return lowercase(basename(lib)) in ignore_libs
end

# Determine whether a library is a "default" library or not, if it is we need
# to map it to `@rpath/$libname` on OSX.
is_default_lib(lib, oh) = false
function is_default_lib(lib, ::MachOHandle)
default_libs = [
"libgcc_s.1.dylib",
"libgfortran.3.dylib",
"libgfortran.4.dylib",
"libquadmath.0.dylib",
]
return lowercase(basename(lib)) in default_libs
end

function relink_to_rpath(prefix::Prefix, platform::Platform, path::AbstractString,
old_libpath::AbstractString; verbose::Bool = false)
ur = UserNSRunner(prefix.path; cwd="/workspace/", platform=platform, verbose=true)
rel_path = relpath(path, prefix.path)
libname = basename(old_libpath)
relink_cmd = ``

if Compat.Sys.isapple(platform)
install_name_tool = "/opt/x86_64-apple-darwin14/bin/install_name_tool"
relink_cmd = `$install_name_tool -change $(old_libpath) @rpath/$(libname) $(rel_path)`
elseif Compat.Sys.islinux(platform)
patchelf = "/usr/local/bin/patchelf"
relink_cmd = `$patchelf --replace-needed $(old_libpath) \$ORIGIN/$(libname) $(rel_path)`
end

# Create a new linkage that looks like $ORIGIN/../lib, or similar
logpath = joinpath(logdir(prefix), "relink_to_rpath_$(libname).log")
run(ur, relink_cmd, logpath; verbose=verbose)
end

"""
update_linkage(prefix::Prefix, platform::Platform, path::AbstractString,
old_libpath, new_libpath; verbose::Bool = false)
Expand Down

0 comments on commit 96871ea

Please sign in to comment.