Pisanie Makefile'a

0

Witam

Mam pliki rozsiane po kilku katalogach. Umiem sobie napisać makefile'a, że się ładnie kompiluje, ale nie umiem zrobić jednej rzeczy.

Otóż w samych plikach źródłowych programu, muszę inkludować pliki pisząc coś w postaci include "../katalog/plik.h"

Trochę to wkurzające, poza tym, gdybym sobie nagle stwierdził, że chcę zmienić katalogi, to musiałbym pogrzebać w plikach.

Kombinowałem w makefilu z opcją -I ale jakoś też działać nie chce :/

Jeśli ktoś z Was ma pomysł lub wie jak to zrobić, proszę o pomoc :)

0

Chyba źle kombinowałeś z opcją -I...
np. taki makefile:

MY_DIR=c:/programy/moje_inc
#...
siakis_plik.o: siakis_plik.c
gcc -c -I$(MY_DIR) siakis_plik.c

0

Mój Makefile wygląda dokładnie tak:

CXX =  g++

CFLAGS = -Wall -O3 -ansi  -I. -I $(DIR1) -I $(DIR2) -I $(DIR3) -I $(DIR4) -I $(DIR5) -I ../$(DIR1) -I ../$(DIR2) -I ../$(DIR3) -I ../$(DIR4) -I ../$(DIR5)
DIR1 = drzwi/
DIR2 = budynek/
DIR3 = obiekty/
DIR4 = main/
DIR5 = ncurses/

kolekcjoner: main.o $(DIR1)DrzwiZszyfrem.o $(DIR1)DrzwiZwykle.o $(DIR1)Drzwi.o $(DIR2)Komnata.o $(DIR2)Muzeum.o $(DIR3)Wiezienie.o $(DIR3)Zlodziej.o $(DIR4)TablicaRekordow.o $(DIR4)Gra.o $(DIR5)Okno.o $(DIR5)OknoGlowne.o $(DIR5)OknoGra.o $(DIR5)MenuWyboru.o

	$(CXX) $(CFLAGS) -o kolekcjoner main.o $(DIR1)DrzwiZszyfrem.o $(DIR1)DrzwiZwykle.o $(DIR1)Drzwi.o $(DIR2)Komnata.o $(DIR2)Muzeum.o $(DIR3)Wiezienie.o $(DIR3)Zlodziej.o $(DIR4)TablicaRekordow.o $(DIR4)Gra.o $(DIR5)Okno.o $(DIR5)OknoGlowne.o $(DIR5)OknoGra.o $(DIR5)MenuWyboru.o -lncurses -lmenu 

main.o: main.cc $(DIR1)DrzwiZszyfrem.cc $(DIR1)DrzwiZszyfrem.h $(DIR1)DrzwiZwykle.cc $(DIR1)DrzwiZwykle.h $(DIR1)Drzwi.cc $(DIR1)Drzwi.h $(DIR2)Komnata.cc $(DIR2)Komnata.h $(DIR2)Muzeum.cc $(DIR2)Muzeum.h $(DIR3)Wiezienie.cc $(DIR3)Wiezienie.h $(DIR3)Zlodziej.cc $(DIR3)Zlodziej.h $(DIR4)TablicaRekordow.cc $(DIR4)TablicaRekordow.h $(DIR4)Gra.cc $(DIR4)Gra.h $(DIR5)Okno.cc $(DIR5)OknoGra.cc $(DIR5)OknoGlowne.cc $(DIR5)Okno.h $(DIR5)OknoGlowne.h $(DIR5)OknoGra.h $(DIR5)MenuWyboru.h $(DIR5)MenuWyboru.cc

	$(CXX) $(CFLAGS) -c main.cc

Okno.o: $(DIR1)Okno.cc $(DIR1)Okno.h

	$(CXX) $(CFLAGS) -c $(DIR5)Okno.cc

OknoGlowne.o: $(DIR1)OknoGlowne.cc $(DIR1)OknoGlowne.h

	$(CXX) $(CFLAGS) -c $(DIR5)OknoGlowne.cc

OknoGra.o: $(DIR1)OknoGra.cc $(DIR1)OknoGra.h

	$(CXX) $(CFLAGS) -c $(DIR5)OknoGra.cc
	

DrzwiZszyfrem.o: $(DIR1)DrzwiZszyfrem.cc $(DIR1)DrzwiZszyfrem.h

	$(CXX) $(CFLAGS) -c $(DIR1)DrzwiZszyfrem.cc	

DrzwiZwykle.o: $(DIR1)DrzwiZwykle.cc $(DIR1)DrzwiZwykle.h

	$(CXX) $(CFLAGS) -c $(DIR1)DrzwiZwykle.cc

Drzwi.o:$(DIR1)Drzwi.cc $(DIR1)Drzwi.h

	$(CXX) $(CFLAGS) -c $(DIR1)Drzwi.cc

Komnata.o: $(DIR2)Komnata.cc $(DIR2)Komnata.h

	$(CXX) $(CFLAGS) -c $(DIR2)Komnata.cc	


Muzeum.o: $(DIR2)Muzeum.cc $(DIR2)Muzeum.h

	$(CXX) $(CFLAGS) -c $(DIR2)Muzeum.cc	

Wiezienie.o: $(DIR3)Wiezienie.cc $(DIR3)Wiezienie.h

	$(CXX) $(CFLAGS) -c $(DIR3)Wiezienie.cc



Zlodziej.o: $(DIR3)Zlodziej.cc $(DIR3)Zlodziej.h

	$(CXX) $(CFLAGS) -c $(DIR3)Zlodziej.cc

TablicaRekordow.o: $(DIR4)TablicaRekordow.cc $(DIR4)TablicaRekordow.h

	$(CXX) $(CFLAGS) -c $(DIR4)TablicaRekordow.cc	

Gra.o: $(DIR4)Gra.cc $(DIR4)Gra.h

	$(CXX) $(CFLAGS) -c $(DIR4)Muzeum.cc

MenuWyboru.o: $(DIR4)MenuWyboru.cc $(DIR4)MenuWyboru.h

	$(CXX) $(CFLAGS) -c $(DIR4)MenuWyboru.cc

clean:
	-@rm -f */*~ */*.o *.o *~

A przy uruchomieniu pojawia się:

g++ -Wall -O3 -ansi  -I. -I drzwi/ -I budynek/ -I obiekty/ -I main/ -I ncurses/ -I ../drzwi/ -I ../budynek/ -I ../obiekty/ -I ../main/ -I ../ncurses/ -c main.ccg++    -c -o drzwi/DrzwiZszyfrem.o drzwi/DrzwiZszyfrem.cc
g++    -c -o drzwi/DrzwiZwykle.o drzwi/DrzwiZwykle.cc
g++    -c -o drzwi/Drzwi.o drzwi/Drzwi.cc
g++    -c -o budynek/Komnata.o budynek/Komnata.cc
In file included from budynek/Komnata.cc:15:
budynek/Komnata.h:17:19: Drzwi.h: Nie ma takiego pliku ani katalogu
budynek/Komnata.h:19:18: Okno.h: Nie ma takiego pliku ani katalogu
In file included from budynek/Komnata.cc:15:
budynek/Komnata.h:22: error: expected class-name before '{' token
budynek/Komnata.h:33: error: `Drzwi' was not declared in this scope
budynek/Komnata.h:33: error: template argument 1 is invalid
budynek/Komnata.h:33: error: template argument 2 is invalid
budynek/Komnata.h:33: error: ISO C++ forbids declaration of `DrzwiKomnaty' with no type
budynek/Komnata.cc:16:27: DrzwiZszyfrem.h: Nie ma takiego pliku ani katalogu
budynek/Komnata.cc:17:25: DrzwiZwykle.h: Nie ma takiego pliku ani katalogu
budynek/Komnata.cc: In member function `bool Komnata::wypiszOpcje(int*, const int&, unsigned int*)':
budynek/Komnata.cc:29: error: `info' undeclared (first use this function)
budynek/Komnata.cc:29: error: (Each undeclared identifier is reported only once for each function it appears in.)
budynek/Komnata.cc:46: error: `pobierzZnak' undeclared (first use this function)budynek/Komnata.cc: In constructor `Komnata::Komnata()':
budynek/Komnata.cc:76: error: request for member `insert' in `((Komnata*)this)->Komnata::DrzwiK', which is of non-class type `int'
budynek/Komnata.cc:76: error: request for member `end' in `((Komnata*)this)->Komnata::DrzwiK', which is of non-class type `int'
budynek/Komnata.cc:76: error: `DrzwiZSzyfrem' has not been declared
budynek/Komnata.cc:78: error: request for member `insert' in `((Komnata*)this)->Komnata::DrzwiK', which is of non-class type `int'
budynek/Komnata.cc:78: error: request for member `end' in `((Komnata*)this)->Komnata::DrzwiK', which is of non-class type `int'
budynek/Komnata.cc:78: error: `DrzwiZwykle' has not been declared
budynek/Komnata.cc: In destructor `Komnata::~Komnata()':
budynek/Komnata.cc:85: error: `DrzwiKomnaty' is not a class or namespace
budynek/Komnata.cc:85: error: `iterator' undeclared (first use this function)
budynek/Komnata.cc:85: error: expected `;' before "iter"
budynek/Komnata.cc:86: error: `iter' undeclared (first use this function)
budynek/Komnata.cc:86: error: request for member `end' in `((Komnata*)this)->Komnata::DrzwiK', which is of non-class type `int'
budynek/Komnata.cc:88: error: request for member `clear' in `((Komnata*)this)->Komnata::DrzwiK', which is of non-class type `int'
budynek/Komnata.cc: In member function `bool Komnata::wykonajAkcje(int, bool*, int*, unsigned int*)':
budynek/Komnata.cc:96: error: invalid types `int[int]' for array subscript
budynek/Komnata.cc:99: error: invalid types `int[int]' for array subscript
budynek/Komnata.cc:102: error: invalid types `int[int]' for array subscript
budynek/Komnata.cc:105: error: invalid types `int[int]' for array subscript
budynek/Komnata.cc: In member function `void Komnata::umiescObraz(int)':
budynek/Komnata.cc:122: error: invalid types `int[int]' for array subscript
make: *** [budynek/Komnata.o] Błąd 1

