Reputation: 325
I found a lot of interesting posts here with multiple source directories (for C). But I am struggling with some very special use case. This is what I have here and works fine:
.
|
\--main/
| |
| |-- (multiple *c files)
| \--obj/
| |
| \-- multiple *o files from the upper *c files
|
| --vent/
| |
| |-- (multiple *c files)
| \--obj/
| |
| \-- multiple *o files from the upper *c files
[...]
Each subdir has it own Makefile
:
include ../Makefile.vars
SOURCES = $(wildcard *.c)
HEADERS = $(wildcard ../*h)
OBJECTS = $(patsubst %.c, obj/%.o, $(SOURCES))
all: $(OBJECTS)
#====================== vent ============================
$(OBJECTS): obj/%.o : %.c $(HEADERS)
$(CC) $(CFLAGS) -c $< -o $@
[...]
The included Makefile.vars
just keep track of the libraries which might be needed:
CFLAGS = -Wall
LIBS := -lconfig -lcurl -ljson-c -lm -lmodbus -lmosquitto -lownet -lpthread -lsystemd
Now I have on the .
directory a single Makefile which crawls down into the subdirectories, does a make
, links the .*o
and finally creates the desired binary:
include Makefile.vars
SUBDIRS := common kluefter vent main mqttd wetter
SOURCES := $(wildcard $(addsuffix /*.c ,$(SUBDIRS)))
OBJECTS := $(subst /,/obj/,$(subst .c,.o,$(SOURCES)))
HEADERS := $(wildcard *h)
BIN := hzgmasterd
server : $(BIN)
#====================== Master ============================
$(BIN) : $(OBJECTS)
$(CC) $(CFLAGS) -rdynamic -o $@ $^ $(LIBS)
@echo "Server done."
$(OBJECTS) : $(SUBDIRS) ;
.PHONY: $(SUBDIRS)
$(SUBDIRS) :
$(MAKE) -C $@
This works pretty smooth!
But I need an additional binary which should make use of most of the existing *.o
files and create a different binary (obviously with a different main()
).
So I added some parts to the master Makefile:
#Define the subdirectory to crawl into for tools
TSUBDIRS := tools
#Define TSOURCES, TOBJECTS and THEADERS derived from the original ones. Exclude the main.c from $(SOURCES):
TSOURCES := $(wildcard $(addsuffix /*.c ,$(TSUBDIRS))) $(filter-out main.c,$(SOURCES))
TOBJECTS := $(subst /,/obj/,$(subst .c,.o,$(TSOURCES)))
THEADERS := $(wildcard *h)
TBIN := tools/hzgtool
all : $(BIN) $(TBIN)
server : $(BIN)
tools : $(TBIN)
# And added the compile/ link lines for tools:
#====================== Tools ============================
$(TBIN) : $(TOBJECTS)
$(CC) $(CFLAGS) -rdynamic -o $@ $^ $(LIBS)
@echo "Tools done."
$(TOBJECTS) : $(TSUBDIRS) ;
Unfortunately, this does not work. When I do a make
on top level I am getting the following feedback (sorry, only in German):
root@zentrale:/heizung/src# make server
Makefile:53: Warnung: Die Befehle für das Ziel „common/obj/vent.o“ werden überschrieben
Makefile:42: Warnung: Alte Befehle für das Ziel „common/obj/vent.o“ werden ignoriert
I refers to the lines starting with $(OBJECTS)
and $(TOBJECTS)
telling me line 42 will get ignored and overwritten by line 53.
Why is $(OBJECTS) : $(SUBDIRS) ;
overwritten by $(TOBJECTS) : $(TSUBDIRS) ;
?
Any idea how to get what i want?
Upvotes: 0
Views: 44