2010-05-20 10 views
7

Mein Job besteht hauptsächlich aus technischen Analysen, aber ich finde, dass ich Code immer häufiger unter meinen Kollegen verteile. Ein großer Schmerz ist, dass nicht jeder Benutzer die Kompliziertheit des Kompilierens von Quellcode beherrscht, und ich ausführbare Dateien nicht verteilen kann.Einfache und effiziente Verteilung von C++/Boost-Quellcode (Verschmelzung)

Ich habe mit C++ mit Boost gearbeitet, und das Problem ist, dass ich nicht jeden Sysadmin von jedem Netzwerk anfordern kann, um die Bibliotheken zu installieren. Stattdessen möchte ich eine einzelne Quelldatei (oder so wenige wie möglich) verteilen, sodass der Benutzer g++ source.c -o program.

Also, die Frage ist: Können Sie Pack die Boost-Bibliotheken mit Ihrem Code, und am Ende mit einer einzigen Datei? Ich spreche über die Boost-Bibliotheken, die "nur Header" oder "nur Vorlagen" sind.

Als Inspiration, sehen Sie sich bitte die Verteilung SQlite oder die Lemon Parser Generator; Der Autor fusioniert das Zeug in eine einzige Quelldatei, die zu kompilieren trivial ist.

Vielen Dank.

bearbeiten:

A related question in SO ist für Windows-Umgebung. Ich arbeite in Linux.

+1

Wie weit wollen Sie diesen Weg gehen? Was ist mit anderen Bibliotheken, die sie nicht installiert haben? Sie möchten sich wahrscheinlich einen Paketmanager oder einen automatischen Kompilierungsmechanismus (vielleicht ein Shar-Archiv?) Ansehen. – KeithB

Antwort

11

Es gibt ein Dienstprogramm mit Boost namens bcp, das Ihre Quelle scannen und Boost-Header-Dateien extrahieren kann, die von der Boost-Quelle verwendet werden. Ich habe ein Skript eingerichtet, das diese Extraktion in unseren Quellbaum bringt, so dass wir die Quelle, die wir benötigen, zusammen mit unserem Code packen können. Es wird auch die Boost-Quelldateien für ein paar Boost-Bibliotheken, die wir verwenden, die keine Header sind, kopieren, die dann direkt in unsere Anwendungen kompiliert werden.

Dies wird einmal gemacht, und dann muss jeder, der den Code verwendet, nicht einmal wissen, dass es auf Boost ankommt. Hier ist, was wir verwenden. Es wird auch bjam und bcp erstellen, wenn sie nicht bereits erstellt wurden.

#!/bin/sh 
BOOST_SRC=.../boost_1_43_0 
DEST_DIR=../src/boost 
TOOLSET= 
if (test `uname` = "Darwin") then 
    TOOLSET="--toolset=darwin" 
fi 

# make bcp if necessary 
if (! test -x $BOOST_SRC/dist/bin/bcp) then 
    if (test -x $BOOST_SRC/tools/jam/*/bin.*/bjam) then 
     BJAM=$BOOST_SRC/tools/jam/*/bin.*/bjam 
    else 
     echo "### Building bjam" 
     pushd $BOOST_SRC/tools/jam 
     ./build_dist.sh 
     popd 
     if (test -x $BOOST_SRC/tools/jam/*/bin.*/bjam) then 
      BJAM=$BOOST_SRC/tools/jam/*/bin.*/bjam 
     fi 

    fi 
    echo "BJAM: $BJAM" 
    pushd $BOOST_SRC/tools/bcp 
    echo "### Building bcp" 
    echo "$BJAM $TOOLSET" 
    $BJAM $TOOLSET 
    if [ $? == "0" ]; then 
     exit 1; 
    fi 
    popd 
fi 

if (! test -x $BOOST_SRC/dist/bin/bcp) then 
    echo "### Couldn't find bpc" 
    exit 1; 
fi 

mkdir -p $DEST_DIR 

