Tracing Software Problems to the Source: Using the gdb Debugger

 < Day Day Up > 

Fiddling with File Locations and Fighting with Installers

For this example, you need the netpbm package, available from http://www.macosxunleashed.com/downloads/netpbm-9.12.tgz or from its original home at http://download.sourceforge.net/netpbm/netpbm-9.12.tgz. A more recent version of netpbm is available, and it's the one you'll actually want to install and use eventually, but this older version makes for a nice tour through the underbelly of a software install. The easy download solution is

 curl -O http://download.sourceforge.net/netpbm/netpbm-9.12.tgz 

The file should be 2057293 bytes in length. Uncompress it, untar it, and check whether it wants configure or make:

 brezup:software source $ gunzip netpbm-9.12.tgz brezup:software source $ tar -xf netpbm-9.12.tar brezup:software source $ cd netpbm-9.12 brezup:software netpbm-9.12 $ ls COPYRIGHT.PATENT          README.VMS                pbmplus.h GNUmakefile               amiga                     pgm GPL_LICENSE.txt           compile.h                 pnm HISTORY                   configure                 ppm Makefile                  empty_depend              scoptions Makefile.common           installosf                shhopt Makefile.config.djgpp     libopt.c                  stamp-date Makefile.config.in        libtiff                   stamp-date.amiga Makefile.depend           magic                     testgrid.pbm Netpbm.programming        make_merge.sh             testimg.ppm README                    mantocat                  urt README.CONFOCAL           mkinstalldirs             version.h README.DJGPP              netpbm.lsm                vms README.JPEG               pbm                       zgv_bigmaxval.patch 

There's a configure file, so run it. This one is going to make some guesses and ask you some questions. Pick the options shown in the following example because they're necessary to get the rest of the example to work:

 brezup:software netpbm-9.12 $ ./configure su: ./configure: /bin/perl: bad interpreter: No such file or directory 

Hold on; problem number one that wasn't the expected behavior. The file configure is right here in the directory with you; what's with this "no such file" business? Actually, it's complaining about something else, not the configure script itself. (If you are running tcsh, you get an even less useful error simply tcsh: ./configure: Command not found).

 brezup:software netpbm-9.12 $ head ./configure #!/bin/perl -w use strict; # This program generates Makefile.config, which is included by all of the # Netpbm makefiles.  You run this program as the first step in building # Netpbm.  (The second step is 'make'). # This program is only a convenience.  It is supported to create # Makefile.config any way you want.  In fact, an easy way is to copy ... 

The problem is that Mac OS X doesn't have Perl as /bin/perl; it's /usr/bin/perl. Fire up vi (or your favorite text editor) and change that first line to #!/usr/bin/perl -w. A more permanent solution to the fact that different systems have Perl in /bin/, /usr/bin/, or /usr/local/bin/ is to make a link back to /usr/bin/perl in each of these places where it isn't, so that software written on other systems can run without modification. If you want, the following should fix Perl for most scripts:

 brezup:root netpbm-9.12 # ln -s /usr/bin/perl /bin/perl brezup:root netpbm-9.12 # ln -s /usr/bin/perl /usr/local/bin/perl 

NOTE

Of course, you do need to be root, or sudo your way to the first of those commands, should you choose to make these links.


Because Perl is only the most common thing you'll find that might be affected by this type of configuration problem, and you're unlikely to want to use the link solution for all of them, we'll take the route of fixing the configure script instead.

 brezup:software netpbm-9.12 $ head ./configure #!/usr/bin/perl -w use strict; ... 

Now try again:

 brezup:software netpbm-9.12 $ ./configure Which of the following best describes your platform? 1) GNU/Linux 2) Solaris or SunOS 3) AIX 4) Tru64 5) Irix 6) Windows (Cygwin or DJGPP) 7) BeOS 8) NetBSD 9) none of these are even close Your choice ==> 1 Enter the installation directory (the prefix on all installation paths for 'make install').  This is not built into any programs; It is used only by 'make install'. install prefix (/usr/local/netpbm)=> Do you want static-linked Netpbm libraries or shared? static or shared (shared)=> static Can't exec ""ginstall"": No such file or directory at ./configure line 195. We have created the file 'Makefile.config'.  You can now proceed to enter the 'make' command. Note, however, that we have only made a rough guess at your configuration, and you may want to look at Makefile.config and edit it to your requirements and taste before doing the make. 

NOTE

