Mam projekt, w którym struktura katalogów wygląda następująco:
$projectroot
|
+---------------+----------------+
| | |
part1/ part2/ part3/
| | |
+------+-----+ +---+----+ +---+-----+
| | | | | | |
data/ src/ inc/ src/ inc/ src/ inc/
Jak napisać plik makefile, który byłby w części / src (lub gdziekolwiek naprawdę), który mógłby w części zawierać / linkować pliki źródłowe c / c ++? / Src?
Czy mogę zrobić coś takiego jak -I $ projectroot / part1 / src -I $ projectroot / part1 / inc -I $ projectroot / part2 / src ...
Jeśli to zadziała, czy jest na to łatwiejszy sposób. Widziałem projekty, w których w każdej odpowiadającej części znajduje się plik makefile? lornetka składana. [w tym poście użyłem znaku zapytania jak w składni basha]
recursive invocation
, która jest dość elegancka.Odpowiedzi:
Tradycyjnym sposobem jest mieć
Makefile
w każdym z podkatalogów (part1
,part2
etc.) pozwalających budować je niezależnie. Co więcej,Makefile
w katalogu głównym projektu, który wszystko buduje. „Katalog główny”Makefile
wyglądałby mniej więcej tak:Ponieważ każda linia w make target jest uruchamiana we własnej powłoce, nie ma potrzeby martwić się o przechodzenie z kopii zapasowej drzewa katalogów lub do innych katalogów.
Proponuję zajrzeć do sekcji 5.7 podręcznika GNU make ; to bardzo pomocne.
źródło
+$(MAKE) -C part1
itd. Dzięki temu kontrola zadań programu Make może działać w podkatalogach.Jeśli masz kod w jednym podkatalogu zależny od kodu w innym podkatalogu, prawdopodobnie lepiej będzie, jeśli masz pojedynczy plik makefile na najwyższym poziomie.
Pełne uzasadnienie można znaleźć w artykule Rekursywne uznawane za szkodliwe , ale zasadniczo chcesz mieć pełne informacje potrzebne do podjęcia decyzji, czy plik musi zostać odbudowany, a nie będzie, jeśli podasz mu tylko jedną trzecią Twój projekt.
Wydaje się, że powyższy link jest nieosiągalny. Ten sam dokument jest dostępny tutaj:
źródło
Przydać się może opcja VPATH, która mówi make, w jakich katalogach szukać kodu źródłowego. Nadal potrzebujesz opcji -I dla każdej ścieżki dołączania. Przykład:
Spowoduje to automatyczne wyszukanie pasujących plików partXapi.cpp w dowolnym z katalogów określonych przez VPATH i skompilowanie ich. Jest to jednak bardziej przydatne, gdy katalog src jest podzielony na podkatalogi. Z tego, co opisujesz, jak powiedzieli inni, prawdopodobnie lepiej będzie, jeśli masz plik makefile dla każdej części, zwłaszcza jeśli każda część może być samodzielna.
źródło
VPATH=..
pracowało dla mnie!Możesz dodać reguły do głównego pliku Makefile, aby skompilować niezbędne pliki cpp w innych katalogach. Poniższy przykład pliku Makefile powinien być dobrym początkiem do przeniesienia Cię tam, gdzie chcesz.
źródło
Jeśli źródła są rozrzucone w wielu folderach i ma sens posiadanie indywidualnych plików Makefile to jak wcześniej zasugerowano, rekurencyjne make jest dobrym podejściem, ale w przypadku mniejszych projektów łatwiej jest wypisać wszystkie pliki źródłowe w Makefile wraz z ich względną ścieżką do pliku Makefile w ten sposób:
Mogę wtedy ustawić w
VPATH
ten sposób:Następnie buduję obiekty:
Teraz zasada jest prosta:
Tworzenie wyniku jest jeszcze łatwiejsze:
Można nawet
VPATH
zautomatyzować generowanie poprzez:Lub korzystając z faktu, że
sort
usuwa duplikaty (chociaż nie powinno to mieć znaczenia):źródło
Myślę, że lepiej jest zauważyć, że używanie Make (rekurencyjnego lub nie) jest czymś, czego zwykle warto unikać, ponieważ w porównaniu z dzisiejszymi narzędziami trudno jest się go nauczyć, utrzymać i skalować.
To wspaniałe narzędzie, ale jego bezpośrednie użycie należy uznać za przestarzałe w 2010+.
Chyba że, oczywiście, pracujesz w specjalnym środowisku, np. Z projektem starszego typu itp.
Użyj IDE, CMake lub, jeśli masz twardy rdzeń, Autotools .
(zredagowane z powodu głosów przeciw, ty Honza za wskazanie)
źródło
Post RC był BARDZO przydatny. Nigdy nie myślałem o użyciu funkcji $ (dir $ @), ale zrobiła dokładnie to, czego potrzebowałem.
W parentDir umieść kilka katalogów z plikami źródłowymi: dirA, dirB, dirC. Różne pliki zależą od plików obiektowych w innych katalogach, więc chciałem móc utworzyć jeden plik z jednego katalogu i sprawić, by zależało od niego, wywołując plik makefile powiązany z tą zależnością.
Zasadniczo utworzyłem jeden plik Makefile w parentDir, który miał (między innymi) ogólną regułę podobną do RC:
Każdy podkatalog zawierał plik makefile wyższego poziomu w celu dziedziczenia tej ogólnej reguły. W pliku Makefile każdego podkatalogu napisałem niestandardową regułę dla każdego pliku, dzięki czemu mogłem śledzić wszystko, od czego zależał każdy plik.
Ilekroć potrzebowałem utworzyć plik, użyłem (zasadniczo) tej reguły, aby rekurencyjnie utworzyć jakiekolwiek / wszystkie zależności. Idealny!
UWAGA: istnieje narzędzie o nazwie „makepp”, które wydaje się wykonywać to zadanie jeszcze bardziej intuicyjnie, ale ze względu na przenośność i niezależność od innego narzędzia, zdecydowałem się to zrobić w ten sposób.
Mam nadzieję że to pomoże!
źródło
Rekurencyjne użycie Make
Pozwala to na
make
podział na zadania i wykorzystanie wielu rdzeniźródło
make -j4
?make
w ogóle sterować pracą. W przypadku wykonywania oddzielnego procesu make nie podlega on kontroli zadań.Szukałem czegoś takiego i po kilku próbach i upadkach tworzę własny plik makefile, wiem, że to nie jest „idiomatyczny sposób”, ale to początek zrozumienia make i to działa dla mnie, może mógłbyś spróbować w swoim projekcie.
Wiem, że to proste i dla niektórych ludzi moje flagi są błędne, ale jak powiedziałem, jest to mój pierwszy plik Makefile, w którym można skompilować mój projekt w wielu katalogach i połączyć je wszystkie razem, aby utworzyć mój bin.
Przyjmuję sugestie: D
źródło
Proponuję użyć
autotools
://##
Umieść wygenerowane pliki obiektów (.o) w tym samym katalogu, co ich pliki źródłowe, aby uniknąć kolizji, gdy używany jest nierekurencyjny make.po prostu dołączając go
Makefile.am
do innych dość prostych rzeczy.Oto samouczek .
źródło