Простое и эффективное распределение исходного кода C++/Boost (объединение)

моя работа в основном состоит из инженерного анализа, но я все чаще и чаще распространяю код среди своих коллег. Большая боль заключается в том, что не каждый пользователь владеет тонкостями компиляции исходного кода, и я не могу распространять исполняемые файлы.

Я работал с C++ с помощью Boost, и проблема в том, что я не могу запросить каждого системного администратора каждой сети для установки библиотек. Вместо этого я хочу распространить один исходный файл (или несколько возможно) , чтобы пользователь мог g++ source.c -o program.

Итак, вопрос: Можете ли вы упаковка библиотеки Boost с вашим кодом и в конечном итоге с одним файлом? Я говорю о библиотеках Boost, которые являются "только заголовками"или" только шаблонами".

в качестве вдохновения, пожалуйста, посмотрите на распределение SQLite в или Генератор Парсера Лимона; автор объединяет материал в один исходный файл, который тривиален для компилировать.

спасибо.

редактировать:

на связанный вопрос в SO для среды Windows. Я работаю в Linux.

5 ответов


существует утилита, которая поставляется с boost под названием bcp, который может сканировать ваш источник и извлекать любые файлы заголовков boost, которые используются из источника boost. Я настроил сценарий, который делает это извлечение в наше дерево источников, чтобы мы могли упаковать источник, который нам нужен, вместе с нашим кодом. Он также скопирует исходные файлы boost для нескольких библиотек boost, которые мы используем, которые не являются только заголовками, которые затем компилируются непосредственно в наши приложения.

Это сделано один раз, и тогда любой, кто использует код, даже не должен знать, что это зависит от boost. Вот что мы используем. Он также построит bjam и bcp, если они еще не были построены.

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

вы рассматривали просто написание сценария сборки для системы сборки, такой как проектов SCons?
Вы можете написать скрипт python для загрузки boost, распаковать его, скомпилировать необходимые файлы (при необходимости вы даже можете запустить bjam) и скомпилировать свой собственный код.
Единственная зависимость ваших коллег понадобится Python и проектов SCons.


запустите препроцессор в коде и сохраните выходные данные. Если вы начали с одного главного.cpp с кучей включает в себя, вы в конечном итоге с одним файлом, где все включает были всасываются. Если у вас есть несколько файлов cpp, вам придется объединить их вместе, а затем запустить препроцессор в объединенном файле, это должно работать до тех пор, пока у вас нет дубликатов глобальных имен символов.

для более портативного метода сделайте то, что делает sqlite, и напишите собственный скрипт, чтобы просто объединить и объединить вместе файлы, которые вы создали + boost, а не получить систему включает. См. mksqlite3c.tcl в коде sqlite
http://www2.sqlite.org/src/finfo?name=tool/mksqlite3c.tcl


Почему бы просто не проверить все необходимые файлы в SVN и не отправить вам сотрудникам URL репозитория? Затем они могут проверить код, когда захотят, сделать "svn up" в любое время, когда они хотят обновить до последней версии и т. д.


Если вы находитесь на Debian-производной разновидности Linux, ну, такие проблемы, как это, просто не должны возникать: пусть система упаковки и руководство по политике делают работу. Просто дайте понять, что libboost-dev или любой другой пакет является зависимостью от сборки вашего кода и должен быть установлен заранее, а затем /usr/include/boost должно быть прямо там, где ваш код ожидает его найти. Если вы используете более позднюю версию boost, чем дистрибутивы, вероятно, стоит выяснить, как ее упаковать вы и работаете в рамках существующей структуры упаковки / зависимостей, а не изобретаете другую.

Я недостаточно знаком с .RPM на основе дистрибутивов, чтобы прокомментировать, как там все работает. Но знание того, что я могу легко настроить именно ту среду сборки, которая мне нужна, является для меня одним из самых больших преимуществ разработки на основе Debian по сравнению с Windows.