Packages
********

Since Octave is Free Software users are encouraged to share their programs amongst each other. To aid this sharing Octave supports the installation of extra packages. The `Octave-Forge' project is a community-maintained set of packages that can be downloaded and installed in Octave. At the time of writing the `Octave-Forge' project can be found on-line at http://octave.sourceforge.net, but since the Internet is an ever-changing place this may not be true at the time of reading. Therefore it is recommended to see the Octave website for an updated reference.

Installing and Removing Packages
================================

Assuming a package is available in the file image-1.0.0.tar.gz it can be installed from the Octave prompt by writing

     pkg install image-1.0.0.tar.gz

If the package is installed successfully nothing will be printed on the prompt, but if an error occurred during installation it will be reported. It is possible to install several packages at once by writing several package files after the pkg install command. If a different version of the package is already installed it will be removed prior to installing the new package. This makes it easy to upgrade and downgrade the version of a package, but makes it impossible to have several versions of the same package installed at once.

To see which packages are installed type

     pkg list
     -| Package Name  | Version | Installation directory
     -| --------------+---------+-----------------------
     -|        image *|   1.0.0 | /home/jwe/octave/image-1.0.0

In this case only version 1.0.0 of the image package is installed. The '*' character next to the package name shows that the image package is loaded and ready for use.

It is possible to remove a package from the system using the pkg uninstall command like this

     pkg uninstall image

If the package is removed successfully nothing will be printed in the prompt, but if an error occurred it will be reported. It should be noted that the package file used for installation is not needed for removal, and that only the package name as reported by pkg list should be used when removing a package. It is possible to remove several packages at once by writing several package names after the pkg uninstall command.

To minimize the amount of code duplication between packages it is possible that one package depends on another one. If a package depends on another, it will check if that package is installed during installation. If it is not, an error will be reported and the package will not be installed. This behaviour can be disabled by passing the -nodeps flag to the pkg install command

     pkg install -nodeps my_package_with_dependencies.tar.gz

Since the installed package expects its dependencies to be installed it may not function correctly. Because of this it is not recommended to disable dependency checking.

Using Packages
==============

By default installed packages are available from the Octave prompt, but it is possible to control this using the pkg load and pkg unload commands. The functions from a package can be removed from the Octave path by typing

     pkg unload package_name

where package_name is the name of the package to be removed from the path.

In much the same way a package can be added to the Octave path by typing

     pkg load package_name

Administrating Packages
=======================

On UNIX-like systems it is possible to make both per-user and system-wide installations of a package. If the user performing the installation is root the packages will be installed in a system-wide directory that defaults to OCTAVE_HOME/share/octave/packages/. If the user is not root the default installation directory is ~/octave/. Packages will be installed in a subdirectory of the installation directory that will be named after the package. It is possible to change the installation directory by using the pkg prefix command

     pkg prefix new_installation_directory

The current installation directory can be retrieved by typing

     current_installation_directory = pkg prefix

To function properly the package manager needs to keep some information about the installed packages. For per-user packages this information is by default stored in the file ~/.octave_packages and for system-wide installations it is stored in OCTAVE_HOME/share/octave/octave_packages. The path to the per-user file can be changed with the pkg local_list command

     pkg local_list /path/to/new_file

For system-wide installations this can be changed in the same way using the pkg global_list command. If these commands are called without a new path, the current path will be returned.

Creating Packages
=================

Internally a package is simply a gzipped tar file that contains a top level directory of any given name. This directory will in the following be referred to as package and may contain the following files

package/DESCRIPTION
     This is a required file containing information about the package. See The DESCRIPTION File, for details on this file.

package/COPYING
     This is a required file containing the license of the package. No restrictions is made on the license in general. If however the package contains dynamically linked functions the license must be compatible with the GNU General Public License.

package/INDEX
     This is an optional file describing the functions provided by the package. If this file is not given then one with be created automatically from the functions in the package and the Categories keyword in the DESCRIPTION file. See The INDEX file, for details on this file.

package/PKG_ADD
     An optional file that includes commands that are run when the package is added to the users path. Note that PKG_ADD directives in the source code of the package will also be added to this file by the Octave package manager. Note that symbolic links are to be avoided in packages, as symbolic links do not exist on some file systems, and so a typical use for this file is the replacement of the symbolic link

          ln -s foo.oct bar.oct

     with an autoload directive like

          autoload ('bar', which ('foo'));

     See PKG_ADD and PKG_DEL directives, for details on PKG_ADD directives.

package/PKG_DEL
     An optional file that includes commands that are run when the package is removed from the users path. Note that PKG_DEL directives in the source code of the package will also be added to this file by the Octave package manager. See PKG_ADD and PKG_DEL directives, for details on PKG_DEL directives.

package/pre_install.m
     This is an optional script that is run prior to the installation of a package.

package/post_install.m
     This is an optional script that is run after the installation of a package.

package/on_uninstall.m
     This is an optional script that is run prior to the removal of a package.

Besides the above mentioned files, a package can also contain on or more of the following directories

package/inst
     An optional directory containing any files that are directly installed by the package. Typically this will include any m-files.

package/src
     An optional directory containing code that must be built prior to the packages installation. The Octave package manager will execute ./configure in this directory if this script exists, and will then call make if a file Makefile exists in this directory. make install will however not be called. If a file called FILES exist all files listed there will be copied to the inst directory, so they also will be installed. If the FILES file doesn't exist, src/*.m and src/*.oct will be copied to the inst directory.

