The programs on the disc are supplied in binary form for the most popular UNIX platforms, as listed in article 52.3. But we also supply C source code for those of you who are on unsupported platforms.
Now, don't run away. You don't have to be a C programmer to compile these sources. I've never written a C program in my life, and I compile public domain software all the time. The CD-ROM provides build scripts for each of the packages, so many of you can just run the script and have everything installed automatically.
If the build scripts don't work, the CD-ROM also has a script to copy the sources to your local hard disk. Although we can't promise that you'll be able to build the sources on your own without a hitch, this article includes some explanation of how to build sources without needing to learn how to program in C.
Before you do anything, try out the build scripts. You might be able to get away without knowing anything at all about the build process.
To build programs from source code, first mount the CD-ROM as described in article 52.5.
Each package on the CD-ROM that has source code can be compiled with the "build" script. The build script will copy the files off the CD into your current directory, compile, and install them.
As the CD-ROM is read-only, you must use a directory on some other disk for the build. For example, if you wanted to build the "compress" package, a directory called compress will be created in the current directory when the build script is run. The build script has default settings for the directory to which the source code will be copied, the directory in which the package will be installed, the directory in which the "shareable" portion of the package will be installed, and a "prefix" for the shareable directories. These settings can be overridden by the following:
This is where the source code for the package resides on the CD-ROM. The build script tries to determine this automatically, so you should not have set SOURCEDIR unless you are using the build script somewhere other than the CD-ROM.
This is the directory where the package will be installed. It is set to /usr/local by default. For example, to change INSTALLDIR to /opt:
setenv INSTALLDIR /optcsh $
INSTALLDIR=/opt ; export INSTALLDIRsh
This "prefix" will be prepended to the directory names for lib, include, spool, and bin. There is no default setting, but you could use s if you wanted to conform to the same scheme used by the "install" program to name shareable directories slib, sinclude, sspool, and sbin.
By default, the files generated by the build process will not be removed. If you set the RM variable before running the build, the entire build directory will be removed once the build finishes:
setenv RM truecsh $
RM=true ; export RMsh
For a list of the available packages, run the build.pt script in the CD-ROM mount directory. The actual name of the script depends on your operating system (as described in article 52.5), but assuming that the CD-ROM is mounted on /cdrom, it is likely to be one of the following commands:
The command will print a list similar to the following:
bash bsdtar bsplit calen cpmod cvtbase delete diff ediff emacs fgrep fileutils find gawk getopt glimpse grabchars grep ...
To build one of these packages, run the same command followed by the package name. For example:
The build script will copy the package to the current directory, compile, and install the package according to the values of the environment variables. For this example, the shareable and non-shareable portions of the package are combined.
% /archive/cdrom/BUILD.PT jot BUILD script provided by Ready-to-Run Software, Inc. Copyright 1997 Ready-to-Run Software, Inc. All Rights Reserved. Assuming CDROM is mounted at /archive/cdrom Assuming MACHINE is ALPHA Assuming SOURCEDIR is /archive/cdrom/SOURCES Ignore any errors about directories already existing tools/ tools/BUGS tools/Makefile tools/jot.c tools/lam.c tools/rs.c cc -O -o jot jot.c
Some of the build scripts expect non-standard programs to be installed. Some of these come on the CD-ROM:
Some other utilities are not included:
Any number of things can go wrong with your build. You might not have the right libraries or include files installed. Your compiler may not work the way the program expects it to. You might not have the right permissions. You might run out of disk space.
These problems are so varied that there's no way we can list any generalized solutions. Try asking an administrator or programmer on your site, or try calling . But we have a few tips that might help:
|bsdtar||If your system has problems with filenames longer than 14 characters, you may have to install bsdtar to be able to "untar" the source code. bsdtar creates unique 14-character filenames as it unpacks an archive.|
If your system lacks theto the mkdir command, you may need to install a new version from the GNU fileutils package. The -p option is used by the installation and build scripts.
And if all else fails, you can try to delve into the source code itself. That brings us to our next section ...
Almost all UNIX binary programs are written in the C language. These programs are written in text files - the text files are referred to as the source code-and then converted to binary files using a compiler. The typical compiler on a UNIX system is called cc.
Although most people call cc a "compiler," it's really a front-end program. Unless you tell it not to, cc first runs a preprocessor. Next it runs the compiler. Then it runs the linker/loader to make the actual executable file. We'll gloss over that in this article and just say that "cc does it."
On top of cc, there's usually another front-end: almost all programs are designed to be compiled using the make program.
Although we can't prepare you for everything you might need to know to compile programs from the CD-ROM for your platform, this section should at least give you an idea of how it's supposed to work.
Before you can actually compile the sources, you need to copy the sources to your local hard disk. You can't just compile the sources directly from the CD-ROM because the CD-ROM is read-only.
The first thing you need to do is to decide where you want to install the sources, and then cd to that directory. For example, I like to build sources in a subdirectory of my home directory. Let's suppose I want to install the pcal program. I create the new directory and then cd there:
For installing the sources onto your local hard disk, the CD-ROM has a script called source.pt. Assuming that the CD-ROM is mounted on /cdrom, the script can be called using one of the following commands:
Where package-name is the name of the package that you want to install sources for. To get a listing of the files, call source.pt without any arguments:
% source.pt SOURCE script provided by Ready-to-Run Software, Inc. Copyright 1997 Ready-to-Run Software, Inc. All Rights Reserved. Assuming CDROM is mounted at /archive/cdrom/ Usage: /archive/cdrom/SOURCE.PT <package Available packages are: ! 80cols Clear _emacs_ml _enter_csh _enter_sh _exit_csh _exit_sh addup age_files ascii awf bash behead bkedit bsdtar bsplit cal_today calen catsaway center cgrep cgrep_sed checksed chmod_edit chunksort cleanup cleanup_sed cls cols count_it count_types cpmod crontab crush csh_init csh_logout cvtbase date-month del delete diff dir_path dirtop doublespace ediff elookfor emacs exrc fgrep fileutils find findcmd findtext flip fmt_sh formprog ftpfile gawk getmac getopt glimpse grabchars grep groff gzip head hey hgrep index ipl ispell jot lensort less lf lndir logerrs longlines look lookfor ls_today make_print manindex motd_diff namesort netpbm nextday no_run nom offset oldlinks opttest paircheck patch pcal perl5 phone pipegrep pstext psutils pushin qcsh qsubst qterm rcs rcsegrep_fast rcsgrep rcsrevs recomment redo relink ren rename rot runsed runtime sc screen screensize script_tidy search_el sedman sh_init sh_logout sharutils shellutils showmatch sl sls smiley squoze stat stree stripper su tar tcap tcsh termtest textutils tgrep tknew tm tpipe tputinit triplespace twin vgrep vis vtree watchq whereiz which wordfreq xgrep xtail zap zloop zmore zvi
(Note that all the packages on the CD-ROM are listed here, shell scripts as well as C sources.)
/cdrom/source.pt pcalSOURCE script provided by Ready-to-Run Software, Inc. Copyright 1993 Ready-to-Run Software, Inc. All Rights Reserved. Copied /POWER_TOOLS/SOURCES/PCAL/PCAL_43.Z to pcal-4.3.tar.Z Copied /POWER_TOOLS/SOURCES/PCAL/RS6000/PCAL to RS6000patch.pcal Copied /POWER_TOOLS/SOURCES/PCAL/RTR/PCAL to rtrpatch.pcal 3 files copied successfully.
The source.pt script copies all the relevant files into your current directory.
If you now list the directory, you'll find the files that were just copied there.
lsRS6000patch.pcal pcal-4.3.tar.Z rtrpatch.pcal
The file called pcal-4.3.tar.Z is the pcal source package, in a tarred and compressed form. The .Z suffix tells you that the file was compressed using thecommand. You need to run uncompress first:
lsRS6000patch.pcal pcal-4.3.tar rtrpatch.pcal
To unpack the file, use tar with the -x option for "extract" and the -f option to specify a filename. (I also like to use -v for verbose output.) My command line might read:
tar xvf pcal-4.3.tarx pcal-4.3/ReadMe, 7673 bytes, 15 tape blocks x pcal-4.3/Descrip.mms, 3713 bytes, 8 tape blocks x pcal-4.3/Make_Pcal.com, 3090 bytes, 7 tape blocks x pcal-4.3/Makefile, 1159 bytes, 3 tape blocks x pcal-4.3/Makefile.Amiga, 1010 bytes, 2 tape blocks x pcal-4.3/Makefile.DOS, 1023 bytes, 2 tape blocks x pcal-4.3/Makefile.VMS, 2505 bytes, 5 tape blocks x pcal-4.3/Orig.ReadMe, 984 bytes, 2 tape blocks x pcal-4.3/Pcal.TEX, 28199 bytes, 56 tape blocks x pcal-4.3/Pcal.hlp, 29099 bytes, 57 tape blocks x pcal-4.3/SetUp.com, 670 bytes, 2 tape blocks x pcal-4.3/VaxCrtl.opt, 31 bytes, 1 tape blocks x pcal-4.3/calendar, 12101 bytes, 24 tape blocks x pcal-4.3/exprpars.c, 8538 bytes, 17 tape blocks x pcal-4.3/moon91, 2828 bytes, 6 tape blocks x pcal-4.3/moon92, 2887 bytes, 6 tape blocks x pcal-4.3/pcal.c, 46440 bytes, 91 tape blocks x pcal-4.3/noprotos.h, 2530 bytes, 5 tape blocks x pcal-4.3/pcalglob.h, 4551 bytes, 9 tape blocks x pcal-4.3/pcalinit.c, 4071 bytes, 8 tape blocks x pcal-4.3/protos.h, 4341 bytes, 9 tape blocks x pcal-4.3/moonphas.c, 17817 bytes, 35 tape blocks x pcal-4.3/troffman.sty, 4894 bytes, 10 tape blocks x pcal-4.3/writefil.c, 24597 bytes, 49 tape blocks x pcal-4.3/pcal.man, 25296 bytes, 50 tape blocks x pcal-4.3/pcaldefs.h, 17643 bytes, 35 tape blocks x pcal-4.3/pcalinit.ps, 14297 bytes, 28 tape blocks x pcal-4.3/pcalutil.c, 21238 bytes, 42 tape blocks x pcal-4.3/pcallang.h, 35465 bytes, 70 tape blocks x pcal-4.3/readfile.c, 32888 bytes, 65 tape blocks
tar creates a subdirectory called pcal-4.3. cd to this directory to continue your build.
Note that if you have the zcat command, you might have combined the steps for uncompressing and untarring the files into a single command line, as shown in article 19.7:
zcat pcal-4.3.tar.Z | tar xvf -
If you are on a System V-based system, you may have to use tar with theto make sure that you get ownership of the files.
Before we go on, let's back up a bit. Some packages aren't stored as tar archives, but as . shar archives are generally distributed in multiple files, under names such as part01.Z, part02.Z, etc. The qterm source package is an example of a package that is distributed as shar files.
/cdrom/source.pt qterm% /archive/cdrom/SOURCE.PT qterm SOURCE script provided by Ready-to-Run Software, Inc. Copyright 1997 Ready-to-Run Software, Inc. All Rights Reserved. Assuming CDROM is mounted at /archive/cdrom/ Copied /archive/cdrom//SOURCES/QTERM/PART01.Z to part01.Z Copied /archive/cdrom//SOURCES/QTERM/PART02.Z to part02.Z Copied /archive/cdrom//SOURCES/QTERM/RS6000/QTERM to RS6000patch.qterm Copied /archive/cdrom//SOURCES/QTERM/I386/QTERM to i386patch.qterm Copied /archive/cdrom//SOURCES/QTERM/SUN4C/QTERM to sun4cpatch.qterm Copied /archive/cdrom//SOURCES/QTERM/HP700/QTERM to hp700patch.qterm Copied /archive/cdrom//SOURCES/QTERM/LINUX/QTERM to linuxpatch.qterm Copied /archive/cdrom//SOURCES/QTERM/SSOL2/QTERM to SSol2patch.qterm Copied /archive/cdrom//SOURCES/QTERM/RTR/QTERM to rtrpatch.qterm 9 file(s) copied successfully.
If you don't have shar and unshar, it's on the CD-ROM; but the true beauty of shar archives is that you can always remove any headers and footers from the file and use the Bourne shell (sh) to unpack the files.
To edit out the header, remove any lines at the top of the
file that don't resemble Bourne shell syntax.
Since many shar
archives are distributed in email or in newsgroups, the files
might include the header of a mail message or news posting.
The author might also precede the actual shar archive with
some explanation of what the program does.
A good bet is to look for a line
#!/bin/sh and remove all lines preceding it.
Even better, most shell archives contain directions right in the file:
(text .... ) #! /bin/sh # This is a shell archive. Remove anything before this line, # then feed it into a shell via "sh file" or similar. # To overwrite existing files, type "sh file -c".
To remove the footer, look for anything resembling a user's mail signature. (shar archives usually have an exit message at the end, so editing out the footer isn't always needed ... but it doesn't hurt.)
vi part0?edit out headers %
sh part01; sh part02...
Note that it's especially important to install and unpack shar archives in discrete, well-named directories (such as qterm_src, in this case). Since shar files are almost always given generic names of part01, part02, etc., it's easy to overwrite files or to get confused if you accidentally unpack more than one package in the same directory.
When I copied the pcal sources using the source.pt shell script, I also got two : rtrpatch.pcal and RS6000patch.pcal. These are patches prepared by Ready-to-Run Software for compiling the pcal package.
The RS6000patch.pcal file is a patch for compilng on IBM's RS6000 platform. If you aren't on a RS6000, then you probably don't need this file. When building other packages, you might see other platform-specific patch files, with prefixes like i386, xenix, hp700, sun3, sun4, etc. Naturally, you shouldn't use these packages if you aren't on one of these platforms.
The rtrpatch.pcal file is a general-purpose patch for all platforms. You should apply this patch for all platforms.
Before you apply any of Ready-to-Run's patches, you should first make sure that there aren't any patch files in the untarred source directory. If the sources did come with patch files, they would have to be applied before Ready-to-Run's. In the pcal-4.3 directory, list the directory contents:
ls -aF./ Makefile.VMS calendar pcal.man protos.h ../ Orig.ReadMe exprpars.c pcaldefs.h readfile.c Descrip.mms Pcal.TEX moon91 pcalglob.h troffman.sty Make_Pcal.com Pcal.hlp moon92 pcalinit.c writefil.c Makefile ReadMe moonphas.c pcalinit.ps Makefile.Amiga SetUp.com noprotos.h pcallang.h Makefile.DOS VaxCrtl.opt pcal.c pcalutil.c
A patch file generally has the string patch or pch in it. There are no patch files in this directory. Now that I'm sure that there aren't any other patches, I run the patch command. (Naturally, if you don't already have patch, you can get its sources off the CD-ROM.) To run patch, make sure you're in the source directory (in this case, the pcal-4.3 subdirectory created when I ran tar). Then run patch, taking input from the patch file in the parent directory:
The patch is now applied.
Up to now, all we've been doing is just getting the source tree together. Now we're up to the part where we actually build the package.
If there's a file called README, read it!
README files often contain esoteric details about the history of the program and what improvements could be made, etc. But they might also contain details about how to build the package. Reading a README can save you hours of frustration trying to figure out what to tweak to make the program build on your platform.
Another file to look for is one called Configure. Configure is a shell script that tries to figure out what sort of platform you're on and how to build the package for you, and it's remarkably effective. The sources for perl and patch both come with Configure scripts.
pcal doesn't come with a README or with a Configure script. But it does come with a file called Makefile. (Actually, it comes with several Makefiles, for different platforms - but the default Makefile is the one for UNIX systems, which is what you want.) The Makefile is used by. There have been entire books written about make, but if you're lucky, all you need to know about it is that if you see a Makefile, then all you need to compile a program is to type make.
First, though, scan through the Makefile to see if there are any comments there. You might have to make some changes in the Makefile to configure it for your system. For example, the qterm Makefile has the following very helpful lines:
# # Add "-DUSG5" to DEFS below, if your system is UNIX System V. # Add "-DHAS_VARARGS" if your system supports varargs. # Add "-DOPT_COMPAT" to support old command line options. # DEFS = -DTABFILE=\"$(TABFILE)\" -DOPT_COMPAT
You probably know whether your system is System V-based or not. If you never used this program before, you probably don't care about old command line options. And if you don't know what varargs are or whether your system supports it ... try seeing if there's afor it. (You might even find out what it is!)
man varargsVARARGS(3) C LIBRARY FUNCTIONS VARARGS(3) NAME varargs - handle variable argument list SYNOPSIS #include <varargs.h> ...
What do you know, I have varargs.
So I add the
command-line option to the
DEFS = -DTABFILE=\"$(TABFILE)\" -DOPT_COMPAT -DHAS_VARARGS
The pcal Makefile, on the other hand, only includes a single line of instruction towards the top:
# Set the configuration variables below to taste.
This isn't particularly helpful, but scan the Makefile anyway for anything obviously wrong. When you're satisfied, just cross your fingers and run make:
make/bin/cc -c pcal.c /bin/cc -c exprpars.c /bin/cc -c moonphas.c /bin/cc -c pcalutil.c /bin/cc -c readfile.c /bin/cc -o pcalinit pcalinit.c pcalinit pcalinit.ps pcalinit.h /bin/cc -c writefil.c /bin/cc -o pcal pcal.o exprpars.o moonphas.o pcalutil.o readfile.o writefil.o -lm
There were no error or warning messages, so you're fine. Errors mean that the program package probably didn't build completely; you'll have to find the cause and fix them. If there were warnings, the programs may not work right or have a subtle flaw. For a program like a spreadsheet, where hidden flaws can be a disaster, you'd better find out what the warnings mean and fix them. Otherwise, just cross your fingers some more and see if the program works.
When you list the pcal source directory now, you should see several new files with a .o suffix, but the most important thing is that the pcal executable is now built and ready to be installed on your system.
ls -aF./ Orig.ReadMe moon91 pcaldefs.h protos.h ../ Pcal.TEX moon92 pcalglob.h readfile.c Descrip.mms Pcal.hlp moonphas.c pcalinit* readfile.o Make_Pcal.com ReadMe moonphas.o pcalinit.c troffman.sty Makefile SetUp.com noprotos.h pcalinit.h writefil.c Makefile.Amiga VaxCrtl.opt pcal* pcalinit.ps writefil.o Makefile.DOS calendar pcal.c pcallang.h Makefile.VMS exprpars.c pcal.man pcalutil.c Makefile.orig exprpars.o pcal.o pcalutil.o
You can now try out the program, and once you're sure it works, install it. To install the program, many Makefiles provide an install target.
On many machines, you'll need to be logged in as root to be able to install the binary and manpage system-wide. If so, it might be a good idea to run make with the -n option first. The -n option says to just show what commands would be executed without actually executing them.
make -n install
Or if you prefer to just install the program by hand, just move the executable and the manpage to the right directories (be sure to rename the manpage as appropriate):
mv pcal /usr/local/bin%
mv pcal.man /usr/local/man/man1/pcal.1
Note, however, that some programs may have extra steps in installing the executable. If all this worked as advertised, you can bail out now. Otherwise, you might need to know more about what goes on behind the scenes before you can figure out what went wrong.
C programs are written almost entirely using functions. Article 15.3 shows an example of a function defined in the Bourne shell programming language. C language functions are basically the same idea: group together a series of commands, give them a name, and then you can execute those commands using that name whenever you want and as many times as you want. Functions are also sometimes referred to as subroutines, library functions, or just routines.
Now, you can define C functions in the same source file. But the operating system also provides a vast collection of function definitions - which is very nice, because otherwise you'd be building every program from scratch. The function definitions are kept in libraries, which are generally installed on your system in /usr/lib/ with a lib prefix and a .a suffix (for example, /usr/lib/libc.a).
Functions also have to be declared in the program. Function declarations are kept in header or include files, which are generally installed on your system in /usr/include/ with .h suffixes (for example, /usr/include/stdio.h).
If you use functions that are defined in libraries (and you most definitely will), you need to make sure that when the program is compiled, it is linked to the libraries it needs. You also have to make sure that the proper header files are read by your program, since the program won't compile unless all functions have been declared.
For example, if you need to take the square root of a number in your program, you need to use the sqrt() function. This function resides in the Math library. This means that you need to link the program with libm.a and you need to read in the math.h header file (which declares sqrt()). So in the program, you need to have the following line near the top of the source file:
and when you compile the program, you need to use the -l (lowercase L) command-line option to link with libm:
Note the following facts:
Since math.h lives in /usr/include, you don't need to give
its absolute pathname on the
#include line, just put the name
of the header file between angle brackets as shown.
starting at /usr/include can be used in angle brackets.
<sys/foo.h> means /usr/include/sys/foo.h.
By default, cc looks for header files in /usr/include, and you can have it look automatically in other directories by specifying them with the -I command-line option. If you want to use a header file in directory that isn't searched by default, supply its absolute or relative pathname in double quotes instead.
When linking with a library on the command line, you should put the -l options at the end. If you use more than one library, you'll need more than one -l option. The order of the -l options is important; check the documentation or look for a comment in the source code.
The compiler found libm.a because it was in /usr/lib, which it searches by default. If you want it to use a library in another directory, you may need to supply the directory using the -L command-line option.
As you can imagine, there's much more to know. But that's the general idea of compiling C programs on UNIX systems, and it's about as much as we can tell you without starting to teach you C.
But more complicated programs (like many of the programs on the CD-ROM) require a bit more work. More complicated programs are easier to handle if you write them in modules. So, for example, the pcal source tree on the CD-ROM contains several .c files: exprpars.c, moonphas.c, pcalinit.c, pcalutil.c, readfile.c, writefil.c, and, of course, pcal.c. Each of these source files needs to be compiled separately into object files (with .o suffixes). If you give the -c option, cc will compile ".c files" into ".o files" and stop without making the finished executable. When you run cc again - but give it the .o filenames (exprpars.o, moonphas.o, and so on) it will link all those object files with the libraries and make the executable file.
This makes compilation a bit harder to keep track of. There are a lot more steps. Furthermore, it means that whenever a file is changed, you have to remember not only to recompile it but also to relink the entire program.
This is a job for the make program. We showed uses for make in articles 21.9 and 28.13, but this is what it was really meant for. The pcal source tree comes with a file called Makefile. (Actually, it comes with several different Makefiles for different platforms, but that's another issue.) The Makefile keeps track of each of the programs and each of their dependencies. It also keeps track of any command-line options you might want passed to cc, including libraries to link to. The result is that when you want to make the pcal program, all you need to do is type:
Or, even better, just:
This is a lot easier than trying to keep track of all the modules and command-line options yourself.
So if you can't compile a program because the header file it needs is
installed in a non-standard place, you'd specify that in the
You could add the appropriate -I
option to the
COPTS declaration line:
COPTS = -I/usr/include/sys
Or if you want to use a different compiler than cc, you could redefine that variable:
CC = /usr/local/bin/gcc
Again, this is only the tip of the iceberg. But a basic understanding of libraries, header files, and make has helped me build many programs that wouldn't compile the first time. For help with make, see O'Reilly & Associates' Managing Projects with make by Andrew Oram and Steve Talbott.