Is there a kind of "include" directive in RPM spec? I couldn't find an answer by googling.
Motivation: I have a RPM spec template which the build process modifies with the version, revision and other build-specific data. This is done by sed
currently. I think it would be cleaner if the spec would #include
a build-specific definitions file, which would be generated by the build process, so I don't need to search and replace in the spec.
If there is no include
, is there an idiomatic way to do this (quite common, I believe) task?
Sufficiently recent versions of rpmbuild certainly do support %include:
Unfortunately, they aren't very smart about it -- there is no known set of directories, in which it will look for the requested files, for example. But it is there and variables are expanded, for example:
RPM does not support includes.
I have solved similar problems with either m4 macro processor or by just concatenating parts of spec (when the "include" was at the beginning).
If you only need to pass a few variables at build time, and not include several lines from another file, you can run
and you can use %myvar in the spec.
I've used scripts (name your favorite) to take a template and create the spec file from that. Also, the
%files
tag can import a file that is created by another process, e.g. Python'sbdist-rpm
.Which version are you talking about? I currently have %include filename.txt in my spec file and it seems to work just like the C #include directive.
I faced this same issue recently. I wanted to define multiple sub-packages that were similar, but each varied just slightly (they were language-specific RPMs). I didn't want to repeat the same boiler-plate stuff for each sub-package.
Here's a generic version of what I did:
The use of
%{expand}
ensures that%(cat)
is only executed a single time, when the macro is defined. The content of the main-foo.spec file is then three times, and each time%1
in the main-foo.spec file expands to each ofbar
,baz
andqux
, in turn, allowing me to treat it as a template. You could easily expand this to more than one parameter, if you have the need (I did not).For the underlying issue, there maybe two additional solutions that are present in all rpm versions that I am aware of.
macro
andrpmrc
files.Subpackages
Another alternative (and perhaps the "RPM way") is to use sub-packages. Maximum RPM also has information and examples of subpackages.
I think the question is trying to structure something like,
%include common.spec
debug and production could also be client and server, etc. For the examples of redefining a variable, each subpackage can have it's own list of variables.
Limitations
The main advantage of subpackages is that only one build takes place; This may also be a disadvantage. The debug and production example may highlight this. That can be worked around using
strip
to create variants or compiling twice with different output; perhaps usingVPATH
with Gnu Make). Having to compile large packages and then only have simple variations, like with/without developer info, likeheaders
, static libraries, etc. can make you appreciate this approach.Macros and Rpmrc
Subpackages don't solve the problem of structural defines that you wish for an entire rootfs hierarchy, or larger collection of RPMs. We have
rpmbuild --showrc
for this. You can have a large amount of variables and macros defined by alteringrpmrc
andmacros
when you runrpm
andrpmbuild
. From theman
page,I think these two features can solve all the problems that
%include
can. However,%include
is a familiar concept and was probably added to make rpm more full-featured and developer friendly.