[GRLUG] Taking A Deep Breath

Adam Tauno Williams awilliam at whitemice.org
Sat Aug 29 18:33:24 EDT 2009


> The issue with upgrading to Firefox 3 from Firefox 1 is one of
> supporting applications.  Firefox, like most programs, cannot run by
> itself.  That is, Firefox requires more than a kernel to run.  With such
> an old installation of Linux, all of the supporting libraries and
> applications that are necessary for a newer version of Firefox are not
> installed.  For example, in the latest version of Debian is Firefox
> v3.0.6.  One of the required underlying packages is libc6.  Firefox
> 3.0.6, as it is packaged in Debian, depends on libc6 being greater than
> or equal to version 2.7-1.  If you were running an old version of
> Debian, the one with Firefox 2.0.0, the version of libc6 would be
> 2.3.5---not recent enough to run 3.0.6.

You can think of it as the UNIX version of DLL-hell.

On a distribution that uses the RPM package manager [which SuSE is] you
can list the requirements ["dependencies"] of a package using the "rpm'
command.

For an installed package -
awilliam at linux-m3mt:~> rpm -qR evolution-data-server
evolution-data-server-lang = 2.24.1.1
libsoup >= 2.2.6
mozilla-nss  
libevoldap-2_4-2  
/sbin/ldconfig  
/sbin/ldconfig  
rpmlib(PayloadFilesHavePrefix) <= 4.0-1
rpmlib(CompressedFileNames) <= 3.0.4-1
/bin/sh  
libORBit-2.so.0
....

For a package [an RPM file, not installed] -
awilliam at linux-m3mt:~> rpm -qpR
Desktop/Downloads/qtnx-0.0.1SVNr281-214.1.i586.rpm
/bin/sh  
/bin/sh  
rpmlib(PayloadFilesHavePrefix) <= 4.0-1
rpmlib(CompressedFileNames) <= 3.0.4-1
libICE.so.6  
libQtCore.so.4  
libQtGui.so.4  
libQtXml.so.4  
libSM.so.6  
libX11.so.6 
...

Note the added "p" in options with essentially means package file.

NOTE: Distributions using the Debian (DEB) package manager, such as
Ubuntu, provide the exact same functionality with just slightly
different syntax.

If you have a specific binary, say the "ls" command, and want to know
what libraries it requires to run you can use the "ldd" command -

awilliam at linux-m3mt:~> ldd /bin/ls
linux-gate.so.1 =>  (0xffffe000)
librt.so.1 => /lib/librt.so.1 (0xb7f21000)
libselinux.so.1 => /lib/libselinux.so.1 (0xb7f04000)
libacl.so.1 => /lib/libacl.so.1 (0xb7efb000)
libc.so.6 => /lib/libc.so.6 (0xb7d9f000)
libpthread.so.0 => /lib/libpthread.so.0 (0xb7d84000)
/lib/ld-linux.so.2 (0xb7f52000)
libdl.so.2 => /lib/libdl.so.2 (0xb7d7f000)
libattr.so.1 => /lib/libattr.so.1 (0xb7d79000)

NOTE: ldd works on installed applications/files so it doesn't care a
whit what distribution you are using or what package manager is in use.

A UNIX oddity is that if your try to run a program and a required
library is not found your attempt to run the program will fail with a
"file not found" error.  Which while not technically incorrect can be
kind of a head-scratcher at first.

If you ldd a file and it says "not a dynamic executable" it means the
file isn't a binary (compiled) application, for example -

awilliam at linux-m3mt:~> ldd /usr/bin/firefox
not a dynamic executable

Eh?  Isn't firefox a program?  Nope -

awilliam at linux-m3mt:~> file /usr/bin/firefox
/usr/bin/firefox: symbolic link to `../lib/firefox/firefox.sh'
awilliam at linux-m3mt:~> file /usr/lib/firefox/firefox.sh
/usr/lib/firefox/firefox.sh: POSIX shell script text

The "file" command is used to identify what kind of file a file is, for
example -

awilliam at linux-m3mt:~> file Documents/zOGIFactory.odg 
Documents/zOGIFactory.odg: OpenDocument Drawing

awilliam at linux-m3mt:~> file
Works/Consonance/bin/Debug/Whitemice.Consonance.exe
Works/Consonance/bin/Debug/Whitemice.Consonance.exe: MS-DOS executable
PE  for MS Windows (console) Intel 80386 32-bit, Mono/.Net assembly

awilliam at linux-m3mt:~> file /bin/ls
/bin/ls: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for
GNU/Linux 2.6.4, dynamically linked (uses shared libs), stripped

Usually "ELF 32-bit LSB executable" is what binary compiled application
files appear as.

Scripts in UNIX have a first line like -

awilliam at linux-m3mt:~> head -1 /usr/bin/firefox 
#!/bin/sh

ASIDE: "head -1 {file}" shows the first line of a file.

The "#!" is a magic sequence that when the file is run is recognized by
the system to mean that the remainder of the file (second line...) is a
script that should be interpreted using the program "/bin/sh".  In this
case /usr/bin/firefox is a shell script (run by the shell /bin/sh) that
does a bunch of gunk and then executes the actual firefox program at
somewhere like /usr/lib/firefox/firefox

awilliam at linux-m3mt:~> file /usr/lib/firefox/firefox
/usr/lib/firefox/firefox: ELF 32-bit LSB executable, Intel 80386,
version 1 (SYSV), for GNU/Linux 2.6.4, dynamically linked (uses shared
libs), stripped

ASIDE: Why do [some] applications have to be started with insanely
complicated scripts rather than just running?  Oh, good question!  The
short answer, IMNSHO: bad design.  Many times this happens on UNIX/LINUX
because the apps are having to work around the lack of a centralized
configuration/system-information repository.  For example the
script /usr/bin/firefox looks around to see where the system stores
browser plugins,  then it starts the actual application and provides it
with that tidbit of critical information.  But since you are developing
Java apps I assume you are familiar with some of that since Java apps
typically require batch/shell scripts to run on any platform including
Windows.

So now you can see what libraries the firefox application requires using
ldd -

awilliam at linux-m3mt:~> ldd /usr/lib/firefox/firefox
linux-gate.so.1 =>  (0xffffe000)
libpthread.so.0 => /lib/libpthread.so.0 (0xb7fd0000)
libasound.so.2 => /usr/lib/libasound.so.2 (0xb7efe000)
libdl.so.2 => /lib/libdl.so.2 (0xb7ef9000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xb7e05000)
libm.so.6 => /lib/libm.so.6 (0xb7ddb000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb7dcc000)
libc.so.6 => /lib/libc.so.6 (0xb7c70000)
/lib/ld-linux.so.2 (0xb8011000)
librt.so.1 => /lib/librt.so.1 (0xb7c66000)

The numbers at the end of the library name [like the 6 in libm.so.6]
indicate the major version of the library.  So if your system only had
libm version 5 [/usr/lib/libm.so.5] then firefox would be unable to run.

Of course all this has equivalence on Windows with DLL files, UNIX just
makes it a bit more in-your-face.  It also make it easier to have
multiple major version of the same library installed:  it is
just /usr/lib/libm.so.5, /usr/lib/libm.so.6, etc...  The runtime linker
when you start a program will deal with that just fine;  but of course
it can't deal with a library that just isn't there.  If you are familiar
with how Microsoft solved DLL hell in .NET the UNIX library layout is
similar. 



More information about the grlug mailing list