Skip to content

Commit 3d5685a

Browse files
authoredMay 13, 2017
Merge pull request #21813 from JuliaLang/sf/murphys_fixup
[WIP] Second round of fixup_libgfortran changes
2 parents b1f668d + 4c501a7 commit 3d5685a

File tree

1 file changed

+55
-38
lines changed

1 file changed

+55
-38
lines changed
 

‎contrib/fixup-libgfortran.sh

+55-38
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
#!/bin/sh
22
# This file is a part of Julia. License is MIT: https://julialang.org/license
33

4-
# Run as: fixup-libgfortran.sh <$private_libdir>
4+
# Run as: fixup-libgfortran.sh [--verbose] <$private_libdir>
5+
6+
# If we're invoked with "--verbose", create a `debug` function that prints stuff out
7+
if [ "$1" == "--verbose" ] || [ "$1" == "-v" ]; then
8+
shift 1
9+
debug() { echo "$*"; }
10+
else
11+
debug() { :; }
12+
fi
513

614
if [ -z "$1" ]; then
715
echo "Usage: $0 <private_libdir>"
@@ -14,7 +22,7 @@ if [ "$UNAME" = "Linux" ]; then
1422
elif [ "$UNAME" = "Darwin" ]; then
1523
SHLIB_EXT="dylib"
1624
else
17-
echo "WARNING: Could not autodetect platform type ('uname -s' == $UNAME); assuming Linux"
25+
echo "WARNING: Could not autodetect platform type ('uname -s' == $UNAME); assuming Linux" >&2
1826
UNAME="Linux"
1927
SHLIB_EXT="so"
2028
fi
@@ -26,27 +34,34 @@ if [ ! -f "$private_libdir/libarpack.$SHLIB_EXT" ]; then
2634
exit 2
2735
fi
2836

29-
find_shlib ()
37+
find_shlib()
3038
{
31-
if [ -f "$private_libdir/lib$1.$SHLIB_EXT" ]; then
39+
lib_path="$1"
40+
if [ -f "$lib_path" ]; then
3241
if [ "$UNAME" = "Linux" ]; then
33-
ldd "$private_libdir/lib$1.$SHLIB_EXT" | grep $2 | cut -d' ' -f3 | xargs
42+
ldd "$lib_path" | grep $2 | cut -d' ' -f3 | xargs
3443
else # $UNAME is "Darwin", we only have two options, see above
35-
otool -L "$private_libdir/lib$1.$SHLIB_EXT" | grep $2 | cut -d' ' -f1 | xargs
44+
otool -L "$lib_path" | grep $2 | cut -d' ' -f1 | xargs
3645
fi
3746
fi
3847
}
3948

49+
private_libname()
50+
{
51+
echo "$private_libdir/lib$1.$SHLIB_EXT"
52+
}
53+
4054
# First, discover all the places where libgfortran/libgcc is, as well as their true SONAMES
4155
for lib in arpack openspecfun lapack; do
4256
if [ -f "$private_libdir/lib$lib.$SHLIB_EXT" ]; then
4357
# Find the paths to the libraries we're interested in. These are almost
4458
# always within the same directory, but we like to be general.
45-
LIBGFORTRAN_PATH=$(find_shlib $lib libgfortran)
46-
LIBGCC_PATH=$(find_shlib $lib libgcc_s)
47-
LIBQUADMATH_PATH=$(find_shlib $lib libquadmath)
59+
LIBGFORTRAN_PATH=$(find_shlib "$(private_libname $lib)" libgfortran)
60+
LIBGCC_PATH=$(find_shlib "$(private_libname $lib)" libgcc_s)
61+
LIBQUADMATH_PATH=$(find_shlib "$(private_libname $lib)" libquadmath)
4862

49-
# Take the directories, add them onto LIBGFORTRAN_DIRS to search for things later
63+
# Take the directories, add them onto LIBGFORTRAN_DIRS, which we use to
64+
# search for these libraries in the future.
5065
LIBGFORTRAN_DIRS="$LIBGFORTRAN_DIRS $(dirname $LIBGFORTRAN_PATH)"
5166
LIBGFORTRAN_DIRS="$LIBGFORTRAN_DIRS $(dirname $LIBGCC_PATH)"
5267
LIBGFORTRAN_DIRS="$LIBGFORTRAN_DIRS $(dirname $LIBQUADMATH_PATH)"
@@ -66,6 +81,8 @@ uniquify()
6681

