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: libfreetype dependencies

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: libcairo dependencies

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: gitdependencies

… 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.