0

I've searched around for this issue, but nobody but me seems to have it, which is why I'll now ask.

If have this basic makefile:

CCPP = arm-none-linux-gnueabi-g++
CFLAGS = "-WALL -DPLATFORM_TARGET -DPRINT_MESSAGE"
LIB = lib/libarm.a

LDFLAGS = -lpthread
OBJECTS = $(wildcard ./*/*.o)
PROG = /exports/appl

MODULES = lib src

all: $(PROG) 
    $(CCPP) $(LDFLAGS) $(OBJECTS) $(LIB) -o $(PROG)

$(PROG): $(MODULES)
    @for i in $(MODULES); do (cd $$i && $(MAKE) \
    CCPP=$(CCPP) LDPP=$(CCPP) CFLAGS=$(CFLAGS) LDFLAGS=$(LDFLAGS)) || exit 1 ;\
    done

clean:
    @for i in $(MODULES); do (cd $$i && $(MAKE) clean) || exit 1 ; done
    rm $(PROG)

lib:
    ar cr ../lib/$(LIB) $(OBJECTS)

This works. It takes whatever source file is within lib and src and compiles and links it nicely together. (By using local makefiles found in these folders which I can post too if need be)

Anyway, what I WANT now, is add more -D directives conditionally. I've tried:

ifdef ALLOW_BACKTRACE
    CFLAGS += -DALLOW_BACKTRACE
    LDFLAGS += -rdynamic
endif

and also:

ifdef ALLOW_BACKTRACE
    CFLAGS := $(CFLAGS) -DALLOW_BACKTRACE
#endif

or by putting the whole thing in quotes etc...but each time I try, it brings up the help page of make, telling me that it can't 'recognize' the new define. Any idea what I'm doing wrong?

Any help is much appreciated.

ATaylor
  • 2,598
  • 2
  • 17
  • 25
  • Your makefile is incorrect. `all` target commands are actually commands for `$(PROG)`. And `$(PROG)` target commands don't produce `$(PROG)`. – Maxim Egorushkin Aug 07 '13 at 08:59
  • @MaximYegorushkin I'm not too good with Makefiles and up to that point it worked fine. Could you please post how it would be correct? Thank you. – ATaylor Aug 07 '13 at 09:00

3 Answers3

1

Okay, this should be a more correct version of your makefile, I can not test it though because I don't have your sources:

export CCPP := arm-none-linux-gnueabi-g++

# Note that -pthread is required for both compiling and linking.
export CFLAGS := -pthread -WALL -DPLATFORM_TARGET -DPRINT_MESSAGE
export LDFLAGS := -pthread

LIB := lib/libarm.a
PROG := /exports/appl
MODULES := lib src

all: $(PROG)

$(PROG): $(MODULES)
    $(CCPP) -o $@ $(LDFLAGS) ./*/*.o $(LIB)

$(MODULES) : % :
    $(MAKE) -C $@
    touch $@

clean-module.%:
    $(MAKE) -C $* clean

clean : $(MODULE:%=clean-module.%)
    rm -f $(PROG)

.PHONY: all clean clean-module.%

What I changed:

  • LDFLAGS = -lpthread: when building multi-threaded applications you need both an extra compiler and linker flag, which is what -pthread/-pthreads gcc options is.
  • Contents of OBJECTS = $(wildcard ./*/*.o) are only correct when $(MODULES) built correctly. Removed it.
  • $(PROG) commands actually build $(PROG) target as it should.
  • $(MODULES) commands build the modules by invoking make in the corresponding directory. And then they update the timestamp of the directory to force rebuild of $(PROG). Since it is a recursive make it can't know whether anything have actually been updated in the module, hence it need to trigger the rebuild of anything that depends on the modules.

I still have a feeling that this won't work for you because your original makefile is missing dependencies.

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
  • A little question, shouldn't '-pthread' (at least for the LDFLAGS) have 'l' in front of it's name? And sorry for the late response, I seem to have missed you posting this. And no, it doesn't seem to work. Upon running 'clean' it doesn't remove any object files, nor does it compile any sources. Thank you anyway. – ATaylor Aug 07 '13 at 10:18
  • @ATaylor It should not. `-pthread` or `-pthreads` is a gcc option. It sets necessary compiler and linker flags. See http://stackoverflow.com/a/2127819/412080 – Maxim Egorushkin Aug 07 '13 at 10:22
0

Try doing this -->

ifeq ($(ALLOW_BACKTRACE),1) 
  CFLAGS += -DALLOW_BACKTRACE 
 endif
Ishmeet
  • 1,540
  • 4
  • 17
  • 34
  • Thank you for your input, that that won't work. (Tried it). The problem isn't exactly, that it doesn't append it, but much rather, that make won't accept it as valid input. – ATaylor Aug 07 '13 at 08:50
0

You've got to be KIDDING me!

Ahem. I seem to have found the solution to my own problem. I don't quite get it, but whatever works, right?

Anyway, here's what I did:

CFLAGS  += -Wall -DPLATFORM_TARGET -DPRINT_MESSAGE
ifdef ALLOW_BACKTRACE
    CFLAGS += -DALLOW_BACKTRACE
    LDFLAGS += -rdynamic
endif

LDFLAGS += -lpthread

$(PROG): $(MODULES)
    @for i in $(MODULES); do (cd $$i && $(MAKE) \
        CCPP=$(CCPP) LDPP=$(CCPP) CFLAGS="$(CFLAGS)" LDFLAGS=$(LDFLAGS)) || exit 1 ;\
    done

First thing: -rdynamic needs to be the first flag in the linker, otherwise it refuses to work. (Don't ask me why, if anyone could enlighten me, be my guest.

Second: I had to put quotes around the expanded $(CFLAGS) in my actual build step. As soon as I did that, it worked like a charm...probably because it had a problem with the spaces.

Thanks to everyone, who went to the trouble of trying to help me.

ATaylor
  • 2,598
  • 2
  • 17
  • 25