The mode is controlled by setting the DEBUG variable on the command-line to yes or no. If DEBUG is set then the first part of the Makefile is used (and it only contains a single all rule). The first part first translates the setting of DEBUG into either debug or release and then executes a sub-Make in the appropriate directory.

For example, if you do make DEBUG=yes then the Makefile will

execute:

make debug -C debug -f ../Makefile DEBUG= That starts GNU Make in the debug sub-directory (that's the -C debug > part), using the same Makefile (the -f ../Makefile ; the .. is necessary because this will be executed from debug/), clears the DEBUG variable and tells the sub-Make to run the debug rule.

When the Makefile is rerun the first part is ignored (because DEBUG was cleared) and the main part runs. In this case the debug target is built. It modifies CPPFLAGS and builds all.

make release -C release -f ../Makefile DEBUG= cc -I ../include -c -o foo.o ../src/foo.c cc -I ../include -c -o bar.o ../src/bar.c cc -I ../include -c -o baz.o ../src/baz.c In both cases the output has been separated into a directory with the sources coming from the same location. For the debug build you can see that the -g option has been added to the compiler command-line.

<size=12pt>You don't need them

Most of the time you can completely avoid using VPATH and vpath. For most dependencies you'll be using some automatic dependency search program (such as makedepend or gcc

- -MP ) and so you won't need to have GNU Make search for those files because the dependencies will be fully specified.

On the other hand, the separation of different binary types (debug/release, or different architectures) is very handy. It can, however, be easily achieved without using the VPATH/vpath by explicitly setting the paths for sources and objects in the Makefile. The only problem with doing this is that GNU Make's built-in pattern rules cannot be used (because they either assume source and binary are in the same directory, or they use a

VPATH/vpath search). To make up for that you have to provide your own versions of those pattern rules.

Here's my sample Makefile rewritten to eliminate vpath entirely (I cheated slightly be omitting the automatic dependency generation part). It still separates output into debug/ and release/ but uses explicit paths to do so, and it doesn't require the GNU Make restart that the previous solution used.

Pages

About the author

John Graham-Cumming is Co-Founder at Electric Cloud, Inc . Prior to joining Electric Cloud, John was a Venture Consultant with Accel Partners, VP of Internet Technology at Interwoven, Inc. (IWOV), VP of Engineering at Scriptics Corporation (acquired by Interwoven), and Chief Architect at Optimal Networks, Inc. John holds BA and MA degrees in Mathematics and Computation and a Doctorate in Computer Security from Oxford University. John is the creator of the highly acclaimed open source POPFile project. He also holds two patents in network analysis and has others pending.