Home Wiki > openSUSE:Build Service Tips and Tricks
Sign up | Login

openSUSE:Build Service Tips and Tricks

tagline: 来自openSUSE


本指南列出了一些小的没有归类的编译服务的技巧和花样。大多数技巧都可以归类为其他指南并从这里移除。本页面旨在第一手搜集那些应该被详细解释或快速修复的信息。

大多数信息都搜集自 编译服务邮件列表 (存档)。

目录

禁用某些软件包在某些源的编译

有好几种方法来禁用一个软件包的编译.一种禁用软件包编译的方法是 使用 'osc' 命令行客户端. 使用:

osc api -X POST "/source/PROJECT/PACKAGE?cmd=set_flag&flag=build&status=disable" # 然后
osc api -X POST "/source/PROJECT/PACKAGE?cmd=set_flag&flag=build&status=enable" # 下面的更好一些
osc api -X POST "/source/PROJECT/PACKAGE?cmd=remove_flag&flag=build"

或者用下面命令编辑源的元数据 XML 文件:

osc meta pkg -e <project> <package>

并在 <build> 下面添加 <disable/> 标签. 你也可以使用:

<!-- [...] -->
<build>
  <disable arch="架构"/>
</build>
<!-- [...] -->

或者:

<!-- [...] -->
<build>
  <disable repository="源名称如 openSUSE_11.3"/>
</build>
<!-- [...] -->

或者两者结合, 如:

<!-- [...] -->
<build>
  <disable repository="SLES_9" arch="x86_64"/>
</build>
<!-- [...] -->

另一种方法是使用 网页客户端 点击问题软件包的源按钮.

注意: 已经开始的工作不会被停止. 想要永久的移除他们, 你需要在你本地 obs 的 /srv/obs/jobs/ 中移除它们.

中止正在编译的软件包

osc abortbuild <project> <package> <repo> <arch>

展开 (Expansion) 错误

如果你编译软件包时遇到像这样的错误:

expansion error have choice for inet-daemon needed by imap: inetd xinetd

你有两个选择:

  • 最快捷的修复是添加一个错误提示中提到的软件包(inetd 或 xinetd)到 BuildRequires
  • 另一个修复办法是在你的 project conf 中设定一个优先包,命令是:osc meta -e prjconf <Project> 然后添加这一行:Prefer: xinetd
  • 长远的修复是写一封邮件给 编译服务邮件列表,请求添加其中一个包到软件源的 .dsc 文件,这样其他有同样问题的软件包也可以自动被修复。

在一个项目中查找软件包

有时候你想要在一个项目中查找一个软件包是如何命名的,尤其是在一个基础项目中查找要用在 BuildRequires 行的软件包。有一条 osc 调用技巧可以用来查找它。

这个命令:

 osc ls -b -r standard -a i586 Fedora:17

会列出所有在 Fedora 17 中的二进制软件包。从输出中选择软件包名。

详情参考:

 osc ls --help 

只在 OBS 里适用的 spec 代码

如果你想要在编译服务之外使用你的 spec 文件,出于一些原因,你想要区别 OBS 专用的代码,你可以使用宏 %opensuse_bs,例如:

%if 0%{?opensuse_bs}
# 只在 OBS 里使用的 spec 代码
%endif

本地编译 32 位 RPM

如果你想要在一个 x86_64 机器上本地编译 32 位软件包,请用:

linux32 build foo.spec

然后 osc build 就会为你完成后续工作。

权限不足 (Permission denied) 错误

注意 本章节与英文相比有更新。目前 OBS 的版本不再需要添加 # norootforbuild 到 spec 范式文件的头部。相反之前添加过的或者自动添加的要删去。(不删也没关系。)

如果你的软件包在本地编译时,编译没有任何问题,但安装时却出现了像下面这样的错误提示:

 /usr/bin/install: cannot create regular file `/usr/lib/libfoo.so.0.0`: Permission denied

这是因为目前编译服务只支持 chroot(虚拟 root)环境下编译(并且你的软件包看起来没有使用 DESTDIR 也就是 %{buildroot})。

