2012-06-15 45 views
9

我们有Boost库在我们身边。它由大量的文件组成,这些文件永远不会改变,只有很小的一部分被使用。如果我们正在更改版本,我们将交换整个boost目录。目前我们在我们的SVN中有Boost源文件,这使得结帐操作非常缓慢,特别是在Windows上。g ++:使用ZIP文件作为输入

如果有一个符号/插件,以解决ZIP文件内的C++文件,像这将是很好:

// @ZIPFS ASSIGN 'boost' 'boost.zip/boost' 
#include <boost/smart_ptr/shared_ptr.hpp> 

是否有以g编译挂钩的任何++的支持?有关ZIP支持的努力吗?其他想法?

+0

如果您使用'g ++',为什么不使用'gzip'来匹配?哈哈糟糕的笑话+1。 –

+6

从SVN转移到现代SCM系统?或者,您可以将boost目录压缩到SVN中,以便快速结帐,然后在必要时让部分构建过程解压缩该文件。 – bames53

+0

@ bames53想到了。由于提取了许多小文件,它不会在Windows上节省太多时间。当然,这会更好一些。 – Notinlist

回答

9

我认为make或类似的构建系统涉及构建软件的过程。我会将zip文件放入存储库中,并在Makefile开始之前向Makefile中添加一条规则以提取它。例如,假设你的zip文件位于“external/boost.zip”的源代码树中,它应该被提取到“external/boost”,并且它的顶级包含一个文件“boost_version.h” 。

# external/Makefile 
unpack_boost: boost/boost_version.h 

boost/boost_version.h: boost.zip 
    unzip $< 

我不知道unzip调用的确切语法,请问你的manpage关于这个。

然后在其他Makefiles中,您可以让源文件依赖于unpack_boost目标,以便make在编译源文件之前解压Boost。

# src/Makefile (excerpt) 
unpack_boost: 
    make -C ../external unpack_boost 

source_file.cpp: unpack_boost 

如果您使用的是Makefile生成器(或一个完全不同的编译系统),请检查这些方案如何创造这样的定制目标unpack_boost的文档。例如,在CMake中,您可以使用add_custom_command指令。

细则:boost/boost_version.h文件不是Makefile工作所必需的。您可以将unzip命令放入unpack_boost目标中,但目标实际上是假的,即:它将在每次构建期间执行。中间文件(当然,您需要用实际存在于zip压缩文件中的文件替换)确保unzip只在必要时运行。

2

这是你不会在g ++中做的事情,因为任何其他想要做它的应用程序也必须修改。

将文件存储在压缩文件系统中。然后每个应用程序自动获得收益。

+0

如果g ++没有像那样“挂钩”,那么注释将被忽略,并且可以手动提取zip(作为后备)。 Boost不需要知道这一切。第二:压缩文件系统不会加速结帐。 – Notinlist

2

在操作系统中应该可以允许透明地访问ZIP文件中的文件。我知道很久以前(2004年左右)我把它放在了我自己的操作系统的设计中,但从来没有达到它可用的程度。不利的一面是,在压缩文件中向后搜索文件的速度比压缩文件慢(并且无法倒回压缩器状态,因此您必须从开始寻找)。这也使得使用拉链内拉链缓慢倒带和阅读。幸运的是,大多数情况下只是依次读取文件。

对于当前的操作系统,至少在客户端空间上也应该是可以改进的。您可以挂钩使用的文件系统访问函数(fopen,open,...)并添加一组虚拟文件描述符,您自己的软件将返回给定文件名。如果它是一个真正的文件传递它,如果它不打开底层文件(可能再次通过这个非常功能)并传递一个虚拟句柄。在访问文件内容时,直接从zip文件中读取而不进行缓存。

在Linux上,您将使用LD_PRELOAD将其注入到现有软件中(在使用时间),在Windows上,您可以挂接系统调用或将DLL注入软件空间以挂接相同的函数。

有谁知道这是否已经存在?我看不出任何明确的理由,它不会...

+1

在LINUX上有FUSE内核模块(Filesystem User Space E-whatever)。 –

4

我们一直在我们公司面临类似的问题。在构建环境中管理boost版本绝非易事。拥有10多个开发人员,所有编码都在他们自己的系统上,您将需要某种自动化。首先,我认为在SVN或任何SCM系统中存储类似boost的大型库的副本并不是一个好主意,但这不是这些系统设计的目的,除非您计划在boost中修改代码你自己。但让我们假设你没有这样做。

下面是我们现在如何管理它,尝试了很多不同的方法后,这对我们最有效。

对于我们使用的每种boost版本,我们将整个树(解压缩)放在一个文件服务器上,并且为每个架构/编译器组合添加额外的子目录,其中放置编译的库。 我们保持每构建系统上这些树的副本,并在全局系统环境中,我们添加变量一样:

BOOST_1_48=C:\boost\1.48 # Windows environment var 

BOOST_1_48=/usr/local/boost/1.48 # Linux environment var, e.g. in /etc/profile.d/boost.sh 

该目录包含升压树(升压/ * HPP)和所添加的预编译库(例如lib/win/x64/msvc2010/libboost_system * .lib,...)

所有构建配置(vs解决方案,vs属性文件,gnu makefiles,...)定义一个内部变量,导入环境变量,如:

BOOSTROOT=$(BOOST_1_48) # e.g. in a Makefile, or an included Makefile 

和进一步的构建规则都使用BOOSTROOT设置来定义包括路径和库搜索路径,例如,

CXXFLAGS += -I$(BOOSTROOT) 
LFLAGS += -L$(BOOSTROOT)/lib/linux/x64/ubuntu/precise 
LFLAGS += -lboost_date_time 

保留本地副本的原因是编译速度。它占用了相当多的磁盘空间,尤其是编译后的库,但是存储成本低廉,而且开发人员不会花费大量时间编译代码。另外,这只需要复制一次。

使用全局环境变量的原因是构建配置可以从一个系统转移到另一个系统,因此可以安全地检入您的SCM系统。

为了使事情平滑一些,我们开发了一个小工具,负责复制和设置全球环境。使用CLI,甚至可以将其包含在构建过​​程中。

不同的工作环境意味着不同的规则和文化,但相信我,我们已经尝试了很多东西,最后,我们决定定义某种约定。也许我们可以激励你...

+0

这与我们如何操作类似,除了我们将symlink boost /添加到存在的各种增强版本之外。 – KitsuneYMG

+0

这很好,只要文件系统支持符号链接即可。我们需要一种适用于Windows和* nix系统的方法。 – Pat

7

一年前,我和你一样处于同样的位置。我们将源码保存在SVN中,更糟糕的是,在与我们自己的代码相同的存储库(同一分支)中包含了增强功能。尝试在多个分支上工作是不可能的,因为这需要大部分时间才能检出新的工作副本。将推动力转移到单独的供应商存储库中有所帮助,但它仍需要花费数小时才能退出。

我把团队转到了git。为了给你一个比SVN好多少的想法,我刚刚创建了一个包含boost 1.45.0版本的存储库,然后通过网络克隆它。 (克隆复制所有存储库历史记录,在这种情况下是单次提交,并创建一个工作副本。)

该克隆耗时六分钟。

在前六秒内,存储库的压缩副本被复制到我的机器上。剩下的时间花在编写所有这些小文件。

我衷心推荐你试试git。学习曲线非常陡峭,但是我怀疑你会在克隆一个boost副本所需的时间内完成很多预编译器黑客工作。