2017-11-22 2 views
0

Das ist mein Makefile:Ärger mit Makefile Kompilieren von Objekten und bewegen sie

.PHONY : clean fclean re $(LIB_PATH) 

NAME = fillit 

FLAGS = -Wall -Wextra -Werror 

LIB_NAME = libft.a 

LIB_DIR = ../libft/ 

LIB_PATH = $(LIB_DIR)$(LIB_NAME) 

OBJ_DIR_NAME = objects 

OBJ_DIR = $(OBJ_DIR_NAME)/ 

HEADER_DIR = ../libft/ 

SRC = main.c func1.c 

OBJ = $(SRC:.c=.o) 

all : 
    mkdir -p $(OBJ_DIR_NAME) 
    $(MAKE) $(NAME) 

$(NAME): $(OBJ_DIR)$(OBJ) $(LIB_PATH) 
    gcc -o $(NAME) $(addprefix $(OBJ_DIR), $(OBJ)) -L$(LIB_DIR) -lft -I$(HEADER_DIR) 

$(LIB_PATH): 
    $(MAKE) -C $(LIB_DIR) --no-print-directory 

$(OBJ_DIR)%.o : %.c 
    gcc $(FLAGS) -I $(HEADER_DIR) -c $< 
    -mv $(@F) $(OBJ_DIR) 

clean : 
    -rm $(addprefix $(OBJ_DIR), $(OBJ)) 
    -rm -rv $(OBJ_DIR_NAME) 

fclean : clean 
    -rm $(NAME) 
    $(MAKE) -C $(LIB_DIR) fclean --no-print-directory 

re: fclean 
    make 

Wenn ich machen, ich erwarte, dass die Regel $(OBJ_DIR)%.o : %.c kompiliert die beiden Objekte (func1.c main.c) und verschieben Sie sie in Objekte Verzeichnis. Aber die Regel geschieht nur mit der ersten Quelldatei geschrieben in SRC

Antwort

0

kompiliert die beiden Objekte (reader.c main.c)

Meinen Sie func1.c statt reader.c?

Wenn das der Fall ist, überprüfen Sie bitte, ob sich die func1.c Datei im selben Verzeichnis wie main.c befindet. Wenn es sich nicht im selben Verzeichnis befindet, müssen Sie eine andere Musterregel schreiben. Etwas wie folgt aus:

FUNC1_DIR = # The directory where your func1.c is located, maybe src/ or something alike 

$(OBJ_DIR)%.o : $(FUNC1_DIR)%.c 
    gcc $(FLAGS) -I $(HEADER_DIR) -c $< 
    -mv $(@F) $(OBJ_DIR) 
+0

Ja war func1.c ich habe es schon entschuldigt. Sie sind im selben Verzeichnis und was ist mehr, wenn ich '$ (NAME) schreiben: $ (OBJ_DIR) main.o $ (OBJ_DIR) func1.o $ (LIB_PATH)' anstelle von '$ (NAME): $ (OBJ_DIR) $ (OBJ) $ (LIB_PATH) 'funktioniert perfekt. – latiagertrutis

+0

Nun, es scheint, dass in '$ (OBJ_DIR) $ (OBJ)' das '$ (OBJ_DIR)' nur für die erste Datei in '$ (OBJ)' funktioniert, das bedeutet, dass 'main.o' perfekt aufgebaut ist, weil sein Pfad ist korrekt, aber 'func1.o' wird nicht erstellt, da der Pfad nicht hinzugefügt wurde und der Compiler denkt, dass sich die Datei im selben Verzeichnis wie das Makefile befindet. Versuchen Sie folgendes: 'OBJ = $ (patsubst% .c, $ (OBJ_DIR)% .o, $ (SRC)' anstelle von 'OBJ = main.o func1.o'. Und dann entfernen Sie auch das' $ (OBJ_DIR) ' aus der Zeile '$ (NAME): $ (OBJ_DIR) $ (OBJ) $ (LIB_PATH)'. –

+0

Vielleicht müssen Sie einen Pfad zu den src-Dateien in '$ (patsubst)' hinzufügen, etwa so: 'OBJ = $ (patsubst $ (SRC_DIR)% .c, $ (OBJ_DIR)% .o, $ (SRC))', es hängt davon ab, wo sich Ihre src-Dateien befinden und weitere Informationen über patsubst finden Sie in [GNU Make Manual] (https://www.gnu.org/software/make/manual/html_node/Text-Functions.html#Text-Functions) Ich hoffe das hilft :) –

0

$(NAME): $(OBJ_DIR)$(OBJ) nicht gilt $ (OBJDIR) zu jedem Punkt $ (OBJ). Es buchstäblich buchstäblich verkettet $ (OBJDIR) auf der Liste. Dies ist der Grund, warum nur eine Instanz Ihrer Musterregel ausgelöst wird (nur eine .o hat das Pfadpräfix, das das Muster zu erreichen versucht).

Verwenden Sie stattdessen:

OBJ_WITH_PATH := $(foreach obj,$(OBJ),$(OBJ_DIR)$(obj)) 

Dann die Abhängigkeit von Ihrem NAMEN Regel aktualisieren, um

$(NAME): $(OBJ_WITH_PATH) $(LIB_PATH) 

Als Nebenwirkung, finde ich es manchmal hilfreich Regeln hinzufügen wie

.PHONY: DEBUG 
DEBUG: 
    @echo MAKING SURE THIS WORKS: $(OBJ_DIR)$(OBJ) 
    @echo ALTERNATE: $(OBJ_WITH_PATH) 

dann können Sie Ihr DEBUG-Ziel ausführen:

$ make DEBUG 
MAKING SURE THIS WORKS temp/a.o b.o 
ALT temp/a.o temp/b.o 
Verwandte Themen