What Actually Is $Rpm_Build_Root

What actually is $RPM_BUILD_ROOT?

$RPM_BUILD_ROOT (or the equivalent %{buildroot} SPEC file macro) always holds the directory under which RPM will look for any files to package. The RPM scripts (e.g. the script that compresses the manual pages) will also use that value to know where to look for the files that were just installed. Normally, this value will be non-empty and contain a location away from the system directories - usually somewhere under /tmp or /var/tmp.

The author of the SPEC file is expected to make sure that make install (or whatever installer the software in question is using) will place any files under $RPM_BUILD_ROOT, with the same hierarchy that should be used when the software is finally installed. E.g. to have RPM install ls in /bin/ls, the %install SPEC file section should make sure that ls is placed in $RPM_BUILD_ROOT/bin/ls.

The author of the SPEC file is also expected to use the BuildRoot: tag to specify a proper location. Alternatively, the build system could have an rpmrc RPM configuration file with a proper entry. In any case the build root should be set, so that:

  • Normal users will be able to build the source package.

  • Should the superuser ever build the source package, the build process will not clobber any system files, unless the superuser installs the resulting binary package. And yes, there may be a good reason to build some packages as root - for example, running the full glibc testsuite requires root privileges for some tests.

That said, RPM can and will build a package with an empty build root variable. In that case both the build install and the final destination locations will coincide. A potential call to e.g. make install will use the default locations, thus clobbering the system files under e.g. /usr/lib if run with sufficient privileges. Additionally, having /usr/bin/* in your %files section will happily pull the whole contents of the build host /usr/bin/ directory into your binary package.

Bottom line:

  • Never use an empty build root.

  • Do not build packages as root unless there is absolutely no other way.

Rpm building and spec file for single script

$RPM_BUILD_ROOT is a "virtual root directory". That is when you build a RPM package you need to form a complete layout of the package, with all paths like /usr/lib/, /etc/, or as in your case /opt/<package>/. But since an ordinary user doesn't have permissions to create files in those system directories (and this is good indeed!) one should create the file system hierarchy under $RPM_BUILD_ROOT which usually resides in a temporary directory like /tmp/<mypackage>-buildroot or something similar:

So a packager creates $RPM_BUILD_ROOT/etc/, $RPM_BUILD_ROOT/usr/lib and so on and then places all the files for the package into those directories.

Some RPM variants require explicit BuildRoot: <somepath> header in the spec to set $RPM_BUILD_ROOT to a non-empty value, while other (including e.g. recent specs from Fedora/RedHat) have this header set implicitly.

All the operations to create package layout are performed in %install section of the spec, and actually %install is simply a shell script, you may do what you would usually do to create a set of files.

Then you need to specify all the files placed under $RPM_BUILD_ROOT in the %files section, this time without $RPM_BUILD_ROOT!

See e.g. this spec for Lua to understand how the things are performed. All those %{_bindir} %{_libdir} and other rpm macros are just a portable replacements for /usr/bin, /usr/lib/ etc directories. This approach allows for example to put x86-64 libraries under /usr/lib64, x86-32 ones - under /usr/lib and this all done from the same spec.

rpmbuild %install section removes buildroot code. How do I keep rpmbuild from doing this

you are misusing the %prep section. In very short how you should use those sections:

  • %prep: to extract your sources, apply patches etc.
  • %build: to compile or build your application (if you need to)
  • %install: to copy the files into $RPM_BUILD_ROOT

So it is logical that $RPM_BUILD_ROOT is emptied at the start of the %isntall section.

Change your code to extract your zip file in %prep, and use the %install section to put the files inside $RPM_BUILD_ROOT.

What is the intended use of each directive (%build, %install, %clean, etc.) in an RPM spec file?

%prep extracts/etc. your sources files, etc. (i.e Untar)

%build builds your binaries, documentation, etc. (i.e. ./configure && make)

%install copies your installed/to-be-packaged files into the %buildroot.



Related Topics



Leave a reply



Submit