Makefile: Problem beim compilieren von mehreren Quelldatein
-
Hallo an alle,
Ich wollte letztens eine Makefile schreiben die mehrere Dateien linkt und compiliert. Da ich vor kurzem noch keine Ahnung von Makefiles unter Linux hatte, habe ich mich in Teile vom GNU manual make eingelesen. Kapitel 2 und 3 habe ich gelesen. http://www.gnu.org/software/make/manual/make.html#Simple-Makefile Da steht ein bischen was, wie man mehrer Quelldateien verwaltet.
Wenn ich die 2 Header Dateien und die main.cpp in eine IDE (QT Creator) lade und dann mit -std=c++11 und -lncurses compiliere, gibt es keine Fehlermeldung und ich kann das Programm(space invaders mit ncurses) im Terminal ausführen.
Mein Ordner in denen sich die Quelldatein befinden sieht wie folgt aus:jo@jo-desktop:~/Dokumente/ncurses_tutorial/my/space_invaders$ ls -la insgesamt 56 drwxrwxr-x 2 jo jo 4096 Jan 25 18:16 . drwxrwxr-x 19 jo jo 4096 Dez 30 15:16 .. -rw-rw-r-- 1 jo jo 4640 Jan 9 19:20 bullet.hpp -rw-rw-r-- 1 jo jo 6996 Jan 24 23:44 enemy.hpp -rw-rw-r-- 1 jo jo 1741 Jan 11 18:03 main.cpp -rw-rw-r-- 1 jo jo 234 Jan 25 17:53 Makefile -rw-rw-r-- 1 jo jo 134 Dez 30 15:16 space_invaders.pro -rw-rw-r-- 1 jo jo 17919 Jan 25 02:28 space_invaders.pro.user jo@jo-desktop:~/Dokumente/ncurses_tutorial/my/space_invaders$
Hier die includes der einzelnen Dateien:
enemy.hpp#include <ncurses.h> #include <vector> #include <chrono>
bullet.hpp
#include <chrono> #include <ncurses.h> #include <enemy.hpp> #include <vector>
main.cpp
#include <ncurses.h> #include <iostream> #include <bullet.hpp>
Meine Makefile sieht wie folgt aus:
CC = g++ TARGET = space_invaders LIBS = -lncurses $(TARGET) : main.o $(CC) -o $(TARGET) main.o $(LIBS) -std=c++11 main.o : main.cpp enemy.hpp bullet.hpp $(CC) -c main.cpp $(LIBS) -std=c++11 clean : rm -f main.o
Hier mal die Ausgabe der Makefile:
jo@jo-desktop:~/Dokumente/ncurses_tutorial/my/space_invaders$ make g++ -c main.cpp -lncurses -std=c++11 main.cpp:3:22: Schwerwiegender Fehler: bullet.hpp: Datei oder Verzeichnis nicht gefunden Kompilierung beendet. make: *** [main.o] Fehler 1 jo@jo-desktop:~/Dokumente/ncurses_tutorial/my/space_invaders$
Zur Vollständigkeit habe ich hier noch die Mafile die mir Qt Creator sozusagen generiert. Die eigentlichen Quelldateien befinden sich nicht im gleichen Ordner worin sich auch die Makefile befindet!
Makefile############################################################################# # Makefile for building: space_invaders # Generated by qmake (3.0) (Qt 5.0.1) on: Sa. Jan. 25 18:33:03 2014 # Project: ../space_invaders/space_invaders.pro # Template: app # Command: /usr/lib/x86_64-linux-gnu/qt5/bin/qmake -spec linux-g++-64 CONFIG+=debug CONFIG+=declarative_debug CONFIG+=qml_debug LIBS+=-lncurses CONFIG+=c++11 -o Makefile ../space_invaders/space_invaders.pro ############################################################################# MAKEFILE = Makefile ####### Compiler, tools and options CC = gcc CXX = g++ DEFINES = -DQT_QML_DEBUG -DQT_DECLARATIVE_DEBUG CFLAGS = -m64 -pipe -g -Wall -W -fPIE $(DEFINES) CXXFLAGS = -m64 -pipe -g -std=c++0x -Wall -W -fPIE $(DEFINES) INCPATH = -I/usr/share/qt5/mkspecs/linux-g++-64 -I../space_invaders -I. LINK = g++ LFLAGS = -m64 LIBS = $(SUBLIBS) -lncurses AR = ar cqs RANLIB = QMAKE = /usr/lib/x86_64-linux-gnu/qt5/bin/qmake TAR = tar -cf COMPRESS = gzip -9f COPY = cp -f SED = sed COPY_FILE = cp -f COPY_DIR = cp -f -R STRIP = strip INSTALL_FILE = install -m 644 -p INSTALL_DIR = $(COPY_DIR) INSTALL_PROGRAM = install -m 755 -p DEL_FILE = rm -f SYMLINK = ln -f -s DEL_DIR = rmdir MOVE = mv -f CHK_DIR_EXISTS= test -d MKDIR = mkdir -p ####### Output directory OBJECTS_DIR = ./ ####### Files SOURCES = ../space_invaders/main.cpp OBJECTS = main.o DIST = /usr/share/qt5/mkspecs/features/spec_pre.prf \ /usr/share/qt5/mkspecs/common/shell-unix.conf \ /usr/share/qt5/mkspecs/common/unix.conf \ /usr/share/qt5/mkspecs/common/linux.conf \ /usr/share/qt5/mkspecs/common/gcc-base.conf \ /usr/share/qt5/mkspecs/common/gcc-base-unix.conf \ /usr/share/qt5/mkspecs/common/g++-base.conf \ /usr/share/qt5/mkspecs/common/g++-unix.conf \ /usr/share/qt5/mkspecs/qconfig.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_bootstrap.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_concurrent.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_core.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_dbus.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_gui.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_network.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_opengl.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_platformsupport.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_printsupport.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_qml.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_qmldevtools.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_qmltest.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_quick.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_quickparticles.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_sql.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_testlib.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_widgets.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_xml.pri \ /usr/share/qt5/mkspecs/features/qt_functions.prf \ /usr/share/qt5/mkspecs/features/qt_config.prf \ /usr/share/qt5/mkspecs/linux-g++-64/qmake.conf \ /usr/share/qt5/mkspecs/features/spec_post.prf \ /usr/share/qt5/mkspecs/features/exclusive_builds.prf \ /usr/share/qt5/mkspecs/features/default_pre.prf \ /usr/share/qt5/mkspecs/features/unix/default_pre.prf \ /usr/share/qt5/mkspecs/features/debug.prf \ /usr/share/qt5/mkspecs/features/default_post.prf \ /usr/share/qt5/mkspecs/features/shared.prf \ /usr/share/qt5/mkspecs/features/c++11.prf \ /usr/share/qt5/mkspecs/features/qml_debug.prf \ /usr/share/qt5/mkspecs/features/declarative_debug.prf \ /usr/share/qt5/mkspecs/features/unix/gdb_dwarf_index.prf \ /usr/share/qt5/mkspecs/features/warn_on.prf \ /usr/share/qt5/mkspecs/features/wayland-scanner.prf \ /usr/share/qt5/mkspecs/features/testcase_targets.prf \ /usr/share/qt5/mkspecs/features/exceptions.prf \ /usr/share/qt5/mkspecs/features/yacc.prf \ /usr/share/qt5/mkspecs/features/lex.prf \ ../space_invaders/space_invaders.pro \ ../space_invaders/space_invaders.pro QMAKE_TARGET = space_invaders DESTDIR = TARGET = space_invaders first: all ####### Implicit rules .SUFFIXES: .o .c .cpp .cc .cxx .C .cpp.o: $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<" .cc.o: $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<" .cxx.o: $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<" .C.o: $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<" .c.o: $(CC) -c $(CFLAGS) $(INCPATH) -o "$@" "$<" ####### Build rules all: Makefile $(TARGET) $(TARGET): $(OBJECTS) $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJCOMP) $(LIBS) { test -n "$(DESTDIR)" && DESTDIR="$(DESTDIR)" || DESTDIR=.; } && test $$(gdb --version | sed -e 's,[^0-9]\+\([0-9]\)\.\([0-9]\).*,\1\2,;q') -gt 72 && gdb --nx --batch --quiet -ex 'set confirm off' -ex "save gdb-index $$DESTDIR" -ex quit '$(TARGET)' && test -f $(TARGET).gdb-index && objcopy --add-section '.gdb_index=$(TARGET).gdb-index' --set-section-flags '.gdb_index=readonly' '$(TARGET)' '$(TARGET)' && rm -f $(TARGET).gdb-index || true Makefile: ../space_invaders/space_invaders.pro /usr/share/qt5/mkspecs/linux-g++-64/qmake.conf /usr/share/qt5/mkspecs/features/spec_pre.prf \ /usr/share/qt5/mkspecs/common/shell-unix.conf \ /usr/share/qt5/mkspecs/common/unix.conf \ /usr/share/qt5/mkspecs/common/linux.conf \ /usr/share/qt5/mkspecs/common/gcc-base.conf \ /usr/share/qt5/mkspecs/common/gcc-base-unix.conf \ /usr/share/qt5/mkspecs/common/g++-base.conf \ /usr/share/qt5/mkspecs/common/g++-unix.conf \ /usr/share/qt5/mkspecs/qconfig.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_bootstrap.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_concurrent.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_core.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_dbus.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_gui.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_network.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_opengl.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_platformsupport.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_printsupport.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_qml.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_qmldevtools.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_qmltest.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_quick.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_quickparticles.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_sql.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_testlib.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_widgets.pri \ /usr/share/qt5/mkspecs/modules/qt_lib_xml.pri \ /usr/share/qt5/mkspecs/features/qt_functions.prf \ /usr/share/qt5/mkspecs/features/qt_config.prf \ /usr/share/qt5/mkspecs/linux-g++-64/qmake.conf \ /usr/share/qt5/mkspecs/features/spec_post.prf \ /usr/share/qt5/mkspecs/features/exclusive_builds.prf \ /usr/share/qt5/mkspecs/features/default_pre.prf \ /usr/share/qt5/mkspecs/features/unix/default_pre.prf \ /usr/share/qt5/mkspecs/features/debug.prf \ /usr/share/qt5/mkspecs/features/default_post.prf \ /usr/share/qt5/mkspecs/features/shared.prf \ /usr/share/qt5/mkspecs/features/c++11.prf \ /usr/share/qt5/mkspecs/features/qml_debug.prf \ /usr/share/qt5/mkspecs/features/declarative_debug.prf \ /usr/share/qt5/mkspecs/features/unix/gdb_dwarf_index.prf \ /usr/share/qt5/mkspecs/features/warn_on.prf \ /usr/share/qt5/mkspecs/features/wayland-scanner.prf \ /usr/share/qt5/mkspecs/features/testcase_targets.prf \ /usr/share/qt5/mkspecs/features/exceptions.prf \ /usr/share/qt5/mkspecs/features/yacc.prf \ /usr/share/qt5/mkspecs/features/lex.prf \ ../space_invaders/space_invaders.pro $(QMAKE) -spec linux-g++-64 CONFIG+=debug CONFIG+=declarative_debug CONFIG+=qml_debug LIBS+=-lncurses CONFIG+=c++11 -o Makefile ../space_invaders/space_invaders.pro /usr/share/qt5/mkspecs/features/spec_pre.prf: /usr/share/qt5/mkspecs/common/shell-unix.conf: /usr/share/qt5/mkspecs/common/unix.conf: /usr/share/qt5/mkspecs/common/linux.conf: /usr/share/qt5/mkspecs/common/gcc-base.conf: /usr/share/qt5/mkspecs/common/gcc-base-unix.conf: /usr/share/qt5/mkspecs/common/g++-base.conf: /usr/share/qt5/mkspecs/common/g++-unix.conf: /usr/share/qt5/mkspecs/qconfig.pri: /usr/share/qt5/mkspecs/modules/qt_lib_bootstrap.pri: /usr/share/qt5/mkspecs/modules/qt_lib_concurrent.pri: /usr/share/qt5/mkspecs/modules/qt_lib_core.pri: /usr/share/qt5/mkspecs/modules/qt_lib_dbus.pri: /usr/share/qt5/mkspecs/modules/qt_lib_gui.pri: /usr/share/qt5/mkspecs/modules/qt_lib_network.pri: /usr/share/qt5/mkspecs/modules/qt_lib_opengl.pri: /usr/share/qt5/mkspecs/modules/qt_lib_platformsupport.pri: /usr/share/qt5/mkspecs/modules/qt_lib_printsupport.pri: /usr/share/qt5/mkspecs/modules/qt_lib_qml.pri: /usr/share/qt5/mkspecs/modules/qt_lib_qmldevtools.pri: /usr/share/qt5/mkspecs/modules/qt_lib_qmltest.pri: /usr/share/qt5/mkspecs/modules/qt_lib_quick.pri: /usr/share/qt5/mkspecs/modules/qt_lib_quickparticles.pri: /usr/share/qt5/mkspecs/modules/qt_lib_sql.pri: /usr/share/qt5/mkspecs/modules/qt_lib_testlib.pri: /usr/share/qt5/mkspecs/modules/qt_lib_widgets.pri: /usr/share/qt5/mkspecs/modules/qt_lib_xml.pri: /usr/share/qt5/mkspecs/features/qt_functions.prf: /usr/share/qt5/mkspecs/features/qt_config.prf: /usr/share/qt5/mkspecs/linux-g++-64/qmake.conf: /usr/share/qt5/mkspecs/features/spec_post.prf: /usr/share/qt5/mkspecs/features/exclusive_builds.prf: /usr/share/qt5/mkspecs/features/default_pre.prf: /usr/share/qt5/mkspecs/features/unix/default_pre.prf: /usr/share/qt5/mkspecs/features/debug.prf: /usr/share/qt5/mkspecs/features/default_post.prf: /usr/share/qt5/mkspecs/features/shared.prf: /usr/share/qt5/mkspecs/features/c++11.prf: /usr/share/qt5/mkspecs/features/qml_debug.prf: /usr/share/qt5/mkspecs/features/declarative_debug.prf: /usr/share/qt5/mkspecs/features/unix/gdb_dwarf_index.prf: /usr/share/qt5/mkspecs/features/warn_on.prf: /usr/share/qt5/mkspecs/features/wayland-scanner.prf: /usr/share/qt5/mkspecs/features/testcase_targets.prf: /usr/share/qt5/mkspecs/features/exceptions.prf: /usr/share/qt5/mkspecs/features/yacc.prf: /usr/share/qt5/mkspecs/features/lex.prf: ../space_invaders/space_invaders.pro: qmake: FORCE @$(QMAKE) -spec linux-g++-64 CONFIG+=debug CONFIG+=declarative_debug CONFIG+=qml_debug LIBS+=-lncurses CONFIG+=c++11 -o Makefile ../space_invaders/space_invaders.pro qmake_all: FORCE dist: @test -d .tmp/space_invaders1.0.0 || $(MKDIR) .tmp/space_invaders1.0.0 $(COPY_FILE) --parents $(SOURCES) $(DIST) .tmp/space_invaders1.0.0/ && (cd `dirname .tmp/space_invaders1.0.0` && $(TAR) space_invaders1.0.0.tar space_invaders1.0.0 && $(COMPRESS) space_invaders1.0.0.tar) && $(MOVE) `dirname .tmp/space_invaders1.0.0`/space_invaders1.0.0.tar.gz . && $(DEL_FILE) -r .tmp/space_invaders1.0.0 clean:compiler_clean -$(DEL_FILE) $(OBJECTS) -$(DEL_FILE) *~ core *.core ####### Sub-libraries distclean: clean -$(DEL_FILE) $(TARGET) -$(DEL_FILE) Makefile check: first compiler_wayland-server-header_make_all: compiler_wayland-server-header_clean: compiler_wayland-client-header_make_all: compiler_wayland-client-header_clean: compiler_wayland-code_make_all: compiler_wayland-code_clean: compiler_yacc_decl_make_all: compiler_yacc_decl_clean: compiler_yacc_impl_make_all: compiler_yacc_impl_clean: compiler_lex_make_all: compiler_lex_clean: compiler_clean: ####### Compile main.o: ../space_invaders/main.cpp ../space_invaders/bullet.hpp \ ../space_invaders/enemy.hpp $(CXX) -c $(CXXFLAGS) $(INCPATH) -o main.o ../space_invaders/main.cpp ####### Install install: FORCE uninstall: FORCE FORCE:
Wenn ich diese Makefile "ausführe" wird das Programm erfolgreich compiliert.
Was ist also an meiner selbstgeschriebenen Makefile falsch?
-
Das Problem ist, dass du deine Headers mit
#include <bullet.hpp>
includest. Die eckigen Klammern bedeuten, dass der Compiler in den Standardpfaden nach der Datei sucht (/usr/include und so).
Er such aber standardmässig nicht im aktuellen Verzeichnis.
Jetzt gibt es zwei Möglichkeiten:
1. Du änderst die Zeile (und das andere Include mit enemy.hpp) zu
#include "bullet.hpp"
oder du sagst dem Compiler, er soll auch im aktuellen Verzeichnis nach den Dateien suchen, und das macht man mit der Option "
-I.
" (Erklärung: -I<pfad> fügt <pfad> zur Liste hinzu und das aktuelle Verzeichnis ist unter Linux ".", deshalb -I.).Der normale Weg wäre dies über CFLAGS zu tun:
CC = g++ CFLAGS = -I. -std=c++11 TARGET = space_invaders LIBS = -lncurses $(TARGET) : main.o $(CC) $(CFLAGS) -o $(TARGET) main.o $(LIBS) main.o : main.cpp enemy.hpp bullet.hpp $(CC) $(CFLAGS) -c main.cpp $(LIBS) clean : rm -f main.o
(ich habe auch gleich -std=c++11 zu CFLAGS hinzugefügt).
Über CFLAGS kannst du später auch Optimierungen anschalten, mit -O3.
-
Ich Danke Dir für deine extreme schnelle und gute Antwort :). Ich kann das Programm nun compilieren.