rpmbuild &Macro syntax& rpmrc File &Specifying File Attributes

http://www.rpm.org/max-rpm-snapshot/rpmbuild.8.html

rpmbuild

Name

rpmbuild -- Build RPM Package(s)

Synopsis

Building Packages:

rpmbuild {-ba|-bb|-bp|-bc|-bi|-bl|-bs} [(1) rpmbuild-options ] SPECFILE...

rpmbuild {-ta|-tb|-tp|-tc|-ti|-tl|-ts} [(1) rpmbuild-options ] TARBALL...

rpmbuild {--rebuild|--recompile} SOURCEPKG...

Miscellaneous:

rpmbuild {--showrc}

rpmbuild-options

(1)  --buildroot DIRECTORY | --clean | --nobuild | --rmsource | --rmspec
| --short-circuit | --sign | --target PLATFORM

Description

rpmbuild is used to build both binary and source software packages. A package consists of an archive of files and meta-data used to install and erase the archive files. The meta-data includes helper scripts, file attributes, and descriptive information about the package. Packages come in two varieties: binary packages, used to encapsulate software to be installed, and source packages, containing the source code and recipe necessary to produce binary packages.

One of the following basic modes must be selected: Build Package, Build Package from Tarball, Recompile Package, Show Configuration.

General Options

These options can be used in all the different modes.

-?, --help

Print a longer usage message then normal.

--version

Print a single line containing the version number of rpm being used.

--quiet

Print as little as possible - normally only error messages will be displayed.

-v

Print verbose information - normally routine progress messages will be displayed.

-vv

Print lots of ugly debugging information.

--rcfile FILELIST

Each of the files in the colon separated FILELIST is read sequentially by rpm for configuration information. Only the first file in the list must exist, and tildes will be expanded to the value of $HOME. The default FILELIST is /usr/lib/rpm/rpmrc:/usr/lib/rpm/redhat/rpmrc:/etc/rpmrc:~/.rpmrc.

--pipe CMD

Pipes the output of rpm to the command CMD.

--dbpath DIRECTORY

Use the database in DIRECTORY rather than the default path /var/lib/rpm

--root DIRECTORY

Use the file system tree rooted at DIRECTORY for all operations. Note that this means the database within DIRECTORY will be used for dependency checks and any scriptlet(s) (e.g. %post if installing, or %prep if building, a package) will be run after a chroot(2) to DIRECTORY.

Build Options

The general form of an rpm build command is

rpmbuild {-bSTAGE|-tSTAGE} [(1) rpmbuild-options ] FILE...

The argument used is -b if a spec file is being used to build the package and -t if rpmbuild should look inside of a (possibly compressed) tar file for the spec file to use. After the first argument, the next character (STAGE) specifies the stages of building and packaging to be done and is one of:

-ba

Build binary and source packages (after doing the %prep, %build, and %install stages).

-bb

Build a binary package (after doing the %prep, %build, and %install stages).

-bp

Executes the "%prep" stage from the spec file. Normally this involves unpacking the sources and applying any patches.

-bc

Do the "%build" stage from the spec file (after doing the %prep stage). This generally involves the equivalent of a "make".

-bi

Do the "%install" stage from the spec file (after doing the %prep and %build stages). This generally involves the equivalent of a "make install".

-bl

Do a "list check". The "%files" section from the spec file is macro expanded, and checks are made to verify that each file exists.

-bs

Build just the source package.

The following options may also be used:

--buildroot DIRECTORY

When building a package, override the BuildRoot tag with directory DIRECTORY.

--clean

Remove the build tree after the packages are made.

--nobuild

Do not execute any build stages. Useful for testing out spec files.

--rmsource

Remove the sources after the build (may also be used standalone, e.g. "rpmbuild --rmsource foo.spec").

--rmspec

Remove the spec file after the build (may also be used standalone, eg. "rpmbuild --rmspec foo.spec").

--short-circuit

Skip straight to specified stage (i.e., skip all stages leading up to the specified stage). Only valid with -bc and -bi.

--sign

Embed a GPG signature in the package. This signature can be used to verify the integrity and the origin of the package. See the section on GPG SIGNATURES in rpm(8) for configuration details.

