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?


  • Mod

    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 und all 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!


Anmelden zum Antworten