SCons to ciekawe narzędzie do kompilacji kodu C++, Javy czy LaTeX'a. Autorzy chwalą się pisząc nieskromnie: next-generation build tool.
Kompilacja prostego programu w C++ wygląda następująco:
- Tworzymy plik SConstruct
- Uruchamiamy polecenie scons
# plik: SConstruct Program('game', 'main.cpp') # pierwszy argument można pominąćJest to równoważne uruchomieniu następujących poleceń:
g++ -o main.o -c main.cpp g++ -o game main.oŁatwo możemy także tworzyć biblioteki:
# plik: SConstruct SharedLibrary('superlib', 'superlib.cpp')Jest to równoważne:
g++ -o superlib.os -c -fPIC superlib.cpp g++ -o libsuperlib.so -shared superlib.osWidzimy, że SCons zadbał o odpowiednie flagi oraz prefix lib- dla nazwy pliku wynikowego.
Ręczne tworzenie bardziej skomplikowanych poleceń może wyglądać np. tak:
env = Environment() env.MergeFlags("-lSDL -lSDL_mixer -lSDL_image -lGL -lGLU") env.MergeFlags("-g -ggdb") env.MergeFlags("-W -Wall -Wextra -Woverloaded-virtual -pedantic") env.Program("game", Glob("*.cpp") + Glob("editor/*.cpp"))Jeżeli nie chcemy wpisywać minusów przed nazwą bibliotek (co prawdopodobnie jest także zachowaniem przeciw wieloplatformowości pliku SConstruct), możemy napisać tak:
env.Append(LIBS = Split('SDL SDL_mixer SDL_image GL GLU'))Dość ciekawy jest fakt, że SCons sam rozpoznaje, które flagi powinny być gdzie użyte. Wpisując
env.MergeFlags("-I /src/include/") env.MergeFlags("-L /src/lib/")pierwsza flaga zostanie użyta podczas kompilacji, a druga dopiero podczas łączenia (konsolidacji).
Konkretnie o problemie
Wydaje się, że odkryliśmy super narzędzie i teraz kompilacja już będzie marzeniem. Rzeczywiście, w prostych przypadkach jest bardzo wygodne. Sprawa trochę się skomplikowała, gdy chciałem dodać flagę zmieniającą używany przez kompilator standard na C++0x.
Po wpisaniu
env.MergeFlags('-std=c++0x')SCons zachowywał się jakbym niczego nie dopisał! Trochę zaskakujące może być, że komendę
env.MergeFlags('-fmessage-length=70')wykonał poprawnie (odpowiednia flaga pojawiła się na wyjściu kompilatora).
Rozwiązanie 1
Dodać flagę w definicji środowiska:
env = Environment(CPPFLAGS = ['-std=c++0x'])
Rozwiązanie 2
Zrezygnować z MergeFlags na rzecz Append:
env.Append(CPPFLAGS = '-std=c++0x')
Kompletny SConstruct może wyglądać np. tak:
EnsurePythonVersion(2, 6) EnsureSConsVersion(2, 0) env = Environment() env.Append(CPPPATH = ['/data/include/boost/', '/usr/include/', ]) env.Append(LIBPATH = []) env.Append(CPPDEFINES = {'DEBUG_BUILD' : '1'}) env.Append(CPPFLAGS = Split('-W -Wall -Wextra -Woverloaded-virtual -pedantic')) env.Append(CPPFLAGS = Split('-std=c++0x -g -ggdb')) env.Append(LIBS = Split('SDL SDL_mixer SDL_image GL GLU')) env.Program("game", Glob("*.cpp") + Glob("editor/*.cpp") + Glob("gui/*.cpp"))
Brak komentarzy:
Prześlij komentarz