--target PLATFORM

When building the package, interpret PLATFORM as arch-vendor-os and set the macros %_target, %_target_cpu, and %_target_os accordingly.

Rebuild and Recompile Options

There are two other ways to invoke building with rpm:

rpmbuild {--rebuild|--recompile} SOURCEPKG...

When invoked this way, rpmbuild installs the named source package, and does a prep, compile and install. In addition, --rebuild builds a new binary package. When the build has completed, the build directory is removed (as in --clean) and the the sources and spec file for the package are removed.

Showrc

The command

rpmbuild --showrc

shows the values rpmbuild will use for all of the options are currently set in rpmrc and macros configuration file(s).

Files

rpmrc Configuration

/usr/lib/rpm/rpmrc
/usr/lib/rpm/redhat/rpmrc
/etc/rpmrc
~/.rpmrc

Macro Configuration

/usr/lib/rpm/macros
/usr/lib/rpm/redhat/macros
/etc/rpm/macros
~/.rpmmacros

Database

/var/lib/rpm/Basenames
/var/lib/rpm/Conflictname
/var/lib/rpm/Dirnames
/var/lib/rpm/Filemd5s
/var/lib/rpm/Group
/var/lib/rpm/Installtid
/var/lib/rpm/Name
/var/lib/rpm/Packages
/var/lib/rpm/Providename
/var/lib/rpm/Provideversion
/var/lib/rpm/Requirename
/var/lib/rpm/Requireversion
/var/lib/rpm/Sha1header
/var/lib/rpm/Sigmd5
/var/lib/rpm/Triggername

Temporary

/var/tmp/rpm*

See Also

popt(3),
rpm2cpio(8),
gendiff(1),
rpm(8),
http://www.rpm.org/

Authors

Marc Ewing <marc@redhat.com>
Jeff Johnson <jbj@redhat.com>
Erik Troan ewt@redhat.com

 

==============

http://www.rpm.org/max-rpm/ch-rpmrc-file.html

Appendix B. The rpmrc File

The rpmrc file is used to control RPM's actions. The file's entries have an effect on nearly every aspect of RPM's operations. Here, we describe the rpmrc files in more detail, as well as the command used to show how RPM interprets the files.

Using the --showrc Option

As we'll see in a moment, RPM can read more than one rpmrc file, and each file can contain nearly thirty different types of entries. This can make it difficult to determine what values RPM is actually using.

Luckily, there's an option that can be used to help make sense of it all. The --showrc option displays the value for each of the entries. The output is divided into two sections:

  1. Architecture and operating system values.

  2. rpmrc values.

The architecture and operating system values define the architecture and operating system that RPM is running on. These values define the environment for both building and installing packages. They also define which architectures and operating systems are compatible with each other.

The rpmrc values define many aspects of RPM's operation. These values range from the path to RPM's database, to the name of the person listed as having built the package.

Here's an example of --showrc's output:

# rpm --showrc
ARCHITECTURE AND OS:
build arch           : i386
build os             : Linux
install arch         : i486
install os           : Linux
compatible arch list : i486 i386
compatible os list   : Linux
RPMRC VALUES:
builddir             : /usr/src/redhat/BUILD
buildroot            : (not set)
cpiobin              : cpio
dbpath               : /var/lib/rpm
defaultdocdir        : /usr/doc
distribution         : (not set)
excludedocs          : (not set)
ftpport              : (not set)
ftpproxy             : (not set)
messagelevel         : (not set)
netsharedpath        : (not set)
optflags             : -O2 -m486 -fno-strength-reduce
packager             : (not set)
pgp_name             : (not set)
pgp_path             : (not set)
require_distribution : (not set)
require_icon         : (not set)
require_vendor       : (not set)
root                 : (not set)
rpmdir               : /usr/src/redhat/RPMS
signature            : none
sourcedir            : /usr/src/redhat/SOURCES
specdir              : /usr/src/redhat/SPECS
srcrpmdir            : /usr/src/redhat/SRPMS
timecheck            : (not set)
tmppath              : /var/tmp
topdir               : /usr/src/redhat
vendor               : (not set)
#
      

