Простое и эффективное распространение исходного кода на C++/Boost (объединение)
Моя работа в основном состоит из инженерного анализа, но я все чаще и чаще распределяю код среди моих коллег. Большая боль в том, что не каждый пользователь владеет тонкостями компиляции исходного кода, и я не могу распространять исполняемые файлы.
Я работал с C++, используя Boost, и проблема в том, что я не могу запросить каждый системный администратор каждой сети для установки библиотек. Вместо этого я хочу распространять один исходный файл (или как можно меньше), чтобы пользователь мог g++ source.c -o program
,
Итак, вопрос: можете ли вы упаковать библиотеки Boost своим кодом и в итоге получить один файл? Я говорю о библиотеках Boost, которые являются "только заголовками" или "только шаблонами".
В качестве вдохновения, пожалуйста, посмотрите на дистрибутив SQlite или Lemon Parser Generator; автор объединяет материал в единый исходный файл, который легко скомпилировать.
Спасибо.
Редактировать:
Схожий вопрос в SO касается среды Windows. Я работаю в Linux.
5 ответов
Существует утилита, которая поставляется с надстройкой под названием 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
Рассматривали ли вы просто написание сценария сборки для системы сборки, такой как SCons?
Вы можете написать скрипт на python для загрузки boost, распаковать его, скомпилировать необходимые файлы (вы даже можете запустить bjam, если необходимо) и скомпилировать свой собственный код.
Ваша коллега будет нуждаться только в Python и SCons.
Запустите препроцессор для своего кода и сохраните вывод. Если вы начали с одного main.cpp с кучей включений в нем, вы получите один файл, в который были добавлены все включения. Если у вас несколько файлов cpp, вам придется объединить их вместе, а затем запустить препроцессор в объединенном файле, это должно работать, пока у вас нет повторяющихся глобальных имен символов.
Для более переносимого метода, сделайте то, что делает sqlite, и напишите свой собственный скрипт, чтобы просто объединить и объединить вместе файлы, которые вы создали + повысить, а не получить включенные в систему. Смотрите mksqlite3c.tcl в коде sqlite.
http://www2.sqlite.org/src/finfo?name=tool/mksqlite3c.tcl
Почему бы просто не проверить все необходимые файлы в SVN и отправить вам коллеги URL хранилища? Затем они могут проверить код, когда захотят, выполнить svn up в любое время, когда захотят обновить его до последней версии, и т. Д.
Если вы используете Linux, основанный на Debian, такие проблемы не должны возникать: пусть система упаковки и руководство по политике выполнят эту работу. Просто дайте понять, что libboost-dev или любой другой пакет является зависимостью сборки вашего кода и должен быть установлен заранее, а затем /usr/include/boost
должен быть там, где ваш код ожидает его найти. Если вы используете более свежую версию boost, чем дистрибутивы, вероятно, стоит выяснить, как упаковать ее самостоятельно и работать в рамках существующей инфраструктуры упаковки / зависимостей, а не изобретать другую.
Я не достаточно знаком с дистрибутивами на основе.rpm, чтобы комментировать, как там все работает. Но знание того, что я могу легко настроить именно ту среду сборки, которая мне нужна, является для меня одним из самых больших преимуществ разработки на основе Debian по сравнению с Windows.