我正在rpmbuild
创建一个自定义 rpm 来从源代码安装 python3.9。rpmbuild
通过描述的方式自动为其确定必要的事物创建依赖关系这里。可以通过AutoReqProv: no
在规范文件中进行设置来完全禁用它,如中所述这邮政。
我的问题是,由于我无法确定的原因, rpmbuild 会自动创建对 file 的依赖关系/usr/local/lib/python
,而我不希望该文件存在。从源代码构建 Python3.9 时不会创建该文件,并且如果另一个 rpm 确实想要安装该文件,我不想出现不必要的文件冲突。有什么方法可以专门告诉 rpmbuild不是为该文件创建依赖项并仅有的该文件,同时仍然允许创建所有其他自动生成的依赖项?
规格文件供参考:
Name: python39
Version: 3.9.0
Release: 1
Summary: Python 3.9
%global _python_bytecompile_errors_terminate_build 0
%define install_dir /usr/local
Source0: Python-3.9.0.tgz
BuildRequires: libffi-devel
%define debug_package %{nil}
%description
%prep
%setup -c -q
%build
umask 022
cd Python-3.9.0
./configure
make
sudo make install
%install
%{__rm} -rf %{buildroot}
%{__mkdir_p} %{buildroot}
%{__cp} -a %{install_dir} %{buildroot}%{install_dir}
%files
%{install_dir}/bin/2to3
%{install_dir}/bin/2to3-3.9
%{install_dir}/bin/easy_install-3.9
%{install_dir}/bin/idle3
%{install_dir}/bin/idle3.9
%{install_dir}/bin/pip3
%{install_dir}/bin/pip3.9
%{install_dir}/bin/pydoc3
%{install_dir}/bin/pydoc3.9
%{install_dir}/bin/python3
%{install_dir}/bin/python3-config
%{install_dir}/bin/python3.9
%{isntall_dir}/bin/python3.9-config
%{install_dir}/include/python3.9
%{install_dir}/lib/libpython3.9.a
%{install_dir}/lib/pkgconfig/python-3.9-embed.pc
%{install_dir}/lib/pkgconfig/python-3.9.pc
%{install_dir}/lib/pkgconfig/python3-embed.pc
%{install_dir}/lib/pkgconfig/python3.pc
%{install_dir}/lib/python3.9
%{install_dir}/share/man/man1/python3.1
%{install_dir}/share/man/man1/python3.9.1
%doc
%post
%postun
%changelog
答案1
您的规范文件存在许多问题。
首先,也是最重要的,你应该绝不构建软件包时使用
sudo make install
:这会将软件包直接安装到本地文件系统上,这绝不是您想要的。根据您的环境,可能会损坏现有的 Python 安装或导致其他意外后果。RPM 背后的整个想法是以非特权用户身份构建软件包;仅当以下情况时才需要特权安装包裹。
由于该
cgi
模块,可能会添加错误的依赖项,该模块在文件顶部包含以下注释:#! /usr/local/bin/python # NOTE: the above "/usr/local/bin/python" is NOT a mistake. It is # intentionally NOT "/usr/bin/env python". On many systems # (e.g. Solaris), /usr/local/bin is not in $PATH as passed to CGI # scripts, and /usr/local/bin is the default directory where Python is # installed, so /usr/bin/env would be unable to find python. Granted, # binary installations by Linux vendors often install Python in # /usr/bin. So let those vendors patch cgi.py to match their choice # of installation.
RPM 看到了这一点
#!/usr/local/bin/python
并将其添加为依赖项。解决方案是按照注释中的说明操作并修补文件以显式引用/usr/local/bin/python3.9
.避免必须
cd
进入目录才能让您的构建正常工作。通过修改参数,%setup
这就变得不必要了。不要只是跑
make install
;你想将文件安装到你的构建根目录中。对于类似 GNU 的软件包(包括 Python),您可以通过DESTDIR
在安装时进行设置来完成此操作:make install DESTDIR=$RPM_BUILD_ROOT
这简化了您的
%install
部分。RPM 将尝试使用
/usr/bin/python
.如果您在 CentOS 7 之类的系统下构建它,则/usr/bin/python
使用 Python 2.7,并且会因许多文件上的语法错误而失败。看来您已尝试通过设置
_python_bytecompile_errors_terminate_build
to来解决此问题0
,但至少在我的测试环境中这并不有效。我最终跟随这些说明从安装后删除字节编译步骤。
所有这一切给了我:
%global _python_bytecompile_errors_terminate_build 0
%define install_dir /usr/local
%define debug_package %{nil}
%global __os_install_post %(echo '%{__os_install_post}' | sed -e 's!/usr/lib[^[:space:]]*/brp-python-bytecompile[[:space:]].*$!!g')
Name: python39
Version: 3.9.0
Release: 1
Summary: Python 3.9
License: Python
Source0: Python-3.9.0.tgz
BuildRequires: libffi-devel
BuildRequires: zlib-devel
%description
%prep
%setup -q -n Python-3.9.0
%build
umask 022
./configure --prefix=%{install_dir}
make
%install
make install DESTDIR=$RPM_BUILD_ROOT
# Patch cgi.py as described in its comments
sed -i 's,/usr/local/bin/python,/usr/local/bin/python3.9,' $RPM_BUILD_ROOT%{install_dir}/lib/python3.9/cgi.py
%files
%{install_dir}/bin/2to3
%{install_dir}/bin/2to3-3.9
%{install_dir}/bin/easy_install-3.9
%{install_dir}/bin/idle3
%{install_dir}/bin/idle3.9
%{install_dir}/bin/pip3
%{install_dir}/bin/pip3.9
%{install_dir}/bin/pydoc3
%{install_dir}/bin/pydoc3.9
%{install_dir}/bin/python3
%{install_dir}/bin/python3-config
%{install_dir}/bin/python3.9
%{install_dir}/bin/python3.9-config
%{install_dir}/include/python3.9
%{install_dir}/lib/libpython3.9.a
%{install_dir}/lib/pkgconfig/python-3.9-embed.pc
%{install_dir}/lib/pkgconfig/python-3.9.pc
%{install_dir}/lib/pkgconfig/python3-embed.pc
%{install_dir}/lib/pkgconfig/python3.pc
%{install_dir}/lib/python3.9
%{install_dir}/share/man/man1/python3.1
%{install_dir}/share/man/man1/python3.9.1
%doc
%post
%postun
%changelog
当我在 CentOS 7 上构建这个包时,生成的依赖项是:
$ rpm -qp --requires RPMS/x86_64/python39-3.9.0-1.x86_64.rpm
/bin/bash
/bin/sh
libcrypt.so.1()(64bit)
libcrypt.so.1(GLIBC_2.2.5)(64bit)
libc.so.6()(64bit)
libc.so.6(GLIBC_2.10)(64bit)
libc.so.6(GLIBC_2.13)(64bit)
libc.so.6(GLIBC_2.14)(64bit)
libc.so.6(GLIBC_2.15)(64bit)
libc.so.6(GLIBC_2.17)(64bit)
libc.so.6(GLIBC_2.2.5)(64bit)
libc.so.6(GLIBC_2.3.2)(64bit)
libc.so.6(GLIBC_2.3.4)(64bit)
libc.so.6(GLIBC_2.3)(64bit)
libc.so.6(GLIBC_2.4)(64bit)
libc.so.6(GLIBC_2.6)(64bit)
libc.so.6(GLIBC_2.7)(64bit)
libc.so.6(GLIBC_2.9)(64bit)
libdl.so.2()(64bit)
libdl.so.2(GLIBC_2.2.5)(64bit)
libffi.so.6()(64bit)
libm.so.6()(64bit)
libm.so.6(GLIBC_2.2.5)(64bit)
libnsl.so.1()(64bit)
libnsl.so.1(GLIBC_2.2.5)(64bit)
libpthread.so.0()(64bit)
libpthread.so.0(GLIBC_2.2.5)(64bit)
libpthread.so.0(GLIBC_2.3.2)(64bit)
libpthread.so.0(GLIBC_2.3.3)(64bit)
librt.so.1()(64bit)
librt.so.1(GLIBC_2.2.5)(64bit)
libutil.so.1()(64bit)
libutil.so.1(GLIBC_2.2.5)(64bit)
libz.so.1()(64bit)
libz.so.1(ZLIB_1.2.0)(64bit)
rpmlib(CompressedFileNames) <= 3.0.4-1
rpmlib(FileDigests) <= 4.6.0-1
rpmlib(PayloadFilesHavePrefix) <= 4.0-1
rpmlib(PayloadIsXz) <= 5.2-1
rtld(GNU_HASH)
/usr/bin/env
/usr/local/bin/python3.9
为了在我的 Fedora 35 系统上构建这个,我必须另外禁用brp-mangle-shebangs
安装后过程(因为它会错误地替换/usr/local/bin/python3.9
为/usr/bin/python3.9
),如下所示:
%global __os_install_post %(echo '%{__os_install_post}' | sed -e 's!/usr/lib[^[:space:]]*/brp-python-bytecompile[[:space:]].*$!!g' -e 's!/usr/lib[^[:space:]]*/brp-mangle-shebangs[[:space:]].*$!!g')