-->
Page 201
As mentioned earlier, the name of a subpackage normally includes the main package name. When the -n option is added to the %package directive, it directs RPM to use the name specified on the %package line as the entire package name. In the preceding example, the following %package line would create a subpackage named foonly-doc:
%package doc
The following %package line would create a subpackage named doc:
%package -n doc
The %package directive plays another role in subpackage building: to act as a place to collect tags that are specific to a given subpackage. Any tag placed after a %package directive will apply only to that subpackage.
Finally, the name string specified by the %package directive is also used to denote which parts of the spec file are a part of that subpackage. This is done by including the string (along with the -n option, if present on the %package line) on the starting line of the section that is to be subpackage specific. Here's an example:
... %package -n bar ... %post -n bar ...
In this heavily edited spec file segment, a subpackage called bar has been defined. Later in the file is a postinstall script. Because it has subpackage bar's name on the %post line, the postinstall script will be part of the bar subpackage only.
For more information on building subpackages, see Chapter 18, "Creating Subpackages."
While the exclude and exclusive tags (excludearch, exclusivearch, excludeos, and exclusiveos) provide some control over whether a package will be built on a given architecture and/or operating system, that control is still rather coarse.
For example, what should be done if a package will build under multiple architectures, but requires slightly different %build scripts? Or what if a package requires a certain set of files under one operating system, and an entirely different set under another operating system? The architecture and operating system_specific tags discussed earlier in the chapter do nothing to help in such situations. What can be done?
Page 202
One approach would be to simply create different spec files for each architecture or operating system. While it would certainly work, this approach has two problems:
The other approach is to somehow permit the conditional inclusion of architecture- or
operating system_specific sections of the spec file. Fortunately, the RPM designers chose this approach, and it makes multiplatform package building easier and less prone to mistakes.
We discuss multiplatform package building in depth in Chapter 19. For now, let's take a quick look at RPM's conditionals.
The %ifarch conditional is used to begin a section of the spec file that is architecture specific. It is followed by one or more architecture specifiers, each separated by commas or whitespace. Here is an example:
%ifarch i386 sparc
The contents of the spec file following this line would be processed only by Intel x86 or Sun SPARC_based systems. However, if only this line were placed in a spec file, this is what would happen if a build were attempted:
# rpm -ba cdplayer-1.0.spec Unclosed %if Build failed. #
The problem that surfaced here is that any conditional must be closed by using either %else or %endif. We'll be covering them a bit later in the chapter.
The %ifnarch conditional is used in a similar fashion to %ifarch, except that the logic is reversed. If a spec file contains a conditional block starting with %ifarch alpha, that block would be processed only if the build were being done on a Digital Alpha/AXP-based system. However, if the conditional block started with %ifnarch alpha, that block would be processed only if the build were not being done on an Alpha.
Page 203
Like %ifarch, %ifnarch can be followed by one or more architectures and must be closed by %else or %endif.
The %ifos conditional is used to control RPM's spec file processing based on the build system's operating system. It is followed by one or more operating system names. A conditional block started with %ifos must be closed by %else or %endif. Here's an example:
%ifos linux
The contents of the spec file following this line would be processed only if the build were done on a Linux system.
The %ifnos conditional is the logical complement to %ifosthat is, if a conditional starting with the line %ifnos irix is present in a spec file, the file contents after the %ifnos will not be processed if the build system is running Irix. As always, a conditional block starting with %ifnos must be closed by %else or %endif.
The %else conditional is placed between an %if conditional of some persuasion, and an %endif. It is used to create two blocks of spec file statements, only one of which will be used in any given case. Here's an example:
%ifarch alpha make RPM_OPT_FLAGS="$RPM_OPT_FLAGS -I ." %else make RPM_OPT_FLAGS="$RPM_OPT_FLAGS" %endif
When a build is performed on a Digital Alpha/AXP, some additional flags are added to the make command. On all other systems, these flags are not added.
A %endif is used to end a conditional block of spec file statements. It can follow one of the %if conditionals, or the %else. The %endif is always needed after a conditional; otherwise the build will fail. Here's a short conditional block, ending with an %endif:
%ifarch i386 make INTELFLAG=-DINTEL %endif
In this example, we see that the conditional block started with an %ifarch and ended with an %endif.