6782
LIBGFORTRAN_DIRS=$(uniquify "$LIBGFORTRAN_DIRS")
6883
SONAMES="$(uniquify "$LIBGFORTRAN_SONAMES $LIBGCC_SONAMES $LIBQUADMATH_SONAMES")"
84+
debug "Discovered traces of libgfortran within $LIBGFORTRAN_DIRS"
85+
debug "Got SONAMES of $SONAMES"
6986

7087
# Copy the SONAMEs we identified above into our private_libdir
7188
for soname in $SONAMES; do
@@ -78,48 +95,48 @@ for soname in $SONAMES; do
7895
fi
7996
fi
8097
done
81-
82-
# Add possible internal directories to LIBGFORTRAN_DIRS so that we can find all possible ways
83-
# That any of our libraries or these libraries we just copied in link to themselves later.
84-
if [ -f "$private_libdir/$soname" ]; then
85-
LIBGFORTRAN_DIRS="$LIBGFORTRAN_DIRS $(dirname $(find_shlib $lib libgfortran))"
86-
LIBGFORTRAN_DIRS="$LIBGFORTRAN_DIRS $(dirname $(find_shlib $lib libgcc_s))"
87-
LIBGFORTRAN_DIRS="$LIBGFORTRAN_DIRS $(dirname $(find_shlib $lib libquadmath))"
88-
fi
8998
done
9099

91-
100+
# On OSX, we need to change the old link (which is usually a full path)
101+
# to point to `@rpath/${soname}` explicitly, so we use `find_shlib()`
102+
# to dynamically find the full path we want to change. On Linux, we
103+
# don't care about full paths, we just set the rpath to `$ORIGIN`.
92104
change_linkage()
93105
{
94-
shlib_path="$1"
95-
old_link="$2"
96-
new_link="$3"
106+
# This is the path of the library we want to edit
107+
lib_path="$1"
108+
109+
# If it doesn't exist, exit quietly
110+
if [ ! -f "$lib_path" ]; then
111+
debug " $lib_path doesn't exist, skipping"
112+
return
113+
fi
114+
115+
# This is the soname of the dependency we want to swap out
116+
soname="$2"
117+
97118
if [ "$UNAME" = "Darwin" ]; then
98-
install_name_tool -change "$old_link" "$new_link" "$shlib_path"
119+
old_link=$(find_shlib "$lib_path" "$soname")
120+
echo " $old_link"
121+
install_name_tool -change "$old_link" "@rpath/$soname" "$lib_path"
99122
else # $UNAME is "Linux", we only have two options, see above
100-
patchelf --set-rpath \$ORIGIN "$shlib_path"
123+
patchelf --set-rpath \$ORIGIN "$lib_path"
101124
fi
102125
}
103126

104-
LIBGFORTRAN_DIRS=$(uniquify "$LIBGFORTRAN_DIRS")
105-
echo "Found traces of libgfortran/libgcc in $LIBGFORTRAN_DIRS"
106-
107-
# For every library that remotely touches libgfortran stuff (so the libraries
108-
# we have copied in ourselves as well as arpack, openspecfun, etc...) we must
127+
# For every library that remotely touches libgfortran stuff (the libraries we
128+
# have copied in ourselves as well as arpack, openspecfun, etc...) we must
109129
# update the linkage to point to @rpath (on OSX) or $ORIGIN (on Linux) so
110130
# that direct links to the old libgfortran directories are instead directed
111131
# to the proper location, which is our $private_libdir.
112-
cd $private_libdir
113-
114-
# Iterate over possible library names
115-
for soname in libopenblas libarpack libcholmod liblapack libopenspecfun $SONAMES; do
132+
for lib in libopenblas libarpack libcholmod liblapack libopenspecfun $SONAMES; do
116133
# Grab every incarnation of that library that exists within $private_libdir
117134
# (e.g. "libopenspecfun.so", and "libopenspecfun.so.0", etc...)
118-
for lib in $private_libdir/$soname*.$SHLIB_EXT*; do
119-
# Look for links to any of the our three musketeers within ANY of the
120-
# potential LIBGFORTRAN_DIRS we've discovered so far
121-
for dir in $LIBGFORTRAN_DIRS; do
122-
change_linkage "$lib" "$dir/$soname" "@rpath/$soname"
135+
for lib_path in $private_libdir/$lib*; do
136+
# Iterate over dependency names that need to be changed
137+
for soname in $SONAMES; do
138+
debug "changing linkage of $lib_path to $soname"
139+
change_linkage "$lib_path" "$soname"
123140
done
124141
done
125142
done

0 commit comments

Comments
 (0)
Please sign in to comment.