By the way, we picked GNU/Linux even though Mac OS X is a BSD flavor because many of the tools are GNU tools. Still, this will cause problems later because Linux typically has things in nonstandard places with respect to BSD, and Apple has maintained a lot of the typical BSD filesystem structure.


The results of the configure script are better, but there's an ominous complaint in there about can't exec ginstall. To get things working will take editing that Makefile.config and making a few changes mostly to patch things back to standard locations from where Linux tends to store them. Start vi and look through Makefile.config for lines that look similar to the following; then change them until they're exactly as shown in the following listings:

  • It seems to have ignored the static option given to configure, so set it here, too.

     # STATICLIB = N STATICLIB = Y 

  • ginstall is GNU's installation program. Apple probably uses it, but has probably named it install instead, so comment out the ginstall line and uncomment the install line.

     #INSTALL = ginstall #Solaris: #INSTALL = /usr/ucb/install #Tru64: #INSTALL = installbsd #OSF1: #INSTALL = installosf #Red Hat Linux : INSTALL = install 

This version of the software and the current version of the C compiler don't quite get along. Adding -no-cpp-precomp and -fno-common to the arguments that are handed to the C compiler usually via a CFLAGS variable helps in many cases. The flag -flat_namespace helps with some things as well, and the flag -undefined suppress, which used to help make the linker happy for this software under 10.1, now seems to cause problems (although it's necessary for some other compiles). Add the -no-cpp-precomp and -fno-common for a first try. Add the -flat_namespace and the -undefined_suppress options if it still bombs.

 CFLAGS = -pedantic -no-cpp-precomp -fno-common -O3 -Wall -Wno-uninitialized $(CDEBUG) 

Linux installations tend to have taken a wrong turn in filesystem design, and include the binaries, libraries, and headers for optional packages in the /usr/bin/, /usr/lib/, and /usr/include directories. This makes system maintenance a real problem because your unprivileged software management user would need root privileges to work in those directories. Fix the defaults so that the jpeglib stuff comes from /usr/local, where we put it not too long ago:

 #JPEGLIB_DIR = /usr/lib/jpeg #JPEGHDR_DIR = /usr/include/jpeg # Netbsd: #JPEGLIB_DIR = ${LOCALBASE}/lib #JPEGHDR_DIR = ${LOCALBASE}/include # OSF, Tru64: #JPEGLIB_DIR = /usr/local1/DEC/lib #JPEGHDR_DIR = /usr/local1/DEC/include # Typical: JPEGLIB_DIR = /usr/local/lib JPEGHDR_DIR = /usr/local/include # Don't build JPEG stuff: #JPEGLIB_DIR = NONE #JPEGHDR_DIR = NONE 

Do the same for the libpng stuff:

 #PNGLIB_DIR = /lib #PNGHDR_DIR = /usr/include/png # NetBSD: #PNGLIB_DIR = $(LOCALBASE)/lib #PNGHDR_DIR = $(LOCALBASE)/include # OSF/Tru64: #PNGLIB_DIR = /usr/local1/DEC/lib #PNGHDR_DIR = /usr/local1/DEC/include # Typical: PNGLIB_DIR = /usr/local/lib PNGHDR_DIR = /usr/local/include # No PNG: #PNGLIB_DIR = NONE #PNGHDR_DIR = NONE 

Now you're ready to try the make. If you're running an older version of Mac OS X, and someone hasn't fixed this peculiar problem already, you'll run into a problem with the compiler. If you're running 10.2 or later, you can skip ahead a couple paragraphs to where it says to "try the make again":

 [Racer-X:~/Documents/source/netpbm-9.12] software% make make -C pbm -f /Users/software/Documents/source/netpbm-9.12/pbm/Makefile all ln -s ../pbmplus.h pbmplus.h ln -s ../version.h version.h ../stamp-date gcc -c -I../shhopt -pedantic -O3 -Wall -Wno-uninitialized -o atktopbm.o ../pbm/atktopbm.c make[1]: gcc: Command not found make[1]: *** [atktopbm.o] Error 127 make: *** [pbm] Error 2 

