是否有任何语法或技巧可以创建多行 rpm 规范文件宏

发布于 2024-10-05 07:26:10 字数 334 浏览 5 评论 0原文

背景。

$ rpmbuild --version
RPM version 4.3.3

我正在处理一个需要处理多个 scriptlet 中的文件列表的规范文件。 DRY(不要重复)让我将列表定义为一个宏,该宏将扩展为各种帮助程序脚本。维护列表很痛苦,因为我还没有找到避免将所有文件放在同一行的方法。

%define LIST \
a \
b 

给出一个错误

%define LIST a\
b\

也给出一个错误

%define LIST a
%define LIST %LIST b

由于递归错误而失败

Background.

$ rpmbuild --version
RPM version 4.3.3

I am working on a spec file that needs to process a list of files in multiple scriptlets. DRY (don't repeat youself) has me defining the list once as a macro which is expanded into the various helper scripts. Maintaining the list is a pain since I haven't seen a way to avoid putting all the files on the same line.

%define LIST \
a \
b 

gives an error

%define LIST a\
b\

gives an error as well

%define LIST a
%define LIST %LIST b

Fails due to a recursion error

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

柏拉图鍀咏恒 2024-10-12 07:26:10

您实际上无法像在 ~/.rpmmacros 文件中那样在规范文件中创建多行宏。有点傻。

我创建了一个子目录 SPECS/inc/ ,其中包含规范文件,这些文件充当多行宏,为我的站点创建的所有包都使用这些宏。您可以直接执行%include inc/foo.spec,而不是将宏用作%foo。您还可以创建快捷方式以避免包含语法 %global foo %include inc/foo.spec。然后它就像多行宏一样工作。

这是一个完整的例子。

inc/env.spec

%global foo %include inc/foo.spec
%global bar %include inc/bar.spec
#Lots of other common things to all packages

inc/foo.spec

a
b
c
d

然后在我的包规范文件 mylib.spec 中:

%include inc/env.spec

Name: mylib
Version: X.Y
#etc...

%foo

You cannot really make multiline macros in a spec file the way you can in your ~/.rpmmacros file. Kind of silly.

I create a subdirectory SPECS/inc/ with spec files which act as multi-line macros which are used by all packages created for my site. Instead of using macros as %foo, you can just do %include inc/foo.spec. You can also create shortcuts to avoid the include syntax %global foo %include inc/foo.spec. Then it works just like a multi-line macro.

Here is a complete example.

inc/env.spec

%global foo %include inc/foo.spec
%global bar %include inc/bar.spec
#Lots of other common things to all packages

inc/foo.spec

a
b
c
d

And then in my package spec file, mylib.spec:

%include inc/env.spec

Name: mylib
Version: X.Y
#etc...

%foo
唐婉 2024-10-12 07:26:10

既然您进一步解释了您的目标,那么让我们尝试不同的方法。在您的规范文件中尝试一下:

Source1:        flist

%{expand:%global LIST %(cat %{SOURCE1})}

在 Source1 文件中(在本例中为 flist):

a \
b \
c 

我已经使用 rpm 4.4.6 对此进行了测试,因为这是我目前可用的最旧版本。

Since you explained your goal a bit more, let's try different approach. Try this in your spec file:

Source1:        flist

%{expand:%global LIST %(cat %{SOURCE1})}

And this in Source1 file (in this case flist):

a \
b \
c 

I have tested this with rpm 4.4.6 since that's the oldest version available to me at this time.

安人多梦 2024-10-12 07:26:10

在宏定义中,行尾反斜杠被删除并用于告诉 RPM 宏定义继续。换行符不会被删除(与 make 文件不同)。因此,如果您正在构建多行脚本,则不需要分号。这也意味着,如果您要拆分单个命令,则必须使用 3 反斜杠。两个用于产生 shell 将看到的反斜杠,一个用于告诉 rpmbuild 继续解析宏。 shell 将删除它看到的反斜杠以及换行符,这将在两行上生成一个命令。 !!

In macro definitions, an end-of-line backslash is removed and used to tell RPM that the macro definition continues. The newline character is NOT stripped (unlike a make file). Therefore, if you are constructing a multi-line script, semi-colons are not needed. This also means that if you are splitting a single command, you must use 3 backslashes. Two to yield a backslash that the shell will see and one to tell rpmbuild to keep parsing the macro. The shell will remove the backslash it sees, plus the newline and that will yield one command on two lines. Whew !!

怎樣才叫好 2024-10-12 07:26:10

这个例子应该有效:

cat file.spec

%define MAKE make \\\
 status=success \\\
 #EOL

%build
${MAKE}


cat Makefile

status?=fail
default: 
    echo "status=${status}"

This example should work:

cat file.spec

%define MAKE make \\\
 status=success \\\
 #EOL

%build
${MAKE}


cat Makefile

status?=fail
default: 
    echo "status=${status}"
灰色世界里的红玫瑰 2024-10-12 07:26:10

您必须在第一行至少包含该值的某些部分,即:

%define LIST a\
b\
c

此宏定义将起作用。如果您打算将它们用作命令,即这样的东西

%define DOSOMETHING rm file1\
rm file2\
rm file3
...
%build
%DOSOMETHING

将不起作用。可执行部分中的行首先被分成单独的命令,然后扩展宏。即定义宏将起作用,但将其作为三个单独的命令执行则不起作用。

如果你想执行3个单独的命令,这样做更容易

%define DOSOMETHING rm file1; rm file2; rm file3

You have to have at least some part of the value on the first line, i.e.:

%define LIST a\
b\
c

This macro definition will work. If you plan to use these as commands, i.e. something like

%define DOSOMETHING rm file1\
rm file2\
rm file3
...
%build
%DOSOMETHING

this will not work. The lines in executable sections are split into separate commands first, THEN the macros are expanded. I.e. defining the macro will work, executing it as three separate commands will not.

If you want to execute 3 separate commands, it's easier to do it like

%define DOSOMETHING rm file1; rm file2; rm file3
若有似无的小暗淡 2024-10-12 07:26:10

如果我是你,我会在源文件中维护该列表。

%{_sourcedir}/LIST 的内容:

a
b
c
d

在规范文件中:

%define process_files() \
    for i in %(cat %{_sourcedir}/LIST)
    do \
        echo "process list of files here" \
    done

If I was you, I'd maintain the list in a source file.

Contents of %{_sourcedir}/LIST:

a
b
c
d

In the spec file:

%define process_files() \
    for i in %(cat %{_sourcedir}/LIST)
    do \
        echo "process list of files here" \
    done
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文