Showing posts with label declarations. Show all posts
Showing posts with label declarations. Show all posts

Thursday, March 6, 2008

Finalizing The Spec File And Building Your Own Linux RPM

Hey There,

We're finally ready to create our very own Linux RPM package! Following up on yesterday's post regarding beginning to write your spec file and the preceding initial software build, we're now going to look at the "build" section of the RPM spec file and compile our new RPM.

The "build" section of the spec file follows the "header section" we went over previously, and contains all that the "rpmbuild" command needs to know in order to create your RPM for you. I should note here that, on some systems, this command may be called "rpm-build" and, on yet others, the rpmbuild flags may simply be options to the rpm command itself (as with SUSE 8.x)

The declarations required in this section are:

%clean <--- Well, not really required, but keeps things nice and tidy ;)
%prep
%setup
%files
%build
%install


These sections are defined as follows (Note that for these declarations, the values are listed beginning on the line below, rather than on the same line, as we did in the "header section":

%clean - this deletes everything in the RPM_BUILD_ROOT, as defined by either the BuildRoot declaration in the "header section" (Which we didn't use for this build) or by the system default. In our case, this should be /usr/src/packages/BUILD. Cautious users may want to add a line of code in front of this, assuring that the RPM_BUILD_ROOT variable isn't set to /. This method is not absolutely necessary, either, so the incredibly cautious can just not call it and remove old garbage files, whenever they want to, manually. It can also cause issues when running concurrent builds if using the same RPM_BUILD_ROOT! Some folks prefer to run this method at the end of the spec file, or script out what it does automatically. It's a matter of preference :)

%prep - This simply indicates that we're moving on to the next section of our spec file. It is necessary, as everything beyond it will be considered part of the build process, rather than part of the RPM definition process, listed above it.

%setup - This part of the spec file indicates that "rpmbuild" should do whatever is necessary to prepare the source for building/compilation. Of course, we've done this already (to make sure we could build from source properly), but this declaration is necessary so that rpmbuild sets everything up for the following sections. Note that without any arguments, in our setup, it's just going to unzip and untar our source package in /usr/src/packages/SOURCES to the /usr/src/packages/BUILD directory.

%files - This is where we have to list all of the files that are going to be in our RPM, for reference when its installed and/or removed using the "rpm" command. In our previous post on building the software from source, we created a file called FILELIST (from the output of the find command). On the line following the %files declaritive, you can just read that file list into your spec file. If you elect to type each file name in, that's your decision, but you should include only one file per line (which can make your spec file pretty long depending on what you're installing. Given how many files most software packages contain, you'll grow sick and tired of this method soon enough ;)

%build - Here you'll provide all the information required to build the software. This can be culled from the notes you took while compiling the program initially.

%install - And finally, here you'll provide all the information required to install the program (Basically, the "make install" command and all arguments from the original compile of the software that you did earlier.

Our spec file will look something like this:

%clean
%prep
%setup
%files
/usr/local/PACKAGE-3.2-1/bin/list
/usr/local/PACKAGE-3.2.1/lib/liblist.so
...
%build
./configure --prefix=%{prefix}
make
make check
%install
make install
/bin/chown -Rv root:root %{prefix}


Before we actually build our RPM, we'll want to change the names of all the files listed in the %files section, that we got from our initial build. Assuming you wanted the RPM to install in /usr/local, you would want to use your favorite editor to replace all instances of "/usr/local/PACKAGE-3.2-1" in this section with "/usr/local" - this would change our %files section from:

%files
/usr/local/PACKAGE-3.2-1/bin/list
/usr/local/PACKAGE-3.2.1/lib/liblist.so
...


to

%files
/usr/local/bin/list
/usr/local/lib/liblist.so
...


Now our spec file is complete and we can create our RPM using this one simple command: rpmbuild. For our purposes, we'll run:

host # rpmbuild -ba PACKAGE.spec

then we'll kick back and watch the magic happen :) Note that I used the "-ba" option to build both source and binary RPM packages. This created the files /usr/src/packages/SRPMS/PACKAGE-3.2-1.src.rpm and /usr/src/packages/RPMS/x86_64/PACKAGE-3.2-1.x86_64.rpm <--- Note that this directory may be slightly different depending on what OS version of Linux you're running.

Now, you're all set to run "rpm -ivh PACKAGE-3.2-1.x86_64.rpm" and your software package will be installed, and can be manipulated by all the standard "rpm" facilities.

Of course there are tons of other options and additions to the spec file (%post, etc) and rpmbuild command, but this should be enough to get you started. For more specific information, check out the online man pages and chat boards - You'd be surprised at what you can do with this software if you use your imagination :)

Best wishes,

, Mike




Wednesday, March 5, 2008

Beginning Your Spec File For Building Linux RPM's.

Hello Again,

This is a continuation of yesterdays post on doing the initial build of your software as the first step toward creating your own Linux RPM. Today we're going to continue on that path with our software package (cleverly named PACKAGE-3.2-1 ;) and move on to the next step in the RPM creation process; the creation of the specification file (which I'll refer to as the "spec file" from here on out) and its basic structure.

For the purposes of our example, we won't be including every single option you can include in a spec file, but we'll touch on all the required ones, and a few that might make your life a bit easier :)

