Alcatel-Lucent nmake Product Builder
How to compile the same code with different compiler options?
Here are a couple simple techniques to build different targets from the
same source code using different compiler options in the same makefile.
The main problem is to make sure the intermediate files, such as
.o files, do not clobber each other which would cause the
targets to keep rebuilding in incremental builds.
If the compiler options affect standard header and/or library search paths or other probe variables it may be necessary to build using different probe configurations. For more info and examples see the FAQ, How to build both 32-bit and 64-bit versions of targets? The techniques below do not support changing compiler options that affect probe variables since they build everything in a single makefile and nmake run.
Copy Source Files
One approach is to make a copy of the source files with modified file names
so the intermediate objects don't clash with the objects from the original
source files. The following example makefile copies each source file to
basename2.c for the second target. The first target is compiled with
-O while the second uses -g. The second target also
has the (DEBUG) state variable prerequisite which causes nmake
to set -DDEBUG on the compile lines for the files that use the
define.
CC = cc FILES = a.c b.c c.c FILES2 = $(FILES:B:S=2.c) DEBUG = 1 .CLOBBER. += $(FILES2) for file $(FILES) $(file:B:S=2.c) :COPY: $(file) end :ALL: targ1 :: $(FILES) CCFLAGS=-O targ2 :: $(FILES2) CCFLAGS=-g (DEBUG)
A single nmake run will make both versions. Notice that modifying one of the original source files correctly updates both targets.
$ nmake + cc -O -I- -c a.c + cc -O -I- -c b.c + cc -O -I- -c c.c + cc -O -o targ1 a.o b.o c.o + cmp -s a.c a2.c + rm -f a2.c + cp a.c a2.c + cc -g -I- -DDEBUG -c a2.c + cmp -s b.c b2.c + rm -f b2.c + cp b.c b2.c + cc -g -I- -DDEBUG -c b2.c + cmp -s c.c c2.c + rm -f c2.c + cp c.c c2.c + cc -g -I- -DDEBUG -c c2.c + cc -g -o targ2 a2.o b2.o c2.o $ vi b.c $ nmake + cc -O -I- -c b.c + cc -O -o targ1 a.o b.o c.o + cmp -s b.c b2.c + rm -f b2.c + cp b.c b2.c + cc -g -I- -DDEBUG -c b2.c + cc -g -o targ2 a2.o b2.o c2.o
Custom Metarule
A variation of the previous technique uses a custom metarule to make the
second object files named as basename2.o while compiling the original
source files. No copies of the source files are needed and the objects do
not clash with the originals. Again the first target is compiled with
-O while the second uses -g and the
(DEBUG) state variable.
CC = cc
FILES = a.c b.c c.c
OBJS = $(FILES:B:S=.o)
OBJS2 = $(FILES:B:S=2.o)
DEBUG = 1
%2.o : %.c (CC) (CCFLAGS) (DEBUG)
$(CC) $(CCFLAGS) -o $(<) -c $(>)
:ALL:
targ1 :: $(OBJS) CCFLAGS=-O
targ2 :: $(OBJS2) CCFLAGS=-g
Again a single nmake run builds both versions, and modifying one of the source files correctly updates both targets.
+ cc -O -I- -c a.c + cc -O -I- -c b.c + cc -O -I- -c c.c + cc -O -o targ1 a.o b.o c.o + cc -g -I- -DDEBUG -o a2.o -c a.c + cc -g -I- -DDEBUG -o b2.o -c b.c + cc -g -I- -DDEBUG -o c2.o -c c.c + cc -g -o targ2 a2.o b2.o c2.o $ vi b.c $ nmake + cc -O -I- -c b.c + cc -O -o targ1 a.o b.o c.o + cc -g -I- -DDEBUG -o b2.o -c b.c + cc -g -o targ2 a2.o b2.o c2.o







