开发者

Is there any syntax or trick to be able to create a multiline rpm spec file macro

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 s开发者_Python百科ame 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


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


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.


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 !!


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


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


This example should work:

cat file.spec

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

%build
${MAKE}


cat Makefile

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