RPM构建找不到文件或目录

8

我想创建一个包含许多小文件的简单RPM文件。

[root@laptop rpm]# tree
.
├── BUILD
├── BUILDROOT
├── RPMS
├── SOURCES
│   └── some_agent-1.0.tar.gz
├── SPECS
│   ├── kernel.spec
│   └── kernel.spec~
└── SRPMS

6 directories, 3 files
[root@laptop rpm]# 

我有这个规范文件:

Summary: some_agent
Name: some_agent
Version: 1.0
Release: 1
License: Apache
Group: application
Source0: %{name}-%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
%description
Test 

%prep
%setup -q

%build


%install
rm -rf $RPM_BUILD_ROOT
make root=$RPM_BUILD_ROOT install

%clean
rm -rf $RPM_BUILD_ROOT

%files
%defattr(-,root,root,-)
%doc
agent/*

但是当我尝试构建RPM包时,出现了以下错误:
[root@laptop ~]$ rpmbuild -bb -v ~/rpm/SPECS/kernel.spec
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.RUwFW5
+ umask 022
+ cd /home/rcbandit/rpm/BUILD
+ LANG=C
+ export LANG
+ unset DISPLAY
+ cd /home/rcbandit/rpm/BUILD
+ rm -rf some_agent-1.0
+ /usr/bin/gzip -dc /home/rcbandit/rpm/SOURCES/some_agent-1.0.tar.gz
+ /bin/tar -xf -
+ STATUS=0
+ '[' 0 -ne 0 ']'
+ cd some_agent-1.0
/var/tmp/rpm-tmp.RUwFW5: line 38: cd: some_agent-1.0: No such file or directory
error: Bad exit status from /var/tmp/rpm-tmp.RUwFW5 (%prep)


RPM build errors:
    Bad exit status from /var/tmp/rpm-tmp.RUwFW5 (%prep)
[root@laptop ~]$ ^C

你有没有想法,我的错误出在哪里?

我复制了源文件,但由于某种原因它找不到了。


看起来rpmbuild在切换目录以解压some_agent目录时出现了一些问题,请检查路径。也许您的源文件没有正确压缩 - 没有'some_agent-1.0'目录,只有文件?尝试手动解压并查看结果。 - jaroslawj
不,手动解压文件并不能解决问题。 - user1285928
2
当您解压缩 some_agent-1.0.tar.gz 压缩包时,您会得到一个名为 some_agent-1.0 的目录吗?还是其他什么东西? - larsks
是的,我需要解压到哪个目录?SOURCES目录吗? - user1285928
现在生成的 RPM 是空的。看起来我又漏了什么。 - user1285928
我回到了原始版本,因为你修改问题并使他们的回答无效的时候已经有了一个(至少部分)回答那个问题的答案。 - Etan Reisner
2个回答

8

查看构建过程的日志。首先,rpmbuild会切换到BUILD目录:

+ cd /home/rcbandit/rpm/BUILD

然后它解压你的源代码压缩包:

+ /usr/bin/gzip -dc /home/rcbandit/rpm/SOURCES/some_agent-1.0.tar.gz
+ /bin/tar -xf -

然后它尝试进入some_agent-1.0目录,这个目录很可能是通过解压源代码存档创建的:

+ cd some_agent-1.0
/var/tmp/rpm-tmp.RUwFW5: line 38: cd: some_agent-1.0: No such file or directory

这里出现了错误,说明解压缩归档文件时没有创建 RPM 要求的目录。你可以通过为 %setup 宏添加参数来解决这个问题。例如,如果我有一个名为 some_agent-1.0.tar.gz 的归档文件,并且它包含:

an-unexpected-name/
an-unexpected-name/README

我需要使用-n参数来指示%setup宏:

%prep
%setup -q -n an-unexpected-name

如果您解压缩了some_agent-1.0.tar.gz文件,会得到什么?rpmbuild将假设它解压缩到一个名为some_agent-1.0的目录中,但从您展示给我们的输出来看,情况并非如此。那么,您的tarball里面有什么? - nos
我有一点进展。我在tar.gz文件中有一个目录代理,它是许多小文件的父级。我设法构建了RPM,但它是空的。你有什么想法我错过了什么吗? - user1285928
也许只需执行 cp -ap agent/* $RPM_BUILD_ROOT/opt/agent/,或者不必执行 install -m 0755 -d $RPM_BUILD_ROOT/opt/agent,而是复制整个目录树:install -m 0755 -d $RPM_BUILD_ROOT/opt/cp -R agent $RPM_BUILD_ROOT/opt/ - nos
我得到了cp: 无法对 `agent/*' 执行 stat 操作:没有那个文件或目录。 - user1285928
在你的规范文件中运行 pwd 命令,然后你就会了解到在 %install 部分中当前工作目录是什么,并发现我犯了一个错误,应该只是 cp -ap * $RPM_BUILD_ROOT/opt/agent/ - nos
显示剩余4条评论

3
%install 
install -m 0755 -d %{buildroot}/opt/agent
cp -a your_milion_files/* %{buildroot}/opt/agent

%files 
/opt/agent

当您指定%dir时,它将仅包括该目录及其中的文件,不包括其内部的其他子目录。如果没有使用%dir编译指示,那么它将包括该目录中以及其子目录中的所有文件。 因此,在%install部分中,您只需要复制该目录中的这些文件。
编辑: 假设some-agent-1.0.tar.gz包含:
agent/binary/agent.sh
agent/data/data1.dat
agent/data/data2.dat
....
agent/data/data1000.dat
agent/LICENSE

如果您的部分应该包括:

%install
install -m 0755 -d %{buildroot}/%{_bindir}/some-agent
install -m 0755 -d %{buildroot}/%{_datadir}/
cp -a binary/agent.sh %{buildroot}/%{_bindir}/some-agent
cp -a data/* %{buildroot}/%{_datadir}/

%files
%doc LICENSE
%{_bindir}/some-agent
%{_datadir}/some-agent

你可以使用以下任意一行代码:

%dir %{_datadir}/some-agent
%{_datadir}/some-agent/*

但是显然
 %{_datadir}/some-agent

缩短了并且意思相同。

在那个%install部分,您可以使用任何bash命令。 因此,请在那里执行通常在命令行上执行的操作。 任何shell扩展都有效,因此请提前使用它们。

我使用了一些宏 - 您应该使用它们而不是硬编码路径。 您可以通过

rpm --showrc

并通过以下方式进行评估:

rpm --eval '%{_datadir}'

最近在RHEL和Fedora上进行了评估,这对IT技术有关。
/usr/share

我也介绍了一个关于LICENSE文件的小技巧。当它存在于tar文件的最上层目录中时,只需将其名称传递给%doc宏,rpm就会自动将其放置在正确的%docdir中。


我不明白在 your_milion_files/* 中应该插入什么?也许是每个文件或特定目录? - user1285928
在%prep部分,您正确地解压了some-agent-1.0.tar.gz,并且在%install部分的开头,您已经切换到./agent/目录,这应该是您的tar文件的最顶层目录。因此,您基本上将这些文件复制到了%{buildroot}中的正确位置。我会尝试编辑我的答案并给出具体的例子。 - msuchy
应该使用 ${SourceX} 而不是 %{buildroot}。 - itsazzad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接