Muszę wygenerować katalog w moim pliku makefile i nie chciałbym, aby komunikat „katalog już istnieje” w kółko, mimo że mogę go łatwo zignorować.
Używam głównie mingw / msys, ale chciałbym czegoś, co działa również w innych powłokach / systemach.
Próbowałem tego, ale nie zadziałało, jakieś pomysły?
ifeq (,$(findstring $(OBJDIR),$(wildcard $(OBJDIR) )))
-mkdir $(OBJDIR)
endif
-p
nie działa w systemie Windows, o co prawdopodobnie chodzi w pytaniu. Nie jestem pewien, jak to kiedykolwiek zostało zaakceptowane.make -p
Unix czy Linux?Patrząc na oficjalną dokumentację marki , oto dobry sposób, aby to zrobić:
Powinieneś zobaczyć tutaj użycie | operator potoku, definiowanie tylko warunku wstępnego zamówienia. Oznacza to, że
$(OBJDIR)
cel powinien istnieć (zamiast być nowszy ), aby zbudować bieżący cel.Zwróć uwagę, że użyłem
mkdir -p
.-p
Flagę dodaną w stosunku do przykładu z dokumentów. Zobacz inne odpowiedzi, aby uzyskać inną alternatywę.źródło
$(OBJDIR)
cel powinien być wcale ” . Sprawdź obecność pliku (i sygnatury czasowe), aby zdecydować, czy musi on zbudować cel. Dlatego tutaj, jeśli$(OBJDIR)
go nie ma, zbuduje go, aby istniał , aby zbudować obecny cel$(OBJS)
, który zostanie utworzony wewnątrz.Możesz użyć polecenia test:
źródło
make -j
) z powodu wyścigu między testowaniem istnienia katalogu a jego utworzeniem. Jedno zadanie może sprawdzić, czy go tam nie ma, ale zanim je utworzy, inne zadanie tworzy katalog. Wtedy, gdy pierwszy spróbuje to zrobić, zakończy się niepowodzeniem, ponieważ katalog już istnieje. Najlepszym rozwiązaniem w tym przypadku jest użycie tylko warunków wstępnych zamówienia, jak wspomniano w odpowiedzi @ TeKa (która powinna być odpowiedzią zaakceptowaną).Oto sztuczka, której używam w GNU make do tworzenia katalogów wyjściowych kompilatora. Najpierw zdefiniuj tę zasadę:
Następnie uzależnij wszystkie pliki, które trafiają do katalogu, od pliku .d w tym katalogu:
Zwróć uwagę na użycie $ <zamiast $ ^.
Wreszcie, zapobiegaj automatycznemu usuwaniu plików .d:
Pominięcie pliku .d i bezpośrednie uzależnienie od katalogu nie zadziała, ponieważ czas modyfikacji katalogu jest aktualizowany za każdym razem, gdy plik jest zapisywany w tym katalogu, co wymusiłoby przebudowę przy każdym wywołaniu make.
źródło
Jeśli posiadanie już istniejącego katalogu nie stanowi dla ciebie problemu, możesz po prostu przekierować stderr dla tego polecenia, pozbywając się komunikatu o błędzie:
źródło
Wewnątrz pliku makefile:
źródło
W systemie Windows
W systemie Unix | Linux
źródło
/bin/sh: 1: Syntax error: end of file unexpected (expecting "then")
źródło
Który działa również dla wielu katalogów, np.
Dodanie
$(OBJDIR)
jako pierwszego celu działa dobrze.źródło
Działa pod mingw32 / msys / cygwin / linux
źródło
Jeśli jawnie zignorujesz kod powrotu i zrzucisz strumień błędów, Twój program zignoruje błąd, jeśli wystąpi:
Nie powinno to powodować zagrożenia wyścigowego w przypadku równoległej marki - ale nie testowałem tego dla pewności.
źródło
Trochę prostsza niż odpowiedź Larsa:
i ogólna zasada:
Brak plików dotykowych do czyszczenia lub tworzenia. PRECIOUS :-)
Jeśli chcesz zobaczyć kolejną małą ogólną sztuczkę gmake lub jeśli interesuje Cię nierekurencyjne make z minimalnym rusztowaniem, możesz zechcieć zapoznać się z dwoma innymi tanimi sztuczkami gmake i innymi postami związanymi z make na tym blogu.
źródło