- Table of Contents
- Copyright
- About the Author
- Acknowledgments
- Tell Us What You Think!
- Introduction
- Part I: Introduction to Mac OS X
- Chapter 1. Mac OS X Component Architecture
- Chapter 2. Installing Mac OS X
- Chapter 3. Mac OS X Basics
- Chapter 4. The Finder: Working with Files and Applications
- Chapter 5. Running Classic Mac OS Applications
- Part II: Inside Mac OS X
- Chapter 6. Native Utilities and Applications
- Chapter 7. Internet Communications
- Chapter 8. Installing Third-Party Applications
- Part III: User-Level OS X Configuration
- Chapter 9. Network Setup
- Chapter 10. Printer and Font Management
- Chapter 11. Additional System Components
- Part IV: Introduction to BSD Applications
- Chapter 12. Introducing the BSD Subsystem
- Chapter 13. Common Unix Shell Commands: File Operations
- Part V: Advanced Command-Line Concepts
- Chapter 14. Advanced Shell Concepts and Commands
- Chapter 15. Command-Line Applications and Application Suites
- Chapter 16. Command-Line Software Installation
- Chapter 17. Troubleshooting Software Installs, and Compiling and Debugging Manually
- Common Sense and Configuration Options
- File Locations, and Fighting with Installers
- Using the gdb Debugger
- Recommended Command-Line Software Installations
- Summary
- Chapter 18. Advanced Unix Shell Use: Configuration and Programming (Shell Scripting)
- Part VI: Server/Network Administration
- Chapter 19. X Window System Applications
- Chapter 20. Command-Line Configuration and Administration
- Chapter 21. AppleScript
- Chapter 22. Perl Scripting and SQL Connectivity
- Chapter 23. File and Resource Sharing with NetInfo
- Chapter 24. User Management and Machine Clustering
- Chapter 25. FTP Serving
- Chapter 26. Remote Access and Administration
- Chapter 27. Web Serving
- Part VII: Server Health
- Chapter 28. Web Programming
- Chapter 29. Creating a Mail Server
- Chapter 30. Accessing and Serving a Windows Network
- Chapter 31. Server Security and Advanced Network Configuration
- Chapter 32. System Maintenance
- Appendix A. Command-Line Reference
- Appendix B. Administration Reference
File Locations, and Fighting with Installers
For this example, you will need the netpbm package, available from http://download.sourceforge.net/netpbm/netpbm-9.12.tgz. The easy solution is
lynx -dump http://download.sourceforge.net/netpbm/netpbm-9.12.tgz > netpbm-9.12.tgz
The file should be 2057293 bytes in length. Uncompress it, untar it, and check whether it wants configure or make:
[localhost:~/Documents] software% gunzip netpbm-9.12.tgz
[localhost:~/Documents] software% tar -xf netpbm-9.12.tar
[localhost:~/Documents/netpbm-9.12] software% 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:
[localhost:~/Documents/netpbm-9.12] software% ./configure
./configure: Command not found.
Hold on, problem number one—that wasn't the expected behavior. The file configure is right here in the directory with you, yet you're getting a command not found error. It could be ./configure isn't executable, but in this case, it's a less obvious, more common problem:
[localhost:~/Documents/netpbm-9.12] software% 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 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.
[localhost:~/Documents/netpbm-9.12] software% head ./configure
#!/usr/bin/perl -w
use strict;
.
.
.
Now try again:
[localhost:~/Documents/netpbm-9.12] software% ./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.
The results of the configure 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, where Linux tends to store them. Fire up 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 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:
- Linux installations tend to have taken a wrong turn in file system 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 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:
[localhost:~/Documents/netpbm-9.12] software% make
make -C pbm -f /Users/software/Documents/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
Again, not the output we wanted! This time, it's complaining 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 has named it cc, instead of gcc. The error for this program could be fixed by modifying the Mak e file.config file again to call cc instead of gcc, but this problem will crop up frequently, and many installers won't know that they can use the special gcc features unless the compiler is called gcc. Let's fix it by creating an alias (symbolic link) named gcc instead, and pointing it at the cc compiler:
[localhost:~/Documents/netpbm-9.12] software% pushd /usr/local/bin
/usr/local/bin ~/Documents/netpbm-9.12
[localhost:/usr/local/bin] software% which cc
/usr/bin/cc
[localhost:/usr/local/bin] software% ln -s /usr/bin/cc ./gcc
[localhost:/usr/local/bin] software% popd
~/Documents/netpbm-9.12
Try the make again:
[localhost:~/Documents/netpbm-9.12] software% make
make -C pbm -f /Users/software/Documents/netpbm-9.12/pbm/Makefile all
gcc -c -I../shhopt -pedantic -O3 -Wall -Wno-uninitialized -o atktopbm.o ../pbm/atktopbm.c
In file included from /usr/include/machine/types.h:30,
from /usr/include/sys/types.h:70,
from /usr/include/stdio.h:64,
from ../pbm/atktopbm.c:13:
/usr/include/ppc/types.h:75: warning: ANSI C does not support `long long'
/usr/include/ppc/types.h:76: warning: ANSI C does not support `long long'
In file included from ../pbm/pbmplus.h:115,
from ../pbm/pbm.h:7,
from ../pbm/atktopbm.c:15:
/usr/include/stdlib.h:181: warning: ANSI C does not support `long long'
/usr/include/stdlib.h:183: warning: ANSI C does not support `long long'
gcc -c -I../shhopt -pedantic -O3 -Wall -Wno-uninitialized -o libpbm1.o ../pbm/libpbm1.c
.
.
.
gcc -o pgmkernel pgmkernel.o -lm `../libopt libpgm.a ../pbm/libpbm.a`
make -C ppm -f /Users/software/Documents/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 -O3 -Wall -Wno-uninitialized -o 411toppm.o /Users/software/Documents/netpbm-9.12/ppm/411toppm.c
/Users/software/Documents/netpbm-9.12/ppm/411toppm.c:60: header file 'malloc.h' not found
cpp-precomp: warning: errors during smart preprocessing, retrying in basic mode
make[1]: *** [411toppm.o] Error 1
make: *** [ppm] Error 2
Did I mention I picked 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 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, its 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:
[localhost:~/Documents/netpbm-9.12] software% pushd /usr/include
/usr/include ~/Documents/netpbm-9.12
[localhost:/usr/include] software% find ./ -name malloc.h -print
.//objc/malloc.h
.//sys/malloc.h
[localhost:/usr/include] software% popd
~/Documents/netpbm-9.12
[localhost:~/Documents/netpbm-9.12] software% pushd /usr/local/include
/usr/local/include ~/Documents/netpbm-9.12
[localhost:/usr/local/include] software% ln -s /usr/include/sys/malloc.h ./
[localhost:/usr/local/include] software% popd
~/Documents/netpbm-9.12
And, back to make again:
[localhost:~/Documents/netpbm-9.12] software% make
make -C pbm -f /Users/software/Documents/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/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/netpbm-9.12/ppm/Makefile all
gcc -c -I../shhopt -I/usr/local/include -pedantic -O3 -Wall -Wno-uninitialized -o 411toppm.o /Users/software/Documents/netpbm-9.12/ppm/411toppm.c
In file included from /usr/include/machine/types.h:30,
from /usr/include/sys/types.h:70,
from /usr/include/stdio.h:64,
from /Users/software/Documents/netpbm-9.12/ppm/411toppm.c:58:
/usr/include/ppc/types.h:75: warning: ANSI C does not support `long long'
/usr/include/ppc/types.h:76: warning: ANSI C does not support `long long'
.
.
.
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 how to fix it…
[localhost:~/Documents/netpbm-9.12] software% ranlib /usr/local/lib/libjpeg.a [localhost:~/Documents/netpbm-9.12] software% make . . . gcc -c parallel.c -o parallel.o -pedantic -O3 -Wall -Wno-uninitialized -I. -Iheaders -I../../shhopt -I/usr/local/include /usr/include/sys/socket.h:175: undefined type, found `u_char' /usr/include/sys/socket.h:176: undefined type, found `u_char' /usr/include/sys/socket.h:186: undefined type, found `u_short' . . . 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
This one is tough—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 complaining about undefined types. It's bad to have undefined things in programs, and there doesn't seem to be anything missing to have caused things to be undefined. Still, it's not like 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 that it's complaining about:
[localhost:~/Documents/netpbm-9.12] software% 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, the most that can go wrong is that it still doesn't work, right? Fire up your editor again, and change those lines so they look like this:
/* #define _POSIX_SOURCE */ /* #define _POSIX_C_SOURCE 2 */
And, make again:
[localhost:~/Documents/netpbm-9.12] software% make
.
.
.
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
/usr/bin/ld: warning -L: directory name (/lib,) does not exist
/usr/bin/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:
[localhost:~/Documents/netpbm-9.12] software% ranlib /usr/local/lib/libpng.a [localhost:~/Documents/netpbm-9.12] software% make . . . 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.alib/libfiasco_lib.a ` `../../libopt ../../pnm/libpnm.a ../../ppm/libppm.a ../../pgm/libpgm.a ../../pbm/libpbm.a
` -lm /usr/bin/ld: archive: codec/libfiasco_codec.a has no table of contents, add one with
ranlib(1) (can't load from it) /usr/bin/ld: archive: input/libfiasco_input.a has no table of contents, add one with
ranlib(1) (can't load from it) /usr/bin/ld: archive: output/libfiasco_output.a has no table of contents, add one with
ranlib(1) (can't load from it) /usr/bin/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 the install not creating the needed directories, it also seems to have trouble ranlibing things, so for some things you have to do it by hand:
[localhost:~/Documents/netpbm-9.12] software% 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 know about make is it might be recursively making things in subdirectories. The path shown in an error might not be the relative path from your location, but 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:
software% find ./ -name libfiasco_codec.a -print
.//pnm/fiasco/codec/libfiasco_codec.a
software% find ./ -name libfiasco_input.a -print
.//pnm/fiasco/input/libfiasco_input.a
software% find ./ -name libfiasco_output.a -print
.//pnm/fiasco/output/libfiasco_output.a
software% find ./ -name libfiasco_lib.a -print
.//pnm/fiasco/lib/libfiasco_lib.a
software% ranlib .//pnm/fiasco/codec/libfiasco_codec.a
software% ranlib .//pnm/fiasco/input/libfiasco_input.a
software% ranlib .//pnm/fiasco/output/libfiasco_output.a
software% ranlib .//pnm/fiasco/lib/libfiasco_lib.a
And, make again:
[localhost:~/Documents/netpbm-9.12] software% make
.
.
.
from ../../pnm/pnmtopalm/pnm.h:7,
from ../../pnm/pnmtopalm/pnmtopalm.c:12:
/usr/include/stdlib.h:181: warning: ANSI C does not support `long long'
/usr/include/stdlib.h:183: warning: ANSI C does not support `long long'
gcc -o pnmtopalm pnmtopalm.o palmcolormap.o `../../libopt ../../pnm/libpnm.a ../../ppm
/libppm.a ../../pgm/libpgm.a ../../pbm/libpbm.a `
[localhost:~/Documents/netpbm-9.12] software%
Hard to believe, but it just finished the compile. Now you can do a make install, and 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: set path=($path /usr/local/netpbm/bin/), and your MANPATH: setenv MANPATH {$MANPATH}:/usr/local/netpbm/man/.
Finally, if you'd like to see whether it works, find something like a JPEG file, and try out the following:
jpegtopnm < ~/Pictures/<oldfile>.jpg | pnminvert | ppmtojpeg > ~/Pictures/<newfile>.jpg
Take a look at the new file in your Pictures directory. The netpbm package is a large collection of programs that perform very 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 18, "Advanced Unix Shell Use: Configuration and Programming (Shell Scripting)." The number of uses is almost unlimited, so you really should read through the man pages for more ideas.
Using the gdb Debugger | Next Section

Account Sign In
View your cart