As you can see, the --showrc option clearly displays the values RPM will use. --showrc can also be used with the --rcfile option, which makes it easy to see the effect of specifying a different rpmrc file.

 
=================

Macro syntax

RPM has fully recursive spec file macros. Simple macros do straight text substitution. Parameterized macros include an options field, and perform argc/argv processing on white space separated tokens to the next newline. During macro expansion, both flags and arguments are available as macros which are deleted at the end of macro expansion. Macros can be used (almost) anywhere in a spec file, and, in particular, in "included file lists" (i.e. those read in using files -f <file>). In addition, macros can be nested, hiding the previous definition for the duration of the expansion of the macro which contains nested macros.

To define a macro use:

	%define <name>[(opts)] <body>

All whitespace surrounding <body> is removed. Name may be composed of alphanumeric characters, and the character `_' and must be at least 3 characters in length. A macro without an (opts) field is "simple" in that only recursive macro expansion is performed. A parameterized macro contains an (opts) field. The opts (i.e. string between parentheses) is passed exactly as is to getopt(3) for argc/argv processing at the beginning of a macro invocation. While a parameterized macro is being expanded, the following shell-like macros are available:

	%0	the name of the macro being invoked
	%*	all arguments (unlike shell, not including any processed flags)
	%#	the number of arguments
	%{-f}	if present at invocation, the flag f itself
	%{-f*}	if present at invocation, the argument to flag f
	%1, %2	the arguments themselves (after getopt(3) processing)

At the end of invocation of a parameterized macro, the above macros are (at the moment, silently) discarded.

If a macro name begins with '.', then later attempts to redefine the macro are an error. Note that the '.' is not part of the name itself.

Within the body of a macro, there are several constructs that permit testing for the presence of optional parameters. The simplest construct is "%{-f}" which expands (literally) to "-f" if -f was mentioned when the macro was invoked. There are also provisions for including text if flag was present using "%{-f:X}". This macro expands to (the expansion of) X if the flag was present. The negative form, "%{!-f:Y}", expanding to (the expansion of) Y if -f was *not* present, is also supported.

In addition to the "%{...}" form, shell expansion can be performed using "%(shell command)". The expansion of "%(...)" is the output of (the expansion of) ... fed to /bin/sh. For example, "%(date +%y%m%d)" expands to the string "YYMMDD" (final newline is deleted). Note the 2nd % needed to escape the arguments to /bin/date. There is currently an 8K limit on the size that this macro can expand to.

There are several builtin macros (with reserved names) that are needed to perform useful operations. The current list is

	%trace		toggle print of debugging information before/after
			expansion
	%dump		print the active (i.e. non-covered) macro table

	%{echo:...}	print ... to stderr
	%{warn:...}	print ... to stderr
	%{error:...}	print ... to stderr and return BADSPEC
 
	%define ...	define a macro
	%undefine ...	undefine a macro
	%global ...	define a macro whose body is available in global context

	%{uncompress:...} expand ... to <file> and test to see if <file> is
			compressed.  The expansion is
				cat <file>		# if not compressed
				gzip -dc <file>		# if gzip'ed
				bzip2 -dc <file>	# if bzip'ed
	%{expand:...}	like eval, expand ... to <body> and (re-)expand <body>

	%{S:...}	expand ... to <source> file name
	%{P:...}	expand ... to <patch> file name
	%{F:...}	expand ... to <file> file name

Macros may also be automatically included from /usr/lib/rpm/macros. In addition, rpm itself defines numerous macros. To display the current set, add "%dump" to the beginning of any spec file, process with rpm, and examine the output from stderr.

Here is an example patch definition from /usr/lib/rpm/macros:

	%patch(b:p:P:REz:) \
	%define patch_file	%{P:%{-P:%{-P*}}%{!-P:%%PATCH0}} \
	%define patch_suffix	%{!-z:%{-b:--suffix %{-b*}}}%{!-b:%{-z:--suffix %{-z*}}}%{!-z:%{!-b: }}%{-z:%{-b:%{error:Can't specify both -z(%{-z*}) and -b(%{-b*})}}} \
		%{uncompress:%patch_file} | patch %{-p:-p%{-p*}} %patch_suffix %{-R} %{-E} \
	...

The first line defines patch with its options. The body of patch is

	%{uncompress:%patch_file} | patch %{-p:-p%{-p*}} %patch_suffix %{-R} %{-E}

The body contains 7 macros, which expand as follows

	%{uncompress:...}	copy uncompressed patch to stdout
	  %patch_file		... the name of the patch file
	%{-p:...}		if "-p N" was present, (re-)generate "-pN" flag
	  -p%{-p*}		... note patch-2.1 insists on contiguous "-pN"
	%patch_suffix		override (default) ".orig" suffix if desired
	%{-R}			supply -R (reversed) flag if desired
	%{-E}			supply -E (delete empty?) flag if desired

There are two "private" helper macros:

	%patch_file	the gory details of generating the patch file name
	%patch_suffix	the gory details of overriding the (default) ".orig"

To use a macro, write:

	%<name> ...

or

	%{<name>}

The %{...} form allows you to place the expansion adjacent to other text. The %<name> form, if a parameterized macro, will do argc/argv processing of the rest of the line as described above. Normally you will likely want to invoke a parameterized macro by using the %<name> form so that parameters are expanded properly.

Example:

	%define mymacro() (echo -n "My arg is %1" ; sleep %1 ; echo done.)

Usage:

	%mymacro 5

This expands to:

	(echo -n "My arg is 5" ; sleep 5 ; echo done.)

This will cause all occurrences of 1 in the macro definition to be replaced by the first argument to the macro, but only if the macro is invoked as "%mymacro 5". Invoking as "%{mymacro} 5" will not work as desired in this case.

When the command line option "--define 'macroname value'" allows the user to specify the value that a macro should have during the build. Note lack of leading % for the macro name. We will try to support users who accidentally type the leading % but this should not be relied upon.

Evaluating a macro can be difficult outside of an rpm execution context. If you wish to see the expanded value of a macro, you may use the option

	--eval '<macro expression>'
that will read rpm config files and print the macro expansion on stdout.

Note: This works only macros defined in rpm configuration files, not for macros defined in specfiles. You can use %{echo: %{your_macro_here}} if you wish to see the expansion of a macro defined in a spec file.

Starting in rpm 3.0, macros rather than rpmrc lines are used to configure rpm. In general, all the rpmrc configuration lines documented in "Maximum RPM" have been converted to macros, usually with a leading underscore, and the same name that was used in rpmrc files. In some cases, there is no leading underscore. Those macros existed in rpm-2.5.x and the underscore is omitted in order to preserve the meaning and usage of macros that are defined during spec file parsing.

Here's an example to illustrate configuration using macros:

   Old way:
	In /etc/rpmrc and/or ~/.rpmrc you put
		something:      some_value

   New way:
	In /etc/rpm/macros and/or ~/.rpmmacros
		%_something     some_value

Here are 2 common FAQ for experienced users of rpm:

  1) --rcfile works differently.
    Old way:	rpm --rcfile whatever
    New way:	rpm --rcfile /usr/lib/rpm/rpmrc:whatever

  2) topdir (and other rpmrc configurables) work differently.

    Old way:
	~/.rpmrc contains
		topdir:         whatever

    New way:
	/usr/lib/rpm/rpmrc contains
		macrofiles:     /usr/lib/rpm/macros: ... :~/.rpmmacros
	~/.rpmmacros contains
		%_topdir        whatever

Several macro definitions provided by the default rpm macro set have uses in packaging similar to the autoconf variables that are used in building packages:

    %_prefix		/usr
    %_exec_prefix	%{_prefix}
    %_bindir		%{_exec_prefix}/bin
    %_sbindir		%{_exec_prefix}/sbin
    %_libexecdir	%{_exec_prefix}/libexec
    %_datadir		%{_prefix}/share
    %_sysconfdir	%{_prefix}/etc
    %_sharedstatedir	%{_prefix}/com
    %_localstatedir	%{_prefix}/var
    %_libdir		%{_exec_prefix}/lib
    %_includedir	%{_prefix}/include
    %_oldincludedir	/usr/include
    %_infodir		%{_prefix}/info
    %_mandir		%{_prefix}/man
====================
 

Specifying File Attributes

In cases where the package builder cannot create the files to be packaged with the proper ownership and permissions, the %attr macro can be used to make things right.

%attr — How Does It Work?

The %attr macro has the following format:

%attr(<mode>, <user>, <group>) <file>
          

  • The <mode> is represented in traditional numeric fashion.

  • The <user> is specified by the login name of the user. Numeric UIDs are not used, for reasons we'll explore in a moment.

  • The <group> is specified by the group's name, as entered in /etc/group. Numeric GIDs are not used, either. Yes, we'll be discussing that, too!

  • <file> represents the file. Shell-style globbing is supported.

There are a couple other wrinkles to using the %attr macro. If a particular file attribute doesn't need to be specified, that attribute can be replaced with a dash "-" and %attr will not change it. Say, for instance, that a package's files are installed with the permissions correctly set, as they almost always are. Instead of having to go to the trouble of entering the permissions for each and every file, each file can have the same %attr:

%attr(-, root, root)
          

This works for user and group specifications, as well.

The other wrinkle is that, although we've been showing the three file attributes separated by commas, in reality they could be separated by spaces as well. Whichever delimiter you choose, it pays to be consistent throughout a spec file.

Let's fix up cdplayer with a liberal sprinkling of %attrs. Here's what the %files list looks like after we've had our way with it:

%files
%attr(-, root, root) %doc README
%attr(4755, root, root) /usr/local/bin/cdp
%attr(-, root, root) /usr/local/bin/cdplay
%attr(-, root, rot) /usr/local/man/man1/cdp.1
          

A couple points are worth noting here. The line for README shows that multiple macros can be used on a line — in this case, one to set file attributes, and one to mark the file as being documentation. The %attr for /usr/local/bin/cdp declares the file to be setuid root. If it sends a shiver down your spine to know that anybody can create a package that will run setuid root when installed on your system — Good! Just because RPM makes it easy to install software doesn't mean that you should blindly install every package you find.

A single RPM command can quickly point out areas of potential problems and should be issued on any package file whose creators you don't trust:

% rpm -qlvp ../RPMS/i386/cdplayer-1.0-1.i386.rpm
drwxr-xr-x-  root  root   1024 Sep 13 20:16 /usr/doc/cdplayer-1.0-1
-rw-r--r---  root  root   1085 Nov 10 01:10 /usr/doc/cdplayer-1.0-1/README
-rwsr-xr-x-  root  root  40739 Sep 13 21:32 /usr/local/bin/cdp
lrwxrwxrwx-  root  root     47 Sep 13 21:32 /usr/local/bin/cdplay -> ./cdp
-rwxr-xr-x-  root   rot   4550 Sep 13 21:32 /usr/local/man/man1/cdp.1
% 
          

Sure enough — there's that setuid root file. In this case we trust the package builder, so let's install it:

# rpm -ivh cdplayer-1.0-1.i386.rpm
cdplayer       ##################################################
group rot does not exist - using root
#
          

What's this about group "rot"? Looking back at the rpm -qlvp output, it looks like /usr/local/man/man1/cdp.1 has a bogus group. Looking back even further, it's there in the %attr for that file. Must have been a typo. We could pretend that RPM used advanced artificial intelligence technology to come to the same conclusion as we did and made the appropriate change, but in reality, RPM simply used the only group identifier it could count on — root. RPM will do the same thing if it can't resolve a user specification.

Let's look at some of the files the package installed, including that worrisome setuid root file:

# ls /usr/local/bin
total 558
-rwsr-xr-x   1 root     root        40739 Sep 13 21:32 cdp*
lrwxrwxrwx   1 root     root           47 Sep 13 21:36 cdplay -> ./cdp*
# 
          

RPM did just what it was supposed to — It gave the files the attributes specified by the %attr macros.

Betcha Thought We Forgot…

At the start of this section, we mentioned that the %attr macro wouldn't accept numeric uids or gids, and we promised to explain why. The reason is simply that, even if a package requires a certain user or group to own the package's files, the user may not have the same uid/gid from system to system. There — wasn't that simple?

In the next chapter, we'll discuss how to make your packaged software safe against modification by unscrupulous people. The name of the game is Pretty Good Privacy, and you'll see how signing packages with PGP is easier than you think!

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值