Makefile sucht sich sourcen zusammen. $< leer
-
Hallo ihrs,
Disclaimer: Makefiles habe ich das letzte Mal vor 137 Jahren gemacht..
Ich bastle mir gerade an einem Projekttemplate für mittelkomplexe C-Projekte herum und habe mir was zusammen gestrickt das sich seine Sourcen selbst zusammen sucht. Wahrscheinlich funktioniert das nicht in allen Fällen super aber es ist ein Anfang..
Grundsätzlich funktioniert das jetzt auch aber eine Kleinigkeit verstehe ich nicht. Daher hier erst mal der Source:
PROG = projectname SRCDIR = src BINDIR = build CC = /usr/bin/gcc CFLAGS = -g -Wall LDFLAGS = # these targets are not incremental .PHONY: clean program # this only gets the source directory structure STRUCTURE = $(shell find $(SRCDIR) -type d) # this lists the files inside the directory structure FILES = $(wildcard $(STRUCTURE)/*) # filter the source files SOURCES = $(filter %.c, $(FILES)) OBJECTS = $(subst $(SRCDIR),$(BINDIR),$(SOURCES:%.c=%.o)) # how to create an object file $(BINDIR)/%.o: $(subst $(BINDIR),$(SRCDIR),$(@:.o=.c)) @echo "Compiling object $@" $(CC) -c $(subst $(BINDIR),$(SRCDIR),$(@:.o=.c)) -o $@ $(CFLAGS) # compile means, that all objects have to exist compile: $(OBJECTS) program: compile $(CC) $(CFLAGS) $(LDFLAGS) -o $(BINDIR)/$(PROG) $(OBJECTS) clean: -rm -r $(BINDIR)/* all: clean compile program
Im Block 21-24 erzeuge ich ein object file im bin directory aus dem C-File. Theoretisch sollte ja hier der Aufruf
$(BINDIR)/%.o: $(subst $(BINDIR),$(SRCDIR),$(@:.o=.c)) $(CC) -c$< -o $@ $(CFLAGS)
reichen, tuts aber nicht. $< ist leer. Kann mir wer sagen warum?
-
Ich würde bei so etwas erst einmal
make -d
versuchen, ob man sich daran erschließen kann, was da falsch läuft. Oder ist das schon, was du gemacht hast, um zu deiner Diagnose zu kommen?Dass da kein Leerzeichen zwischen
-c
und$<
ist, ist das bei dir wirklich so oder nur ein Tippfehler in der Frage hier?compile
undall
sollten Phony-Targets sein, oder? Da könnte es eventuell Probleme geben, wenn irgendwelche Sourcen verwandte Namen haben.
-
Ich habe das makefile etwas umgeschrieben, und es macht nun das was Du wohl erreichen willst. Wenn man automatisch Listen von Objekten generieren will, kommt man um die höheren Funktionen von make nicht herum. Ich hoffe es ist halbwegs nachvollziehbar.
PROG=projectname SRCDIR=src BINDIR=objs C_SRC_SUFFIX=.c C_OBJ_SUFFIX=.o CC=gcc CFLAGS= -g -Wall -Wextra -std=c11 -Wpedantic LDFLAGS= # these targets are not incremental .PHONY: clean program directories # this only gets the source directory structure STRUCTURE = $(shell find $(SRCDIR) -type d) # this lists the files inside the directory structure FILES = $(wildcard $(STRUCTURE)/*) #$(info $(FILES)) # filter the source files SOURCES = $(filter %.c, $(FILES)) BASEFILE=$(basename $(notdir $(SOURCES))) OBJECTS=$(addprefix $(BINDIR)/, $(addsuffix .o, $(BASEFILE))) define GENERATE_OBJECT_RULES $(BINDIR)/$O$(C_OBJ_SUFFIX): $(SRCDIR)/$O$(C_SRC_SUFFIX) $(CC) $(CFLAGS) -c $$< -o $$@ endef all: program $(foreach O, $(BASEFILE), $(eval $(GENERATE_OBJECT_RULES))) #$(foreach O, $(BASEFILE), $(info $(GENERATE_OBJECT_RULES))) #$(info $(OBJECTS)) directories: @mkdir -p $(BINDIR) program: directories $(OBJECTS) $(CC) $(CFLAGS) -o $(BINDIR)/$(PROG) $(LDFLAGS) $(OBJECTS) clean: @rm -rf $(BINDIR)
-
@john-0 So im Groben versteh ich das Ganze glaub ich. Habe bisher define nie genutzt aber hat wohl Sinn.. danke dir!