Mannix
Mannix

Reputation: 431

Treat one object in Makefile separately

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

Answers (1)

Chris Dodd
Chris Dodd

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

Related Questions