echo "### Copying boost source" 
MAKEFILEAM=$DEST_DIR/libs/Makefile.am 
rm $MAKEFILEAM 
# Signals 
# copy source libraries 
mkdir -p $DEST_DIR/libs/signals/src 
cp $BOOST_SRC/libs/signals/src/* $DEST_DIR/libs/signals/src/. 
echo -n "boost_sources += " >> $MAKEFILEAM 
for f in `ls $DEST_DIR/libs/signals/src | fgrep .cpp`; do 
    echo -n "boost/libs/signals/src/$f " >> $MAKEFILEAM 
done 
echo >> $MAKEFILEAM 

echo "### Extracting boost includes" 
$BOOST_SRC/dist/bin/bcp --scan --boost=$BOOST_SRC ../src/*/*.[Ch] ../src/boost/libs/*/src/*.cpp ../src/smart_assert/smart_assert/priv/fwd/*.hpp $DEST_DIR 
if [ $? != "0" ]; then 
    echo "### bcp failed" 
    rm -rf $DEST_DIR 
    exit 1; 
fi 
+0

Danke. Das ist sehr nah an dem, was ich am Ende machen werde. – Escualo

0

Warum nicht einfach alle notwendigen Dateien auf SVN einchecken und Ihnen die URL des Repositories schicken? Dann können sie den Code auschecken, wann immer sie wollen, ein 'svn up' machen, wann immer sie auf die neuste Version updaten wollen, usw.

+0

Dies würde für Sie und für mich funktionieren, aber für einige meiner Kollegen würde dies mehr Raffinesse erfordern, als sie bereit sind/Zeit haben, damit umzugehen. – Escualo

+1

Sie könnten wahrscheinlich die Komplexität in einem Skript oder GUI-Frontend für sie einpacken. Es ist nur eine Frage eines einzelnen Befehls "svn co" (oder "svn up"), gefolgt von configure; make oder was auch immer. Mit ein wenig Arbeit könnte alles durch einen Doppelklick auf ein Symbol gestartet werden. –

3

Haben Sie darüber nachgedacht, ein Build-Skript für ein Build-System wie SCons zu schreiben?
Sie könnten ein Python-Skript schreiben, um Boost herunterzuladen, es zu entpacken, die benötigten Dateien zu kompilieren (Sie können sogar bjam ausführen, falls nötig) und Ihren eigenen Code kompilieren.
Die einzige Abhängigkeit, die Ihre Kollegen benötigen, ist Python und SCons.

1

Führen Sie den Präprozessor auf Ihrem Code und speichern Sie die Ausgabe. Wenn Sie mit einer main.cpp mit einer Reihe von Includes begonnen haben, erhalten Sie eine Datei, in die alle Includes hineingesaugt wurden. Wenn Sie mehrere cpp-Dateien haben, müssen Sie sie zusammen erstellen und dann ausführen Der Präprozessor in der Concateinated-Datei sollte funktionieren, solange Sie keine doppelten globalen Symbolnamen haben.

Für eine portablere Methode, machen Sie was sqlite tut und schreiben Sie Ihr eigenes Skript, um nur die von Ihnen erstellten + Boost-Dateien zu kombinieren und zusammenzufassen und nicht die System-Includes zu bekommen. Siehe mksqlite3c.tcl in dem SQLite-Code
http://www2.sqlite.org/src/finfo?name=tool/mksqlite3c.tcl

+0

Stimmt, aber ich beantworte die Frage, die er gestellt hat, wie man es zu einer Datei macht. – Zanson

+0

Vielen Dank für das Tcl-Skript. – Escualo

0

Wenn Sie auf einer Debian-derived Vielzahl von Linux sind, wie dies auch Probleme sollten einfach nicht kommen: Lassen Sie das Verpackungssystem und Politik Handbuch die Arbeit machen. Machen Sie einfach klar, dass das libboost-dev- oder was auch immer Paket eine Build-Abhängigkeit Ihres Codes ist und vorher installiert werden muss, und dann sollte /usr/include/boost genau da sein, wo Ihr Code es erwartet. Wenn Sie eine aktuellere Version von Boost verwenden, als die Distro ausgeliefert, ist es wahrscheinlich sinnvoll, herauszufinden, wie Sie es selbst verpacken und innerhalb des bestehenden Packaging/Abhängigkeiten-Frameworks arbeiten, anstatt ein anderes neu zu erfinden.

Ich bin nicht vertraut genug mit. RPM basierten Distributionen zu kommentieren, wie die Dinge dort arbeiten. Aber zu wissen, dass ich die Build-Umgebung, die ich brauche, einfach einrichten kann, ist für mich einer der größten Vorteile der Debian-basierten Entwicklung gegenüber Windows.