This is not the output we wanted! If the results of your make are more voluminous, skip ahead to where we run make again; otherwise, you need to deal with this complaint that it can't find the compiler. cc is the standard name for a C compiler, but gcc is the GNU C Compiler, and many software packages are written to take advantage of special features that the GNU compiler provides. Apple has been nice enough to provide the GNU compiler with the development tools, but on some versions of Mac OS X, Apple has named it cc instead of gcc. This causes programs that try to accommodate the compiler to break because they don't realize that they're working with gcc, and make the wrong assumptions about what the compiler wants. It also causes problems with software that simply assumes that everyone out there has gcc installed. The error for this program could be fixed by modifying the Makefile.config file again to call cc instead of gcc, but a similar problem will frequently crop up with installations wondering where gcc is, and many installers won't know that they can use the special gcc features unless the compiler is called gcc. If your system is missing a properly named gcc, a better fix is to create an alias (symbolic link) named gcc instead and point it at the cc compiler:

 [Racer-X:~/Documents/source/netpbm-9.12] software% pushd /usr/local/bin /usr/local/bin ~/Documents/source/netpbm-9.12 [Racer-X:/usr/local/bin] software% which cc /usr/bin/cc [Racer-X:/usr/local/bin] software% ln -s /usr/bin/cc ./gcc [Racer-X:/usr/local/bin] software% popd ~/Documents/source/netpbm-9.12 

Try the make again:

brezup:software netpbm-9.12 $ make make -C pbm -f /Users/software/Documents/source/netpbm-9.12/pbm/Makefile all ln -s ../pbmplus.h pbmplus.h ln -s ../version.h version.h ../stamp-date gcc -c -I../shhopt -pedantic -no-cpp-precomp -fno-common -O3 -Wall -Wno-uninitialized -o atktopbm.o ../pbm/atktopbm.c ../pbm/atktopbm.c: In function `ReadATKRaster': ../pbm/atktopbm.c:307: warning: unsigned int format, int arg (arg 3) ../pbm/atktopbm.c:314: warning: implicit declaration of function `strcmp' gcc -c -I../shhopt -pedantic -no-cpp-precomp -fno-common -O3 -Wall -Wno-uninitialized -o libpbm1.o ../pbm/libpbm1.c gcc -c -I../shhopt -pedantic -no-cpp-precomp -fno-common -O3 -Wall -Wno-uninitialized -o libpbm2.o ../pbm/libpbm2.c gcc -c -I../shhopt -pedantic -no-cpp-precomp -fno-common -O3 -Wall -Wno-uninitialized -o libpbm3.o ../pbm/libpbm3.c gcc -c -I../shhopt -pedantic -no-cpp-precomp -fno-common -O3 -Wall -Wno-uninitialized -o libpbm4.o ../pbm/libpbm4.c gcc -c -I../shhopt -pedantic -no-cpp-precomp -fno-common -O3 -Wall -Wno-uninitialized -o libpbm5.o ../pbm/libpbm5.c cd ../shhopt; make shhopt.o gcc -o shhopt.o -c -pedantic -no-cpp-precomp -fno-common -O3 -Wall -Wno-uninitialized -I. shhopt.c rm -f libpbm.a ar rc libpbm.a libpbm1.o libpbm2.o libpbm3.o libpbm4.o libpbm5.o ../shhopt/shhopt.o ranlib libpbm.a make -C .. libopt ... ln -s ../../pbmplus.h pbmplus.h ln -s ../../pbm/pbm.h pbm.h gcc -pedantic -no-cpp-precomp -fno-common -O3 -Wall -Wno-uninitialized -I../../shhopt -c pbmtoppa.c -o pbmtoppa.o gcc -pedantic -no-cpp-precomp -fno-common -O3 -Wall -Wno-uninitialized -I../../shhopt -c ppa.c -o ppa.o gcc -pedantic -no-cpp-precomp -fno-common -O3 -Wall -Wno-uninitialized -I../../shhopt -c pbm.c -o pbm.o gcc -pedantic -no-cpp-precomp -fno-common -O3 -Wall -Wno-uninitialized -I../../shhopt -c cutswath.c -o cutswath.o cd ../../pbm ; make libpbm.a make[3]: `libpbm.a' is up to date. gcc -o pbmtoppa pbmtoppa.o ppa.o pbm.o cutswath.o \ `../../libopt ../../pbm/libpbm.a` make -C pgm -f /Users/software/Documents/source/netpbm-9.12/pgm/Makefile all ln -s ../pbmplus.h pbmplus.h ln -s ../pbm/pbm.h pbm.h ln -s ../pbm/libpbm.h libpbm.h gcc -c -I../shhopt -pedantic -no-cpp-precomp -fno-common -O3 -Wall -Wno-uninitialized -o asciitopgm.o /Users/software/Documents/source/netpbm-9.12/pgm/asciitopgm.c gcc -c -I../shhopt -pedantic -no-cpp-precomp -fno-common -O3 -Wall -Wno-uninitialized -o libpgm1.o /Users/software/Documents/source/netpbm-9.12/pgm/libpgm1.c gcc -c -I../shhopt -pedantic -no-cpp-precomp -fno-common -O3 -Wall -Wno-uninitialized -o libpgm2.o /Users/software/Documents/source/netpbm-9.12/pgm/libpgm2.c rm -f libpgm.a ar rc libpgm.a libpgm1.o libpgm2.o ranlib libpgm.a ... gcc -o pgmtexture pgmtexture.o -lm `../libopt libpgm.a ../pbm/libpbm.a` gcc -c -I../shhopt -pedantic -no-cpp-precomp -fno-common -O3 -Wall -Wno-uninitialized -o rawtopgm.o /Users/software/Documents/source/netpbm-9.12/pgm/rawtopgm.c gcc -o rawtopgm rawtopgm.o -lm `../libopt libpgm.a ../pbm/libpbm.a` gcc -c -I../shhopt -pedantic -no-cpp-precomp -fno-common -O3 -Wall -Wno-uninitialized -o pgmkernel.o /Users/software/Documents/source/netpbm-9.12/pgm/pgmkernel.c gcc -o pgmkernel pgmkernel.o -lm `../libopt libpgm.a ../pbm/libpbm.a` make -C ppm -f /Users/software/Documents/source/netpbm-9.12/ppm/Makefile all ln -s ../pbmplus.h pbmplus.h ln -s ../pbm/pbm.h pbm.h ln -s ../pbm/libpbm.h libpbm.h ln -s ../pbm/pbmfont.h pbmfont.h ln -s ../pgm/pgm.h pgm.h ln -s ../pgm/libpgm.h libpgm.h gcc -c -I../shhopt -I/usr/local/include -pedantic -no-cpp-precomp -fno-common -O3 -Wall -Wno-uninitialized -o 411toppm.o /Users/software/Documents/source/netpbm-9.12/ppm/411toppm.c cc1: warning: changing search order for system directory "/usr/local/include" cc1: warning: as it has already been specified as a non-system directory /Users/software/Documents/source/netpbm-9.12/ppm/411toppm.c:60:20: malloc.h: No such file or directory make[1]: *** [411toppm.o] Error 1 make: *** [ppm] Error 2

