Bereits im letzten Beitrag habe ich die Boost-Library erwähnt, als ich ein praktisches Beispiel über den Umgang mit RAII-Objekten listete. Allerdings genügt nicht immer eine einfache Inkludierung der entsprechenden Headerdatei. So müssen für einige Teile der Bibliothek Shared-Libraries installiert werden, da diese systemabhängige Teile kapseln. Hierbei handelt es sich um:
date_time, filesystem, graph, iostreams, program_options, python, regex, serialization, signals, test, thread, wave
In diesem Beitrag werde ich anhand eines Beispiels mit Threads zeigen, wie man diese Bibliotheken richtig kompiliert und installiert. Man wird sehen, dass der exakt selbe Sourcecode danach unter Linux und Windows kompiliert und ausgeführt werden kann.
Das Beispiel-Programm sieht folgendermassen aus:
1 #include <boost/thread/thread.hpp>
2 #include <boost/thread/xtime.hpp>
3 #include <boost/bind.hpp>
4 #include <boost/thread/mutex.hpp>
5 #include <iostream>
6 #include <cstdlib>
7
8 boost::mutex cnt_mutex;
9
10 void helloworld(unsigned int n = 1)
11 {
12 {
13 boost::mutex::scoped_lock lock(cnt_mutex);
14 std::cout << "Thread " << n << ": Hello World!" << std::endl;
15 }
16 boost::xtime xt;
17 boost::xtime_get(&xt, boost::TIME_UTC);
18 xt.sec += 60*60;
19 boost::thread::sleep(xt);
20 }
21
22 int main()
23 {
24 boost::thread_group thrd;
25
26 for(int i=0; i<5; i++){
27 thrd.create_thread(boost::bind(helloworld,i));
28 }
29 thrd.join_all();
30
31
32 system("PAUSE");
33 return EXIT_SUCCESS;
34 }
- In der Funktion main wir eine Thread-Group mit fünf Threads initialisiert, die alle die Funktion helloworld aufrufen.
- bind erstellt hier ein Funktionsobjekt mit dem entsprechenden Argument (hier die Nummerierung der Threads).
- Mit dem globalen Mutex wird der cout vor gleichzeitigem Zugriff der Threads gesichert (durch scoped_lock wird der Mutex ähnlich wie beim shared_ptr am Ende seines Gültigkeitsbereichs wieder freigegeben).
- Anschliessend werden die Threads schlafen gelegt (nur so zum Spass).
Installation unter Linux
- Im root-Verzeichnis von Boost mit configure die Installation konfigurieren:
./configure --with-libraries=thread --libdir=/usr/local/lib --includedir=/usr/local/include
(weitere Bibliotheken können dem Argument with-libraries komagetrennt angefügt werden). - make & make install
- vi /etc/ld.so.conf
+/usr/local/lib
So wird dem System bekannt gemacht wo sich die Shared-Libraries befinden wenn ein Programm darauf zugreifen möchte. - run: ldconfig
Ein Programm kann anschliessend wie folgt übersetzt werden:
gcc -I/usr/local/include/boost_1_34_1 -L/usr/local/lib -lboost_thread-gcc41-mt-1_34_1 boost_test.cpp -o boost_test
Oder mit dem folgenden Makefile:
CC = gcc
OBJECTS = boost_test.o
LIBS = -L/usr/local/lib -lboost_thread-gcc41-mt-1_34_1 -L/usr/lib
LIBPATH = -I/usr/local/include/boost_1_34_1
CFLAGS = -c -O
boost_test: $(OBJECTS)
$(CC) -o $@ $(OBJECTS) $(LIBS)
boost_test.o: boost_test.cpp
$(CC) $(CFLAGS) $(LIBPATH) $*.cpp
clean:
rm *.o boost_test
Installation unter Windows
Unter Windows erfordert die Installation mehr Schritte. Ich verwende einerseits die Entwicklungsumbebung Dev-C++ 4.9.9.2 mit dem GNU GCC 3.4.5 Compiler und andererseits Microsoft Visual C++ 2008 Express Edition mit dem Microsoft 32-bit C/C++ Optimizing Compiler Version 15.
Um die Bibliotheken kompilieren zu können, muss BJam separat installiert werden. Eine detaillierte Anleitung hierfür finden sie hier.
Meine Umgebungsvariablen sehen wie folgt aus:
DevEnvDir=C:\Programme\Microsoft Visual Studio 9.0\Common7\IDE
PATH=%PATH%;C:\Programme\Microsoft Visual Studio 9.0\Common7\IDE;C:\Programme\Microsoft Visual Studio 9.0\VC\BIN;C:\Programme\Microsoft Visual Studio 9.0\Common7\Tools;C:\WINDOWS\Microsoft.NET\Framework\v3.5;C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727;C:\Programme\Microsoft Visual Studio 9.0\VC\VCPackages;C:\Boost\lib
INCLUDE=C:\Programme\Microsoft Visual Studio 9.0\VC\INCLUDE;C:\Boost\include\boost-1_34_1
LIB=C:\Programme\Microsoft Visual Studio 9.0\VC\LIB;C:\Boost\lib
LIBPATH=C:\WINDOWS\Microsoft.NET\Framework\v3.5;C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727;C:\Programme\Microsoft Visual Studio 9.0\VC\LIB;C:\Boost\lib
Patchen vor Beginn:
Die Boost-Bibliothek 1.34.1 ist noch nicht für Visual C++ 9.0 upgedated worden. Darum sollten vor Beginn der Installation folgende Zeilen in den Sourcen angepasst werden:
lists.boost.org
(Falls der Link nicht mehr aktuell ist finden Sie die erforderlichen Änderungen am Ende dieses Posts)
Installieren von BJam (mit msvc):
c:\...\boost_1_34_1\tools\jam\build_dist.bat
oder
c:\...\boost_1_34_1\tools\jam\src\build.bat msvc
Installieren/Kompillieren der gewünschten Libraries:
%path_to_bjam% --toolset=compiler --with-%library-list% install
z.B.
c:\...\boost_1_34_1>tools\jam\src\boost-jam-3.1.14-1-ntx86\bjam --toolset=msvc --with-thread install
c:\...\boost_1_34_1>tools\jam\src\boost-jam-3.1.14-1-ntx86\bjam --toolset=gcc --with-thread install
Projekteinstellungen:
Bei beiden Entwicklungsumgebungen muss nun das include- und lib-Verzeichnis angegeben werden:
C:\Boost\include\boost-1_34_1
C:\Boost\lib
Bei Dev-C++ müssen zusätzlich die Bibliotheken unter dem Register Parameter dem Linker bekannt gemacht werden. VC++ findet dies über die Umgebungsvariablen.
Ausgabe des Programms:
Die Reihenfolge muss nicht immer genau diese sein. Im Taskmanager kann man die Anzahl Threads des Programms anzeigen lassen.
Boost-Patch für Visual C++ 9.0:
msvc.jam
{
# Even if version is not explicitly specified, try to detect the version
# from the path.
+ if [ MATCH "(Microsoft Visual Studio 9.0)" : $(command) ]
+ {
+ version = 9.0 ;
+ }
+else if [ MATCH "(Microsoft Visual Studio 8)" : $(command) ]
-if [ MATCH "(Microsoft Visual Studio 8)" : $(command) ]
{
version = 8.0 ;
.ProgramFiles = [ path.make [ common.get-program-files-dir ] ] ;
-.known-versions = 8.0 8.0express 7.1 7.1toolkit 7.0 6.0 ;
+.known-versions = 9.0 9.0express 8.0 8.0express 7.1 7.1toolkit 7.0 6.0 ;
# Version aliases
.version-alias-6 = 6.0 ;
.version-alias-6.5 = 6.0 ;
.version-alias-7 = 7.0 ;
.version-alias-8 = 8.0 ;
+.version-alias-9 = 9.0 ;
# Name of the registry key that contains Visual C++ installation path
# (relative to "HKEY_LOCAL_MACHINE\SOFTWARE\\Microsoft"
.version-7.1-reg = "VisualStudio\\7.1\\Setup\\VC" ;
.version-8.0-reg = "VisualStudio\\8.0\\Setup\\VC" ;
.version-8.0express-reg = "VCExpress\\8.0\\Setup\\VC" ;
+.version-9.0-reg = "VisualStudio\\9.0\\Setup\\VC" ;
+.version-9.0express-reg = "VCExpress\\9.0\\Setup\\VC" ;
# Visual C++ Toolkit 2003 do not store its installation path in the registry.
# The environment variable 'VCToolkitInstallDir' and the default installation
auto_link.hpp
// vc71:
# define BOOST_LIB_TOOLSET "vc71"
-#elif defined(BOOST_MSVC) && (BOOST_MSVC >= 1400)
+#elif defined(BOOST_MSVC) && (BOOST_MSVC == 1400)
// vc80:
# define BOOST_LIB_TOOLSET "vc80"
+#elif defined(BOOST_MSVC) && (BOOST_MSVC >= 1500)
+
+ // vc90:
+# define BOOST_LIB_TOOLSET "vc90"
+
#elif defined(__BORLANDC__)
visualc.hpp
#error "Compiler not supported or configured - please reconfigure"
#endif
//
-// last known and checked version is 1400 (VC8):
-#if (_MSC_VER > 1400)
+// last known and checked version is 1500 (VC9):
+#if (_MSC_VER > 1500)
# if defined(BOOST_ASSERT_CONFIG)
# error "Unknown compiler version - please run the configure tests and report the results"
# else
named_slot_map.hpp
|| slot_ == other.slot_));
}
-#if BOOST_WORKAROUND(_MSC_VER, <= 1400)
+#if BOOST_WORKAROUND(_MSC_VER, <= 1500)
void decrement();
void advance(difference_type);
#endif
named_slot_map.cpp
typedef slot_container_type::const_iterator const_group_iterator;
-#if BOOST_WORKAROUND(_MSC_VER, <= 1400)
+#if BOOST_WORKAROUND(_MSC_VER, <= 1500)
void named_slot_map_iterator::decrement() { assert(false); }
void named_slot_map_iterator::advance(difference_type) { assert(false); }
#endif
Keine Kommentare:
Kommentar veröffentlichen