检查你的 spec 范式文件的 %install 章节,看看你是不是使用了:

make install

而不是 %make_install 宏。

%make_install 只能在 openSUSE 下使用; %makeinstall 在 openSUSE 和 SuSE SLE 下都可以使用; make DESTDIR=%{buildroot} install 可以用于所有 RPM 系发行版,如 Fedora。

_link 链接和 _aggregate 聚合

_link 链接和 _aggregate 聚合的区别

为了避免重新编译那些只是作为其他软件包的编译依赖而被需要的或者只是因为某项目想要为最终用户分发全系列的软件包而被需要的软件包,编译服务提供了 _aggregate 聚合 特性。

通过 聚合(aggregate)而被 "linked 链接" 到一个新项目的软件包不会在新项目中重新编译,而只是提供了原项目编译好的二进制软件包,只有原项目升级时这些软件包才会更新。(如果你没有动 Source 下面的文件的话)

下面是 _link 链接或 _aggregate 聚合的优缺点列表:

原因 _link 链接 _aggregate 聚合 评论
无需改动源文件   X 聚合满足条件,但会拖慢你的编译,并需要双倍的空间。最好是直接引入其他源作为源层面的依赖来编译。
需要为我的项目改动一些源文件 X    
原软件包没有针对所有需要的发行版或架构编译过 X X 最好的方法是使用两个不同的虚包:第一个使用 _aggregate 聚合功能来从原项目获取编译好的软件包,第二个使用 _link 链接功能来为其他需要的发行版或架构编译软件包。(但最简单的方法当然是让原来的维护者在他的项目里启用缺失的发行版/架构。)

_link 链接的例子

一个简单 _link 链接 的例子

在你的项目里创建一个新软件包 (名字可以和原项目一样 - 但这不是必须的) 然后添加一个名为 _link 的文件,内容如下:

<link project='openSUSE:Factory' package='tse3'/>

链接其他 OBS 上的软件包

注意 本技巧主要适用于 Packman 和私人架设的 OBS。

如果你在本地跑了一个 OBS,想要从 官方编译服务 或其他有提供 api 服务器的 OBS 链接一些软件包进来,添加一个像这样的 _link 文件:

<link project='openSUSE.org:openSUSE:Factory' package='tse3'/>

这样就会从 openSUSE.org 编译服务的 openSUSE:Factory 项目链接 tse3 软件包到你的项目里来了。

在本例中,如果你的编译服务管理员已经在你的本地 OBS 里创建了一个空的名为 openSUSE.org 的,在项目定义里包含了如下一行的项目:
<remoteurl>https://api.opensuse.org/public</remoteurl>
那你就不需要再去做任何事了,直接就可以链接到。如果没有,管理员需要设定一下外部项目导入。否则上述方法无效。

为链接进来的软件包打补丁

> 今天我试着从其他项目链接了一个软件包到我的项目,没有问题。 
> 接着我用 osc co 了一下新软件包,但我只在软件包目录下找到一个 "_link" 文件。
> 那么我怎么添加补丁或者修改 spec 范式文件?

可以向链接进来的软件包添加单个文件,也可以去替换原项目中的同名文件。这也包括 spec 范式文件。补丁文件可以用来补缀原项目中的文件而不用去覆盖它们。但该补丁必须在 _link 文件中有所定义。

<link project='openSUSE:Factory' package='tse3'>
  <patches>
    <apply name="补丁名" />
  </patches>
</link>

添加补丁到链接进来的软件包

为源代码打补丁(或为任何在 spec 范式文件中提及的补丁打补丁),你需要创建一个针对 spec 文件的补丁,添加你的补丁到 spec 文件并启用它,但也有一个简单的方法,那就是使用 <add> 命令:

<link project='openSUSE:Factory' package='tse3'>
  <patches>
    <add name="mybugfix.patch" />
  </patches>
</link>

这会添加 'mybugfix.patch' 补丁到 spec 文件的待启用补丁列表(会在编译服务的层面为你插入合适的代码到 spec 文件)。新补丁会在所有现有补丁打上以后被打上。当然了,这个补丁本身你必须上传到你链接的软件包目录里。

<add> 命令也支持 'popt="NUMBER"' 属性,来为 %patch 添加 -pNUMBER 补丁层级的参数,和 'dir="some/dir"' 属性来在打补丁之前定位到某些文件夹,以及 'after="NUMBER"' 属性来把补丁正好插入到某行号的下一行。

如何添加一行到 spec 文件的顶部

想要在 spec 文件的顶部添加一行(比如 %define),你不要补缀 spec 文件。你可以使用 <topadd> 命令:

<link project="myproject" package="theotherpackage">
  <patches>
    <topadd>%define small_build 1</topadd>
  </patches>
</link>

想要获得 _link 文件,可以使用 --unexpand-link 参数捡出软件包,就像这样:

osc checkout --unexpand-link someProject somePackage


在这之后到软件包目录里面寻找名为 _link 的文件,编辑该文件并添加上面的代码片段到该文件。

为了验证代码起了作用,在另一个位置正常的捡出软件包,检查 spec 文件的顶部,应该会有 <topadd> 命令之内的内容。

源代码和细节: [1]

聚合的例子

一个 _aggregate 聚合的例子

在你的项目里创建一个新的软件包(名字可以和原项目的一样-但这不是必须的),然后添加一个名为 _aggregate 的文件,内容如下。请注意,_aggregates 聚合通常被认为是不好的做法,因为项目实际上需要双倍的空间,编译服务也可能推迟你的软件包编译,不兼容的编译失败风险也非常高。通常更好的办法是针对额外的软件源编译软件包,就像下面要解释的一样,以从其他源获取软件包:

<aggregatelist>
  <aggregate project="KDE:Backports">
    <package>ksimus</package>
  </aggregate>
</aggregatelist>

如果软件源的名字与你的不匹配,你可以使用在 <repository> 要素中使用 绑定 的方法 (source 是原软件包所在的源名称):

<aggregatelist>
  <aggregate project="KDE:Backports">
    <package>ksimus</package>
    <repository target="openSUSE_10.2" source="SUSE_10.2" />
    <repository target="openSUSE_10.1" source="SUSE_10.1" />
  </aggregate>
</aggregatelist>

在 i586 上编译 i686 软件包

如果你需要一个其他架构的软件包,而不是默认的架构(例如在 i586 上编译 i686 的 glibc),你需要:

osc meta prjconf <你的项目名> -e


添加:

ExportFilter: \.i686\.rpm$ .

到 project conf。

之后,添加:

<aggregatelist>
  <aggregate project="openSUSE:Factory">
    <package>glibc.i686</package>
  </aggregate>
</aggregatelist>

就能在 i586 上编译 i686 了。

添加多个软件源到一个项目

如果一个软件包依赖(Requires 或者 BuildRequires)大于一个编译服务软件源时,添加多个软件源到一个项目是非常管用的。

 osc meta -e prj <project name>

这会打开项目元数据编辑器,使用 <path "projectname"/> 添加多个软件源到任何目标中。请注意不需要添加你添加了的软件源的依赖软件源。下面的例子只从 openSUSE:Tools 项目添加了一个软件源。但是这个软件源是针对 openSUSE:10.3/standard 编译的,所以所有 10.3 中的软件包也能用。

 <repository name="openSUSE_10.3">
   <path project="openSUSE:Tools" repository="openSUSE_10.3"/>
   <arch>i586</arch>
   <arch>x86_64</arch>
 </repository>

另一个例子:添加 NonFree 和 Update 软件源到一个 openSUSE:10.2 项目。最基础的 openSUSE:10.2/standard 软件源就不需要了,因为 NonFree 和 Update 都是针对它编译的。请注意添加了 :Update 项目通常会导致这样一个场景就是用户在使用你编译出来的软件包时必须先升级他们的系统,不然就会出问题; 而针对基础发行版编译出来的软件包,用户可以升级也可以不升级。唯一的必须要 :Update 软件源的例外就是内核模块(因为 Linux 内核经常前后不兼容,但所有其他的包在策略上都不允许前后不兼容):

<repository name="openSUSE_10.2">
   <path project="openSUSE:10.2:Update" repository="standard"/>
   <path project="openSUSE:10.2:NonFree" repository="standard"/>
   <arch>i586</arch>
   <arch>x86_64</arch>
</repository>

请注意:

  • 软件源的顺序很重要:编译服务总是会试图使用第一个软件源中的软件包,即使版本号对不上。
  • 依赖关系是从上到下递归查找的。
  • 用户需要在他们的系统上启用所有的软件源,这样 zypper 才能在安装时解决 Requires 依赖问题。如果你使用了不普遍的项目,那用户就没法猜了。

例子: 项目 A 有

 <repository name="openSUSE_Factory">
   <path repository="snapshot" project="openSUSE:Factory"/>
   <arch>i586</arch>
   <arch>x86_64</arch>
</repository>

如果你想要在项目 B 中针对项目 A 中的软件包编译,可以使用:

 <repository name="openSUSE_Factory">
   <path repository="openSUSE_Factory" project="A"/>
   <path repository="snapshot" project="openSUSE:Factory"/>
   <arch>i586</arch>
   <arch>x86_64</arch>
</repository>

或者(因为 openSUSE:Factory/snapshot 已经包含在项目 A 中了):

 <repository name="openSUSE_Factory">
   <path repository="openSUSE_Factory" project="A"/>
   <arch>i586</arch>
   <arch>x86_64</arch>
</repository>

编译环境是如何定义的?

定义在 build 软件包的 /usr/lib/build/configs/$distro.conf 文件里。 这里有详细描述。

在这个文件中说明所有设定编译环境所需知道的内容。

我们也在这里做依赖关系展开,因此出于软件包依赖关系需要的软件包会自动添加添加到 "Required" 列表里面去。

软件包在编译时需要一个 X-Server/DISPLAY 怎么办?

此方法适合解决 “RuntimeError: Gtk couldn't be initialized” 错误。这是 openSUSE 12.3 上 python3-gobject 的一个 bug。"WARNING **: Could not open X display" 也可以照此办理。
> 软件包 XXXXXX 需要一个 X-server (或者至少一个 DISPLAY) 才能编译 (不需要修改 X 的配置文件)。
> 我能在编译服务中访问 X-Server 吗?
> 我需要在我的 spec 文件中改点什么?

你需要运行一个 Xvfb 来绕过这个问题。(在 spec 文件中启动)。

例如,你可以在 spec 文件中使用下面这样的行:

BuildRequires:  xorg-x11-server-extra
%define         X_display         ":98"
...
%install
#############################################
##  Launch a virtual framebuffer X server  ##
#############################################
export DISPLAY=%{X_display}
Xvfb %{X_display} >& Xvfb.log &
trap "kill $! || true" EXIT
sleep 10
...
# 在这里启动你的应用程序/测试程序

需要 /etc/machine-id

当你遇到以下错误时:

D-Bus library appears to be incorrectly set up; failed to read machine uuid: Failed to open "/etc/machine-id"

可以为 dbus 在 %{_localstatedir}/lib/dbus/ 生成一个 machine-id。这条消息有点误导,dbus 会在 /var/lib/dbus/machine-id 和 /etc/machine-id 这两个位置查找。OBS 上的编译虚拟机没有权限写入 /etc。

BuildRequires:  dbus-1
...
%install
dbus-uuidgen %{_localstatedir}/lib/dbus/machine-id

参考:http://lists.freedesktop.org/pipermail/dbus/2013-March/015525.html

针对不同的平台使用不同的 spec 文件

在理想状态下,无论过去,现在还是将来,你都可以使用单一的 spec 文件来应对所有的基于 RPM 的平台。但现实中要不就是不可能,要么就是需要在你的 spec 文件中吸入好多的 %if 分支以至于它完全就不可读。