Did I mention that I chose this install because it wasn't easy? Those error messages are just gcc being pedantic about the code. The C programming language has gone through a few revisions, and some programs still don't adhere to the most recent standards. The warnings won't hurt anything, but the error at the bottom of the output will. A few lines above the error is the complaint header file malloc.h not found. This is the actual source of the error. If you were a programmer, you'd be expected to clean up all those warnings as well, but for your purposes, just fixing the error is enough. If you were to read the code looking for occurrences of malloc.h (grep might help with this), you'd find there are comments detailing the ambiguities of different Unix flavors and their oddball malloc.h implementations. In Apple's case, it's that malloc.h isn't where the source expects it to be. You've got a choice of fixing all the code to point to /usr/include/sys/malloc.h instead of /usr/include/malloc.h, or cheating a little and making it available somewhere that the makefile already has the compiler looking. We're going to take the cheating route and make a link to /usr/include/sys/malloc.h in /usr/local/include/malloc.h, where the compiler should be able to find it. There's actually another option, adding a path to the places that the compiler will search for header files, but it turns out that fix will break something else later on, so stick with our cheat:

 brezup:software netpbm-9.12 $ pushd /usr/include /usr/include ~/Documents/source/netpbm-9.12 brezup:software include $ find ./ -name malloc.h -print .//malloc/malloc.h .//objc/malloc.h .//sys/malloc.h brezup:software include $ popd ~/Documents/source/netpbm-9.12 brezup:software netpbm-9.12 $ pushd /usr/local/include /usr/local/include ~/Documents/source/netpbm-9.12 brezup:software include $ ln -s /usr/include/sys/malloc.h ./ brezup:software include $ popd ~/Documents/source/netpbm-9.12 

CAUTION

