使用RPM spec文件

时间:2015-11-18 04:15:52

标签: bash rpm rpmbuild software-packaging specfiles

我有一个RPM Spec文件,在rhel7上使用rpmbuild构建,我想用脚本定义Version。

我在这里阅读http://www.techrepublic.com/article/rpmproc-spec-file/,我可以这样做:

%define version 1.2

Version: %{version}

这里RPM spec file - Is it possible to dynamically populate a spec file variable,我可以用脚本定义:

%define whoami %(cmd)

所以我尝试在我的规范文件中执行此操作:

%define version %(echo "$(sed -n 's|^[ ]*appVersion = "\(.*\)"|\1|p' /fullfilepath/values.txt | sed 's/^\(.*\)-.*$/\1/')")

Version: %{version}  **Line 23**

但我得到了

error: line 23: Empty tag: Version:

到目前为止我测试过的事情:

%define version %(echo "12") --basic script works ok, version becomes 12

//As a command straight in terminal
$ echo "$(sed -n 's|^[ ]*appVersion = "\(.*\)"|\1|p' /fullfilepath/values.txt | sed 's/^\(.*\)-.*$/\1/')"
//returns 1.2

这些工作得很好,所以我不知道是什么导致它失败。当我在spec文件中的define标签中调用相同的东西时,有什么想法会让它失败?

更新

我尝试用实际值替换文件名,所以看起来像这样

echo "$(sed -n 's|^[ ]*appVersion = "\(.*\)"|\1|p' <<< "appVersion = \"1.2-SNAPSHOT\"" | sed 's/^\(.*\)-.*$/\1/')"

在终端中调用但作为

时有效
%(echo "$(sed -n 's|^[ ]*appVersion = "\(.*\)"|\1|p' <<< "appVersion = \"1.2-SNAPSHOT\"" | sed 's/^\(.*\)-.*$/\1/')") 

但我还是得到了

Empty tag: Version: Error

更新2

我测试了一个不同的更复杂的命令,然后echo "12"

%define version %(echo "$(git log -1 | grep commit | awk -F"commit " '{print $2}' | cut -c1-8)")

这也可以!使版本成为提交哈希的7位数字。

更新3

这个谜团还在继续,我做了一个测试来检查它的sed命令是否是原因,但是下面的命令给了我1.2版本

%define version %(echo "$( sed 's/.*= //' <<< "appVersion = 1.2" )")

如果这个命令工作但不是我的第一个命令,那么它必须在我的第一个命令中有一些东西只能在直接在终端中调用而不在%(cmd)中调用。越来越近了!

更新4

好吧所以我似乎已经孤立了它必须是什么,好奇,看起来它可能是rpmbuild不喜欢的-ns| | \1 |p语法。我制作了原版的更简单版本。看看:

#Error, doesn`t set version to 1.2
%define version %(echo "$( sed -n 's|^.*-\(-*\)|\1|p' <<< "foo-1.2" )") 

#Works ok! sets version to 1.2
%define version %(echo "$( sed 's/.*= //' <<< "appVersion = 1.2" )") 

不幸的是,虽然我认为我不能再孤立并找出问题所在。在第二个命令的样式中使用sed没有任何问题,但它仍然非常有趣,为什么第一个命令不起作用。

更新5

我发现在使用spec文件和rpmbuild处理%()内的任何脚本时,存在一些深层次的问题。我尝试使用awk只是为了看看会发生什么,它也会破坏!这比我最初想的更深入,比如发现一个阴谋:

#In terminal it prints 1.2-SNAPSHOT, but in Spec it's an error 
%define version %(echo "$(awk '/appVersion /{ print $3 }' <<< "appVersion = \"1.2-SNAPSHOT\"" | tr -d \")")

sh: -c: line 0: unexpected EOF while looking for matching `)'
sh: -c: line 1: syntax error: unexpected end of file
error: line 23: Empty tag: Version:

更新6

对每个人来说都是好消息和坏消息,我发现rpm似乎在后台做了一些自己的工作而没有显示它的作用,我终于找到了一个通过rpm调用时给出不同值的命令:

%define version %(echo "$(awk '/midonetVersion /{ print $3 }' <<< "midonetVersion = \"5.1-SNAPSHOT\"")")
#In terminal it echos "5.1-SNAPSHOT" (literally wrapped in "" )
#When in spec it set version to 5.1-SNAPSHOT , rpmbuild is removing the ""

所以现在我做了一个调整并称之为:

#echos "5.1 in terminal and sets version to 5.1 in spec
%define version %(echo "$(awk '/appVersion /{ print $3 }' <<< "appVersion = \"1.2-SNAPSHOT\"")"| cut -d'-' -f1)

所以从这看起来,我认为可能有类似的幕后解析我的第一个sed命令从rpm的结果。我们将采用rpm方式!

最终更新

使用rpm进行休战,我将使用此命令:

%define version %(echo "$(awk '/ appVersion =/{ print $3 }' /filepath/values.txt" | sed 's/\"//g' | cut -d'-' -f1)

它与我的第一个命令完全相同,并在specfile中正确设置版本号。如果有人猜测为什么第一个命令不会运行,我会很高兴阅读它。和平!

2 个答案:

答案 0 :(得分:3)

您必须拥有一个调用rpmbuild命令的shell脚本。您可以使用该脚本来计算版本(或者就此而言,您尝试在rpm规范文件中使用的任何命令)。

更改原始代码,

%define version %(echo "$(sed -n 's|^[ ]*appVersion = "\(.*\)"|\1|p' /fullfilepath/values.txt | sed 's/^\(.*\)-.*$/\1/')")
Version: %{version}

要,

%define version _VERSION_
Version: %{version}

并将 VERSION 发送到调用rpmbuild的shell脚本中的计算值(在调用rpmbuild之前)。将实际规范内容转储到某个文件后,将该生成的文件传递给同一shell脚本中的rpmbuild。

以下是步骤摘要:

假设您有一个调用rpmbuild的builder.sh shell脚本,请按照以下步骤操作:

  1. 更新您的规范文件,使其具有 VERSION 占位符字符串/宏,如上所示
  2. 将当前rpm规范文件移至my_package_template.spec
  3. 在builder.sh中,运行命令以获取您的版本并将版本保存到变量
  4. 在my_package_template.spec文件上使用sed命令将此计算版本替换为 VERSION ,并将sed输出保存到my_package.spec
  5. 将my_package.spec传递给rpmbuild命令。
  6. 重复步骤1,3和4,以替换spec文件中任何其他shell命令的使用。

答案 1 :(得分:1)

我会做一个包装脚本。这允许您决定诸如它是常规版本还是开发版本等等。然后您可以使用--define选项传递变量 - 请参阅this question for more options