幸好,编译服务提供了一种方法,你可以针对不同的平台使用不同的 spec 文件。

假设你有一个名为 "foo" 的软件包,其下有一个叫做 "foo.spec" 的 spec 文件。假設该文件能完美工作在基于 SuSE 的发行版如 openSUSE,SLES 和 SLED 上,但是包布局的不同意味着你真心的需要一个单独的 spec 來完成在一个完全不同的发行版如 Fedora 上的打包。如果编译服务上的源名称为 "Fedora_Extras_6",那你可以创建一个名为 "foo-Fedora_Extras_6.spec" 的 spec 文件,该文件在那个源上编译的時候会替换默认的 "foo.spec"。

这种方法的唯一不足在于它只能针对单一的源。没有办法使用单一的 spec 文件来对应多个不同的源,还是上面的例子,如果你想为 Fedora Extras 4, 5 和 6 编译 "foo",那你就不得不创建三个 spec 文件:"foo-Fedora_Extras_4.spec","foo-Fedora_Extras_5.spec","foo-Fedora_Extras_6.spec",即使三个文件的内容一模一样。

一个使用了本方法的实例软件包是 net-snmp 项目中的 "net-snmp-main-snapshot" 软件包

从软件源中移除 已禁用 但 编译好 的软件包

目前,网页客户端不支持这样做。在命令行客户端 osc 中简单的输入:

osc wipebinaries <项目名称> 

就可以做到。

你还可以直接与编译服务应用程式接口(buildservice-API)交互来实现。如果你想要全源范围(比如:home:foo)的移除所有的编译好了却被标记为已禁用的 RPM,试试下面的方法:

  • 创建一个包含了你在 build.opensuse.org 的登陆信息的 ~/.netrc 文件,或者使用 "-u username:password" 参数
  • 使用
    curl -n -X POST -d '' 'https://api.opensuse.org/build/home:foo?cmd=wipe&code=disabled'
    或者
    curl -u username:password -X POST -d '' 'https://api.opensuse.org/build/home:foo?cmd=wipe&code=disabled'

想知道更多的 "指令" 请参阅 API 文档

列出 指定版本的发行版 的 所有可用软件包

当你不知道你编译需要的软件包的精确名字的时候,你既可以使用 网页搜索 也可以使用 osc ls -b。

举例:Ubuntu 上那个软件包包含了 mysql 的开发文件?

#              <源名称>     <架构> <车库>
$ osc ls -b -r standard -a i586 Ubuntu:7.10 | grep 'mysql.*dev'
libmysqlclient15-dev_5.0.45-1ubuntu3_i386.deb
# -> 这个软件包叫做 "libmysqlclient15-dev"。

在 编译服务 源中启用 rpmlint 检查

请参阅 RpmLint 页面和 该章节

为其他架构编译 xxbit 软件包 (baselibs)

参阅 openSUSE:Build Service_baselibs.conf

如何控制得到的软件包的 释出 版本号?

通常 编译服务 会自动处理 释出号 标签,因此 Release 部分的内容被元组 CI_CNT.B_CNT 替换,在这里 CI_CNT 是提交的次数,B_CNT 是重编译的次数(如果有重编译被触发的话)。

上述的行为类似于把

Release: <CI_CNT>.<B_CNT>

放到 prjconf (通过 osc meta prjconf -e [PROJECT] 访问) 里。

你可以改进它。例如为了引入 jpackage.org 的 RPM 你可以定义

Release: %%{?release_prefix}.<CI_CNT>.<B_CNT>

RPM 宏 %{release_prefix} 是在 spec 文件里定义的。产出的 RPM 的释出号会和 jpackage.org 项目以及 openSUSE 都兼容。这意味着你可以升级你的 SUSE 软件包到 jpackage.org 的软件包。

当试图删除一个项目时如何修复 "不存在" 错误?

当 后端 超时的时候,你会进入一种 api 数据库和后端不一致的状态。想要删除一个项目只需要用 osc 编辑它的 元数据 文件:

osc meta prj -e <项目名称>

保存它,之后删除它:

osc rdelete <项目名称>

编译一个 SLES 11 SP1 LiveCD

在 kiwi-3.74-5.101.1 上测试成功。

在编译系统上安装 clicfs-1.1.3-3.1.x86_64.rpm 和 liblzma0-4.999.9beta-11.1.x86_64.rpm,然后复制这些文件到软件源目录,该目录在 /usr/share/kiwi/image/isoboot/suse-SLES11/config.xml 中配置。

修改 /usr/share/kiwi/image/isoboot/suse-SLES11/config.xml 并添加如下行到 <packages type="bootstrap"> 章节。

<package name="clicfs"/>

可能是一个 Bug,下面这行走不通 (CD 不能引导)

<packages type="bootstrap" profiles="std">

但是带有 type=image 参数,CD 引导就没有问题了:

<packages type="image" profiles="std">


  1. kiwi --createhash /usr/share/kiwi/image/isoboot/suse-SLES11

接下来修改你的 Live CD 的 config.xml (不是你刚编辑的那个 config.xml ) 来启用 clicfs: <type primary="true" boot="isoboot/suse-SLES11" flags="clic">iso</type>

设定一个带 squashfs 和 aufs 的 SLES 10 SP2/SP3 KIWI 镜像

我的编译平台也是 SLES 10 SP2 x86_64。

这只是一个快速指南,详情参考其他的 KIWI 文档。

第一步 安装 KIWI

注意:你或许需要到 SLES 10 SDK 软件源去查找一个软件包。我安装了当前的 kiwi-3.01-93.1 自

http://download.opensuse.org/repositories/openSUSE:/Tools/SLE_10

注意:如果需要 kiwi-desc-oemboot 和 kiwi-desc-vmxboot 的话你需要 qemu,我没装它们。

安装 smart 软件包管理器

rpm -ivh /usr/share/kiwi/repo/suse-repo/suse-sle10-repo/smart-0.41-23.4.$(arch).rpm

下载针对 SLES 10 SP2/SP3 的 squashfs 自

http://download.opensuse.org/repositories/home:/mopp:/squashfs/

下载针对 SLES 10 SP2/SP3 的 aufs 自

http://download.opensuse.org/repositories/home:/mopp:/aufs

安装 squashfs 软件包到 KIWI 服务器

rpm -ivh /tmp/kiwi/squashfs-3.4-35.1.x86_64.rpm

第二步 创建 KIWI 引导镜像环境

当然你需要 SLES 10 SP2/3 源文件,我复制它们到一个本地文件夹。

变更路径到该文件夹

cp -a aufs-kmp* squashfs-kmp* /usr/share/kiwi/repo/suse-repo/suse-sle10-repo/

注意:aufs 和 squashfs 模块会被安装到 /lib/modules/<kernel>/updates/。确保这些内核模块匹配你安装到 KIWI 镜像中的内核版本。

下面就要修改 config.xml (boot/initrd 镜像) 以找到 aufs 和 squashfs 模块。你或许应该在编辑前备份一下,因为在升级了 kiwi 之后 config.xml 可能会被覆写。

cd /usr/share/kiwi/image/isoboot/suse-SLES10
vi config.xml

添加 aufs 和 squashfs 到 <drivers type="drivers"> 章节是非常关键的,添加下面的行,没有这些模块 LiveCD 是找不到的。

<file name="../updates/aufs.ko"/>
<file name="../updates/fs/squashfs/*"/>

添加下面的行到 <packages type="bootstrap"> 章节:

<package name="squashfs-kmp-default"/>
<package name="squashfs-kmp-smp"/>
<package name="aufs-kmp-default"/>
<package name="aufs-kmp-smp"/>

创建新的哈希值:

kiwi --createhash /usr/share/kiwi/image/isoboot/suse-SLES10

第三步 准备系统镜像

确保你没弄混启动镜像的内核和本机系统的内核 (-default 和 -smp) 版本。

准备系统镜像 (我使用了 suse-11.0 的配置文件,因为这是最简的配置文件)

cp -pr /usr/share/doc/packages/kiwi/examples/suse-11.0/suse-live-iso /usr/local/kiwi/suse-sle10sp2-live-iso

编辑 /usr/local/kiwi/suse-sle10sp2-live-iso 中的 config.xml,至少你需要改动 "boot" 标签和 "repository"

修改

<type primary="true" boot="isoboot/suse-11.0" flags="unified">iso</type>

<type primary="true" boot="isoboot/suse-SLES10" flags="unified">iso</type>

移除 "bootsplash-branding-openSUSE" 软件包,因为 SLES 10 里没有这个包。

你需要添加源来查找额外的软件包,像 smart 这种。

       <repository type="rpm-dir">
 <source path="/usr/share/kiwi/repo/suse-repo/suse-sle10-repo/"/>
       </repository>

在 config.xml 中添加或删除你需要的软件包,并自定义你的系统。

你或许需要添加 dhcpcd 软件包来启用 dhcp。

opensusePattern 看起来在 SLES 上没用。

第四步 创建 ISO 镜像

确保你有足够的磁盘空间。

kiwi --prepare /usr/local/kiwi/suse-sle10sp2-live-iso --root /tmp/myiso

检查日志文件。

要检查创建好的系统你可以运行:

chroot /tmp/myiso

如果都还好的话,下面该创建 ISO 镜像了:

kiwi --create /tmp/myiso -d /tmp/myiso-result

检查日志文件。

接着试着引导一下该 ISO 镜像。

如何直接从代码存放地下载源码, 并制作 nightly build 源

OBS 目前已经通过 _service 文件支持直接从 VCS 下载。参考 该概念页面该 OBS 文档(草稿)

你需要一台安装有 cron 服务和编译服务的命令行客户端 osc 的本地计算机.

准备一个工作目录,从 VCS 中捡出你的代码,然后从编译服务上取回你的软件包。准备一个 spec 模板,但 version 部分要用一个占位符。就像这样:

Name:         monitord
Version:      ##TIMESTAMP##
Requires:     alsa
...

准备一个命令行脚本来做本地升级,制作 tar 压缩包,修改 spec 文件,上传到编译服务这些工作。

下面是一个针对 SVN 源的样板:

#!/bin/bash

# 编译服务上的相对路径
PACK_PATH=home:cwh:monitord-nightly/monitord

# SVN 上的相对路径
REPO_PATH=trunk

TIMESTAMP=`date +"%Y%m%d"`

# 进入 SVN 目录
pushd $REPO_PATH

# SVN 升级
svn up

# 准备压缩包
make dist

# 移动生成的压缩包到软件包目录
cp monitord-2.0svn.tar.gz ../$PACK_PATH

popd

# 复制一份修改过的 spec 文件到软件包目录
perl -p -e "s/##TIMESTAMP##/$TIMESTAMP/" monitord.spec > $PACK_PATH/monitord.spec

# 进入软件包目录
pushd $PACK_PATH

# 上传修改(新的压缩包和 spec 文件)到 OBS
osc commit -m "updated to current SVN snapshot $TIMESTAMP"

popd

echo "Done"

然后通过 cron 服务调用该脚本。

实例:

0 5 * * *       cd /space/monitord-nightly && ./push_to-obs.sh

could not retrieve ssl certificate: 400 remote error

常见于在自己的源里编译内核的时候。原因是需要制作 UEFI 的硬件签名。

解决方法:

osc signkey --create home:MargueriteSu

当然这个签名是未经微软审核的,依然不可用于 UEFI 的硬件上面。只是让编译能够继续而已。

Out of memory: Kill process N (python) score N or sacrifice child

多见于编译 firefox/chromium/输入法词库的时候。

原因是因为常规虚拟编译环境只有 256 MB 内存。score 超过 256 太多就会被 kill。

解决方法:

在项目根目录下添加一个 _constraints 文件,内容如下:

<constraints>
  <hardware>
    <memory>
      <size unit="G">4</size>
    </memory>
  </hardware>
</constraints>