Kompilieren beschleunigen

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
Glocke
Beiträge: 332
Registriert: Fr Okt 26, 2012 8:39 am

Kompilieren beschleunigen

Beitrag von Glocke » Di Okt 30, 2012 11:07 am

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

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Kompilieren beschleunigen

Beitrag von Xin » Di Okt 30, 2012 12:06 pm

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.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Glocke
Beiträge: 332
Registriert: Fr Okt 26, 2012 8:39 am

Re: Kompilieren beschleunigen

Beitrag von Glocke » Di Okt 30, 2012 3:24 pm

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 :)

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Kompilieren beschleunigen

Beitrag von Xin » Di Okt 30, 2012 3:36 pm

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.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Benutzeravatar
Kerli
Beiträge: 1456
Registriert: So Jul 06, 2008 10:17 am
Wohnort: Österreich
Kontaktdaten:

Re: Kompilieren beschleunigen

Beitrag von Kerli » Di Okt 30, 2012 3:46 pm

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
"Make it idiot-proof and someone will invent an even better idiot." (programmers wisdom)

OpenGL Tutorials und vieles mehr rund ums Programmieren: http://www.tomprogs.at

Glocke
Beiträge: 332
Registriert: Fr Okt 26, 2012 8:39 am

Re: Kompilieren beschleunigen

Beitrag von Glocke » Di Okt 30, 2012 6:11 pm

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

Glocke
Beiträge: 332
Registriert: Fr Okt 26, 2012 8:39 am

Re: Kompilieren beschleunigen

Beitrag von Glocke » Di Okt 30, 2012 6:42 pm

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

Benutzeravatar
Kerli
Beiträge: 1456
Registriert: So Jul 06, 2008 10:17 am
Wohnort: Österreich
Kontaktdaten:

Re: Kompilieren beschleunigen

Beitrag von Kerli » Di Okt 30, 2012 7:48 pm

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...
)
"Make it idiot-proof and someone will invent an even better idiot." (programmers wisdom)

OpenGL Tutorials und vieles mehr rund ums Programmieren: http://www.tomprogs.at

Antworten