# RpmSpec Type documentation

### Background/Abstract

- The RpmSpec Type generates .spec files suitable for use by the rpmbuild utility to build and package. It additionally creates a Bourne shell script that automates creation of source tarball and proper dependency-order building/packaging of .spec files.
- The RpmSpec type refines the existing aggregated workspace MPC concept, as well as introduces the ability to have specific clauses inside workspace declarations (.mwc files). Consequently, workspace files utilizing these new features are not backwards-compatible with prior releases of MPC.
- Since RPM is primarily Linux-based, RpmSpec only officially supports use on Linux-based systems. It may work on platforms for which an RPM port exists, but such success would be coincidental and neither intended, tested, nor guaranteed.

### Pre-requisites

- The following software items are required and in the execution path (as well as any of their respective dependencies):
  RPM
    Minimum of version 4.7.1 recommended (not tested with other versions).
  Development toolchain
    This can be the standard development toolchain. Packaging for other architectures is supported if the toolchain in the path is a cross-compiler for that architecture.

### Usage

The RpmSpec type refines an existing concept in MPC known as aggregate workspaces to define package scopes. When mwc.pl is run on a top-level workspace with -type rpmspec, each aggregated workspace is presumed to define the scope of a package that will become an RPM. Inter-project dependencies that exist between any projects known to the top-level workspace automatically turn into inter-package dependencies in RPMs.

#### Generic workflow

###### Figure: RPM Workflow

Presuming .mwc files already exist, and that inter-project dependencies are complete and well-formed (i.e., contain sufficient after statements to insure proper build ordering):

1. Use the command mwc.pl -type rpmspec top-level-workspace.mwc to generate .spec files and *_rpm.sh builder script.

2. Run the top-level-workspace_rpm.sh script to build/package.

### Adapting/Writing Projects for Packaging

#### Creating Workspaces

The RpmSpec type uses aggregate workspaces to define the scope of a package. In other words, defining a package involves writing a .mwc file that includes all the projects that should go into that package. An additional .mwc file must be written for each additional package. Finally, these package workspaces get aggregated into a workspace.

RPM packages require extra information not needed by "normal" MPC projects or workspaces. This information is defined in a specific clause in the workspace for the rpmspec type, e.g.,

> // top-level workspace

> workspace {

> specific (rpmspec) {

> rpm_version = 1.0

> rpm_release = 1

> }

> package1.mwc

> package2.mwc

> }

Details on the variables allowed in the specific clause can be found in the $MPC_ROOT/docs/templates/rpmspec.txt file.

If you use workspaces as a part of building right now, you may wish to write additional workspace files specifically for packaging via RPM.

#### Making Projects Install-Ready

MPC-assisted packaging requires some attention from the developer in order to yield its full potential. What this means is that in order for a project to avail itself to be packaged, it must take care to insure that any collateral (such as files) that it needs to end up in the package get installed via MPC's install feature. Note that this feature is currently only implemented within the gnuace project type.

Typically, this involves inheriting from the install base project in order to enable auto-generation of installation rules in the makefiles. MPC defaults to making educated guesses as to what files should be installed (e.g., for an exe project, it figures that the executable should be installed), but a developer can augment or replace MPC's guesses using Install*_Files groupings. See the documentation on the gnuace installation feature for details.

### Notes

#### Notes on Generated RPMs

1. RPMs are relocatable using the --prefix or --relocate options to rpm.

2. The RpmSpec type has no control over where the RPM system performs it's "work" (building, staging, packaging, etc.). In the past, this was often /usr/src/redhat, though your system may be configured differently.
   rpmbuild holds this directory in its _topdir configuration variable. To see the value of _topdir on your system, execute the following command:

   > $ rpmbuild --showrc | grep '_topdir[^}]'

   > -14: _topdir %{getenv:HOME}/rpmbuild

3. Binary RPMs land in _topdir/RPMS.

4. Source RPMs land in _topdir/SRPMS.

#### Notes on Generated Script

1. The script takes one optional argument indicating the architecture for which it should create packages. The script makes no attempt to "find" a toolchain for that architecture, instead presuming that whatever toolchain is needed can be found in the PATH or is specified in the .spec file.

2. The script performs a build/install activity for each package. Installation is not into the running system, but rather into a "fake" area. Installation is necessary to satisfy inter-package dependency requirements.

   The location of the "fake" area defaults to /tmp/mpcrpm but can be changed by setting the <%rpm_mpc_temp%> in a workspace specific clause, typically in the top-level workspace.