Jest to część mojego makefile:

SRC     =   ./
DIRS    =   src libs/maths libs/struct
BIN_DIR =   ./bin/

SRC_DIRS=   $(foreach dir, $(DIRS), $(addprefix $(SRC), $(dir)))
SRC_TEST=   $(sort $(SRC_DIRS))

SRCS    =   $(foreach msrc, $(SRC_DIRS), $(wildcard $(msrc)/*.c))

DEL_PRE =   $(foreach target, $(SRCS), $(notdir $(target)))
ADD_PRE =   $(foreach target, $(DEL_PRE), $(addprefix $(BIN_DIR), $(target)))
OBJS    =   $(ADD_PRE:.c=.o)

.PHONY: all clean re

all:        $(EXEC)

$(EXEC):    $(OBJS)
    $(CC) $(OBJS) -o $@ $(LDLIBS)

$(OBJS):    $(SRCS)
    $(CC) -o $@ -c $<

Kiedy używam, mam na wyjściu:

gcc -o bin/main.o -c src/main.c
gcc -o bin/cosin.o -c src/main.c
gcc -o bin/pears.o -c src/main.c
gcc -o bin/outil.o -c src/main.c
gcc -o bin/verif.o -c src/main.c

Ale chciałbym mieć dla każdego celu, przydzielonej zależności:

gcc -o bin/main.o -c src/main.c
gcc -o bin/cosin.o -c libs/maths/cosin.c
gcc -o bin/pears.o -c libs/maths/pears.c
gcc -o bin/outil.o -c libs/struct/outil.c
gcc -o bin/verif.o -c libs/struct/verif.c

Jak mogę to naprawić?

1
anderson 21 listopad 2020, 23:49

1 odpowiedź

Najlepsza odpowiedź

Wydaje się to bardzo powszechne nieporozumienie; Wczoraj odpowiedziałem na to samo pytanie. Nie jestem pewien, skąd pochodzi lub jak go walczyć.

Ta reguła:

$(OBJS):    $(SRCS)
       $(CC) -o $@ -c $<

Nie w jakiś sposób magicznie łączy zawartość zmiennej {x0}} i zmiennej SRCS, aby dowiedzieć się, jak się zgadzają. Zmienne odniesienia są po prostu rozszerzone, a wynik to:

bin/main.o bin/cosin.o ... : src/main.c libs/maths/cosin.c ...
       $(CC) -o $@ -c $<

Który jest taki sam jakby napisałeś to:

bin/main.o : src/main.c libs/maths/cosin.c ...
       $(CC) -o $@ -c $<
bin/cosin.o : src/main.c libs/maths/cosin.c ...
       $(CC) -o $@ -c $<
...

Teraz możesz mieć nadzieję, dlaczego skompilasz ten sam plik: W każdej reguły masz te same warunki wstępne, więc $< jest zawsze pierwszym, który jest zawsze src/main.c.

Istnieje wiele sposobów na to, ale jeśli naprawdę chcesz mieć wszystkie pliki źródłowe z różnych katalogów skompilowanych do plików obiektów w tym samym katalogu, Twojej pracy jest trudniejsze, ponieważ nie ma wspólnego wzoru, który pasuje do ich wszystkich. W tym przypadku najprostsza rzecz do zrobienia jest używanie VPath do wyszukiwania katalogów: Zastąp powyższą regułę:

$(BIN_DIR)/%.o : %.c
       $(CC) -o $@ -c $<

Następnie powiedz, jak znaleźć swoje pliki źródłowe, takie jak:

VPATH := $(sort $(dir $(SRCS))

Należy pamiętać, że ta metoda nie może być używana do żadnych plików źródłowych, które są generowane same wyjście, które sprawiają, że zostanie utworzyć.

0
MadScientist 21 listopad 2020, 21:08