Skip to content

Instantly share code, notes, and snippets.

@linuxundich
Forked from jmazzi/getlibs
Created May 7, 2013 21:10
Show Gist options
  • Save linuxundich/5536156 to your computer and use it in GitHub Desktop.
Save linuxundich/5536156 to your computer and use it in GitHub Desktop.
#!/bin/bash
#The MIT License
#
#Copyright (c) 2007 Cappy
#Permission is hereby granted, free of charge, to any person obtaining a copy
#of this software and associated documentation files (the "Software"), to deal
#in the Software without restriction, including without limitation the rights
#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
#copies of the Software, and to permit persons to whom the Software is
#furnished to do so, subject to the following conditions:
#
#The above copyright notice and this permission notice shall be included in
#all copies or substantial portions of the Software.
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
#THE SOFTWARE.
#---
#Author: Cappy of ubuntuforums.org
#Website: http://ubuntuforums.org/showthread.php?t=474790
#Version: 2.07
#Purpose: Download and install native and non-native libraries
#---
print_usage()
{
echo "\
Usage: getlibs /path/to/binary
getlibs -l i386librarytoinstall.so
getlibs -p i386packagename
getlibs -w www.website.com/i386package.deb
getlibs -i /home/$USER/i386package.deb
See 'man getlibs' for more commands"
clean_up_err
}
clean_up()
{
rm -rf $tempdir #Normal exit without errors
}
clean_up_err()
{
rm -rf $tempdir
exit 1 #Exit code 1
}
wget_fail()
{
echo "\
The mirrors do not have the requested file or there is no internet connection"
#clean_up_err
}
#Trap exits
trap clean_up_err 1 2 3 13 15 #Script error or interrupt
trap clean_up 0 #Normal exit
PATH="/usr/bin:/bin:/sbin:/usr/sbin:$PATH"; export PATH
version="Getlibs version 2.06 - March 1st 2008"
architecture=`uname -m`
targetarch="x86" #Set 64-bit machines to download 32-bit if no options are set
if [ "$architecture" != "x86_64" ] && [ "$architecture" != "ia64" ]; then
architecture="x86"
else
architecture="x86_64"
fi
tempdir=`mktemp -d /tmp/getlibs.XXXXXXXXXX || echo "Unable to create temp directory in /tmp"; clean_up_err`
shopt -s xpg_echo
#Get distro and release
distro=`lsb_release -i | cut -f2`
if [ "$distro" = "Ubuntu" ]; then
release=`lsb_release -c | cut -f2` #dapper, edgy, gutsy, etc.
else
if [ "$architecture" = "x86_64" ]; then
if [ -d /emul/ia32-linux ]; then
distro="Debian"
else
distro="Ubuntu"; release="gutsy";
fi
else
distro="Debian"
fi
fi
#If 64-bit ubuntu and ia32-libs is not installed
if [ "$architecture" = "x86_64" ] && [ "$distro" = "Ubuntu" ] && [ ! -e "/usr/lib/i386-linux-gnu/libGLU.so.1" ]; then
sudo apt-get install ia32-libs
elif [ "$architecture" = "x86_64" ] && [ "$distro" = "Debian" ] && [ ! -d "/emul/ia32-linux" ]; then
sudo apt-get install ia32-libs
fi
if [ $# -lt 1 ]; then
print_usage
fi
set -- `getopt -u -a --longoptions="32: 64: binary: library: package: distro: release: file: link: mirror: ldconfig remove: help update version yes verbose apt-file extract build savebuild" "b: l: p: d: r: i: w: m: c r: u v h" "$@"`
while [ $# -gt 0 ]; do
case "$1" in
--32) targetarch="x86";;
--64) targetarch="x86_64";;
--binary) binarypath="$2"; shift;;
-b) binarypath="$2"; shift;;
--library) library="true"; parameters="$parameters $2"; shift;;
-l) library="true"; parameters="$parameters $2"; shift;;
--package) package="true"; parameters="$parameters $2"; shift;;
-p) package="true"; parameters="$parameters $2"; shift;;
--distro) distro="$2"; shift;;
-d) distro="$2"; shift;;
--release) release="$2"; shift;;
-r) release="$2"; shift;;
--file) file="true"; parameters="$parameters $2"; shift;;
-i) file="true"; parameters="$parameters $2"; shift;;
--link) download="true"; parameters="$parameters $2"; shift;;
-w) download="true"; parameters="$parameters $2"; shift;;
--mirror) mirror2="$2"; parameters="$parameters $2"; shift;;
-m) mirror2="$2"; parameters="$parameters $2"; shift;;
--ldconfig) ldconfig="true";;
-c) ldconfig="true";;
--remove) remove="true"; parameters="$parameters $2"; shift;;
-r) remove="true"; parameters="$parameters $2"; shift;;
--update) update="true";;
-u) update="true";;
--version) echo "$version";;
-v) echo "$version";;
--yes) prompt="yes";;
--verbose) verbose="true";;
--apt-file) aptfile="true";;
--extract) extract="true";;
--build) build="true";;
--savebuild) savebuild="true";;
--help) print_usage;;
-h) print_usage;;
--) shift; break;;
-*) print_usage; exit;;
*) break;;
esac
shift
done
#If no parameters decide if it is a binary or a library
if [ -n "$1" ] && [ -z "$library" ] && [ -z "$binarypath" ] && [ -z "$download" ] && [ -z "$package" ] && [ -z "$file" ]; then
if [ -n "`echo "$1" | grep "\.so"`" ]; then
library="true";
else
#if [ -f "$1" ]; then
binarypath="$1"
#else
#echo "$1 is not an existing file. Assuming this is a package name.\n"
#package="true"
#fi
fi
fi
while [ $# -gt 0 ]; do
if [ "$1" != "--" ]; then
parameters="$parameters $1"
fi
shift
done
not_an_executable()
{
echo "\
Cannot determine the dependencies required by this program, it may be a script:
If this program needs a 32-bit library use:
getlibs -l i386librarytoinstall.so
If this program needs a 64-bit library use:
getlibs -64l amd64librarytoinstall.so"
clean_up_err
}
#Find missing dependencies for a binary
if [ -n "$binarypath" ]; then
if [ ! -f "$binarypath" ]; then
echo "The file \"$binarypath\" does not exist"
print_usage
elif [ ! -r "$binarypath" ]; then
echo "The file \"$binarypath\" does not have read permissions"
clean_up_err
elif [ -z "`file "$binarypath" | grep ELF`" ]; then
not_an_executable
fi
if [ -n "`file "$binarypath" | grep "32-bit"`" ]; then
targetarch="x86"
elif [ -n "`file "$binarypath" | grep "64-bit"`" ]; then
targetarch="x86_64"
else
echo "Not a 32-bit or 64-bit binary"; echo `file "$binarypath"`; clean_up_err;
fi
cd `dirname "$binarypath" || echo "cd $binarypath failed"; clean_up_err` #Change to the program's directory
binarypath=`basename "$binarypath"`
dependencylist=`ldd "$binarypath" | grep "not found" | awk '{print $1}'`
neededlocallibraries=`echo "$dependencylist" | grep "\./"`
if [ -n "$neededlocallibraries" ]; then
neededlocallibraries=`echo ${neededlocallibraries//\.\//}`
echo "You need to be copy the following libraries to the same directory as the binary:"
echo "$neededlocallibraries"
dependencylist=`echo "$dependencylist" | grep -v "\./"`
fi
if [ -z "`echo "$dependencylist" | grep "[[:alpha:]]"`" ]; then
echo "This application isn't missing any dependencies"
exit
fi
parameters="$dependencylist"
library="true"
binarypath="`pwd`/`basename "$binarypath"`"
fi
#Determine how to install library
if [ "$architecture" = "$targetarch" ]; then
installtype="native" #apt-get
elif [ "$architecture" = "x86" ]; then
echo "Cannot install 64-bit libraries on a 32-bit system"; clean_up_err;
else
installtype="nonnative" #32-bit on 64-bit system
fi
while true; do #Loop for incase there are new dependencies created for binary
returned=""
stored_list()
{
stored="
libXss.so.1 libxss1
libdbus-1.so.2 libdbus-1.so.3 libdbus-1-3
libQtCore.so.4 libQtNetwork.so.4 libQtDBus.so.4 libqt4-core
libQtGui.so.4 libqt4-gui
libsigc-2.0.so.0 libsigc++-2.0-0c2a
libasound_module_pcm_pulse.so libasound2-plugins
libglitz-glx.so.1 libglitz-glx1
libglitz.so.1 libglitz1
librsvg-2.so.2 librsvg2-2
libcroco-0.6.so.3 libcroco3
libgsf-1.so.114 libgsf-1-114
libqt-mt.so.3 libqt3-mt
libgtk-1.2.so.0 libgtk1.2
libgmodule-1.2.so.0 libglib1.2
libSDL-1.2.so.0 libsdl1.2debian-all
libXxf86vm.so.1 libxxf86vm1
libXxf86dga.so.1 libxxf86dga1
libcurl.so.3 libcurl3
"
found=`echo "$stored" | grep -m 1 "$1" | grep -o "[^ ]*$"`
if [ -n "$found" ]; then
echo "$found"
fi
}
use_web_interface()
{
PACKAGE=`echo $1 | sed s/\+/%2B/g`
if [ "$distro" = "Ubuntu" ]; then
searchaddress="http://packages.ubuntu.com/search?searchon=contents&keywords=$PACKAGE&mode=exactfilename&suite=$release&arch=i386"
else
searchaddress="http://packages.ubuntu.com/search?searchon=contents&keywords=$PACKAGE&mode=exactfilename&suite=gutsy&arch=i386"
fi
packagenames=`wget --user-agent="getlibs" -q -O- "$searchaddress"`
if [ -z "$packagenames" ]; then
echo 'Not able to connect to http://packages.ubuntu.com to find the package name'
fi
packagenames=`echo "$packagenames" | sed -n '/<td class=\"file\">/,/<\/td>/p' | grep -v '"keyword"' | grep -v "\(/debug/\|-dbg\)" | sed 's/<[^>]*>,*//g' | grep -m1 '[[:alnum:]]' | sed 's/[[:space:]]//g'`
if [ -n "$packagenames" ]; then
echo "$packagenames"
fi
}
apt_file()
{
returned=`apt-file search $1 | grep -m 1 -v "\(debug\|dbg\)" | cut -f1 -d ' '`
if [ -n "$returned" ]; then
echo ${returned/:/}
fi
}
video_drivers() #Attempts to link libGL.so.1 to a driver if libGL.so.1 does not exist
{
if [ "$installtype" = "native" ]; then
videopath="/usr/lib"
else
videopath="/usr/lib32"
fi
if [ -z "`ls $videopath/libGL.so.* 2> /dev/null`" ]; then
echo "libGL is installed from video drivers, please install or reinstall your video drivers"
elif [ -f "$videopath/libGL.so.1" ]; then
echo "libGL is installed from video drivers, please install or reinstall your video drivers"
else
videodriver=`ls $videopath/libGL.so.* | grep -o -m 1 '[^ ]*'`
ln -s "$videodriver" "$videopath/libGL.so.1"
echo "Created symbolic link from $videodriver to $videopath/libGL.so.1"
fi
}
#Find the package name using the library filename
if [ -n "$library" ]; then
packagelist=""
for lib in $parameters; do
lib=`basename $lib`
returned=`stored_list "$lib"`
if [ -n "`echo "$lib" | grep "libGL.so."`" ]; then
video_drivers
elif [ -n "$aptfile" ]; then
returned=`apt_file "$lib"`
if [ -n "$returned" ]; then
packagelist="$packagelist$returned
"
else
echo "Apt-file returned no results for $lib"
fi
elif [ -n "$returned" ]; then
echo "$lib: $returned"
packagelist="$packagelist$returned
"
else
returned=`use_web_interface "$lib"`
if [ -n "$returned" ]; then
echo "$lib: $returned"
packagelist="$packagelist$returned
"
else
echo "No match for $lib"
fi
fi
done
parameters="$packagelist"
package="true"
fi
#If it is native it can apt-get and stop here
if [ "$installtype" = "native" ]; then
if [ "`echo "$parameters" | grep "[[:alpha:]]"`" ]; then
sudo apt-get install $parameters
fi
package=""
parameters=""
exit
fi
if [ -n "$package" ] && [ "`echo "$parameters" | grep "[[:alpha:]]"`" ]; then #If there are packages to download
#Sort list of names and download links
parameters=`echo "$parameters" | sort -u`
echo -n "The following i386 packages will be installed:"
echo "$parameters"
if [ -z "$prompt" ]; then
echo -n "Continue [Y/n]? "
read prompt
fi
case $prompt in
[nN]) clean_up_err;;
[nN][oO]) clean_up_err;;
[yY]) ;;
[yY][eE][sS]) ;;
"") ;;
*) echo "Not understood. Aborting."; clean_up_err;; #Default to no
esac
else
if [ -n "$verbose" ]; then
echo "No packages to download"
fi
fi
#Find the download link using the name of the package
if [ -n "$package" ]; then
links=""
mirrorlist=""
for pack in $parameters; do
templink=`apt-cache --no-all-versions show $pack | grep -o -m 1 '[^ ]*\.deb$'`
if [ -n "$templink" ]; then
linkmirror="`apt-cache policy $pack | grep -m 1 -i -o '\(http:\|www.\|ftp:\|https:\)[^ ]*'`"
if [ -n "$linkmirror" ]; then
if [ -f "/etc/apt/sources.list" ]; then
linkmirror=`grep -o -m 1 "$linkmirror[^ ]*" /etc/apt/sources.list`
elif [ -f "/etc/apt/sources.lst" ]; then
linkmirror=`grep -o -m 1 "$linkmirror[^ ]*" /etc/apt/sources.lst`
else
echo "/etc/apt/sources.list not found"
fi
if [ -n "$linkmirror" ]; then
if [ -z "`echo $linkmirror | grep '/$'`" ]; then
linkmirror="$linkmirror/"
fi
mirrorlist="$mirrorlist$linkmirror "
templink="$linkmirror$templink"
fi
fi
if [ -n "$verbose" ]; then
echo "queue: $templink"
echo "mirror: $linkmirror"
fi
links="$links $templink"
else
echo "$pack was not found in your repositories"
echo "Make sure you have all repositories enabled and updated"
fi
done
links=`echo ${links//amd64\.deb/i386\.deb}`
mirrorlist=`echo "$mirrorlist" | sort -u`
parameters="$links"
link="true"
fi
if [ -z "$mirror" ]; then
if [ "$distro" = "Ubuntu" ]; then
mirror2='http://mirrors.kernel.org/ubuntu/'
else
mirror2='http://mirrors.kernel.org/debian/'
fi
fi
#Create the links to the packages
if [ -n "$link" ]; then
fulllinks=""
for eachlink in $parameters; do
if [ -z "`echo "$eachlink" | grep -i '\(http:\|www.\|ftp:\|https:\)'`" ]; then
if [ -n "$verbose" ]; then
echo "$mirror2 is the new mirror for $eachlink"
fi
fulllinks="$fulllinks $mirror2$eachlink"
else
fulllinks="$fulllinks $eachlink"
fi
done
parameters="$fulllinks"
download="true"
fi
#Local file(s) to install
if [ -n "$file" ]; then
if [ "$architecture" = "x86" ]; then
sudo dpkg -i $parameters; exit
fi
for eachfile in $parameters; do
cp $eachfile $tempdir
done
parameters=""
#build="true"
fi
copy_fail()
{
echo "Copying files failed - run getlibs with \"sudo getlibs\" or as root"
clean_up_err
}
#Download and install
if [ -n "$download" ] && [ -n "`echo "$parameters" | grep "[[:alpha:]]"`" ]; then
echo "Downloading ..."
for eachlink in $parameters; do
if [ -n "$verbose" ]; then
echo "Downloading $eachlink"
fi
wget -q "--directory-prefix=$tempdir" "$eachlink"
if [ $? -ne 0 ]; then
echo "Failed to download file $eachlink"
for eachmirror in $mirrorlist; do
eachlink=`echo ${eachlink//$eachmirror/$mirror2}`
done
wget -q "--directory-prefix=$tempdir" "$eachlink"
if [ $? -ne 0 ]; then
wget_fail
else
echo "$eachlink downloaded successfully from $mirror2"
fi
fi
done
#build="true"
fi
dpkg_repack() {
eachdeb="$1"
debdir="`echo $eachdeb | sed 's/.deb//'`"
debbase=`basename $debdir`
dpkg --extract "$eachdeb" "$debdir-tmp"
dpkg --control "$eachdeb" "$debdir-tmp/DEBIAN"
mkdir -p "$debdir/DEBIAN"
cd "$debdir-tmp"
if [ -d "$debdir-tmp/lib" ]; then
mv "lib" "lib32"
cp -R "lib32/" "$debdir"
fi
if [ -d "$debdir-tmp/usr/lib" ]; then
mkdir -p "$debdir/usr/"
mv "usr/lib" "usr/lib32"
cp -R "usr/lib32/" "$debdir/usr"
fi
if [ -f "DEBIAN/md5sums" ]; then
grep ' \(usr/lib/\|lib/\)' DEBIAN/md5sums | sed 's+ lib/+ lib32/+g' | sed 's+ usr/lib/+ usr/lib32/+g' > "$debdir/DEBIAN/md5sums"
fi
debarch=`grep 'Architecture:' DEBIAN/control`
debpackage=`grep 'Package:' DEBIAN/control`
if [ -n "`echo $debpackage | grep lib`" ]; then
newdebpackage=`echo ${debpackage/lib/lib32}`
else
newdebpackage="$debpackage-i386"
fi
sed "s/$debarch/Architecture: all/g" DEBIAN/control | sed "s/$debpackage/$newdebpackage/" | grep -v 'Depends:' | grep -v 'Conflicts:' | grep -v 'Replaces:' > "$debdir/DEBIAN/control"
if [ -f "DEBIAN/postinst" ]; then
cp "DEBIAN/postinst" "$debdir/DEBIAN"
fi
if [ -f "DEBIAN/postrm" ]; then
cp "DEBIAN/postrm" "$debdir/DEBIAN"
fi
cd "$tempdir/build"
dpkg --build "$debdir" "$debbase.deb"
echo "Installing new $newdebpackage"
sudo dpkg -i "$debbase.deb"
if [ -n "$savebuild" ]; then
echo "Moving new package $debbase.deb to /home/$USER/"
cp $debbase.deb "/home/$USER/"
fi
}
if [ -z "`ls $tempdir/*.deb 2> /dev/null`" ]; then
echo "No packages to install"
exit
fi
if [ -n "$build" ]; then #future default option
mkdir "$tempdir/build"
for eachdeb in `ls $tempdir/*.deb 2> /dev/null`; do
if [ -n "$verbose" ]; then
echo "extracting: $eachdeb"
fi
output=`dpkg_repack "$eachdeb"`
done
else # --extract
for eachdeb in `ls $tempdir/*.deb`; do
if [ -n "$verbose" ]; then
echo "extracting: $eachdeb"
fi
dpkg -x "$eachdeb" "$tempdir/extracted"
done
echo "Installing libraries ..."
ldconfigparam=""
if [ "$distro" = "Ubuntu" ]; then
if [ -d $tempdir/extracted/usr/lib/ ]; then #If dir exists (and thus files to move)
sudo cp -R $tempdir/extracted/usr/lib/i386-linux-gnu/* /usr/lib/i386-linux-gnu/ || copy_fail
ldconfigparam="$ldconfigparam/usr/lib/i386-linux-gnu/ "
fi
if [ -d $tempdir/extracted/lib/ ]; then #If dir exists (and thus files to move)
sudo cp -R $tempdir/extracted/lib/i386-linux-gnu* /lib/i386-linux-gnu/ || copy_fail
ldconfigparam="$ldconfigparam/lib/i386-linux-gnu/ "
fi
elif [ "$distro" = "Debian" ]; then
sudo cp -R $tempdir/extracted/* /emul/ia32-linux/ || copy_fail
ldconfigparam="$ldconfigparam/emul/ia32-linux/ "
fi
fi
# --ldconfig
if [ -n "$ldconfig" ]; then
sudo ldconfig -n $ldconfigparam
fi
#Check binary for new dependencies
if [ -n "$binarypath" ]; then
runningdependencylist="$runningdependencylist
$dependencylist"
dependencylist=`ldd "$binarypath" | grep "not found" | awk '{print $1}' | grep -v "\./"`
if [ -z "$dependencylist" ]; then
exit #All dependencies satisfied
fi
for eachdependency in $runningdependencylist; do
dependencylist=`echo ${dependencylist//$eachdependency/}`
done
dependencylist=`echo "$dependencylist" | grep "[[:alnum:]]"`
if [ -n "$dependencylist" ]; then
rm -rf $tempdir/*
echo "New depedencies have been detected"
parameters="$dependencylist"
else
exit #No new dependencies
fi
else
exit
fi
done
@linuxundich
Copy link
Author

Updates getlibs, so that it works on current Ubuntu versions. According https://wiki.ubuntu.com/MultiarchSpec directories have been moved to

/lib/i386-linux-gnu
/lib/x86_64-linux-gnu
/usr/lib/i386-linux-gnu
/usr/lib/x86_64-linux-gnu

Tested on Ubuntu Raring 13.04 64-Bit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment