C++ kompilacja klas makefile


(marcinkk) #1

witam, chciałbym prosić o pomoc jak zmodyfikować plik Makefile aby kompilował programy z klasami jeżeli mam je w innym pliku. Jeżeli mam program jedno plikowy kompilacja przez make działa bez problemu. Gdy tworze programy i klasy w osobnych plikach to mam komunikat o błędzie undefined reference to `Window::Window(std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&, int, int)'
Jeżeli kompiluje program bez użycia pliku Makefile to nie ma problemu. Niżej treść pliku Makefile:
CXX = clang++

INC=

LIB= -lSDL2

CFLAGS = -Wall -Wextra -pedantic -g -std=c++14

SRCS = $(wildcard *.cpp)

PROGS = $(patsubst %.cpp,%,$(SRCS))

all: $(PROGS)

%: %.cpp
$(CXX) $(CFLAGS) $(INC) $(LIB) -o $@ $<

.PHONY: clean

clean:
@echo usuwam gotowe pliki
rm -f $(PROGS)


(tomms) #2

Kompilowanie programu składającego się z wielu plików źródłowych polega na kompilacji (bez linkowania tzn z parametrm -c) samych plików źródłowych i na końcu na zlinkowaniu ich w gotowy program wynikowy, czyli:
clang++ -c mojplik.cpp
clang++ -c innyplik.cpp
clang++ -o wynikowyprogram mojplik.o innyplik.o

Poniżej poprawiony Makefile

CXX = clang++

INC=

#LIB= -lSDL2
LIB=

CFLAGS = -Wall -Wextra -pedantic -g -std=c++14

SRCS = $(wildcard *.cpp)
HEADERS = $(wildcard *.h)
PROGS = $(patsubst %.cpp,%.o,$(SRCS))
PROGRAMNAME = mojprogram


all: $(PROGRAMNAME)

$(PROGRAMNAME): $(PROGS)
	$(CXX) $(CFLAGS) $(INC) $(LIB) -o $(PROGRAMNAME) $(PROGS)

%.o: %.cpp $(HEADERS)
	$(CXX) -c $(CFLAGS) $(INC) -o $@ $<

.PHONY: clean

clean:
	@echo usuwam gotowe pliki
	rm -f $(PROGS)
	rm -f $(PROGRAMNAME)

Zauważ że jako zależność dla plików .o dałem wszystkie pliki nagłówkowe. To taki szybki sposób budowania zależności między plikami mający tą negatywną konsekwencje że jak zmodyfikujemy jakikolwiek plik nagłówkowy to przebudowany zostanie cały program. Jako zadanie domowe zostawiam zapoznanie się z narzędziem makedepend które przeskanuje pliki źródłowe i stworzy prawidłową liste zależności.


(marcinkk) #3

jak mam używać twojej wersji pliku makefile??


(tomms) #4

Przejdź do katalogu z projektem, zapisz tam plik Makefile i wydaj polecenie ‘make’.


(marcinkk) #5

mam taki błąd:

ksardas@ksardas-NC-V3-371-54TF:~/Dokumenty/programowanie/progGL$ make
clang++ -c -Wall -Wextra -pedantic -g -std=c++14 -o prog0002.o prog0002.cpp
prog0002.cpp:3:14: warning: unused parameter ‘argc’ [-Wunused-parameter]
int main(int argc, char **argv)
^
prog0002.cpp:3:27: warning: unused parameter ‘argv’ [-Wunused-parameter]
int main(int argc, char **argv)
^
2 warnings generated.
clang++ -c -Wall -Wextra -pedantic -g -std=c++14 -o prog0001.o prog0001.cpp
prog0001.cpp:5:14: warning: unused parameter ‘argc’ [-Wunused-parameter]
int main(int argc, char **argv)
^
prog0001.cpp:5:27: warning: unused parameter ‘argv’ [-Wunused-parameter]
int main(int argc, char **argv)
^
2 warnings generated.
clang++ -c -Wall -Wextra -pedantic -g -std=c++14 -o window.o window.cpp
clang++ -Wall -Wextra -pedantic -g -std=c++14 -lSDL2 -o mojprogram prog0002.o prog0001.o window.o
prog0001.o: In function main': /home/ksardas/Dokumenty/programowanie/progGL/prog0001.cpp:6: multiple definition ofmain’
prog0002.o:/home/ksardas/Dokumenty/programowanie/progGL/prog0002.cpp:4: first defined here
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Makefile:12: polecenia dla obiektu ‘mojprogram’ nie powiodły się
make: *** [mojprogram] Błąd 1


(tomms) #6

Masz kilkukrotnie zdefiniowaną funkcję main(). Powyższy Makefile jest przykładem do kompilacji jeśli w jednym katalogu masz jeden program. Jeśli chcesz kompilować kilka programów to albo rozdziel te programy pomiędzy katalogi i do każdego katalogu daj osobny Makefile albo zmodyfikuj powyższy Makefile. Ja nie wiem które pliki u ciebie co oznaczają więc więcej nie pomogę.


(marcinkk) #7

tak mam kilka funkcji main(), dlatego ponieważ chcę kompilować wiele programów w jednym katalogu z pomocą tego pliku Makefile.