Seite 1 von 1

Kompilieren beschleunigen

Verfasst: Di Okt 30, 2012 11:07 am
von Glocke
Hiho :)

mein Projekt umfasst inzwischen 166kb Quellcode (Header und Sourcefiles zusammen). Zum kompilieren habe ich folgende Makefile erstellt:

Code: Alles auswählen

CC = g++
FILES = src/core/*.cpp src/*.cpp
LIBS = -lSDL -lSDL_image -lSDL_mixer -lSDL_ttf -lSDL_net -lpthread
FLAGS = -Wall -std=c++0x
NAME = demo.out

all:
	$(CC) $(FLAGS) $(FILES) -o $(NAME) $(LIBS)

release:
	$(CC) $(FLAGS) -O2 $(FILES) -o $(NAME) $(LIBS)

debug:
	clear && $(CC) $(FLAGS) -Wfatal-errors -O0 -g $(FILES) -o $(NAME) $(LIBS)
Da ich mit gedit, gnome-terminal und ddd bzw. gdb arbeite, habe ich mir angewöhnt häufig zu kompilieren und Änderungen zu testen. Allerdings dauert das bauen von make debug ziemlich lange.
Wie man an $FILES sieht, unterteilt sich mein Code in core und in src. Inzwischen baue ich aber kaum noch in core rum. Würde es sich da anbieten den Code aus core zu einer Library zu kompilieren und beim Bauen meines Projektes nur den übrigen Code zu kompilieren und die core-Lib zu linken? Würde das Zeitersparnis bringen?

LG Glocke

Re: Kompilieren beschleunigen

Verfasst: Di Okt 30, 2012 12:06 pm
von Xin
Dein Makefile hat ein grundsätzliches Problem: Du hast feste Ziele: Dein 'all'-Ziel nimmt alle Quelldateien und kompiliert sie. Änderungen hast Du meist nur wenige.

all: kennt keine Abhängigkeiten.

Aus einer .cpp Datei wird eine .o Datei.

Code: Alles auswählen

all: main.o
  $(CC) $(FLAGS) $(OBJECTFILES) -o $(NAME) $(LIBS)

main.o: main.cpp  # main.o ist von main.cpp abhängig
  $(CC) -c $(FLAGS) main.cpp -o main.o $(LIBS)
usw.

Du kannst das weiter vereinfachen mit Suffix-Regeln oder Pattern-Regeln.

Die Abhängigkeiten von Headerfiles kannst Du automatisiert mit 'makedepend' erstellen lassen.

Hiermit werden nur noch die geänderten Files kompiliert und das alles wieder zu $(NAME) gelinkt. Das geht bedeutend schneller.

Re: Kompilieren beschleunigen

Verfasst: Di Okt 30, 2012 3:24 pm
von Glocke
Erstmal danke, aber so richtig kann ich damit noch nichts anfangen. Kannst du mir sagen wie du die Makefile in meinem Beispiel formulieren würdest? Ich glaube nicht, dass ich für jede Quellcode-Datei eine extra Regel erstellen müsste, oder?
Hier mal eine Dateiliste:

src/
  • src/core/
    • Utilities.cpp
    • Utilities.hpp
    • Engine.cpp
    • Engine.hpp
    • Network.cpp
    • Network.hpp
    • TiledModel.cpp
    • TiledModel.hpp
    • IsometricView.cpp
    • IsometricView.hpp
    • Widget.cpp
    • Widget.hpp
  • main.cpp
  • Menu.cpp
  • Menu.hpp
  • GameModel.cpp
  • GameModel.hpp
  • GameView.cpp
  • GameView.hpp
  • Client.cpp
  • Client.hpp
  • Server.cpp
  • Server.hpp
Dabei ist die main.cpp quasi der Startpunkt des Programms.

Ich hab von der ganzen Kompiler- und Makefile-Sache keine tiefergehende Ahnung. Aber ein gutes Beispiel würde mir da sicher viel helfen 8-)

LG Glocke :)

Re: Kompilieren beschleunigen

Verfasst: Di Okt 30, 2012 3:36 pm
von Xin
Glocke hat geschrieben:Erstmal danke, aber so richtig kann ich damit noch nichts anfangen. Kannst du mir sagen wie du die Makefile in meinem Beispiel formulieren würdest? Hier mal eine Dateiliste:
Ich habe eine ähnliche Struktur. Hierbei hat jedes Verzeichnis ein Makefile, dass grundlegende Variablen setzt: Wo bin ich? Was brauche ich.
Wo bin ich klärt sich mit der Position, wo das Hauptverzeichnis ist, z.B. "../../.." ist der Pfad zum Ursprung. Was brauche ich sind die hier verwendeten Libs. Nicht jedes Verzeichnis braucht mysql, gtk, qt, opengl und alles andere, die meisten brauchen nix.

Anschließend inkludiere ich das eigentliche Make-File.

Dieses kompiliert alle .cpp-Dateien im aktuellen Verzeichnis und sucht dann in einer for-Schleife nach Verzeichnissen. Wenn in dem Verzeichnis ein Makefile ist, führe ich das aus, dieses funktioniert genauso: Wo bin ich, was brauche ich, inkludieren, ab dafür.

Das meiste sind eher kleine Bash-Skripts innerhalb des Make-Files.
Glocke hat geschrieben:Dabei ist die main.cpp quasi der Startpunkt des Programms.
Ich hab von der ganzen Kompiler- und Makefile-Sache keine tiefergehende Ahnung. Aber ein gutes Beispiel würde mir da sicher viel helfen 8-)
Bist Du halbwegs fit mit Bash?

Du kannst mit Wildcards bereits alle Dateien im lokalen Verzeichnis zusammenfassen:

Code: Alles auswählen

CPPFILES = $(wildcard *.cpp)
Die kannst Du nun entweder einzeln kompilieren. Ich habe eine weitere Variable, in die ich die Liste der "*.cpp" in eine Liste der "*.o" Dateien umgestalte. Das müsste ich selbst googlen.
Der Rest fällt in eine Pattern-Regel, die dann kompiliert.

Die OBJFILES kannst Du ja in der ersten Runde einfach mal auflisten für ein Verzeichnis und das ans Laufen bringen. Damit bist Du schonmal auf dem richtigen Weg.

Re: Kompilieren beschleunigen

Verfasst: Di Okt 30, 2012 3:46 pm
von Kerli
Ich würde dir einmal empfehlen CMake anzuschauen. Es ist deutlich einfacher zu verwenden als Makefiles und bietet viele nette Features wie zb. das Suchen und anschließende Linken mit externen Bibliotheken. Hier ein paar Beispiele:

http://wiki.ubuntuusers.de/CMake#Erstel ... s-Projekts
http://www.cmake.org/cmake/help/examples.html

Re: Kompilieren beschleunigen

Verfasst: Di Okt 30, 2012 6:11 pm
von Glocke
So, ich hab mir jetzt meine CMakeLists.txt erstellt:

Code: Alles auswählen

Project (Demo)
cmake_minimum_required (VERSION 2.6)

find_package (SDL REQUIRED)
find_package (SDL_image REQUIRED)
find_package (SDL_mixer REQUIRED)
find_package (SDL_ttf REQUIRED)
find_package (SDL_net REQUIRED)

set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++0x -lSDL -lSDL_image -lSDL_mixer -lSDL_ttf -lSDL_net")

if (CMAKE_BUILD_TYPE STREQUAL "release")
    set (CMAKE_CXX_FLAGS "-O2 -g")
elseif (CMAKE_BUILD_TYPE STREQUAL "debug")
    set (CMAKE_CXX_FLAGS "-O0 -g -Wfatal-errors")
endif()

set (SOURCES
    ./src/core/Utilities.cpp
    ./src/core/Engine.cpp
    ./src/core/Network.cpp
    ./src/core/Widget.cpp
    ./src/core/TiledModel.cpp
    ./src/core/IsometricView.cpp
    ./src/Menu.cpp
    ./src/GameModel.cpp
    ./src/GameView.cpp
    ./src/Server.cpp
    ./src/Client.cpp
    ./src/main.cpp
)

add_Executable (application ${SOURCES})

install (TARGETS application
         RUNTIME DESTINATION verzeichnis
         LIBRARY DESTINATION bilbiothek
)
Beim Linken schmeißt er mir eine undefined reference nach der anderen gegen den Kopf. Alle beziehen sich auf SDL-Funktionen.
CMakeFiles/application.dir/src/core/Engine.cpp.o: In function `State::handle()':
/home/christian/Dropbox/Projekte/sdl_engine/src/core/Engine.cpp:110: undefined reference to `SDL_GetMouseState'
/home/christian/Dropbox/Projekte/sdl_engine/src/core/Engine.cpp:115: undefined reference to `SDL_PollEvent'
CMakeFiles/application.dir/src/core/Engine.cpp.o: In function `Engine':
/home/christian/Dropbox/Projekte/sdl_engine/src/core/Engine.cpp:180: undefined reference to `SDL_Init'
/home/christian/Dropbox/Projekte/sdl_engine/src/core/Engine.cpp:181: undefined reference to `SDL_GetError'
/home/christian/Dropbox/Projekte/sdl_engine/src/core/Engine.cpp:183: undefined reference to `SDL_WM_SetCaption'
/home/christian/Dropbox/Projekte/sdl_engine/src/core/Engine.cpp:185: undefined reference to `SDL_SetVideoMode'
/home/christian/Dropbox/Projekte/sdl_engine/src/core/Engine.cpp:186: undefined reference to `SDL_GetVideoSurface'
/home/christian/Dropbox/Projekte/sdl_engine/src/core/Engine.cpp:188: undefined reference to `SDL_GetError'
/home/christian/Dropbox/Projekte/sdl_engine/src/core/Engine.cpp:191: undefined reference to `Mix_OpenAudio'
/home/christian/Dropbox/Projekte/sdl_engine/src/core/Engine.cpp:192: undefined reference to `SDL_GetError'
/home/christian/Dropbox/Projekte/sdl_engine/src/core/Engine.cpp:195: undefined reference to `SDLNet_Init'
/home/christian/Dropbox/Projekte/sdl_engine/src/core/Engine.cpp:196: undefined reference to `SDL_GetError'
/home/christian/Dropbox/Projekte/sdl_engine/src/core/Engine.cpp:199: undefined reference to `TTF_Init'
/home/christian/Dropbox/Projekte/sdl_engine/src/core/Engine.cpp:200: undefined reference to `SDL_GetError'
/home/christian/Dropbox/Projekte/sdl_engine/src/core/Engine.cpp:203: undefined reference to `TTF_OpenFont'
/home/christian/Dropbox/Projekte/sdl_engine/src/core/Engine.cpp:227: undefined reference to `SDL_EnableUNICODE'
usw... Was mache ich falsch?

LG Glocke

Re: Kompilieren beschleunigen

Verfasst: Di Okt 30, 2012 6:42 pm
von Glocke
Ich hab mal die Bash-Variante durchgespielt:

Code: Alles auswählen

#!/bin/bash

binary="demo.out"
src="src"

# iterate through given source files
for var in "$@"
do
    echo "Compiling $src/$var.cpp ..."
    # compile source file
    g++ -g -Wall -std=c++0x $src/$var.cpp -c
done

echo "Linking project $binary ..."
g++ -o $binary *.o -lSDL -lSDL_image -lSDL_mixer -lSDL_ttf -lSDL_net
und mit ./build.sh main Menu GameModel GameView Server Client core/Utilities core/Engine core/Network core/Widget core/TiledModel core/IsometricView aufgerufen. Klappt soweit. Wenn ich dann nur zB die Server.cpp bzw. Server.hpp geändert habe, calle ich ./build.sh Server, das Skript lompiliert nur den Server neu und linkt alle .o-Files zur Anwendung zusammen. :lol:

Ich weiß nur gerade nicht, wie ich dem Compiler sage, dass die .o files in Verzeichnis XY sollen... im Hauptverzeichnis sieht es etwas durcheinander aus :D

LG Glocke

Re: Kompilieren beschleunigen

Verfasst: Di Okt 30, 2012 7:48 pm
von Kerli
Du solltest du Bibliotheken die CMake gefunden hat auch linken lassen. Nicht manuell zu CMAKE_CXX_FLAGS hinzufügen sonder mit target_link_libraries:

Code: Alles auswählen

target_link_libraries( application
  ${SDL_LIBRARY}
  ${SDLIMAGE_LIBRARY}
  ${SDLNET_LIBRARY}
  # more libraries...
)