Nokia Networks Home

Nokia nmake Product Builder

Quick Links

Related Products

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
Last Update: Friday,12-Aug-2016 10:44:45 EDT