3 pierwsze pliki kompilują się bo są w tym samym katalogu, natomiast plik Komnata.cc jest w innym katalogu i nie widzi już tych poczatkowych plików "drzwi", dlatego też na razie zrobienie #include "Drzwi.h" jest niemożliwe - muszę zrobić #include "../drzwi/Drzwi.h"

Czekam na pomoc :)

0

kompilator nie wie, że chcesz zrobić up-dir ("..") z katalogu, który TY chcesz ;-P

BASE_DIR=E:/Marcin/temp/f
MY_DIR=inc

plik.o: plik.cpp
gcc -c -I$(BASE_DIR)/$(MY_DIR) plik.cpp

0

Ale zauważ, co mam we flagach:

CFLAGS = -Wall -O3 -ansi -I. -I $(DIR1) -I $(DIR2) -I $(DIR3) -I $(DIR4) -I $(DIR5) -I ../$(DIR1) -I ../$(DIR2) -I ../$(DIR3) -I ../$(DIR4) -I ../$(DIR5)
czyli mam też właśnie przejście o jeden wyżej i wyjście do katalogu.

A na takie rozwiązanie jakie Ty proponujesz, nie mogę sobie pozwolić, bo to by znaczyło, że jeśli program zostanie przekopiowany do innego katalogu, to kompilacja będzie niemożliwa, co nie jest chyba zbyt dobrym rozwiązaniem, a poza tym, że to jest program na zaliczenie, to nawet gdybym tak chciał zrobić, to by nie wypadało ;)

0

Ale przeginasz w drugą stronę z tymi katalogami, co za dużo to niezdrowo. Ustal strukturę drzewa katalogów w projekcie i sie jej trzymaj, np.
/src
/include
/docs
/bin
No ja nie wiem co Ci szkodzi napisac "../include/plik.h" ?? Przerzucając na inny komputer cały projekt masz wszystko OK.

Zauważ, że scieżki do bibliotek standardowych (i niestandardowych) w systemie są przeważnie już ustawione.
A właśnie przez te ../$(dir) się tego nie da kompilować

0

Szkodzić oczywiście nie szkodzi, ale pewnie da się to jakoś zrobić - pytanie tylko jak :)
Chciałem po prostu, żeby to ładniej wyglądało i że w razie zmiany np. nazwy katalogu (mówię tylko teoretycznie, bo nie mam zamiru nic zmieniać), wystarczyły tylko zmiany w Makefile'u ...

0

Szkodzić oczywiście nie szkodzi, ale pewnie da się to jakoś zrobić - pytanie tylko jak :)
Chciałem po prostu, żeby to ładniej wyglądało i że w razie zmiany np. nazwy katalogu (mówię tylko teoretycznie, bo nie mam zamiru nic zmieniać), wystarczyły tylko zmiany w Makefile'u ...

Qrna no też właśnie po to jest BASE_DIR we wcześniejszym poście.
Wtedy pliki .h widzą się przynajmniej nawzajem, bo są konkretne ścieżki przeszukiwane.

Może potrzebujesz użyć opcji make -C (change directory)?

0

Hehe, nie do końca się jeszcze zrozumieliśmy. Tego BASE_DIR mieć nie chcę, ale chodziło mi o to, że gdybym stwierdził , że np. katalog oznaczany w maku jako DIR1 ma się teraz nazywać np. cos, to wtedy musiałbym dokonać zmiany w makefilu, ale oprócz tego, ponieważ we wszystkich innych plikach miałbym #include "../dotychczasowaNazwa/plik.h", to musiałbym pozmieniać w tych plikach na #include "../cos.plik.h".

Mam nadzieję, że teraz rozumiesz mój punkt widzenia :)

Chciałem zrobić tak, że muszą się zgadzać tylko nazwy plików, a nazwy katalogów są niejako dyktowane przez make'a. Może coś jeszcze wykombinuję. Ale jak mówiłem, jak się nie uda, to tragedii nie będzie :)

0

Na to samo wychodzi:
albo make -C i tylko podkatalogi w makefile'u
albo base_dir + podkatalogi w makefile'u
Tak czy tak masz podkatalogi ustalane w makefile'u, przez '../' to niezbyt sie uda...

0

Przyznam się, że nie za bardzo wiem jak tej opcji -C używać, chociaż mam przed sobą manuala? Może wiesz coś więcej o tym i możesz wyjaśnić? W razie czego z góry dzięki, a jak nie, to w wolnej chwili jeszcze pokombinuję...

0

wywal spacje pomiedzy -I a sciezka:

-I../include

a te katalogi zadeklaruj wczesniej niz CFLAGS...

moze zadziala

0

Niestety to nic nie zmienia :(

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.