Note that you might want to remove that link to malloc.h after you're finished with the compile. You can always put it back later if you need it, but there are many pieces of software out there that try to figure out what system they're being built on by checking where various files appear to be located. This one doesn't know about Apple's locations, and other bits of the install will break if you make the build find malloc.h where Apple has it stored. Others will misidentify your system if they see a copy in /usr/local/include. Apparently, you simply can't win them all at least not all simultaneously. Because such files only need to be in place while an application's being built, you can put any file anywhere to satisfy the make process and then remove it later, so at least you can win them one at a time.


Back to make again:

brezup:software netpbm-9.12 $ make make -C pbm -f /Users/software/Documents/source/netpbm-9.12/pbm/Makefile all make -C pbmtoppa all cd ../../pbm ; make libpbm.a make[3]: `libpbm.a' is up to date. make -C pgm -f /Users/software/Documents/source/netpbm-9.12/pgm/Makefile all cd ../pbm ; make libpbm.a make[2]: `libpbm.a' is up to date. make -C ppm -f /Users/software/Documents/source/netpbm-9.12/ppm/Makefile all gcc -c -I../shhopt -I/usr/local/include -pedantic -no-cpp-precomp -fno-common -O3 -Wall -Wno- ... gcc -o ppmtojpeg ppmtojpeg.o `../libopt libppm.a ../pbm/libpbm.a ../pgm/libpgm.a` \ -L/usr/local/lib -ljpeg /usr/bin/ld: table of contents for archive: /usr/local/lib/libjpeg.a is out of date; rerun ranlib(1) (can't load from it) make[1]: *** [ppmtojpeg] Error 1 make: *** [ppm] Error 2

Well, at least this time it not only tells us what the error is but also how to fix it.

 brezup:software netpbm-9.12 $ ranlib /usr/local/lib/libjpeg.a 

NOTE

Your system might or might not encounter the error with libjpeg.a and the other subsequent ranlib-related problems. It depends on the order in which you've done a number of things on your system. If you do encounter complaints about library tables of contents being out of date, just follow the instruction given and ranlib it.

You also might or might not encounter this next error in parallel.c. This depends more on which compiler your system is currently set to use, and which set of include and library files it's using. Because Mac OS X ships with a number of gcc versions, and cross-compilation setups for previous versions of the operating system, it's possible to get the system into a situation in which it actually won't experience this error.


brezup:software netpbm-9.12 $ make . . . gcc -c parallel.c -o parallel.o -pedantic -no-cpp-precomp -fno-common -O3 -Wall -Wno-uninitialized -I. -Iheaders -I../../shhopt -I/usr/local/include cc1: warning: changing search order for system directory "/usr/local/include" cc1: warning: as it has already been specified as a non-system directory In file included from parallel.c:89: /usr/include/sys/socket.h:77: parse error before "sa_family_t" /usr/include/sys/socket.h:77: ISO C forbids data definition with no type or storage class /usr/include/sys/socket.h:212: parse error before "u_char" /usr/include/sys/socket.h:213: ISO C forbids data definition with no type or storage class /usr/include/sys/socket.h:215: parse error before '}' token /usr/include/sys/socket.h:223: parse error before "u_short" ... parallel.c:1764: storage size of `nameEntry' isn't known parallel.c:1790: sizeof applied to an incomplete type parallel.c:1764: warning: unused variable `nameEntry' make[2]: *** [parallel.o] Error 1 make[1]: *** [all] Error 2 make: *** [ppm] Error 2

If you see this one, it's a tough problem tough enough that this would be where most people would throw up their hands and decide they don't need the software that badly. It hasn't complained that there's a file missing, but it's making some noise about parse errors and undefined types. It's bad to have parse errors and undefined things in programs, and there doesn't seem to be anything missing to have caused things to be undefined. Still, it's not as if doing some poking around is going to do anything worse than waste a bit of time, and you never know when you might get lucky, so let's press ahead. First, find the file it's complaining about:

 brezup:software netpbm-9.12 $ find ./ -name parallel.c -print .//ppm/ppmtompeg/parallel.c 

Looking at this file, we see

 #include <sys/types.h> #include <sys/socket.h> #include <sys/times.h> #include <time.h> #include <netinet/in.h> #include <unistd.h> #include <netdb.h> 

The make process complained that there were undefined things in socket.h, and the only thing included before socket.h that could have defined them is types.h. types.h almost certainly lives in /usr/include/sys, based on the angle brackets surrounding the include filename in parallel.c. Searching in /usr/include/sys/types.h for the undefined u_char type, we find

 #ifndef _POSIX_SOURCE typedef unsigned char   u_char; typedef unsigned short  u_short; typedef unsigned int    u_int; typedef unsigned long   u_long; typedef unsigned short  ushort;         /* Sys V compatibility */ typedef unsigned int    uint;           /* Sys V compatibility */ #endif 

