Display Name
Display Name

Reputation: 2403

Variables and escaping in RPM SPEC file macros?

I want to define a macro that will replace some placeholders in makefiles and systemd unit files with the results of RPM variables (macros). However, I don't know if the way expansion works will make the following behave correctly:

%define repl_vars() (sed -e "s:\${LIBEXECDIR}:%{_libexecdir}:g" -e "s:\${LOCALSTATEDIR}:%{_localstatedir}:g" -e "s:\${SYSCONFIGDIR}:%{_sysconfdir}:g" %{1} > %{1}.new && mv %{1}.new %{1})

Where the capitalized ${...} are the placeholders to be replaced with the actual paths held by the standard RPM variables (macros).

Also, escaping the $ of the placeholders with \ works in Bash and stuff I put in the %install section of the SPEC file, but is that still valid in a macro? And is the %{1} valid, as I've never seen an example -- and if not, how do I concatenate .new to %1?

If this is wrong, how do I do it?

Upvotes: 3

Views: 4085

Answers (1)

Etan Reisner
Etan Reisner

Reputation: 80911

tl;dr Yes, that looks basically correct to me. See http://www.rpm.org/wiki/PackagerDocs/Macros for some (somewhat outdated but still largely relevant) documentation.

Macros that are to be expanded in a shell context in a spec file just want to expand to the literal lines that you would write in the spec file section manually.

So assuming you want something to the effect of:

%install
....
sed -e 's:${LIBEXECDIR}:%{_libexecdir}:g' -e 's:${LOCALSTATEDIR}:%{_localstatedir}:g' -e 's:${SYSCONFIGDIR}:%{_sysconfdir}:g' 'some_file' > 'some_file.new' && mv 'some_file.new' 'some_file'
....

And you want to call your macro as %repl_vars some_file then you want a macro roughly like this:

%define repl_vars() sed -e 's:${LIBEXECDIR}:%{_libexecdir}:g' -e 's:${LOCALSTATEDIR}:%{_localstatedir}:g' -e 's:${SYSCONFIGDIR}:%{_sysconfdir}:g' '%{1}' > '%{1}.new' && mv '%{1}.new' '%{1}'

Notice I switched to single quotes instead of double quotes to avoid $ from being evaluated and needing to be escaped. I also dropped the wrapping () because this didn't seem to need the forced sub-shell.

Upvotes: 2

Related Questions