Online Book Reader

Home Category

Running Linux, 5th Edition - Matthias Kalle Dalheimer [389]

By Root 1450 0
flags, one set is seen so often that it's worth a special mention. This is the -D option, which is used to define symbols in the source code. Since all kinds of commonly used symbols appear in #ifdefs, you may need to pass lots of such options to your makefile, such as -DDEBUG or -DBSD. If you do this on the make command line, be sure to put quotation marks or apostrophes around the whole set. This is because you want the shell to pass the set to your makefile as one argument:

papaya$ make CFLAGS="-DDEBUG -DBSD" ...

GNUmake offers something called pattern rules, which are even better than suffix rules. A pattern rule uses a percent sign to mean "any string." So C source files would be compiled using a rule such as the following:

%.o: %.c

gcc -c -o $@ $(CFLAGS) $<

Here the output file %.o comes first, and the dependency %.c comes after a colon. In short, a pattern rule is just like a regular dependency line, but it contains percent signs instead of exact filenames.

We see the $< string to refer to the dependency, but we also see $@, which refers to the output file. So the name of the .o file is plugged in there. Both of these are built-in macros; make defines them every time it executes an entry.

Another common built-in macro is $*, which refers to the name of the dependency stripped of the suffix. So if the dependency is edit.c, the string $*.s would evaluate to edit.s (an assembly-language source file).

Here's something useful you can do with a pattern rule that you can't do with a suffix rule: add the string _dbg to the name of the output file so that later you can tell that you compiled it with debugging information:

%_dbg.o: %.c

gcc -c -g -o $@ $(CFLAGS) $<

DEBUG_OBJECTS = main_dbg.o edit_dbg.o

edimh_dbg: $(DEBUG_OBJECTS)

gcc -o $@ $(DEBUG_OBJECTS)

Now you can build all your objects in two different ways: one with debugging information and one without. They'll have different filenames, so you can keep them in one directory:

papaya$ make edimh_dbg

gcc -c -g -o main_dbg.o main.c

gcc -c -g -o edit_dbg.o edit.c

gcc -o edimh_dbg main_dbg.o edit_dbg.o

Multiple Commands

Any shell commands can be executed in a makefile. But things can get kind of complicated because make executes each command in a separate shell. So this would not work:

target:

cd obj

HOST_DIR=/home/e

mv *.o $HOST_DIR

Neither the cd command nor the definition of the variable HOST_DIR has any effect on subsequent commands. You have to string everything together into one command. The shell uses a semicolon as a separator between commands, so you can combine them all on one line:

target:

cd obj ; HOST_DIR=/home/e ; mv *.o $$HOST_DIR

One more change: to define and use a shell variable within the command, you have to double the dollar sign. This lets make know that you mean it to be a shell variable, not a macro.

You may find the file easier to read if you break the semicolon-separated commands onto multiple lines, using backslashes so that make considers them to be on one line:

target:

cd obj ; \

HOST_DIR=/home/e ; \

mv *.o $$HOST_DIR

Sometimes makefiles contain their own make commands; this is called recursive make. It looks like this:

linuxsubdirs: dummy

set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i; done

The macro $(MAKE) invokes make. There are a few reasons for nesting makes. One reason, which applies to this example, is to perform builds in multiple directories (each of these other directories has to contain its own makefile). Another reason is to define macros on the command line, so you can do builds with a variety of macro definitions.

GNUmake offers another powerful interface to the shell as an extension. You can issue a shell command and assign its output to a macro. A couple of examples can be found in the Linux kernel makefile, but we'll just show a simple example here:

HOST_NAME = $(shell uname

-n)

This assigns the name of your network node—the output of the uname -n command—to the macro HOST_NAME.

make offers a couple of conventions you may occasionally want to use. One is to put

Return Main Page Previous Page Next Page

®Online Book Reader