# 4 - Advanced Packaging with EPM

This chapter describes the advanced packaging features of EPM.

## Including Other List Files

The `%include` directive includes another list file:

    %include filename

Includes can be nested, usually up to 250 levels (depends on the host operating system and libraries.)

## Conflicts, Provides, Replaces, and Requires

Software conflicts and requirements are specified using the `%incompat` and `%requires` directives. If your software replaces another package, you can specify that using the `%replaces` directive (`%replaces` is silently mapped to `%conflicts` when the distribution format does not support package replacement.) If your package provides certain functionality associated with a standard name, the `%provides` directive can be used.

Dependencies are specified using the package name and optionally the lower and upper version numbers:

    %requires foobar
    %requires foobar 1.0
    %incompat foobar
    %incompat foobar 0.9
    %replaces foobar
    %replaces foobar 1.2 3.4
    %provides foobar

or the filename:

    %requires /usr/lib/libfoobar.so
    %incompat /usr/lib/libfoobar.so.1.2

Package dependencies are currently enforced only for the same package format, so a portable distribution that requires package "foobar" will only look for an installed "foobar" package in portable format.

Filename dependencies are only supported by the Debian, portable, and RPM distribution formats.

## Scripts

Bourne shell script commands can be executed before or after installation, patching, or removal of the software. The `%preinstall` and `%postinstall` directives specify commands to be run before and after installation, respectively:

    %preinstall echo Command before installing
    %postinstall echo Command after installing

Similarly, the `%prepatch` and `%postpatch` directives specify commands to be executed before and after patching the software:

    %prepatch echo Command before patching
    %postpatch echo Command after patching

Finally, the `%preremove` and `%postremove` directives specify commands that are run before and after removal of the software:

    %preremove echo Command before removing
    %postremove echo Command after removing

To include an external script file, use the `<filename` notation:

    %postinstall <filename

To include multiple lines directly, use the `<<string` notation:

    %postinstall <<EOF
    echo Command before installing
    /usr/bin/foo
    EOF

Note that all commands specified in the list file will use the variable expansion provided by EPM, so be sure to quote any dollar sign (`$`) characters in your commands. For example, "$foo" is replaced by the value of "foo", but "$$foo" becomes "$foo".

## Conditional Directives

The `%system` directive can match or not match specific operating system names or versions. The operating system name is the name reported by `uname` in lowercase, while the operating system version is the major and minor version number reported by `uname -r`:

`%system irix`
  Only include the following files when building a distribution for the IRIX operating system.
`%system linux-2.0`
  Only include the following files when building a distribution for Linux 2.0.x.
`%system !irix !linux-2.0`
  Only include the following files when building a distribution for operating systems other than IRIX and Linux 2.0.x.

The special name `all` is used to match all operating systems:

    %system all

For format-specific files, the `%format` directive can be used:

`%format rpm`
  Only include the following files when building an RPM distribution.
`%format !rpm`
  Only include the following files when not building an RPM distribution.x.
`%format all`
  Include the following files for all types of distributions.

Finally, EPM can conditionally include lines using the `%if`, `%elseif`, `%ifdef`, `%elseifdef`, `%else`, and `%endif` directives. `%if` directives include the text that follows if the named variable(s) are defined to a non-empty string, while `%ifdef` directives only include the text if the named variable(s) are defined to any value.

## Protecting Object Files from Stripping

The `nostrip()` option can be included at the end of a file line to prevent EPM from stripping the symbols and debugging information from the file:

    f 755 root sys /usr/lib/libfoo.so libfoo.so nostrip()

## Software Patches

EPM supports portable software patch distributions which contain only the differences between the original and patch release. Patch files are specified using uppercase letters for the affected files. In the following example, the files /usr/bin/bar and /etc/foo.conf are marked as changed since the original release:

    f 755 root sys /usr/bin/foo foo
    F 755 root sys /usr/bin/bar bar
    f 755 root sys /usr/share/man/man1/foo.1 foo.man
    f 755 root sys /usr/share/man/man1/bar.1 bar.man
    C 644 root sys /etc/foo.conf foo.conf

## Variables

EPM imports the current environment variables for use in your list file. You can also define new variable in the list file or on the command-line when running EPM.

Variables are defined by starting the line with the dollar sign (`$`) followed by the name and value:

    $name=value
    $prefix=/usr
    $exec_prefix=${prefix}
    $bindir=$exec_prefix/bin

Variable substitution is performed when the variable is defined, so be careful with the ordering of your variable definitions.

Also, any variables you specify in your list file will be overridden by variables defined on the command-line or in your environment, just like with `make`. This can be a useful feature or a curse, depending on your choice of variable names.

As you can see, variables are referenced using the dollar sign (`$`). As with most shells, variable names can be surrounded by curly braces (`${variable}`) to explicitly delimit the name.

If you need to insert a `$` in a filename or a script, use `$$`:

    %install echo Enter your name:
    %install read $$name
    %install echo Your name is $$name.

## Init Scripts

Initialization scripts are generally portable between platforms, however the location of initialization scripts varies greatly.

The `i` file type can be used to specify and init script that is to be installed on the system. EPM will then determine the appropriate init file directories to use and create any required symbolic links to support the init script:

    i 755 root sys foo foo.sh

The previous example creates an init script named foo on the end-user system and will create symbolic links to run levels 0, 2, 3, and 5 as needed, using a sequence number of 00 (or 000) for the shutdown script and 99 (or 999) for the startup script.

To specify run levels and sequence numbers, use the `runlevel()`, `start()`, and `stop()` options:

    i 755 root sys foo foo.sh "runlevel(02) start(50) stop(30)"