2010-05-20 16 views
7

Mi trabajo consiste principalmente en análisis de ingeniería, pero me encuentro distribuyendo código cada vez más frecuentemente entre mis colegas. Un gran problema es que no todos los usuarios son competentes en las complejidades de compilar el código fuente, y no puedo distribuir los archivos ejecutables.Distribución simple y eficiente del código fuente C++/Boost (amalgamación)

He estado trabajando con C++ usando Boost, y el problema es que no puedo solicitar que todos los administradores de sistemas de todas las redes instalen las bibliotecas. En su lugar, quiero distribuir un único archivo fuente (o el menor número posible) para que el usuario pueda g++ source.c -o program.

Entonces, la pregunta es: ¿puedes paquete las bibliotecas de Boost con tu código, y terminar con un solo archivo? Estoy hablando de las bibliotecas de Boost que son solo "encabezados" o "solo plantillas".

Como inspiración, mire la distribución de SQlite o Lemon Parser Generator; el autor amalgama las cosas en un único archivo fuente que es trivial de compilar.

Gracias.

Editar:

Un related question in SO es para entorno Windows. Yo trabajo en Linux.

+1

¿Qué tan lejos quieres ir por este camino? ¿Qué pasa con otras bibliotecas que quizás no hayan instalado? Es probable que desee ver algún tipo de gestor de paquetes o mecanismo de compilación automatizado (¿quizás un archivo shar?). – KeithB

Respuesta

11

Hay una utilidad que viene con boost llamada bcp, que puede escanear su fuente y extraer cualquier encabezado de impulso que se use de la fuente de impulso. He configurado una secuencia de comandos que realiza esta extracción en nuestro árbol de fuentes, para que podamos empaquetar la fuente que necesitamos junto con nuestro código. También copiará los archivos fuente de refuerzo para un par de bibliotecas de refuerzo que utilizamos que no son solo encabezados, que luego se compilan directamente en nuestras aplicaciones.

Esto se hace una vez, y luego cualquiera que use el código ni siquiera necesita saber que depende del impulso. Esto es lo que usamos. También construirá bjam y bcp, si aún no se han construido.

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

Gracias. Esto está muy cerca de lo que terminaré haciendo. – Escualo

0

¿Por qué no simplemente registrar todos los archivos necesarios en SVN, y enviarle a los compañeros de trabajo la URL del repositorio? Luego pueden consultar el código cuando lo deseen, hacer un 'svn up' en cualquier momento que deseen actualizar a la última versión, etc.

+0

Esto funcionaría para usted y para mí, pero para algunos de mis colegas esto requeriría más sofisticación de la que están dispuestos/tienen tiempo para soportar. – Escualo

+1

Probablemente pueda resumir la complejidad en una secuencia de comandos o interfaz gráfica de usuario para ellos. Realmente solo se trata de un solo comando "svn co" (o "svn up"), seguido de configure, make o lo que sea. Con un poco de trabajo, todo podría iniciarse haciendo doble clic en un ícono. –

3

¿Ha considerado escribir un script de compilación para un sistema de compilación como SCons?
Puede escribir un script de python para descargar boost, descomprimirlo compilar los archivos necesarios (incluso puede ejecutar bjam si es necesario) y compilar su propio código.
La única dependencia que sus colegas necesitarán es Python y SCons.

1

Ejecute el preprocesador en su código y guarde la salida. Si comenzaste con un main.cpp con un montón de includes en él, terminarás con un archivo donde todos los includes han sido absorbidos. Si tienes varios archivos cpp, tendrás que juntarlos y luego ejecutarlos el preprocesador en el archivo concatenado, esto debería funcionar siempre y cuando no tenga ningún nombre de símbolo global duplicado.

Para un método más portátil, haz lo que hace sqlite y escribe tu propia secuencia de comandos para simplemente combinar y combinar juntos los archivos que creaste + boost, y que no incluye el sistema. Ver mksqlite3c.TCL en el código SQLite
http://www2.sqlite.org/src/finfo?name=tool/mksqlite3c.tcl

+0

Es cierto, pero estoy respondiendo a la pregunta que hizo, que fue cómo convertirlo en un solo archivo. – Zanson

+0

Gracias por señalar el script Tcl. – Escualo

0

Si estás en una variedad derivada de Debian de Linux, así problemas como éste simplemente no debería llegar: dejar que el sistema de embalaje y manual de políticas hacen el trabajo. Simplemente deje en claro que el paquete libboost-dev o lo que sea es una dependencia de compilación de su código y debe instalarse de antemano, y luego /usr/include/boost debería estar allí donde su código espera encontrarlo. Si está utilizando una versión de impulso más reciente que los barcos de distribución, probablemente valga la pena averiguar cómo empaquetarlo usted mismo y trabajar dentro del marco existente de empaquetado/dependencias en lugar de reinventar otro.

No estoy lo suficientemente familiarizado con las distribuciones basadas en .rpm para comentar cómo funcionan las cosas allí. Pero saber que puedo configurar fácilmente exactamente el entorno de compilación que necesito es, para mí, una de las mayores ventajas del desarrollo basado en Debian con respecto a Windows.

Cuestiones relacionadas