Loongnix Server 8.4中本地编译module软件包
0 实验环境
CPU :龙芯3A5000
操作系统 :Loongnix Server 8.4
module-build
工具在编译module stream时依赖到mock
和rpkg
,所以需要在系统中先安装这两个软件包。其中mock
工具的使用可以参考mock知识点1。rpkg
可以参考rpkg使用帮助。
1 module-build
1.1 module-build简介
软件包主页:https://github.com/mcurlej/module-build
module-build
是一个本地构建module stream软件包的工具。目前支持modulemd v3规则。
1.2 module-build编译、安装
module-build
工具0.2.0以上版本中用到的:=
Python语法从Python3.8版本开始支持。目前Loongnix Server 8.4系统中的默认Python版本为3.6。当然可以通过切换Python38 stream来满足,但是此处没有这样做。以下内容为module-build 0.1版本的验证。
# 安装module-build 0.1版本SRPM源码包
[loongson@bogon ~]$ rpm -ivh https://download.fedoraproject.org/pub/fedora/linux/releases/36/Everything/source/tree/Packages/m/module-build-0.1.0-1.fc36.src.rpm
......
# 安装module-build构建时依赖包
[loongson@bogon rpmbuild]$ sudo yum-builddep SPECS/module-build.spec
......
# 编译module-build
[loongson@bogon rpmbuild]$ rpmbuild -ba SPECS/module-build.spec
......
# 安装module-build RPM包
[loongson@bogon rpmbuild]$ sudo yum install /home/loongson/rpmbuild/RPMS/noarch/module-build-0.1.0-1.lns8.noarch.rpm
......
1.3 module-build使用
在使用module-build
之前,需要先要按规则存放软件包。具体的存放方式可以参考fedora,也可以参考后面第2章。
项目存放好之后,执行module-build
命令进行编译。具体编译参数可以参考项目主页中的README内容,也可以参考后面第三章内容。
在Loongnix Server系统中,刚开始因为配置问题,可能会遇到以下问题。
1.3.1 tarball checksum error
1.3.1.1 错误现象
DEBUG: SCM checkout command: rpkg clone -a --branch lns8-stream-5.32 perl perl
DEBUG: SCM checkout post command: rpkg sources
DEBUG: SCM checkout directory: /tmp/tmp1qk_ln5r.mock-scm.perl
DEBUG: child environment: None
DEBUG: Executing command: ['rpkg', 'clone', '-a', '--branch', 'lns8-stream-5.32', 'perl', 'perl'] with env environ({'LANG': 'zh_CN.UTF-8', 'SHELL': '/bin/bash', 'TERM': 'xterm-256color', 'PATH': '/usr/sbin:/usr/bin:/sbin:/bin:/root/bin', 'LOGNAME': 'root', 'USER': 'root', 'COLUMNS': '173', 'USERHELPER_UID': '1000', 'HOME': '/home/loongson'}) and shell False
DEBUG: 正克隆到 'perl'...
DEBUG: warning: 重定向到 https://gitlab.com/loongnix/rpms/perl.git/
DEBUG: Child return code was: 0
DEBUG: child environment: None
DEBUG: Executing command: ['rpkg', 'sources'] with env environ({'LANG': 'zh_CN.UTF-8', 'SHELL': '/bin/bash', 'TERM': 'xterm-256color', 'PATH': '/usr/sbin:/usr/bin:/sbin:/bin:/root/bin', 'LOGNAME': 'root', 'USER': 'root', 'COLUMNS': '173', 'USERHELPER_UID': '1000', 'HOME': '/home/loongson'}) and shell False
DEBUG: Downloading perl-5.32.1.tar.xz from rpms/perl at https://gitlab.com:
DEBUG: /tmp/tmp1qk_ln5r.mock-scm.perl/perl/perl-5.32.1.tar.xz failed checksum
DEBUG: Child return code was: 1
ERROR: Command failed:
# rpkg sources
1.3.1.2 错误分析
这一步错误时,module-build已经再执行rpkg source
命令,所以我们可以来到下载源码的/tmp/tmp1qk_ln5r.mock-scm.perl
目录下,手动执行rpkg source
命令,这时,可以通过-v
选项查看执行过程中的细节。
......
Downloading perl-5.32.1.tar.xz from rpms/perl at gitlab.com:
Full url: https://gitlab.com/repo/pkgs/rpms/perl/perl-5.32.1.tar.xz/sha512/3443c75aea91f0fe3712fee576239f1946d2301b8f7390b690e2f5d070fe71af8f9fa7769e42086c2d33d5f84370f80368fa9350b4f10cc0ac3e6c1f6209d8f9/perl-5.32.1.tar.xz
######################################################################## 100.0%
Traceback (most recent call last):
File "/usr/bin/rpkg", line 23, in <module>
rpkg_util.main()
File "/usr/lib/python3.6/site-packages/rpkglib/__init__.py", line 51, in main
cmd()
File "/usr/lib/python3.6/site-packages/rpkglib/__init__.py", line 518, in sources
self.lookaside.sources(repo_path, self.args.outdir)
File "/usr/lib/python3.6/site-packages/rpkglib/lookaside_cache.py", line 297, in sources
entry.hash)
File "/usr/lib/python3.6/site-packages/rpkglib/lookaside_cache.py", line 100, in download
raise RpkgError('%s failed checksum' % outfile)
rpkglib.errors.RpkgError: /tmp/tmp1qk_ln5r.mock-scm.perl/perl/perl-5.32.1.tar.xz failed checksum
从这里我们就能看出来错误的原因。是因为下载链接是一个空地址,而这个地址本来是用于存放tarball源码包的位置。
1.3.1.3 解决方法
修改/etc/rpkg.conf
配置文件中的download_url
选项,让其指向tarball的位置。
1.3.2 AddMacro() argument TypeError
1.3.2.1 错误现象
DEBUG: 正克隆到 'perl'...
DEBUG: warning: 重定向到 https://gitlab.com/loongnix/rpms/perl.git/
DEBUG: Child return code was: 0
DEBUG: child environment: None
DEBUG: Executing command: ['rpkg', 'sources'] with env environ({'LANG': 'zh_CN.UTF-8', 'SHELL': '/bin/bash', 'TERM': 'xterm-256color', 'PATH': '/usr/sbin:/usr/bin:/sbin:/bin:/root/bin', 'LOGNAME': 'root', 'USER': 'root', 'COLUMNS': '173', 'USERHELPER_UID': '1000', 'HOME': '/home/loongson'}) and shell False
DEBUG: Downloading perl-5.32.1.tar.xz from rpms/perl at src.fedoraproject.org:
DEBUG: Child return code was: 0
DEBUG: Fetched sources from SCM
DEBUG: Preparing SCM sources
ERROR: AddMacro() argument 2 must be str, not int
Traceback (most recent call last):
File "/dev/fd/5", line 1059, in <module>
exitStatus = main()
File "/usr/lib/python3.6/site-packages/mockbuild/trace_decorator.py", line 93, in trace
result = func(*args, **kw)
File "/dev/fd/5", line 825, in main
result = run_command(options, args, config_opts, commands, buildroot, state)
File "/usr/lib/python3.6/site-packages/mockbuild/trace_decorator.py", line 93, in trace
result = func(*args, **kw)
File "/dev/fd/5", line 848, in run_command
(options.sources, options.spec) = scmWorker.prepare_sources()
File "/usr/lib/python3.6/site-packages/mockbuild/scm.py", line 153, in prepare_sources
rpm.addMacro(macro.lstrip('%'), expression)
TypeError: AddMacro() argument 2 must be str, not int
1.3.2.2 解决方法
修改/usr/lib/python3.6/site-packages/mockbuild/scm.py
第153行代码,对第二个参数使用str()
函数。
修改后如下:
150 # Add passed RPM macros before parsing spec file
151 for macro, expression in list(self.macros.items()):
152 # pylint: disable=no-member
153 rpm.addMacro(macro.lstrip('%'), str(expression))
1.3.3 编译及结果
此处示例只演示了perl-bootstrap模块流编译perl包的过程
[loongson@bogon perl-bootstrap]$ module-build -f perl-bootstrap.yaml -c /etc/mock/loongnix-8-loongarch64.cfg --module-name=perl ../workdir/
......
......
#经过比较长时间之后,编译完成,然后就可以在workdir目录下看到内容:
[loongson@bogon perl-bootstrap]$ ls ../workdir/perl
perl:5.32:20230316120202:058368ca:loongarch64/ perl:5.32:20230317025330:058368ca:loongarch64/ perl-bootstrap-module-build-1678969394.log
perl:5.32:20230316122314:058368ca:loongarch64/ perl-bootstrap-module-build-1678968122.log perl-bootstrap-module-build-1679021610.log
[loongson@bogon perl-bootstrap]$ ls ../workdir/perl\:5.32\:20230317025330\:058368ca\:loongarch64/build_batches/
batch_0/ batch_1/ repodata/
[loongson@bogon perl-bootstrap]$ ls ../workdir/perl\:5.32\:20230317025330\:058368ca\:loongarch64/build_batches/batch_0/
batch0:0:20230317031455:b0:loongarch64.modulemd.yaml finished perl/
[loongson@bogon perl-bootstrap]$ ls ../workdir/perl\:5.32\:20230317025330\:058368ca\:loongarch64/build_batches/batch_0/perl/
build.log perl-IPC-SysV-debuginfo-2.07-477.module_lns8+058368ca.loongarch64.rpm
finished perl-JSON-PP-4.04-477.module_lns8+058368ca.noarch.rpm
hw_info.log perl-less-0.03-477.module_lns8+058368ca.noarch.rpm
installed_pkgs.log perl-lib-0.65-477.module_lns8+058368ca.loongarch64.rpm
mock_stdout.log perl-libnet-3.11-477.module_lns8+058368ca.noarch.rpm
perl-5.32.1-477.module_lns8+058368ca.loongarch64.rpm perl-libnetcfg-5.32.1-477.module_lns8+058368ca.noarch.rpm
perl-5.32.1-477.module_lns8+058368ca.src.rpm perl-libs-5.32.1-477.module_lns8+058368ca.loongarch64.rpm
perl-Archive-Tar-2.36-477.module_lns8+058368ca.noarch.rpm perl-libs-debuginfo-5.32.1-477.module_lns8+058368ca.loongarch64.rpm
......
2 项目存放示例
2.1 整体概览
module-build
工具默认会到Fedora仓库中查找这些信息,如果此处和我一样,使用自己存放的路径,则需要修改/etc/rpkg.conf
文件中的anon_clone_url
配置项。
2.2 模块流项目的内容
此处主要的是modulemd文件,sources文件内容为空,此处内容来自于Fedora。
2.3 rpm项目的内容
这个项目中存放着编译时要使用的内容,但是其中源码包是分开、存放在其他地方的。也就是说此处只是存放了patch内容。
1)需要注意的是其中名为sources
的文件,它里面存放了源码包的sha512的值,用于校验。
2)另一个需要注意的点是分支名需要和2.2中yaml文件中对应项目的分支名对应。
3 module-build工具编译
3.1 基础示例
# -f:指定modulemd yaml文件
# -c:指定mock配置文件
# workdir:用于存放编译结果及过程日志的地方
[loongson@bogon perl-bootstrap]$ module-build -f perl-bootstrap.yaml -c /etc/mock/loongnix-8-loongarch64.cfg ../workdir/
如果modulemd yaml文件中没有指定module 那么的话,编译时会提示让指定module name,如下所示:
# --module-name :指定module name
# --module-stream:指定module stream,此处没有用
[loongson@bogon perl-bootstrap]$ module-build -f perl-bootstrap.yaml -c /etc/mock/loongnix-8-loongarch64.cfg --module-name=perl ../workdir/
可以通过--module-context
指定context内容。
3.2 恢复某次构建
如果一个组件的构建失败,你可以从该组件恢复构建。使用 --resume
标志和 --module-version=<version_timestapm>
选项,以确定你要恢复的构建环境。
如果没有选项恢复构建,module-build
会在workdir目录重新从头开始按照module yaml文件进行构建处理。而恢复构建则会接着处理过的失败构建继续进行。
[loongson@bogon perl-bootstrap]$ module-build -f perl-bootstrap.yaml -c /etc/mock/loongnix-8-loongarch64.cfg --module-name=perl --resum --module-version=20230316091731 ../workdir/
3.3 构建依赖其他模块的模块流
当你的模块流具有模块化依赖项时,你必须以createrepo_c
创建的repo的形式将这些依赖项提供给模块构建。
例如,flatpak-runtime
模块是模块 flatpak-common
的模块化依赖项。 要提供 flatpak-runtime
,您需要在构建中使用 --add-repo
选项。
下面这个示例来自module-build
:
$ module-build -f flatpak-common.yaml -c /etc/mock/fedora-35-x86_64.cfg --add-repo=/path/to/repository/containin/flatpak-runtime/module ./workdir
3.4 在指定chroot目录构建模块流组件
有些情况下,组件的构建会消耗大量磁盘空间。 默认情况下,mock
将其所有chroot存储在 /var/lib/mock
目录,如果磁盘空间不足,可能会导致构建失败。 可以使用选项--rootdir
将chroot目录的位置更改为自定义目录。
下面这个示例来自module-build
:
$ module-build -f flatpak-runtime.yaml -c /etc/mock/fedora-35-x86_64.cfg --rootdir=/path/to/custom/dir/ ./workdir
3.5 从SRPM 构建模块流组件
此选项允许直接从SRPM构建所有组件,而不是使用SCM。 可以通过在--srpm-dir
中指定带有SRPM 的目录路径来启用。
V0.2.0版本开始支持!
下面这个示例来自module-build
:
$ module-build -f flatpak-runtime.yaml -c /etc/mock/fedora-35-x86_64.cfg --srpm-dir /path/to/srpms ./workdir
3.6 多线程构建模块
此选项允许同时构建组件。 要使用此模式,需要指定--workers
大于 1 的数量。还需要通过--no-stdout
参数关闭logger标准输出。
module-build
v0.2.0版本开始支持。
[loongson@bogon perl-bootstrap]$ module-build -f perl-bootstrap.yaml -c /etc/mock/loongnix-8-loongarch64.cfg --module-name=perl -w 32 --no-stdout ../workdir/