Interestingly, the type is defined, but there's a cryptic #ifndef POSIX_SOURCE … #endif surrounding the definition. If you were a programmer, the problem would be almost immediately obvious at this point. Because you're probably not a programmer, the most information you can get is that if something named POSIX_SOURCE is not defined, the needed u_char type is defined. Presumably, if POSIX_SOURCE is defined, u_char doesn't get defined here. Armed with this knowledge, if you search in parallel.c again, you'll find the following lines:

 #define _POSIX_SOURCE #define _POSIX_C_SOURCE 2 

What do you know! Right there in parallel.c, it's shooting itself in the foot. Let's see what happens if we just comment that out and have at it again. It already doesn't work, so the most that can go wrong is that it still won't work, right? Fire up your editor again, and change those lines so that they look like this:

 /* #define _POSIX_SOURCE */ /* #define _POSIX_C_SOURCE 2 */ 

NOTE

No, I'm not sure what the #define _POSIX_C_SOURCE 2 line is doing I'm playing nonprogramming user here. If I were playing programmer, I'd spend the time to figure out what it's doing, and whether there's anything I can do to correct the particular condition we're seeing. You might not want to be a programmer, so let's play around and see what a nonprogrammer can accomplish. I commented the POSIX_SOURCE lines out on a nonprogrammer-like hunch, and things seem to have worked. There are undoubtedly numerous other possible solutions. You're welcome to try other solutions without commenting out the line and see what happens. I can't guarantee that the rest of the install will follow the course shown if you do, but it's just as possible that it will work better.


And make again:

brezup:software netpbm-9.12 $ make . . . /usr/include/ppc/ansi.h:94: warning: ISO C89 does not support `long long' In file included from /Users/software/Documents/source/netpbm-9.12/pnm/pbmplus.h:115, from /Users/software/Documents/source/netpbm-9.12/pnm/pbm.h:7, from /Users/software/Documents/source/netpbm-9.12/pnm/pgm.h:7, from /Users/software/Documents/source/netpbm-9.12/pnm/ppm.h:7, from /Users/software/Documents/source/netpbm-9.12/pnm/pnm.h:7, from /Users/software/Documents/source/netpbm-9.12/pnm/pnmtopng.c:58: /usr/include/stdlib.h:206: warning: ISO C89 does not support `long long' /usr/include/stdlib.h:208: warning: ISO C89 does not support `long long' /usr/include/stdlib.h:210: warning: ISO C89 does not support `long long' /usr/include/stdlib.h:212: warning: ISO C89 does not support `long long' gcc -o pnmtopng pnmtopng.o `../libopt libpnm.a ../ppm/libppm.a ../pgm/libpgm.a ../pbm /libpbm.a ` \ -L/lib, -lz -L/usr/local/lib -lpng -lm ld: warning -L: directory name (/lib,) does not exist ld: table of contents for archive: /usr/local/lib/libpng.a is out of date; rerun ranlib(1) (can't load from it) make[1]: *** [pnmtopng] Error 1 make: *** [pnm] Error 2

You've already seen that one before:

