2010-05-20 11 views
7

Il mio lavoro consiste principalmente in analisi ingegneristiche, ma mi ritrovo a distribuire il codice sempre più frequentemente tra i miei colleghi. Un grande problema è che non tutti gli utenti conoscono bene la complessità della compilazione del codice sorgente e non sono in grado di distribuire file eseguibili.Distribuzione semplice ed efficiente del codice sorgente C++/Boost (amalgamazione)

Ho lavorato con C++ usando Boost, e il problema è che non posso richiedere ad ogni sysadmin di ogni rete di installare le librerie. Invece, voglio distribuire un singolo file sorgente (o il minor numero possibile) in modo che l'utente possa g++ source.c -o program.

Quindi, la domanda è: puoi pack le librerie Boost con il tuo codice e finire con un singolo file? Sto parlando delle librerie Boost che sono "solo intestazioni" o "solo modelli".

Come ispirazione, consultare la distribuzione di SQlite o Lemon Parser Generator; l'autore amalgama le cose in un unico file sorgente che è banale da compilare.

Grazie.

Edit:

Un related question in SO è per ambiente Windows. Lavoro in Linux.

+1

Quanto vuoi percorrere questa strada? Che dire delle altre librerie che potrebbero non aver installato. Probabilmente vorrai dare un'occhiata a qualche tipo di gestore di pacchetti o meccanismo di compilazione automatizzata (forse un archivio shar?). – KeithB

risposta

11

C'è un programma di utilità che viene fornito con boost chiamato bcp, che può scansionare la fonte ed estrarre qualsiasi file di intestazione di boost che viene utilizzato dalla fonte di boost. Ho impostato uno script che esegue questa estrazione nel nostro albero dei sorgenti, in modo da poter impacchettare la fonte di cui abbiamo bisogno insieme al nostro codice. Copierà anche i file sorgente di boost per un paio di librerie di boost che usiamo che non sono solo intestazione, che vengono poi compilate direttamente nelle nostre applicazioni.

Questo è fatto una volta, e quindi chiunque usi il codice non ha nemmeno bisogno di sapere che dipende dall'aumento. Ecco cosa usiamo. Costruirà anche bjam e bcp, se non sono già stati compilati.

#!/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

Grazie. Questo è molto vicino a quello che finirò per fare. – Escualo

0

Perché non basta archiviare tutti i file necessari in SVN e inviare ai colleghi l'URL del repository? Poi possono controllare il codice ogni volta che vogliono, fare un 'svn up' ogni volta che vogliono aggiornare alla versione più recente, ecc.

+0

Questo potrebbe funzionare per voi e per me, ma per alcuni dei miei colleghi ciò richiederebbe più sofisticazione di quanto non vogliano/abbiano il tempo di sopportare. – Escualo

+1

Si potrebbe probabilmente concludere la complessità in uno script o front-end GUI per loro. Si tratta semplicemente di un singolo comando "svn co" (o "svn up"), seguito dal configure, make o quant'altro. Con un po 'di lavoro tutto potrebbe essere lanciato facendo doppio clic su un'icona. –

3

Hai mai pensato di scrivere uno script di compilazione per un sistema di build come SCons?
Si può scrivere uno script python per scaricare boost, decomprimere compilare i file necessari (è possibile anche eseguire bjam se necessario) e compilare il proprio codice.
L'unica dipendenza di cui i tuoi colleghi avranno bisogno è Python e SCons.

1

Eseguire il preprocessore sul codice e salvare l'output. Se hai iniziato con un main.cpp con un gruppo di include in esso, ti ritroverai con un file in cui sono stati risucchiati tutti gli include. Se hai più file cpp, dovrai concatenarli insieme e poi eseguire il preprocessore sul file concatenato, questo dovrebbe funzionare fintanto che non si hanno nomi di simboli globali duplicati.

Per un metodo più portatile, eseguire ciò che fa sqlite e scrivere il proprio script per combinare e concatenare insieme i file creati + boost e non includere il sistema. Vedi mksqlite3c.TCL nel codice SQLite
http://www2.sqlite.org/src/finfo?name=tool/mksqlite3c.tcl

+0

Vero, ma sto rispondendo alla domanda che ha posto, che era come renderlo un file. – Zanson

+0

Grazie per aver segnalato lo script Tcl. – Escualo

0

Se siete su una varietà derivata Debian di Linux, così problemi come questo proprio non dovrebbe venire: lasciare che il sistema di confezionamento e manuale politica di fare il lavoro. È sufficiente chiarire che libboost-dev o qualsiasi altro pacchetto è una dipendenza del codice e deve essere installato in anticipo, e quindi /usr/include/boost dovrebbe essere proprio lì dove il codice si aspetta di trovarlo. Se stai utilizzando una versione più recente di boost rispetto alla distribuzione, probabilmente vale la pena di capire come impacchettarla tu stesso e lavorare all'interno del framework esistente di packaging/dipendenze piuttosto che reinventarne un'altra.

Non ho familiarità con le distribuzioni basate su .rpm per commentare come funzionano le cose lì. Ma sapere che posso facilmente configurare esattamente l'ambiente di costruzione di cui ho bisogno è, per me, uno dei maggiori vantaggi dello sviluppo basato su Debian su Windows.