RPM 构建错误: /var/tmp/rpm-tmp.gAmM5N (%prep) 退出状态不好,怎么办
第一次尝试linux打包,但是进展不太顺利,当然这也跟查询的资料有关,我这边用的AI工具 kimi,一直没解决,没找到原因!不过后来跟着其他ai工具,很快就找到了原因,并且解决了!
一、打包步骤
在 CentOS 上,通常使用 RPM(Red Hat Package Manager)格式来创建安装包。RPM 是 CentOS 和其他基于 Red Hat 的系统(如 Fedora 和 RHEL)的标准包管理格式。以下是创建 RPM 包的详细步骤:
1. 安装必要的工具
首先,确保你已经安装了 rpm-build
和 rpmlint
工具。这些工具可以帮助你构建和检查 RPM 包。
sudo yum install rpm-build rpmlint
2. 创建 RPM 构建目录结构
RPM 构建需要一个特定的目录结构。通常,这些目录位于 ~/rpmbuild
下。你可以使用以下命令创建这些目录:
mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
3. 准备源代码
将你的程序源代码或二进制文件准备好,并将其压缩为一个归档文件(如 .tar.gz
或 .zip
)。例如,假设你的程序源代码在 /path/to/your/program
目录下,你可以使用以下命令创建一个压缩包:
tar -czvf ~/rpmbuild/SOURCES/myprogram-1.0.tar.gz -C /path/to/your/program .
4. 创建 .spec
文件
.spec
文件是 RPM 包的核心,它包含了构建和安装程序的所有必要信息。在 ~/rpmbuild/SPECS
目录下创建一个 .spec
文件,例如 myprogram.spec
。
以下是一个简单的 .spec
文件示例:
Name: myprogram
Version: 1.0
Release: 1%{?dist}
Summary: A short description of your programLicense: GPL
Source0: myprogram-1.0.tar.gzBuildArch: x86_64%description
A longer description of your program.%prep
%setup -q%build
# Add build commands here if you have a build process
# For example, if you have a Makefile:
# make%install
mkdir -p %{buildroot}/usr/local/bin
cp myprogram %{buildroot}/usr/local/bin/%files
/usr/local/bin/myprogram%changelog
* Tue Sep 02 2025 Your Name <your.email@example.com> - 1.0-1
- Initial release
5. 构建 RPM 包
使用 rpmbuild
命令构建 RPM 包。在 ~/rpmbuild/SPECS
目录下运行以下命令:
rpmbuild -ba myprogram.spec
这个命令会执行以下步骤:
- 解压源代码
- 构建程序(如果有构建步骤)
- 安装程序到构建根目录
- 打包为 RPM 文件
6. 检查 RPM 包
使用 rpmlint
工具检查生成的 RPM 包是否符合规范:
rpmlint ~/rpmbuild/RPMS/x86_64/myprogram-1.0-1.x86_64.rpm
7. 安装 RPM 包
你可以使用 rpm
命令安装生成的 RPM 包:
sudo rpm -Uvh ~/rpmbuild/RPMS/x86_64/myprogram-1.0-1.x86_64.rpm
示例
假设你的程序是一个简单的可执行文件 myprogram
,位于 /path/to/your/program
目录下。以下是完整的步骤:
-
创建目录结构
mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
-
准备源代码
tar -czvf ~/rpmbuild/SOURCES/myprogram-1.0.tar.gz -C /path/to/your/program .
-
创建
.spec
文件
在~/rpmbuild/SPECS
目录下创建myprogram.spec
文件:Name: myprogram Version: 1.0 Release: 1%{?dist} Summary: A short description of your programLicense: GPL Source0: myprogram-1.0.tar.gzBuildArch: x86_64%description A longer description of your program.%prep %setup -q%build # Add build commands here if you have a build process # For example, if you have a Makefile: # make%install mkdir -p %{buildroot}/usr/local/bin cp myprogram %{buildroot}/usr/local/bin/%files /usr/local/bin/myprogram%changelog * Tue Sep 02 2025 Your Name <your.email@example.com> - 1.0-1 - Initial release
-
构建 RPM 包
rpmbuild -ba ~/rpmbuild/SPECS/myprogram.spec
-
检查 RPM 包
rpmlint ~/rpmbuild/RPMS/x86_64/myprogram-1.0-1.x86_64.rpm
-
安装 RPM 包
sudo rpm -Uvh ~/rpmbuild/RPMS/x86_64/myprogram-1.0-1.x86_64.rpm
二、遇到问题并尝试解决
打包遇到问题
执行(%prep): /bin/sh -e /var/tmp/rpm-tmp.gAmM5N
+ umask 022
+ cd /root/rpmbuild/BUILD
+ cd /root/rpmbuild/BUILD
+ rm -rf mypro_linux_3.3.1
+ /usr/bin/gzip -dc /root/rpmbuild/SOURCES/mypro_linux_3.3.1.tar.gz
+ /usr/bin/tar -xf -
+ STATUS=0
+ '[' 0 -ne 0 ']'
+ cd mypro_linux_3.3.1
/var/tmp/rpm-tmp.gAmM5N: line 35: cd: mypro_linux_3.3.1: No such file or directory
错误:/var/tmp/rpm-tmp.gAmM5N (%prep) 退出状态不好RPM 构建错误:/var/tmp/rpm-tmp.gAmM5N (%prep) 退出状态不好
尝试解决
修改如下:
%setup -q -n mypro_linux_3.3.1
依旧报错!
问题原因分析
-
压缩包结构不符
- 压缩包
/root/rpmbuild/SOURCES/teamlink_linux_3.3.1.tar.gz
解压后生成的目录名不是teamlink_linux_3.3.1
。 - 可能是压缩包内没有顶层目录,直接包含了源代码文件。
- 压缩包
-
SPEC文件配置错误
- SPEC文件中可能错误地硬编码了目录名(如
teamlink_linux_3.3.1
),但实际解压后的目录名不同。
- SPEC文件中可能错误地硬编码了目录名(如
新的解决步骤
1. 检查压缩包的实际结构
解压压缩包,确认生成的目录名:
tar -tf /root/rpmbuild/SOURCES/mypro_linux_3.3.1.tar.gz | head -n 1
输出示例:
mypro_linux_3.3.1/ # 如果存在顶层目录
或
file1.c # 如果没有顶层目录,直接列出文件
2. 修改SPEC文件
根据压缩包的实际结构调整SPEC文件的%prep
阶段:
-
如果压缩包有顶层目录:
确保SPEC文件中使用正确的目录名(例如%{name}-%{version}
或实际名称):%prep %setup -q
-
如果压缩包没有顶层目录:
需要手动创建目录并解压:%prep rm -rf %{_builddir}/%{name}-%{version} mkdir -p %{_builddir}/%{name}-%{version} tar -xzf %{_sourcedir}/%{name}-%{version}.tar.gz -C %{_builddir}/%{name}-%{version}
3. 使用宏变量(推荐)
在SPEC文件中使用宏变量(如 %{name}
、%{version}
)避免硬编码:
Name: mypro
Version: 3.3.1%prep
%setup -q -n %{name}-%{version} # 或实际目录名
修改示例
假设解压后目录是 mypro-3.3.1
,则SPEC文件中应写:
%prep
%setup -q -n mypro-3.3.1
验证修复
重新构建RPM:
rpmbuild -ba ~/rpmbuild/SPECS/teamlink.spec
还是没有解决,重新分析问题原因!
新的报错
执行(%prep): /bin/sh -e /var/tmp/rpm-tmp.ubSKCQ
+ umask 022
+ cd /root/rpmbuild/BUILD
+ mkdir -p /root/rpmbuild/BUILD/mypro-3.3.1
+ tar -xzf '/root/rpmbuild/SOURCES/%{source0}' -C /root/rpmbuild/BUILD/mypro-3.3.1
tar (child): /root/rpmbuild/SOURCES/%{source0}: Cannot open: No such file or directory
tar (child): Error is not recoverable: exiting now
tar: Child returned status 2
tar: Error is not recoverable: exiting now
错误:/var/tmp/rpm-tmp.ubSKCQ (%prep) 退出状态不好RPM 构建错误:/var/tmp/rpm-tmp.ubSKCQ (%prep) 退出状态不好
三、找到根本原因并解决
看起来问题在于路径解析错误。错误信息显示 RPM 正在尝试访问 /root/rpmbuild/SOURCES//root/rpmbuild/SOURCES/mypro_linux_3.3.1.tar.gz
,这明显是错误的路径。
这表明 RPM 宏展开可能有问题。让我们简化 SPEC 文件,使用硬编码路径来避免这个问题:
Name: mypro
Version: 3.3.1
Release: 1%{?dist}
Summary: mypro Network UtilityLicense: Proprietary
Source0: mypro_linux_3.3.1.tar.gzBuildArch: x86_64%description
mypro is a network utility that includes%prep
# 创建构建目录并解压文件
mkdir -p teamlink-3.3.1
tar -xzf ../SOURCES/mypro_linux_3.3.1.tar.gz -C mypro-3.3.1%build
# No build process needed for this package%install
mkdir -p %{buildroot}/usr/local/bin
cp test1%{buildroot}/usr/local/bin/
cp test2%{buildroot}/usr/local/bin/
cp test3%{buildroot}/usr/local/bin/%files
/usr/local/bin/test1
/usr/local/bin/test2
/usr/local/bin/test3
%changelog
* Tue Sep 02 2025 Your Name <your.email@example.com> - 3.3.1-1
- Initial release
主要修改:
- 在
%prep
部分使用相对路径../SOURCES/mypro_linux_3.3.1.tar.gz
而不是宏 - 使用相对目录名
mypro-3.3.1
而不是完整的构建路径 - 在
%install
部分,假设文件已经在当前目录中(因为%prep
阶段已经解压了文件)
如果这仍然不起作用,可以尝试一个更简单的方法,直接在 %prep
阶段解压文件而不创建子目录:
%prep
# 直接解压文件到当前目录
tar -xzf ../SOURCES/mypro_linux_3.3.1.tar.gz
或者,如果压缩包确实没有顶层目录,可能需要先检查压缩包的内容结构:
# 查看压缩包内容
tar -tf /root/rpmbuild/SOURCES/mypro_linux_3.3.1.tar.gz
根据压缩包的实际结构,可能需要调整 SPEC 文件。如果压缩包确实没有顶层目录,那么直接解压到当前目录应该可以工作。
到此完美解决!!!