2010-05-20 3 views
7

Mon travail consiste principalement en une analyse technique, mais je me retrouve à distribuer de plus en plus de code parmi mes collègues. Une grande difficulté est que tous les utilisateurs ne maîtrisent pas les subtilités de la compilation du code source, et je ne peux pas distribuer d'exécutables.Distribution simple et efficace du code source C++/Boost (amalgamation)

J'ai travaillé avec C++ en utilisant Boost, et le problème est que je ne peux pas demander à tous les sysadmin de tous les réseaux d'installer les bibliothèques. Au lieu de cela, je veux distribuer un seul fichier source (ou aussi peu que possible) afin que l'utilisateur puisse g++ source.c -o program.

Donc, la question est: pouvez-vous pack les bibliothèques Boost avec votre code, et se retrouver avec un seul fichier? Je parle des bibliothèques Boost qui sont des "en-têtes seulement" ou des "modèles seulement". Pour une inspiration, veuillez regarder la distribution de SQlite ou Lemon Parser Generator; l'auteur amalgame le contenu en un seul fichier source qui est trivial à compiler.

Merci.

Modifier:

Un related question in SO est pour l'environnement Windows. Je travaille sous Linux.

+1

Jusqu'où voulez-vous aller dans cette voie? Qu'en est-il des autres bibliothèques qu'ils n'ont peut-être pas installées? Vous voulez probablement regarder une sorte de gestionnaire de paquets, ou un mécanisme de compilation automatique (peut-être une archive shar?). – KeithB

Répondre

11

Il existe un utilitaire qui vient avec boost appelé bcp, qui peut analyser votre source et extraire tous les fichiers d'en-tête boost utilisés à partir de la source boost. J'ai installé un script qui fait cette extraction dans notre arborescence source, afin que nous puissions empaqueter la source dont nous avons besoin avec notre code. Il copiera également les fichiers sources boost pour quelques bibliothèques boost que nous utilisons et qui ne sont pas en-tête, et qui sont ensuite compilées directement dans nos applications. Ceci est fait une seule fois, et puis quiconque utilise le code n'a même pas besoin de savoir qu'il dépend de boost. Voici ce que nous utilisons. Il construira aussi bjam et bcp, s'ils n'ont pas déjà été construits.

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

Merci. C'est très proche de ce que je finirai par faire. – Escualo

0

Pourquoi ne pas simplement archiver tous les fichiers nécessaires dans SVN, et envoyer à vos collègues l'URL du référentiel? Ensuite, ils peuvent vérifier le code chaque fois qu'ils veulent, faire une « svn up » chaque fois qu'ils veulent mettre à jour à la dernière version, etc.

+0

Cela fonctionnerait pour vous et pour moi, mais pour certains de mes collègues, cela nécessiterait plus de sophistication qu'ils ne le voudraient. – Escualo

+1

Vous pourriez probablement envelopper la complexité dans un script ou une interface graphique pour eux. Il s'agit simplement d'une seule commande "svn co" (ou "svn up"), suivie de configure, make ou de quoi que ce soit. Avec un peu de travail, tout pourrait être lancé en double-cliquant sur une icône. –

3

Avez-vous songé à écrire juste un script de compilation pour un système de construction comme SCons?
Vous pouvez écrire un script python pour télécharger boost, décompressez-le compiler les fichiers nécessaires (vous pouvez même lancer bjam si nécessaire) et compiler votre propre code.
La seule dépendance dont vos collègues auront besoin est Python et SCons.

1

Exécutez le préprocesseur sur votre code et enregistrer la sortie. Si vous avez commencé avec un fichier main.cpp avec un tas d'inclusions, vous vous retrouverez avec un fichier où tous les fichiers inclus ont été aspirés. Si vous avez plusieurs fichiers cpp, vous devrez les concaténer ensemble, puis les exécuter le préprocesseur sur le fichier concaténé, cela devrait fonctionner tant que vous n'avez pas de noms de symboles globaux en double. Pour une méthode plus portable, faites ce que sqlite fait et écrivez votre propre script pour combiner et concaténer ensemble les fichiers que vous avez créés + boost, et ne pas inclure le système. Voir mksqlite3c.tcl dans le code sqlite
http://www2.sqlite.org/src/finfo?name=tool/mksqlite3c.tcl

+0

C'est vrai, mais je réponds à la question qu'il a posée, qui était de savoir comment en faire un fichier. – Zanson

+0

Merci d'avoir signalé le script Tcl. – Escualo

0

Si vous êtes sur une variété de Linux dérivée de Debian, bien des problèmes comme celui-ci ne devrait tout simplement pas venir: laisser le système d'emballage et manuel des politiques font le travail. Sachez simplement que le paquet libboost-dev ou quel que soit le paquet dépend de la construction de votre code et doit être installé au préalable, puis /usr/include/boost devrait être là où votre code s'attend à le trouver. Si vous utilisez une version plus récente de boost que la distribution, il vaut probablement la peine de trouver comment l'empaqueter vous-même et de travailler dans le cadre existant de l'empaquetage/dépendances plutôt que d'en réinventer un autre. Je ne suis pas assez familier avec les distributions basées sur .rpm pour commenter comment les choses fonctionnent là-bas. Mais sachant que je peux facilement configurer exactement l'environnement de construction dont j'ai besoin est, pour moi, l'un des plus grands avantages du développement basé sur Debian sur Windows.

Questions connexes