oreilly.comSafari Books Online.Conferences.


make for Nonprogrammers

by Dru Lavigne

If you're a typical FreeBSD user, you don't have a background in C programming. Yet, if you've ever used make world to upgrade your operating system or issued a make install somewhere within your ports tree, you've compiled C code.

This article covers some make basics so you have an idea what is happening behind the scenes. It also examines some of the options you have available when issuing make commands.

Why C?

You may be wondering why you should care about C if you have no intention of becoming a C programmer. The reason is simple: most operating systems (including FreeBSD) are written in C, as are most executable programs. As an example, use the file command to see the type of third-party programs installed on your system:

% file /usr/local/bin/* | more

You'll find some Bourne shell scripts and perl scripts, but the rest will be executables compiled from C source code and say something like "ELF 32-bit LSB executable, Intel 80386, version 1 (FreeBSD), for FreeBSD 5.3.0, dynamically linked (uses shared libs), stripped."

Keep in mind that you can run FreeBSD for years without ever typing make. Simply install the operating system from scratch whenever you want to upgrade to a new version. Leave the kernel as is. That's right, the kernel is also written in C, which is why you type make buildkernel and make installkernel. Don't install the ports collection, and always install software using pkg_add -r. Think of all the disk space you'll save, as you'll have no need to install src or ports.

However, you won't be taking full advantage of the many benefits of an open source operating system--other than the free price tag.

make Basics

OK, so what is make, anyway? According to man make, it maintains program dependencies. As any C programmer who has ever worked on a software project can tell you, there can be literally hundreds of source files, header files, and object files to compile and link in order to generate an executable program. make's job is to ensure that everything happens in the correct order.

In order for make to do its thing, it reads a Makefile in the same directory from which you run the make command. For example, say I try this in my home directory:

% cd
% make
make: no target to make.

That message means that there isn't a file called Makefile in the directory. However, suppose I issue the same command (as superuser) from somewhere in the ports tree:

# cd /usr/ports/shells/bash
# make

make will go out on the internet looking for some source code to compile. This makes sense, as you need C source code in order to make this program.

How did make know to go to the internet looking for that source code, and more importantly, how did it know which specific FTP site contained the source code it needed? If you guessed that the instructions were in a Makefile in that directory, you are correct:

# ls /usr/ports/shells/bash
Makefile	files		pkg-descr	pkg-plist
distinfo	pkg-deinstall	pkg-install

If you read through that Makefile, you'll find a MASTER_SITES variable that lists the URLs to sites containing the required source code.

Note: In case you're wondering where that downloaded source ends up, the Makefile copies it to /usr/ports/distfiles/ as a tarball. It then extracts this tarball into a subdirectory of your current directory called work. Typing make install clean will delete work--don't type clean if you want to keep the work directory.

Deciphering the Makefile for a Port

You don't have to be that brave to wade through a port's Makefile, as most of the uppercase variables have explanatory names. If you come across one that isn't self-explanatory or want a bird's-eye view of what each variable does, check out the make file that explains the format of port Makefiles:

% more /usr/ports/Mk/

Knowing the names of some of these variables can be useful to you, not just make. For example, I can search for the MAN variable to determine which man pages a port will install:

% grep MAN /usr/ports/mail/postfix/Makefile
MAN1=	mailq.1 newaliases.1 postalias.1 postcat.1 postconf.1 postdrop.1 \
MAN5=	access.5 aliases.5 canonical.5 cidr_table.5 ldap_table.5 \
MAN8=	bounce.8 cleanup.8 defer.8 error.8 flush.8 lmtp.8 local.8

The MAN variable uses a number to represent the section of the manual. By using grep to search for this variable, I know that this port will install six man pages into section 1, five into section 5, and seven into section 8. Looks like I'll be doing a lot of reading if I install this port!

make Targets

Besides using grep to glean information out of a Makefile, you can also take advantage of make targets. Target is the proper term for the action word(s) you type after make. For example, you've probably used the install and clean targets when building a port. Not surprisingly, /usr/ports/Mk/ contains a list of all the targets supported when compiling a port. You can find this list by using / to search for the Default targets section once you've opened this file in a pager:

% more /usr/ports/Mk/
/Default targets

However, you may find it easier to read man ports, as it further explains the common targets.

If you've never done anything fancier than make install, you should practice using each of the targets on a test system, as they may not necessarily work the way you think they would after reading the descriptions.

For example, try running make configure instead of make install from /usr/ports/shells/bash. At first glance, this looks like a normal compile, as make goes out looking for source code, extracts it, and configures it for your system. Note that it doesn't actually build the code or install the program, though.

If you read man ports carefully, you'll see that the usual make install is really a whole bunch of targets run in this order: config, fetch, checksum, depends, extract, patch, configure, build, and finally install. If you specify any other target, make will start at config and run every target up to and including the specified target. So, make configure does everything from make config to make configure.

Next, run make configure from /usr/ports/mail/postfix. The make process will begin, and depending upon the speed of your internet connection, some moments later you'll see a dialog menu box where you can pick and choose which options to pass to the configuration script.

This may have bitten you before: you type make install, leave your computer to attend to something else, and come back an hour later only to find not a newly compiled program but instead a dialog menu waiting for your input. Wanna know a secret? The ports that pop up such menus always have a scripts directory containing a dialog script called configure. If you see such a directory when you cd into a ports skeleton, stick around, as it will ask you for some interaction before the build begins.

Pages: 1, 2

Next Pagearrow

Sponsored by: