My job mostly consists of engineering analysis, but I find myself distributing code more and more frequently among my colleagues. A big pain is that not every user is proficient in the intricacies of compiling source code, and I cannot distribute executables.
我的工作主要是工程分析,但我发现自己越来越频繁地在同事之间分发代码。一个很大的痛苦是并不是每个用户都精通编译源代码的复杂性,而且我不能分发可执行文件。
I've been working with C++ using Boost, and the problem is that I cannot request every sysadmin of every network to install the libraries. Instead, I want to distribute a single source file (or as few as possible) so that the user can g++ source.c -o program
.
我一直在使用c++使用Boost,但问题是我不能要求每个网络的每个系统管理员安装库。相反,我希望分发单个源文件(或尽可能少),以便用户能够使用g++源。c - o程序。
So, the question is: can you pack the Boost libraries with your code, and end up with a single file? I am talking about the Boost libraries which are "headers only" or "templates only".
因此,问题是:是否可以将Boost库与代码打包,并最终得到一个文件?我说的是Boost库,它们是“只包含头部”或“只包含模板”。
As an inspiration, please look at the distribution of SQlite or the Lemon Parser Generator; the author amalgamates the stuff into a single source file which is trivial to compile.
作为灵感,请查看SQlite或Lemon Parser Generator的分布;作者将这些内容合并到一个单独的源文件中,这对于编译是很容易的。
Thank you.
谢谢你!
Edit:
编辑:
A related question in SO is for Windows environment. I work in Linux.
SO中的一个相关问题是Windows环境。我在Linux中工作。
5 个解决方案
#1
11
There is a utility that comes with boost called bcp
, that can scan your source and extract any boost header files that are used from the boost source. I've setup a script that does this extraction into our source tree, so that we can package the source that we need along with our code. It will also copy the boost source files for a couple of boost libraries that we use that are no header only, which are then compiled directly into our applications.
有一个叫做bcp的实用工具,它可以扫描您的源代码并提取boost源代码中使用的任何boost头文件。我已经设置了一个脚本,该脚本在源代码树中进行提取,这样我们就可以将所需的源代码与代码一起打包。它还将复制boost源文件,用于我们使用的几个不只是头文件的boost库,然后将这些文件直接编译到我们的应用程序中。
This is done once, and then anybody who uses the code doesn't even need to know that it depends on boost. Here is what we use. It will also build bjam and bcp, if they haven't been build already.
这样做一次,然后使用代码的人甚至不需要知道它依赖于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
#2
3
Have you considered just writing a build script for a build system like SCons?
You could write a python script to download boost, unpack it compile the needed files (you can even run bjam if needed) and compile your own code.
The only dependency your colleagues will need is Python and SCons.
您是否考虑过为像SCons那样的构建系统编写构建脚本?您可以编写一个python脚本来下载boost,解压缩它来编译所需的文件(如果需要,您甚至可以运行bjam)并编译您自己的代码。您的同事将需要的惟一依赖项是Python和SCons。
#3
1
Run the preprocessor on your code and save the output. If you started with one main.cpp with a bunch of includes in it, you will end up with one file where all of the includes have been sucked in. If you have multiple cpp files, you will have to concatinate them together and then run the preprocessor on the concatinated file, this should work as long as you don't have any duplicate global symbol names.
在代码上运行预处理器并保存输出。如果你从一条主线开始。cpp中包含了一系列的include,您最终会得到一个文件,其中所有的include都被包含进来了。如果您有多个cpp文件,那么您将不得不将它们合并在一起,然后在concatated文件上运行预处理器,只要您没有任何重复的全局符号名称,这应该可以工作。
For a more portable method, do what sqlite does and write your own script to just combine and concatinate together the files you created+boost, and not get the system includes. See mksqlite3c.tcl in the sqlite code
http://www2.sqlite.org/src/finfo?name=tool/mksqlite3c.tcl
对于更便携的方法,按照sqlite的做法,编写您自己的脚本,将您创建的+boost文件合并在一起,而不获取系统包含。看到mksqlite3c。tcl在sqlite代码http://www2.sqlite.org/src/finfo?name=tool/mksqlite3c.tcl。
#4
0
Why not just check in all the necessary files to SVN, and send you co-workers the URL of the repository? Then they can check out the code whenever they want to, do an 'svn up' any time they want to update to the latest version, etc.
为什么不直接将所有必需的文件签入SVN,并将存储库的URL发送给您的同事呢?然后,他们可以在任何时候查看代码,在任何时候更新最新版本时进行“svn up”等等。
#5
0
If you're on a Debian-derived variety of Linux, well problems like this just shouldn't come up: let the packaging system and policy manual do the work. Just make it clear that the libboost-dev or whatever package is a build-dependency of your code and needs to be installed beforehand, and then /usr/include/boost
should be right there where your code expects to find it. If you're using a more recent version of boost than the distro ships, it's probably worth figuring out how to package it yourself and work within the existing packaging/dependencies framework rather than reinventing another one.
如果您使用的是debian派生的Linux,那么这样的问题不应该出现:让打包系统和策略手册来完成工作。只需说明libboost-dev或其他包是代码的构建依赖项,需要预先安装,然后/usr/include/boost应该在您的代码希望找到它的地方。如果您使用的是比发行版更新的boost版本,那么您应该考虑如何自己打包它,并在现有的打包/依赖框架中工作,而不是重新创建另一个。
I'm not familiar enough with .rpm based distros to comment on how things work there. But knowing I can easily setup exactly the build environment I need is, for me, one of the biggest advantages of Debian based development over Windows.
我对基于.rpm的发行版还不够熟悉,无法评论那里的工作方式。但是知道我可以轻松地设置我需要的构建环境,对我来说,基于Debian的开发相对于Windows的最大优势之一。
#1
11
There is a utility that comes with boost called bcp
, that can scan your source and extract any boost header files that are used from the boost source. I've setup a script that does this extraction into our source tree, so that we can package the source that we need along with our code. It will also copy the boost source files for a couple of boost libraries that we use that are no header only, which are then compiled directly into our applications.
有一个叫做bcp的实用工具,它可以扫描您的源代码并提取boost源代码中使用的任何boost头文件。我已经设置了一个脚本,该脚本在源代码树中进行提取,这样我们就可以将所需的源代码与代码一起打包。它还将复制boost源文件,用于我们使用的几个不只是头文件的boost库,然后将这些文件直接编译到我们的应用程序中。
This is done once, and then anybody who uses the code doesn't even need to know that it depends on boost. Here is what we use. It will also build bjam and bcp, if they haven't been build already.
这样做一次,然后使用代码的人甚至不需要知道它依赖于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
#2
3
Have you considered just writing a build script for a build system like SCons?
You could write a python script to download boost, unpack it compile the needed files (you can even run bjam if needed) and compile your own code.
The only dependency your colleagues will need is Python and SCons.
您是否考虑过为像SCons那样的构建系统编写构建脚本?您可以编写一个python脚本来下载boost,解压缩它来编译所需的文件(如果需要,您甚至可以运行bjam)并编译您自己的代码。您的同事将需要的惟一依赖项是Python和SCons。
#3
1
Run the preprocessor on your code and save the output. If you started with one main.cpp with a bunch of includes in it, you will end up with one file where all of the includes have been sucked in. If you have multiple cpp files, you will have to concatinate them together and then run the preprocessor on the concatinated file, this should work as long as you don't have any duplicate global symbol names.
在代码上运行预处理器并保存输出。如果你从一条主线开始。cpp中包含了一系列的include,您最终会得到一个文件,其中所有的include都被包含进来了。如果您有多个cpp文件,那么您将不得不将它们合并在一起,然后在concatated文件上运行预处理器,只要您没有任何重复的全局符号名称,这应该可以工作。
For a more portable method, do what sqlite does and write your own script to just combine and concatinate together the files you created+boost, and not get the system includes. See mksqlite3c.tcl in the sqlite code
http://www2.sqlite.org/src/finfo?name=tool/mksqlite3c.tcl
对于更便携的方法,按照sqlite的做法,编写您自己的脚本,将您创建的+boost文件合并在一起,而不获取系统包含。看到mksqlite3c。tcl在sqlite代码http://www2.sqlite.org/src/finfo?name=tool/mksqlite3c.tcl。
#4
0
Why not just check in all the necessary files to SVN, and send you co-workers the URL of the repository? Then they can check out the code whenever they want to, do an 'svn up' any time they want to update to the latest version, etc.
为什么不直接将所有必需的文件签入SVN,并将存储库的URL发送给您的同事呢?然后,他们可以在任何时候查看代码,在任何时候更新最新版本时进行“svn up”等等。
#5
0
If you're on a Debian-derived variety of Linux, well problems like this just shouldn't come up: let the packaging system and policy manual do the work. Just make it clear that the libboost-dev or whatever package is a build-dependency of your code and needs to be installed beforehand, and then /usr/include/boost
should be right there where your code expects to find it. If you're using a more recent version of boost than the distro ships, it's probably worth figuring out how to package it yourself and work within the existing packaging/dependencies framework rather than reinventing another one.
如果您使用的是debian派生的Linux,那么这样的问题不应该出现:让打包系统和策略手册来完成工作。只需说明libboost-dev或其他包是代码的构建依赖项,需要预先安装,然后/usr/include/boost应该在您的代码希望找到它的地方。如果您使用的是比发行版更新的boost版本,那么您应该考虑如何自己打包它,并在现有的打包/依赖框架中工作,而不是重新创建另一个。
I'm not familiar enough with .rpm based distros to comment on how things work there. But knowing I can easily setup exactly the build environment I need is, for me, one of the biggest advantages of Debian based development over Windows.
我对基于.rpm的发行版还不够熟悉,无法评论那里的工作方式。但是知道我可以轻松地设置我需要的构建环境,对我来说,基于Debian的开发相对于Windows的最大优势之一。