Generating and using libpng-config |
The libpng-config file generated at libpng build time is a *NIX shell script (therefore not applicable to MS Win native toolchains).
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:
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.
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.
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:
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.
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.
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:
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 ...
... 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".-Wl,-rpath,/opt/beta/lib -Wl,-dn -L/opt/beta/lib -lpng12 -Wl,-dy -lz -lm
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.
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.
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!