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 fullglibc
testsuite requiresroot
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
Boost with Qt Creator and Linux
Makefile with Multiple Targets
How to Split Mailbox into Single File Per Message
How to Get Cmake to Use the Default Compiler on System Path
Best Way to Set Environment Variables in Calling Shell
How to Use Stdin Twice from Pipe
In Bash, Why 'X=100 Echo $X' Doesn't Print Anything
Join on First Column of Two Files
Qimage to Cv::Mat Convertion Strange Behaviour
Why Does '/Proc/Meminfo' Show 32Gb When Aws Instance Has Only 16Gb
Bash Output Stream Write to a File
How to Configure Bash to Handle Crlf Shell Scripts
Identifying Which Linux System Library Contains a Function
Gcc: Putchar(Char) in Inline Assembly
How to Remove X Bytes from the End of a Large File Without Reading the Whole File