brezup:software netpbm-9.12 $ ranlib /usr/local/lib/libpng.a brezup:software netpbm-9.12 $ make . . . ar -rc libfiasco_lib.a arith.o bit-io.o dither.o error.o image.o list.o misc.o rpf.o make -C ../../pnm libpnm.a make[3]: `libpnm.a' is up to date. make -C ../../ppm libppm.a make[3]: `libppm.a' is up to date. make -C ../../pgm libpgm.a make[3]: `libpgm.a' is up to date. make -C ../../pbm libpbm.a make[3]: `libpbm.a' is up to date. gcc -o pnmtofiasco binerror.o cwfa.o getopt.o getopt1.o params.o \ `../../libopt codec/libfiasco_codec.a input/libfiasco_input.a output/libfiasco_output.a lib/libfiasco_lib.a ` \ `../../libopt ../../pnm/libpnm.a ../../ppm/libppm.a ../../pgm/libpgm.a ../../pbm/libpbm.a ` -lm ld: archive: codec/libfiasco_codec.a has no table of contents, add one with ranlib(1) (can't load from it) ld: archive: input/libfiasco_input.a has no table of contents, add one with ranlib(1) (can't load from it) ld: archive: output/libfiasco_output.a has no table of contents, add one with ranlib(1) (can't load from it) ld: archive: lib/libfiasco_lib.a has no table of contents, add one with ranlib(1) (can't load from it) make[2]: *** [pnmtofiasco] Error 1 make[1]: *** [all] Error 2 make: *** [pnm] Error 2

That's getting a little boring! Don't you wish it would just run ranlib for you, instead of telling you it needs to be run? Actually, the installers are supposed to take care of that stuff for you. Like one of the earlier installs not creating the needed directories, this one also seems to have trouble running ranlib, so for some things you have to do it by hand:

 brezup:software netpbm-9.12 $ ranlib codec/libfiasco_codec.a ranlib: can't open file: codec/libfiasco_codec.a (No such file or directory) 

Oops! That wasn't expected. Something else you don't (usually) need to worry about is that make might be recursively making things in subdirectories. The path shown in an error might not be the relative path from your location, but rather the relative path from wherever make is currently operating. In this case, we can just find the directories by name and ranlib them that way:

 brezup:software netpbm-9.12 $ find ./ -name libfiasco_codec.a -print .//pnm/fiasco/codec/libfiasco_codec.a brezup:software netpbm-9.12 $ find ./ -name libfiasco_input.a -print .//pnm/fiasco/input/libfiasco_input.a brezup:software netpbm-9.12 $ find ./ -name libfiasco_output.a -print .//pnm/fiasco/output/libfiasco_output.a brezup:software netpbm-9.12 $ find ./ -name libfiasco_lib.a -print .//pnm/fiasco/lib/libfiasco_lib.a brezup:software netpbm-9.12 $ ranlib .//pnm/fiasco/codec/libfiasco_codec.a brezup:software netpbm-9.12 $ ranlib .//pnm/fiasco/input/libfiasco_input.a brezup:software netpbm-9.12 $ ranlib .//pnm/fiasco/output/libfiasco_output.a brezup:software netpbm-9.12 $ ranlib .//pnm/fiasco/lib/libfiasco_lib.a 

And make again:

brezup:software netpbm-9.12 $ make gcc -o pnmtofiasco binerror.o cwfa.o getopt.o getopt1.o params.o \ `../../libopt codec/libfiasco_codec.a input/libfiasco_input.a output/libfiasco_output.a lib/libfiasco_lib.a ` \ `../../libopt ../../pnm/libpnm.a ../../ppm/libppm.a ../../pgm/libpgm.a ../../pbm/libpbm.a ` -lm ld: multiple definitions of symbol _mv_code_table codec/libfiasco_codec.a(mwfa.o) definition of _mv_code_table in section (__DATA,__data) output/libfiasco_output.a(mc.o) definition of _mv_code_table in section (__DATA,__common) make[2]: *** [pnmtofiasco] Error 1 make[1]: *** [all] Error 2 make: *** [pnm] Error 2

And we encounter another new problem. Here, it complains that a variable, mv_code_table, has been defined in multiple places. Programs can't get built very cleanly when that happens because a specific memory location is used for each thing defined, and the system has no way of knowing which location is intended if a variable name is defined in multiple places. Again, this is a place where many would stop, but we intrepid few will forge ahead. Always remember it's already broken, what more harm can you do? Note that the system's been nice enough to tell you the .c files where the multiple definitions occur: mwfa.c and mc.c. Apparently, there's a definition of mv_code_table in both. The codec (that stands for enCOder/DECoder) is probably the more important one to keep the value defined in, so let's dig around in the definition in the output module.

 brezup:software netpbm-9.12 $ find ./ -name mc.c -print .//pnm/fiasco/input/mc.c .//pnm/fiasco/output/mc.c 

If you look in the input/mc.c file, you'll see that mv_code_table is defined as a static int and has a bunch of data included in it. If you look in the codec/mwfa.c file, you'll see something similar (with a note that this variable is supposed to be local). The version in the output directory, however, just defines the variable and stores no data in it. One of these things is not like the other one of these things just doesn't belong. The one that's different looks like fair game to me. Change the line for mv_code_table in mc.c of the output directory so that it reads:

 extern int mv_code_table [33][2];      /* VLC table for coordinates, mwfa.c */ 

This tells the compiler "go look somewhere else for this data." It's already defined somewhere else; the compiler told you so. Somewhere else must be a good place to look, right? And try the make, yet again.

brezup:software netpbm-9.12 $ make . . . make -C output libfiasco_output.a gcc -c -I.. -I../lib -I../codec -pedantic -no-cpp-precomp -fno-common -O3 -Wall -Wno-uninitialized -o mc.o /Users/software/Documents/source/netpbm-9.12/pnm/fiasco/output /mc.c ar -rc libfiasco_output.a matrices.o mc.o nd.o tree.o weights.o write.o make -C lib libfiasco_lib.a make[3]: `libfiasco_lib.a' is up to date. make -C ../../pnm libpnm.a make[3]: `libpnm.a' is up to date. make -C ../../ppm libppm.a make[3]: `libppm.a' is up to date. make -C ../../pgm libpgm.a make[3]: `libpgm.a' is up to date. make -C ../../pbm libpbm.a make[3]: `libpbm.a' is up to date. gcc -o pnmtofiasco binerror.o cwfa.o getopt.o getopt1.o params.o \ `../../libopt codec/libfiasco_codec.a input/libfiasco_input.a output/libfiasco_output.a lib/libfiasco_lib.a ` \ `../../libopt ../../pnm/libpnm.a ../../ppm/libppm.a ../../pgm/libpgm.a ../../pbm/libpbm.a ` -lm ld: table of contents for archive: output/libfiasco_output.a is out of date; rerun ranlib (1) (can't load from it) make[2]: *** [pnmtofiasco] Error 1 make[1]: *** [all] Error 2 make: *** [pnm] Error 2

You know what to do:

 brezup:software netpbm-9.12 $ ranlib ./pnm/fiasco/output/libfiasco_output.a 

and make again.

[Racer-X:~/Documents/source/netpbm-9.12] software% make . . . gcc -o palmtopnm palmtopnm.o palmcolormap.o `../../libopt ../../pnm/libpnm.a ../../ppm /libppm.a ../../pgm/libpgm.a ../../pbm/libpbm.a ` \ gcc -c -I../../shhopt -pedantic -no-cpp-precomp -fno-common -O3 -Wall -Wno-uninitialized -o pnmtopalm.o ../../pnm/pnmtopalm/pnmtopalm.c ../../pnm/pnmtopalm/pnmtopalm.c: In function `main': ../../pnm/pnmtopalm/pnmtopalm.c:42: warning: implicit declaration of function `strcmp' ../../pnm/pnmtopalm/pnmtopalm.c:220: warning: implicit declaration of function `memset' ../../pnm/pnmtopalm/pnmtopalm.c:290: warning: implicit declaration of function `memcpy' gcc -o pnmtopalm pnmtopalm.o palmcolormap.o `../../libopt ../../pnm/libpnm.a ../../ppm /libppm.a ../../pgm/libpgm.a ../../pbm/libpbm.a ` \ [Racer-X:~/Documents/source/netpbm-9.12] software%

Hard to believe, but it just finished the compile. Now if you do a make install, you'll be all set. netpbm installs its applications into /usr/local/netpbm/bin/; its man pages and so on go into directories in /usr/local/netpbm. Because of this, you'll again need to extend your path: PATH=$PATH:/usr/local/netpbm/bin or set path=($path /usr/local/netpbm/bin/), depending on whether you're using bash or tcsh, respectively.

Finally, if you want to see whether it works, find something like a JPEG file, and try out the following:

pnm/jpegtopnm < ~/Pictures/<oldfile>.jpg | pnm/pnminvert | ppm/ppmtojpeg > ~/Pictures /<newfile>.jpg

If you've installed it, that'd be just

 jpegtopnm < ~/Pictures/<oldfile>.jpg | pnminvert | ppmtojpeg > ~/Pictures/<newfile>.jpg 

Now take a look at the new file in your Pictures directory. The netpbm package is a large collection of programs that perform specific graphics manipulations. They can be chained together in arbitrary combinations to create arbitrarily complex graphics manipulations. We'll cover a few of the things it can do in Chapter 15. The number of uses is almost unlimited, so you really should read through the man pages for more ideas.

Now that you've gone through all of that, remember that this is an older version of netpbm. Installing the most recent version is much easier, but rather than have you go through the compile, you can even more easily install it with fink.

     < Day Day Up > 


    Mac OS X Tiger Unleashed
    Mac OS X Tiger Unleashed
    ISBN: 0672327465
    EAN: 2147483647
    Year: 2005
    Pages: 251

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net