Pytanie w sprawie makefile, c++ – makefile automatyczne wykrywanie plików src i generowanie zależności

2

Mam następujące ustawienia dla mojego projektu c ++:

w folderze src znajdują się pliki * .cpp i odpowiadające im pliki * .h, aw folderach obj-chcę mieć pliki .o.

jak dotąd kompilowanie i łączenie nie stanowi problemu. Ale teraz mam zbyt wiele plików .cpp i .h, aby ręcznie umieścić je w Makefile. Postanowiłem więc napisać tę małą instrukcję w makefile:

<code>collect_sources:
@echo "collecting source files";
@echo "SRCS = \\" > sources;
@for file in ./src/*.cpp; \
do \
    echo "$$file \\" >> sources; \
done
</code>

Ja też

<code>-include sources
</code>

na początku makefile

Plik wynikowysources wygląda dobrze, chociaż w ostatnim wierszu jest odwrotny ukośnik, którego nie lubię. Ale afaik też powinien być szkodliwy.

Teraz muszę także automatycznie budować zależności. W mojej ostatniej wersji, w której zdefiniowałem pliki * .cpp jakoSRCS bezpośrednio w pliku Makefile, następujący kod był dobry:

<code>$(SRCDIR)/%.cpp:
  @$(CXX) $(DEPFLAGS) -MT \
  "$(subst $(SRCDIR),$(OBJDIR),$(subst $(EXT_SRC),$(EXT_OBJ),$$file))" \
  $(addprefix ,$$file) >> $(DEP);
clear_dependencies:
    echo "" > $(DEP);

depend: clear_dependencies $(SRCS)
</code>

Ale z włączeniemsources-file, nigdy nie osiąga górnego bloku kodu.

Oto stałe zdefiniowane na górze pliku Makefile:

<code>CXX = g++
CXXFLAGS = -Wall \
       -Wextra \
       -Wuninitialized \
       -Wmissing-declarations \
       -pedantic \
       -O3 \
       -p -g -pg
LDFLAGS =  -p -g -pg
DEPFLAGS = -MM

SRCDIR  = ./src
OBJDIR  = ./obj

TARGET = ./bin/my_funky_function_which_is_not_the_real_name

-include sources

OBJSTMP =   $(SRCS:.cpp=.o)
OBJS        =   $(OBJSTMP:$(SRCDIR)=$(OBJDIR))
DEP = depend.main
EXT_SRC =   .cpp
EXT_OBJ =   .o
</code>

czego mi brakuje? Czy moje podejście jest prawidłowe / wykonalne?

krok po kroku do absolutnego optimum ;-) stefan
Jest jeden prosty błąd i wiele możliwych ulepszeń. Jak daleko chcesz iść? Beta
na marginesie: proszę nie sugerować żadnego narzędzia, które już to robi. Naprawdę chcę to zrozumieć i mieć pełną kontrolę nad tym, co się dzieje. stefan

Twoja odpowiedź

1   odpowiedź
7

1: Twójcollect_sources:... include sources jest wspaniałą hakerią Rube Goldberg. Po prostu zrób to:

<code>SRCS = $(wildcard ./src/*.cpp)
</code>

A jeśli chcesz to potwierdzić, możesz to zrobić:

<code>$(info $(SRCS))
</code>

2:

<code>clear_dependencies:
    echo "" > $(DEP);
</code>

Dla dobra estetyki, naprawmy to.

<code>clear_dependencies:
    $(RM) $(DEP);
</code>

3:

<code>$(SRCDIR)/%.cpp:
    @$(CXX) $(DEPFLAGS) -MT \
  "$(subst $(SRCDIR),$(OBJDIR),$(subst $(EXT_SRC),$(EXT_OBJ),$$file))" \
  $(addprefix ,$$file) >> $(DEP);
</code>

To zajmie trochę pracy. Najpierw bezpośredni problem: cel jest prawdziwym plikiem, który istnieje, a reguła nie ma żadnych wymagań wstępnych. Dlatego reguła nie zostanie uruchomiona (nie mam pojęcia, dlaczego działała w poprzedniej wersji, może coś innego było inne). Jako tymczasowa poprawka proponuję przełączyć się na statyczną regułę wzoru i cele PHONY:

<code>.PHONY:$(SRCS)
$(SRCS) : $(SRCDIR)/%.cpp:
    @$(CXX) $(DEPFLAGS) -MT \
   ...
</code>

Zobacz, czy to wszystko działa, a potem możemy poradzić sobie z dużymi rzeczami.

Nie, to efekt uboczny tworzenia celów PHONY źródeł. Beta
Fajne. Za kilka godzin będę miał czas, aby dodać więcej. Beta
W rzeczywistości byłoby to genialne :) Z jakiegoś powodu, którego jeszcze nie rozumiem, kompilator buduje każdy obiekt bez zmiany pliku. Prawdopodobnie wpadłem tutaj ... stefan
@stefan, prawdopodobnie[email protected]. W praktyce Make użyje tej reguły przy rozważaniu, czy przebudować coś podobnego./src/foo.cpp. Prawie na pewno będzie to plik, który już istnieje (chyba że w tym problemie jest więcej niż powiedziałeś). Tak więc Make wywnioskuje, że plik jest aktualny i nie musi być odbudowywany. Nawet jeśli / kiedy Make uruchamia regułę, nie sądzę$$file rzeczy będą działać. Beta

Powiązane pytania