Простое и эффективное распространение исходного кода на C ++ / Boost (объединение) - PullRequest
7 голосов
/ 20 мая 2010

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

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

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

В качестве вдохновения, пожалуйста, посмотрите на распределение SQlite или Lemon Parser Generator ; автор объединяет материал в единый исходный файл, который легко скомпилировать.

Спасибо.

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

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

Ответы [ 5 ]

11 голосов
/ 20 мая 2010

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

Это делается один раз, и тогда любому, кто использует код, даже не нужно знать, что это зависит от наддува. Вот что мы используем. Он также будет собирать 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
3 голосов
/ 20 мая 2010

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

1 голос
/ 20 мая 2010

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

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

0 голосов
/ 21 мая 2010

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

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

0 голосов
/ 20 мая 2010

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

...