git-buildpackage示例(一)

在《为tolua的deb包作一个补丁》中,我介绍了如何利用quilt为Ubuntu已有包做一个补丁包的办法。可以看出quilt具有一定的版本管理能力,然而与流行版本管理系统相比,功能较弱也不灵活。

Debian New Maintainers’ Guide中,了解到deb包的制作和维护管理已经与现有流行版本管理系统结合在了一块,其中一款工具为git-buildpackage,它将包制作和维护,特别是第三方补丁包维护,与git紧密的结合了起来。

下面仍然以tolua的补丁制作为例,一步一步展示git-buildpackage的基本操作。

  • 安装必要的工具:
sudo apt-get install git-buildpackage build-essential debhelper quilt
  • 下载libtolua-dev的源码(建立upstream目录单独存放Ubuntu的deb源码包是为了保证清洁和正确):
mkdir upstream
apt-get source libtolua-dev
  • 导入upsteam的dsc文件(将生成与目录upstream同级的目录tolua):
cd ..
git-import-dsc upstream/tolua_5.1.3-1.dsc
cd tolua

这时,运行

git log --format=%d:%s

输出:

 (HEAD, debian/5.1.3-1, master):Imported Debian patch 5.1.3-1
 (upstream/5.1.3, upstream):Imported Upstream version 5.1.3

从下至上,首条提交导入了tolua 5.1.3的源码,次条提交导入了deb包维护者的deb包文件(debian/*);并且建立了upstream和master两个分支,标签upstream/5.1.3位于upstream分支上,标签debian/5.1.3-1位于master分支头部。

此外,upstream分支用于维护源码作者的发布版本更新情况,master分支用于维护deb包描述文件及其补丁文件。git-buildpackage工具集的正确运行将依赖于标签upstream/5.1.3和debian/5.1.3-1,不能随意删改。

  • 导入quilt patches到patch queue中——创建patch-queue/master分支,并将debian/patches/*逐一变成该分支的提交,并自动切换到该分支上:
gbp-pq import
  • 执行make后发现构建目标libtolua.a的生成目录lib不存在,这是git只针对文件做版本,所以upstream导入git时,该目录被忽略了。为此,我将src/lib/Makefile中
$T: $(OBJS)
	$(AR) $@ $(OBJS)
	$(RANLIB) $@

修改为:

$T: $(OBJS)
	mkdir -p $(@D)
	$(AR) $@ $(OBJS)
	$(RANLIB) $@

这样,它将在每次构建该目标时,创建该目标所在目录。更进一步不难发现,src/bin/tolua_lua.o和src/bin/toluabind.c为受版本控制的中间文件,将影响构建的正确运行。为此,删除这两个文件并提交日志。

Ubuntu VirtualBox的Host-only网卡上外网和DHCP永久地址

VirtualBox支持各种虚拟网络:NAT, Bridge Adapter, Internal Network和Host-only Adapter等。其中Bridged Adapter最为简单和常用,它几乎是0配置,直接桥接有线或无线物理网卡就可以与互联网通信。

然而,我工作场所内部网和家里内部网的网段不相同,DHCP存在一定租赁时间,如果使用Bridged Adapter并DHCP获取IP地址的时候,虚拟机地址经常会改变。为此,我将笔记本电脑的VirtualBox虚拟机都修改为Host-only Adapter模式。

存在2个问题:

  • Host-only Adapter(网段为192.168.56.0/24)默认不能与互联网通信。
  • VirtualBox内置DHCP的IP租赁时间设置,也无法将MAC地址与IP地址静态绑定,这造成虚拟机IP地址每隔一段时间改变一次,给使用带来诸多不方便。另一方面,我也不想静态设置IP地址,因为如果这样做,我必须每安装一次虚拟机都要重新设置IP地址。

以前就听说过dnsmasq,不仅集成DNS、DHCP和TFTP功能,而且占用资源很少,设置也相对简单。

安装dnsmasq

sudo apt-get install -y dnsmasq

创建/etc/dnsmasq.d-available/vboxnet0,针对vboxnet0配置DHCP。

interface=vboxnet0

dhcp-option=vboxnet0,option:dns-server,192.168.56.1,208.67.222.222,208.67.220.220

dhcp-range=vboxnet0,192.168.56.2,192.168.56.254,infinite
  • dhcp-option: 192.168.56.1是默认网关 (host机器的vboxnet0地址). 208.67.222.222和208.67.220.220是DNS地址 (这里使用了OpenDNS).
  • dhcp-range: 192.168.56.2和192.168.56.254为分配地址范围. infinite表示IP永远不过期.

创建/etc/network/interfaces.d/vboxnet0

auto vboxnet0
allow-hotplug vboxnet0
iface vboxnet0 inet static
	address 192.168.56.1
	netmask 255.255.255.0
	post-up ln -sf /etc/dnsmasq.d-available/vboxnet0 /etc/dnsmasq.d/vboxnet0
	post-up service dnsmasq restart
	post-up rm -f /etc/dnsmasq.d/vboxnet0
	post-up iptables -t nat -I POSTROUTING -s 192.168.56.0/24 -j MASQUERADE
	post-down service dnsmasq restart
	post-down iptables -t nat -D POSTROUTING -s 192.168.56.0/24 -j MASQUERADE
  • allow-hotplug: 当启动VirtualBox图形界面时,它将创建vboxnet0. 这将触发NetworkManager自动执行ifup vboxnet0
  • post-up
    1. 启用/etc/dnsmasq.d-available/vboxnet0
    2. 重启dnsmasq,让它监听192.168.56.1
    3. 删除/etc/dnsmasq.d-available/vboxnet0. vboxnet0通常不会随系统启动而自动创建,若默认配置vboxnet0于dnsmasq中,将导致dnsmasq启动失败。
    4. 路由192.168.56.0/24网段,使VirtualBox虚拟机与外网通讯。

激活vboxnet0

sudo ifup vboxnet0

重启动dnsmasq

sudo service dnsmasq restart

静态地址绑定

/etc/dnsmasq.d/dhcp-host 中针对MAC地址08:00:27:81:51:85,分配机器名vbox-xp,分配IP地址192.168.56.2

为tolua的deb包作一个补丁

近日在学习tolua时发现在Kubuntu 11.10 amd64平台下将其链接到so时报告如下错误:

relocation R_X86_64_32 against ‘.rodata’ can not be used when making a shared object; recompile with -fPIC

为此,我决定在其原deb基础上加一个补丁,这样生成的新包可以安装到其他开发机器上,省去了每次重编译tolua的重复劳动。

为构建和修改deb安装必要的工具(配置quilt):

sudo apt-get install build-essential debhelper quilt

下载libtolua-dev的源码,创建补丁add-fpic-O2-for-amd64.patch,并将config文件加入其中:

apt-get source libtolua-dev
cd tolua-5.1.3
mkdir -p debian/patches
quilt new add-fpic-O2-for-amd64.patch
quilt add config

将config文件中,如下内容

CFLAGS = -g $(WARN) $(INC)
CPPFLAGS = -g $(WARN) $(INC)

替换为

CFLAGS = -fPIC -O2 -pipe -g $(WARN) $(INC)
CPPFLAGS = -fPIC -O2 -pipe  -g $(WARN) $(INC)
CFLAGS = -fPIC -O2 -pipe -g $(WARN) $(INC)

生成补丁add-fpic-O2-for-amd64.patch

quilt refresh

为补丁增加描述信息

MakeProjectCreator (MPC) 简介

Makefile, Project, and Workspace Creator (MPC) 原始OCI为网络通信库ACE开发的跨平台工程文件生成工具,它可以生成很多种工程文件,例如Windows平台的Borland Developer Studio, Borland C++ Build 2007, Borland Makefile,Microsoft eMbedded VC3, Microsoft Visual C++ 6/7/71/8/9/10, nmake;Linux平台的automake, make等。

下面将以Windows平台的nmake和vc9为例介绍MPC的使用方法。首先,我们需要下载

  1. ActivePerl,双击执行安装;
  2. MPC,以解压到C:盘为例,设置系统环境变量MPC_ROOT为C:\MPC,以及将%MPC_ROOT%追加系统环境变量PATH。当然,你也可以通过双击执行C:\MPC\registry.pl将生成工程文件的功能注册到右键菜单中。

一、一个Hello World工程

首先,建立目录helloworld,并且在这个目录下且创建helloworld.cpp,内容如下:

int main ()
{
    std::cout << "Hello World!" << std::endl;
}

然后,创建MPC工程文件helloworld.mpc,内容如下:

project {
	exename = helloworld
}

最后,打开Visual Studio 2008 Command Prompt(也可以用VS2003或2005的),进入helloworld的目录, 然后输入

mwc.pl -type nmake

就生成了格式为nmake的Makefile,它默认包含两个配置Debug和Release。让我们编译一下Debug版本:

nmake CFG="Win32 Debug"

你会发现helloworld.exe就生成在当前目录。

或许你希望debug和release生成的exe分别放在debug和release目录,修改一下MPC文件

project {
	exename = helloworld
	specific (nmake, vc6, vc7, vc71, vc8, vc9, vc10) {
		Debug::install = debug
		Release::install = release
	}
}

或许你更喜欢用IDE,让我们生成VS2008的工程文件吧: