dependencies.sh - listing dependencies recursively
What are dependencies
When you write a program (in C or C++) you typically use a couple of
libraries to ease and speed up your development. Let’s say you want to
do vector graphics, then chances are you would use the software
library Cairo
Graphics. This adds a dependency to
your program. Cairo itself might use (see below) libraries
itself. These libraries are Cairo’s dependenices. Your program will
depend on Cairo and all of its dependencies.
My goal
Updated 2020-11-01
I would like to have a tree like view of the dependencies. I don’t want them as a list.
List a program’s or library’s dependencies
There are a couple of ways I know to do this. There are probably tons
more ways to do this, but we’re focusing on “my” solutions. Let’s
check the library libfreetype.so
(FreeType
project.
objdump
About objdump (from the man page)
objdump - display information from object files
To list the dependencies for a program/library, use the option -x
.
$ objdump -x /usr/lib/x86_64-linux-gnu/libfreetype.so.6.17.1 | grep NEEDED
NEEDED libpng16.so.16
NEEDED libz.so.1
NEEDED libc.so.6
ldd
About ldd (from the man page
ldd - print shared object dependencies
To list the dependencies for a program/library no option is needed.
$ ldd /usr/lib/x86_64-linux-gnu/libfreetype.so.6.17.1
linux-vdso.so.1 (0x00007ffc179d2000)
libpng16.so.16 => /lib/x86_64-linux-gnu/libpng16.so.16 (0x00007f9d0b8e5000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f9d0b8c9000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9d0b6d7000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f9d0b588000)
/lib64/ld-linux-x86-64.so.2 (0x00007f9d0ba00000)
readelf
About readelf (from the man page)
readelf - display information about ELF files
To list the dependencies for a program/library, we need to add the option -d
and grep for NEEDED
.
$ readelf -d /usr/lib/x86_64-linux-gnu/libfreetype.so.6.17.1| grep NEEDED
0x0000000000000001 (NEEDED) Shared library: [libpng16.so.16]
0x0000000000000001 (NEEDED) Shared library: [libz.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
Summarising
Let’s exclude the libc related libraries
Tool | Found dependencies |
---|---|
objdump | libpng, libz |
ldd | libpng, libz |
readelf | libpng, libz |
Let’s do it recursively
For each found library, check out that library’s dependencies and so
on. It is a pretty straight forward task but you don’t have to write
that. It’s already done for you. In the next section, we’re going to
introduce dependencies.sh
.
Introducing dependencies.sh
This time we’re going to use a small script over at vinland-technology called dependencies.sh.
Let’s continue with freetype.so
and let dependencies.sh
do the work:
$ ~/opt/vinland/compliance-utils/bin/dependencies.sh libfreetype.so
libfreetype.so.6.17.1
libpng16.so.16
libz.so.1
libz.so.1
We can see, using the Nobel Prize award worthy formating, that
libpng
has a dependency (libz
) by itself.
If you want some graphics for that, you chose between png
,
pdf
, jpg
and svg
. Let’s for creating a png version (since this is easy to display on an HTML page likes this):
$ ~/opt/vinland/compliance-utils/bin/dependencies.sh --png libfreetype.so
Log file created: /home/hesa/.vinland/elf-deps/libfreetype.so.log
Created dot file: /home/hesa/.vinland/elf-deps/libfreetype.so.6.17.1.dot
Created png file: /home/hesa/.vinland/elf-deps/libfreetype.so.6.17.1.dot.png
Here’s the result:
Let’s create and overview of the library libcairo.so
:
$ ~/opt/vinland/compliance-utils/bin/dependencies.sh --png libcairo.so
Log file created: /home/hesa/.vinland/elf-deps/libcairo.so.log
Created dot file: /home/hesa/.vinland/elf-deps/libcairo.so.2.11600.0.dot
Created png file: /home/hesa/.vinland/elf-deps/libcairo.so.2.11600.0.dot.png
Here’s the result:
Other options
You can chose between using ldd
, readelf
(default) or objdump
.
As already mentioned you can generate ASCII printout or a bit fancier
formats as pdf, png, jpg and svg. These are created from a dot
(Graphviz) file so obviously that format is
supported as well
Looking at a program’s dependency
Let’s have a look at git:
$ dependencies.sh --long git
/usr/bin/git
/usr/lib/x86_64-linux-gnu/libpcre2-8.so.0.9.0
/usr/lib/x86_64-linux-gnu/libz.so.1.2.11
$ ~/opt/vinland/compliance-utils/bin/dependencies.sh --png git
Log file created: /home/hesa/.vinland/elf-deps/git.log
Created dot file: /home/hesa/.vinland/elf-deps/git.dot
Created png file: /home/hesa/.vinland/elf-deps/git.dot.png
Yes, there’s a long
option to dependencies.sh
which gives
you the libraries and program with path.
Here’s the result:
… that’s all for now.
Some words about coming posts
So far everything is nice and dandy. libcairo.so
has a couple of
dependencies (recursively). But what if we were to look into a bit
higher level libraries or even programs? It will be a lot of
dependencies. Yes, a lot. I’ll leave you with this cliff hanger.
About the cover image
This post, we simply use one of the graphis produced by
dependencies.sh
.