Generating and using libpng-config

It's a shell script

The libpng-config file generated at libpng build time is a *NIX shell script (therefore not applicable to MS Win native toolchains).

Errr, How Come?

By keeping build/install -time option parameters in a shell script, they are available for easy access at a later date (when it is quite likely, errr, possible, that the user settings chosen when libpng was built and installed, have been forgotten). Please note that not every packager of libpng for the many "client" projects uses libpng-config: on Debian GNU/Linux, for example, none is installed (as doing thus: $dpkg -L libpng{2,3}-dev  "   will confirm, for you Debian users).

Hey, Packaging Guru: If you are beginning to port or package libpng to a project, please consider not disabling (or failing to install) libpng-config.

In keeping with the principles embodied in the GNU Auto* tools, for example, the use of shell scripting as a common baseline facility (available in all *NIX-like development platforms) helps to keep software packages as portable as possible. Such a shell script, provided it is installed in a known location (i.e., on the system PATH), can be easily invoked from a autoconf- generated configure script included in the "client" software source kit. It needn't be hard to link applications to the right installed version of libpng, and it should not be something that one worker after another after another has to wrestle with an re-invent solutions for over and over again (a shameful waste of human resources).

It should go without saying that software packagers basing their distribution methodology on technologies like apt or rpm have at their disposal some methods for solving these sorts of problems. I still urge such good persons to not neglect libpng-config when they create their installation packages. Please think about portability, universality and the cases of users who want to work with the canonical upstream software releases independently of your pet management system.

A test harness for the libpng-config tool

In order to facilitate the continued testing and deployment of the libpng-config mechanism, I've written a tool intended for use by libpng developers and users to make sure that libpng-config is doing what it needs to. This tool (written in Perl) is named libpng-cyoke and is being donated to the libpng project for use by the libpng maintainers in whatever way they chose. Since it hasn't been accepted yet (as of this writing), I cannot say for sure, but my intention is that it shall be available for use under the Licensing terms of the libpng package itself.

libpng-cyoke usage

The libpng-cyoke tool is very simple to use. Invoke it either by its name alone or with the pathname to a libpng-config script to execute as an argument.

       $ libpng-cyoke

       # or ...

       $ libpng-cyoke <path/to/some/libpng-config>

The utility will output to stdout (the console) a table of all the configuration parameters known to libpng-config for the installed instance of libpng that it belongs to. It will also show if there are any option flag arguments to libpng-config that are supposed to be "known" but will trigger a script error (as is the case for libpng release 1.2.5).

The first release of libpng-cyoke is available for download here (release 0.05). Unroll the gztar-ball into a build directory and check the README file for standard Perl-ish installation instructions (hint: it comes with a Makefile.PL).

The output from the libpng-cyoke utility is shown below for two installations of libpng. The first is libpng-1.2.5 built without modifications to the libpng-config -generating apparatus, the second shows the data stored in libpng-config after my modifications are applied.
If the reader is having any difficulty viewing these files as presented in Inline-Frames (IFRAME), see them independently at these locations:

  1. libpng-config_tool_diag.html
  2. libpng-config_tool_good.html

Some commentary on the differences between the two will be posted on a later update of this page. Please note the difference in how the option parameters are populated.


Work It Baby

So what? So let's see how it works when we try to build an application that needs libpng. The example selected this time is from the contrib/gregbook subtree in the libpng src kit. The "GregBook Apps" are a couple of PNG display applications (rpng, rpng2) and a writer (wpng). Let's make this extra fun by trying to specify that we need to link in libpng static-ly instead of resolving the symbols by finding the dynamic library at run-time.

Notice that the screen output displayed above reflects the workings of the make program directing the compilation of these binaries based on the contents of the Makefile I rewrote and not on the makefile Greg wrote, that is found in the contrib/gregbook part of libpng's src kit.

Breakdown

In the output above, lines [001] through [012] are just informational output (program feedback to user, letting them know what it thinks it is going to do ... IMHO, always a good thing to provide if possible). The lines after break down as follows:

  1. lines [013] and [014] show the compilation (gcc-2.95.4 on GNU/Linux, btw) of the C code for wpng  and then line [015] shows gcc operating on the object files just created, thus invoking the linker ld to create the output executable file.

    Notice the linker flags being given to gcc, for it to pass through to ld ...

    -Wl,-rpath,/opt/beta/lib -Wl,-dn -L/opt/beta/lib -lpng12 -Wl,-dy -lz -lm
    ... on the GNU/Linux platform, most GCC installations default to finding the shared-object (*.so*) versions of libs to link against, rather than static object archives. This means we must convince GCC that we really need to have the .a rendition of -lpng instead of the DLL. To do this we say -Wl,-dn which in ld-speak means "dynamic: no".

    The -Wl,-dn directive is, note well, placed before the -L<dir> token. In GCC, the linker arguments are basically parsed left-to-right, and a directive targets (is applied to) those arguments that come after (to the right of) it. The placement of the linker directives thus matters. Following the -L token we finally see -lpng[12]. The -L token and -l<somelibstem> are a syntactic unit for GCC! The meaning changes dramatically if there has been no -L</somedir/where> placed before it in the sequence of GCC arguments. Alone, -lpng says "find me any old libpng to satisfy my lust for its symbols". If the libpng you meant for GCC to find isn't first in GCC's default search path list, then no matter how fervently you desired it, you will not see a final product executable that's been linked against the libpng you intended.

  2. In lines [016] through [031] above, we get the satisfying confirmation that GCC has made ld do the thing we wanted. Because of the argument -Wl,-t (-t for trace) seen early in the commandline for gcc, the output on stderr (shown in green) lists each source of resolved symbols as ld finds that source. Some of the objects listed at the very beginning and end are basic stuff needed in every ELF-format executable. Then we see wpng.o and writepng.o in our current working directory — ahhhhh. Then comes the listing of module objects archived in our static libpng library, found (as we intended) in /opt/beta/lib/libpng12.a.

  3. Lastly in lines [032]-[036] we see the effects of the -Wl,-dy -lz -lm tail of our GCC commandline. The ld tool graciously acknowledges that we said "if you need to satisfy some symbol-hunger from libz or libm, please try first to do so with a shared ( dynamic ) version of those". If we had not stated -Wl,-dy after -lpng12, ld would have most likely thought it best to obediently seek out all remaining unresolved symbols in a static fashion ... including the implicit search for libc symbols. This would be weird. If you really meant to do something as weird as that, having to write your own custom build configuration that bypasses this convenience mechanism and this makefile would be your richly-deserved just desserts. :-)

    Hopefully the importance of libpng-config begins to grow clear now, for the doubter. It really isn't such a simple matter to tell GCC just exactly what you need it to do. No makefile alone, no matter how cleverly complexicatified it is made, is likely to do a fully satisfactory job of covering all possible installed locations of libpng or the linker args needed to perform a very specific selection of dynamic vs static versions of the library, etc.

    I'll have to come back another time to add to this walk-through. Life is calling. Thanks for reading!



Page still Under Construction Tue, 13 Jul 2004 17:11:59 +0000
This document is Copyright (c) 2004 Soren Andersen. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the most recent version of the license may be viewed at

Some content on this page was generated using the Open Source tools "HTML::TextToHTML" (a Perl module on the CPAN) and "HTML Tidy".

communicate to the author about this document:
perlspinr -AT- att *DOT* net   OR   somian -AT- pobox *DOT* com
use irc: look for somian on #pound-perl.pm (EFNet, freenode, etc.)