package/doc
     An optional directory containing documentation for the package. The files in this directory will be directly installed in a sub-directory of the installed package for future reference.

package/bin
     An optional directory containing files that will be added to the Octave EXEC_PATH when the package is loaded. This might contain external scripts, etc, called by functions within the package.

The DESCRIPTION File
--------------------

The DESCRIPTION file contains various information about the package, such as it's name, author, and version. This file has a very simple format

  * Lines starting with # are comments.

  * Lines starting with a blank character are continuations from the previous line.

  * Everything else is of the form NameOfOption: ValueOfOption.

The following is a simple example of a DESCRIPTION file

     Name: The name of my package
     Version: 1.0.0
     Date: 2007-18-04
     Author: The name (and possibly email) of the package author.
     Maintainer: The name (and possibly email) of the current
      package maintainer.
     Title: The title of the package
     Description: A short description of the package. If this
      description gets too long for one line it can continue
      on the next by adding a space to the beginning of the
      following lines.
     License: GPL version 3 or later

The package manager currently recognizes the following keywords

Name
     Name of the package.

Version
     Version of the package.

Date
     Date of last update.

Author
     Original author of the package.

Maintainer
     Maintainer of the package.

Title
     A one line description of the package.

Description
     A one paragraph description of the package.

Categories
     Optional keyword describing the package (if no INDEX file is given this is mandatory).

Problems
     Optional list of known problems.

Url
     Optional list of homepages related to the package.

Autoload
     Optional field that sets the default loading behavior for the package. If set to yes, true or on, then Octave will automatically load the package when starting. Otherwise the package must be manually loaded with the pkg load command. This default behavior can be overridden when the package is installed.

Depends
     A list of other Octave packages that this package depends on. This can include dependencies on particular versions, with a format

          Depends: package (>= 1.0.0)

     Possible operators are <, <=, ==, >= or >. If the part of the dependency in () is missing, any version of the package is acceptable. Multiple dependencies can be defined either as a comma separated list or on separate Depends lines.

License
     An optional short description of the used license (e.g. GPL version 3 or newer). This is optional since the file COPYING is mandatory.

SystemRequirements
     These are the external install dependencies of the package and are not checked by the package manager. This is here as a hint to the distribution packager. They follows the same conventions as the Depends keyword.

BuildRequires
     These are the external build dependencies of the package and are not checked by the package manager. This is here as a hint to the distribution packager. They follows the same conventions as the Depends keyword. Note that in general, packaging systems such as rpm or deb and autoprobe the install dependencies from the build dependencies, and therefore the often a BuildRequires dependency removes the need for a SystemRequirements dependency.

The developer is free to add additional arguments to the DESCRIPTION file for their own purposes. One further detail to aid the packager is that the SystemRequirments and BuildRequires keywords can have distribution dependent section, and the automatic build process will use these. An example of the format of this is

     BuildRequires: libtermcap-devel [Mandriva] libtermcap2-devel

where the first package name will be used as a default and if the RPMs are built on a Mandriva distribution, then the second package name will be used instead.

The INDEX file
--------------

The optional INDEX file provides an categorical view of the functions in the package. This file has a very simple format

  * Lines beginning with # are comments.

  * The first non-comment line should look like this

          toolbox >> Toolbox name

  * Lines beginning with an alphabetical character indicates a new category of functions.

  * Lines starting with a white space character indicate that the function names on the line belong to last mentioned category.

The format can be summarized with the following example

     # A comment
     toolbox >> Toolbox name
     Category Name 1
      function1 function2 function3
      function4
     Category Name 2
      function2 function5

If you wish to refer to a function that users might expect to find in your package but is not there, providing a work around or ponting out that  the function is available elsewhere, you can use:

     fn = workaround description

This workaround description will not appear when listing functions in the package with pkg describe but they will be published in the html documentation online. Workaround descriptions can use any html markup, but keep in mind that it will be enclosed in a bold-italic environment. For the special case of:

     fn = use <code>alternate expression</code>

the bold-italic is automatically suppressed.  You will need to use <code> even in references:

     fn = use <a href="someothersite.html"><code>fn</code></a>

Sometimes functions are only partially compatible, in which case you can list the non-compatible cases separately. To refer to another function in the package, use <f>fn</f>. For example,

     eig (a, b) = use <f>qz</f>

Since sites may have many missing functions, you can define a macro rather than typing the same link over and again.

     $id = expansion

defines the macro id.  You can use $id anywhere in the description and it will be expanded.  For example,

     $TSA = see <a href="link_to_spctools">SPC Tools</a>
     arcov = $TSA <code>armcv</code>

id is any string of letters, numbers and _.

PKG_ADD and PKG_DEL directives
------------------------------

If the package contains files called PKG_ADD or PKG_DEL the commands in these files will be executed when the package is added or removed from the users path. In some situations such files are a bit cumbersome to maintain, so the package manager supports automatic creation of such files. If a source file in the package contains a PKG_ADD or PKG_DEL directive they will be added to either the PKG_ADD or PKG_DEL files.

In m-files a PKG_ADD directive looks like this

     ## PKG_ADD: some_octave_command

Such lines should be added before the function keyword. In C++ files a PKG_ADD directive looks like this

     // PKG_ADD: some_octave_command

In both cases some_octave_command should be replaced by the command that should be placed in the PKG_ADD file. PKG_DEL directives work in the same way, except the PKG_ADD keyword is replaced with PKG_DEL and the commands get added to the PKG_DEL file.