We'll create our spec file by simply opening it up as a new file in our favorite editor. The spec file is simply a plain text file, describing our RPM's attributes, that we'll be supplying to the "rpmbuild" command later on. We'll look at the spec file, line by line, for our soon-to-be-completed package. We'll call it PACKAGE.spec

The first section is what I like to call the "header section," although I don't know that it's ever actually referred to as that. It looks like the following

Summary: The World Famous PACKAGE software
Name: PACKAGE
Version: 3.2
Release: 1
Copyright: Gnu Public License
Group: Applications
Source0: PACKAGE-3.2-1.tar.gz
Prefix: /usr/local
Provides: PACKAGE3, PACKAGE-devel, bunk
Requires: PACKAGE1, db
URL: http://xyz.com
Packager: Mike Tremell
# %define _topdir /users/me/softbuilds/rpm
%description
PACKAGE 3.2-1 Standard Build
%define PACKAGEDIR %{prefix}


The lines in this section are defined as follows:

Summary - This line should be a descriptive summary of your RPM package, in short form. It shouldn't be too wordy, but you can make it as long as you want.

Name - This is simply the name of your package. It must match the source package's name (which we created in /usr/src/packages/SOURCES/ in yesterday's post on setting up the initial build for your RPM. It will later be used (with the Version and Release keyword values appended) by rpmbuild to determine what source file it should look for in /usr/src/packages/SOURCES

Version - The version of your software. Again this must be exactly the same version of the source package you're building from.

Release - The release of the software. This, again, must be exactly the same as the release you're building from. Using the "Name," "Version," and "Release" variables, rpmbuild will surmise that we want to build our RPM from PACKAGE-3.2-1.tar.gz in /usr/src/packages/SOURCES. Note: The Release variable is required and (for whatever reason) cannot be an empty value. Thus we put in the obligatory 1 for our new build of the generic PACKAGE software. Whatever you're building will probably have a release number.

Copyright - Just attribution for the package and/or package source's author(s)

Group - This identifies our package as belonging to the "Applications" package group in Linux.

Source0 - The name (Yes, this is redundant ;) of the source package in /usr/src/packages/SOURCES. As the name implies, you can have more than one source in certain circumstances. Note that there is also a "Patch0," etc, declaration that you can use to specify diff files you may need to include, but that's beyond the scope of our exercise.

Prefix - The root under which the RPM will install itself. Note: You need to include the Prefix declaration if you want your RPM package to be "relocatable." If your package is not relocatable, all installs will always install to the same place. If your package is relocatable, it allows the user or administrator to change the prefix, or root install directory, of the RPM when they run the "rpm" command to install it!

Provides - What your RPM will "provide" once it is installed. This is mainly for rpm's dependency checking. You can have your package provide anything, but it's best to have it provide only useful values. This variable isn't necessary if your software package isn't providing anything significant and/or doesn't have another package that's dependant on it.

Requires - The RPM packages your RPM package needs to have installed on your system before it will install correctly. In our example, PACKAGE will not install correctly (it will fail the dependency check) if some version of the "db" (Berkeley Database) RPM isn't already installed on our system.

URL - The location where a user can download the latest version of the RPM source. Not necessary, but can be helpful.

Packager - The name of the guy (or gal) who put together the RPM. Again, not necessary unless you're seeking notoriety ;)

# %define _topdir /users/me/softbuilds/rpm - Note that this line is commented out for our build, since we're going with the system defaults. However, comments in spec files work just like comments in shell scripts, so if you wanted to change the top level directory for your RPM structure, you could do it by redefining the _topdir variable (In this case, simply by removing the comment). You may need to create its required BUILD, BUILDROOT, RPMS, SOURCES, SPECS and SRPMS subdirectories manually. This option is useful if you're trying to do a build as a regular user and don't have the system privilege that will allow you to manipulate your server's main RPM package working directories :)

%description - Just like the summary above, but should be more descriptive. Also, you should add your description on a new line following the %description declaration (unlike all the others). "rpmbuild" will spew error messages if you put your description's value on the same line as the variable. You can actually include "one" word on the same line as the %description variable, but the rest of your description must be below that line. It should also be noted that you can have multiple %description declarations, which is useful if you're building multiple RPM's from one spec file (although that's deeper than we want to go for now).

%define - This directive can be used over and over again. It's simple format is: %define variable_name value. You can call the variable name you define here using the %{} notation. For instance:

%define mydir /usr/local/bin

Would allow you to reference /usr/local/bin, at any point (from the point of definition on) in your spec file as %{mydir}

Tomorrow, we'll check out the next, and final section of the RPM spec file and use "rpmbuild" to create our RPM package!

Cheers,

, Mike