Reputation: 431
I have a Makefile which is used to build several different programs. These programs use common object files.
One program crashes with *** buffer overflow detected ***
when one of the modules that is linked to it is compiled with any optimizations.
Here is the Makefile:
CC=gcc
WFLAGS=-W \
-Wall \
-Werror \
-Wextra \
-Wshadow \
-Wcast-qual \
-Wcast-align \
-Wwrite-strings \
-Wpointer-arith \
-Wnested-externs \
-Wstrict-prototypes \
-Wmissing-prototypes
CFLAGS=$(WFLAGS) \
-g \
-O2 \
-ansi \
-pedantic \
-Dinline= \
-fno-common \
-fshort-enums
LFLAGS=-lm
TARGETS=lzdata \
lzmcro \
mknlrescs \
mknrescs \
levels \
degen
OBJ1=couplings.o \
crossing.o \
element.o \
lzdata.o \
utils.o \
lzcxs.o \
nist.o
OBJ2=lzmcro.o
OBJ3=mknlrescs.o \
csheader.o \
xsection.o \
labels.o \
csdata.o \
utils.o
OBJ4=mknrescs.o \
csheader.o \
xsection.o \
labels.o \
csdata.o \
utils.o
OBJ5=levels.o \
utils.o
OBJ6=degen.o \
utils.o \
nist.o
OBJECTS=$(OBJ1) $(OBJ2) $(OBJ3) $(OBJ4) $(OBJ5) $(OBJ6)
SOURCES=mknlrescs.c \
couplings.c \
mknrescs.c \
xsection.c \
crossing.c \
csheader.c \
element.c \
csdata.c \
labels.c \
lzmcro.c \
lzdata.c \
levels.c \
degen.c \
utils.c \
lzcxs.c \
nist.c
HEADERS=couplings.h \
xsection.h \
csheader.h \
crossing.h \
element.h \
csdata.h \
labels.h \
utils.h \
lzcxs.h \
nist.h
MANPAGES=lzdata.1\
lzmcro.1
SCRIPTS=mclz.sh \
fnist1.pl \
fnist2.pl
DATAFILES=elements.dat
ALL=$(SOURCES) $(HEADERS) $(MANPAGES) $(SCRIPTS) $(DATAFILES)
all: $(TARGETS)
levels: $(OBJ5)
$(CC) $(CFLAGS) $(LFLAGS) -o $@ $^
degen: $(OBJ6)
$(CC) $(CFLAGS) $(LFLAGS) -o $@ $^
mknlrescs: $(OBJ3)
$(CC) $(CFLAGS) $(LFLAGS) -o $@ $^
mknrescs: $(OBJ4)
$(CC) $(CFLAGS) $(LFLAGS) -o $@ $^
lzmcro: $(OBJ2)
$(CC) $(CFLAGS) -o $@ $< $(LFLAGS)
lzdata: $(OBJ1)
$(CC) $(CFLAGS) -o $@ $^ $(LFLAGS)
%.o: %.c %.h
$(CC) $(CFLAGS) -c $<
install: $(TARGETS)
mv $^ /usr/local/bin
clean:
@rm -f $(OBJECTS) $(TARGETS)
The program that crashes is mknrescs
when labels.c
is compiled with optimizations.
I could remove -O2
from the CFLAGS
macro, but I would rather not, since some programs take a while and that will make them even slower.
I could build each object separately, instead of using this rule: %.o: %.c %.h
.
The other programs, which used labels.o
do not crash, even if it is compiled with optimzations.
So, what other options to I have to build ONLY labels.o
with no optimizations ONLY when it is linked to mknrescs
?
Thanks
Upvotes: 0
Views: 57
Reputation: 126203
You could add a target-specific variable for labels.o
to override the CFLAGS
setting:
labels.o: CFLAGS = $(WFLAGS) -g -O0 -ansi -pedantic -Dinline= -fno-common -fshort-enums
This variable will apply to all rules building labels.o
, so it will be built with no optimization. Since all the program targets share the same object file, however, they'll all use the non-optimized version. You can simplify this a bit by splitting the optimization level out of the CFLAGS
var:
OPTLEVEL=2
CFLAGS=$(WFLAGS) \
-g \
-O$(OPTLEVEL) \
-ansi \
-pedantic \
-Dinline= \
-fno-common \
-fshort-enums
labels.o: OPTLEVEL = 0
If you really must have the non-optimized version just for the one program and not for the others, you need to use a different name for the object file. You can add a generic rule to generate unoptimized objects:
%-noopt.o: %.c %.h
$(CC) $(CFLAGS_NOOPT) -c -o $@ $<
define the CFLAGS_NOOPT
variable the same as CFLAGS
but with -O0
, and then change your OBJ
list for the problematic binary to include labels-noopt.o
instead of labels.o
Upvotes: 2