     [file version.texi not included]

Autodist
********

Autodist is a source distribution management system that allows powerful mechanisms to define what is included in and excluded from a distribution and what license is used. It is especially targeted at large software projects that create multiple distributions from a source tree. Autodist supports distribution management in directory, file, and file content level, and automatic relicensing of a distribution.

Introduction
************

The Autodist is a source distribution management system that allows powerful mechanisms to define what is included in and excluded from a distribution, and what license the distribution is released under.  It is also used to create the actual distribution source packages.  Autodist allows distribution management in file, directory and file content level. Different distributions may include different portions of files, for example, excluding certain features from certain distributions.  It is always guaranteed that anything not defined for the distribution, is removed automatically (files, file content, directories), thus ensuring that nothing is accidentally included in the distribution.

The Autodist creates 'Makefile.am' files from 'Makefile.ad' files and 'configure.ac' file from one or more 'configure.ad' files.  Any other file ending with '.ad' suffix will also be processed.  The processed file will have the '.ad' suffix removed (see Preparing source tree). Autodist also creates and packages the distribution using common GNU distribution creation process, specifically `make dist'.  Autodist, however, controls this process and during packaging phase the Autodist processes all files in the distribution (other than '*.ad' files, which has already been processed earlier by Autodist).  The resulted package is a processed source distribution package, processed according to the rules specified in the distribution file(s) (see Creating distribution).

Any file in the source tree may use distdefs (distribution defines (see Distdefines)) which are defined in the distributions.  When distribution is packaged only the files, directories and file content that is either outside of any distdef, or inside the defined distdefs will be included in the distribution.  Any other file, directory or content in the file will be removed.  It is guaranteed, if a file, a directory or a piece of file content is not inside a defined distdef it will not be delivered to the distribution.

Any file, 'Makefile.am', 'configure.ac', or source file processed with Autodist is always compliant with the tools needed to process them.  All files can also be processed with the corresponding tools even before processing them with Autodist.  This makes it possible, for example, to compile sources before they have been processed, and undefined lines are removed.  The distdefs are respected in source files by the preprocessor.

Autodist is not a binary packaging system.  It is specifically used to create source distributions.  A binary packaging system, however can be hooked to the distribution creation process, if needed.

Reasons for using Autodist
==========================

Autodist is closely related to the Autoconf and Automake tools, and complements the features Autoconf and Automake provides.  It is especially targeted into circumstances where multiple distributions are created from one source tree.  The Autoconf and Automake environment is mainly designed for one distribution (one application) per one source tree situations. Autodist provides mechanisms to create all kinds of distributions that can be created from one source tree.  To be able to use Autodist, the Autoconf and Automake must be installed into the system (see Integrating Autodist). Autoconf version must be at least 2.52g.

Small software projects usually do very well with Autoconf and Automake and their distribution management features.  Often these projects do not need Autodist, though they can benefit from it.  However, if your software project is large, you need to create multiple distributions from one source tree, you have complex licensing terms for different distributions, you have different target users or customers that may require different feature set or licenses in different distributions, you have need to continue concurrent development in the main source tree and still be able to create stable distributions, and/or you have need to control file content in different distributions (to avoid distributing code or features that aren't supposed to be distributed, or to avoid leaking information to your competitors on what new features you are working on), then Autodist is a tool you may find usefull.

The motivation behind Autodist stems from need to be able to create multiple distributions from one large source tree in a precise and controllable manner, and guarantee that anything that is not part of the distribution is removed from the distribution.  The Autoconf and Automake provides mere basic control what is included in and excluded from distributions and how the distributions are created.  They also do not provide mechanism to define different licensing conditions for different distributions, or changing the license automatically for different user or customer purposes.  Many large software projects, companies and corporations have commonly been using Autoconf and Automake tools, but have had the need to create their own ad-hoc mechanisms to control distribution creation.  The Autodist attempts to provide a tool that any size software project can effectively use to manage their distributions.

Without a tool like Autodist, large software projects usually have to be split into separate source trees, which may not always be possible because they may share large portions of common code (which may further make concurrent development of the applications hard), or multiple Autoconf and Automake environments (multiple configure scripts) needs to be created in one source tree.  In this case the source tree usually gets very complicated and controlling what is compiled and what is included in distributions becomes harder, especially when different parts code is shared between applications and libraries.

Integrating Autodist
********************

Integrating Autodist into existing software project can be a very simple task or a fairly complicated task.  It depends on the size and complexity of the software project.  Generally speaking, integrating Autodist into software project is fairly straightforward process:

1. The distributions directory and 'default' distribution are created

2. The 'configure.ad' is created

3. If needed, 'Makefile.ad' file(s) are created

After this the Autodist can already be used to prepare the source tree for configuration and compilation (see Preparing source tree). Adding a new distribution would then allow the actual distribution packaging also.

If the software project has had own ad-hoc distribution system already in place, it may take some work to move from that system into the Autodist. If there are multiple applications and distributions created from the source tree, the distributions and distribution defines for them need to be created.  While this may be unthankful job, it only needs to be done once.

Integrating Autodist into a new software project is a very simple task as renaming 'configure.ac' and possibly 'Makefile.am' files are not required, as they may not exist yet.

Creating distributions directory
================================

The distributions directory is 'distdir', which is expected to be located in the root of the source tree.  This directory will hold all the distribution files, and the Autodist configuration file 'autodist.conf' (see autodist.conf). If this directory does not exist it can be created with the Autodist.

       autodist -i

This will create the 'distdir' and copy the default 'autodist.conf' configuration file and the 'default' distribution into the directory. The 'default' distribution will be used by default by the Autodist unless other distribution is specified.

After this the Autodist has effectively been integrated into the software project.  However, usually after this, one would create new distributions, the 'configure.ad' and possibly 'Makefile.ad' file(s). Without 'configure.ad' file a distribution package cannot be created. However, even without 'configure.ad' file the source tree can be prepared for configuration and compilation (see Preparing source tree).

Configuring Autodist
====================

After the Autodist has been integrated into the software by creating the 'distdir', the 'autodist.conf' configuration file was added to the 'distdir' also.  Usually software projects will want to modify some of the 'autodist.conf' options, mainly specifying the distdef prefix.

The 'autodist.conf' is a text file.  The following options are available in 'autodist.conf':

     DISTPREFIX=""

By default the distdef prefix is '_DIST_'.  To add own software package specific prefix the 'DISTPREFIX' can be defined.

Example:

     DISTPREFIX="SILC"

Will set the distdef prefix as 'SILC_DIST_'.

     DISTDEFS="distdefs.h"

The 'DISTDEFS' option specifies the file name of the distdef header file which Autodist will create.  The software project should '#include' the header file in order for the preprocessor to respect the distdef conditionals (see Distdefines).  By default the file name is 'distdefs.h' and is created at the root of source tree.  Other location may be specified if needed.

Example:

     DISTDEFS="include/distdefs.h"

     ACLOCAL="aclocal"

The 'ACLOCAL' specifies the location of the 'aclocal' tool.  If Autodist should not run 'aclocal' this option may be removed or set to empty value. User need to then run it manually.

     AUTOHEADER="autoheader"

The 'AUTOHEADER' specifies the location of the 'autoheader' tool.  If Autodist should not run 'autoheader' this option may be removed or set to empty value.  User need to then run it manually.

     AUTOCONF="autoconf"

The 'AUTOCONF' specifies the location of the 'autoconf' tool.  If Autodist should not run 'autoconf' this option may be removed or set to empty value.  User need to then run it manually.

     AUTOMAKE="automake -a -c"

The 'AUTOMAKE' specifies the location of the 'automake' tool.  If Autodist should not run 'automake' this option may be removed or set to empty value.  User need to then run it manually.  By default, the '-a'  and '-c' options are given to 'automake' to add any missing required files.

     LIBTOOLIZE="libtoolize --automake -c"

The 'LIBTOOLIZE' specifies the location of the 'libtoolize' tool. This option should be removed or ste to empty value if 'libtool' is not used in the source tree.

     MAKE=make

The 'MAKE' specifies the location of the 'make' program.  This option must be set to valid value in order to create distributions.

Creating new distribution
=========================

After the Autodist has been integrated into the software project by creating the 'distdir' and 'default' distribution, the source tree can be prepared for configuration and compilation (see Preparing source tree).  However, the 'default' distribution should be used only as a development distribution.  Usually it is used to prepare the raw source tree (such as a tree just checkout from CVS) for configuration and compilation.  By default, the 'default' distribution cannot be packaged.  However, if the software project is small (one distribution), it may be convenient to edit the 'default' distribution to be as the distribution that is packaged from the source tree.  In software project where multiple distributions are created using the 'default' only as a development distribution is recommended.  The real distributions should be defined as separate distributions.

Creating a new distribution is a simple process.  Each distribution is placed in the 'distdir' and the file name of the distribution file is used to reference to it.  By default, the distribution name is the file name of the distribution file.  The actual distribution file is a simple text file with various directives that define the distribution.

If the 'default' distribution is used as a development distribution it might be desired to inherit some or all of the created distributions in it, so that development becomes possible with the 'default' distribution. Adding 'inherit' directive into the 'distdir/default' will inherit the specified distribution.

Distribution file format in detail
==================================

The distribution file, or distfile from now on, defines your distribution, distribution defines, options, included and excluded files and directories, license, and additional processing.  Each distribution is defined in a separate file and the distributions are referenced by their file name.

The distfile is a text file that contains various directives that define the actual distribution.  Lines starting with '#' are considered comments and are ignored.

Directive: name <name>
======================

The 'name' directive defines the name of the distribution.  It is optional directive, and if omitted the distribution name will be the name of the distfile.  The 'PACKAGE_NAME' define delivered by Autoconf will contain this name string.

Example:

     name FOO Application

Will set your distribution name as 'Foo Application'.

Directive: package <package>
============================

The 'package' directive defines the name of the distribution package.  It is optional directive, and if omitted the distribution package name will be the name of the distribution, if defined, or if omitted, then the name of the distfile.  If this directive is omitted then normal GNU convention is used to decide the package name, derived from the distribution name. The 'PACKAGE_TARNAME' define delivered by Autoconf will contain this package name string.

Example:

     package foo-client

Will create distribution packages named, for example, as 'foo-client-1.0.tar.gz'.

Directive: bug-report <email address>
=====================================

The 'bug-report' directive can be used to define the email address where the bug-reports for the distribution should be sent.  The directive is optional.  The 'PACKAGE_BUGREPORT' define delivered by Autoconf will contain this bug report string.

Directive: license <filename>
=============================

The 'license' directive can be used to define the license file for the distribution.  This directive is optional.  The license file will be copied into the distribution in the name 'COPYING'.  If the 'COPYING' file already exist it will be replaced.

Example:

     license license/GPL

Will include the file 'license/GPL' into the distribution in the file name 'COPYING'.

Directive: license-header <current-license> <new-license>
=========================================================

The 'license-header' can be used to re-license your files into a new license.  This directive is optional.  There may be zero or more 'license-header' directives in distribution.  The 'license-header' directive will compare the license header that usually appear at the start of a file to the <current-license>.  If it matches it will be replaced with the <new-license>.  The license header in the file will be replaced and the file will have effectively been re-licensed.

Example:

     license-header license/BSD-header license/GPL-header

Will replace all appearances of the license header in 'license/BSD-header' file to the license header in 'license/GPL-header' in any file in the distribution.  Note that, the header change will be performed when the distribution is packaged (see Creating distribution). The 'makedist.log' file created by Autodist during distribution packaging will list all files that were not re-licensed.  The log file can be used to check that the distribution is re-licensed correctly, and fix any possible mistakes.

With 'license-header' directive you may initially set your files in the source tree into what ever license you prefer.  However, if you need to re-license parts of the source tree in certain distributions the 'license-header' will achieve this automatically.  For example, suppose one wants to create two different versions of a library distribution, with different feature sets, in two different licenses.

There are several limitations in the current implementation of Autodist with the 'license-header' directive:

First limitation is that the header files must have equal amount of lines. If the new header file has fewer lines that the current header file, all of the lines from the current header will not be replaced.  If the new header has fewer lines, empty lines must be added to it.  If the new header file has more lines than the current header file, the extra lines will not appear in the replaced header.  Basic rule is to always make sure the header files have equal amount of lines in them.

Second limitation is in indentation of the header files.  It is suggested, though not mandatory, that the header files have the same indentation as is commonly used in the source tree; if the license header text in a file starts at the second character instead of at the start of the line, then the header file should start the license text at the second character also. If same indentation is not used the appearance of the replaced header may not be perfect.  While this is a cosmetic issue, one still to remember.

Third limitation is that the distribution cannot be partially re-licensed. If the 'license-header' directive is used then all files that have the specified header will be replaced with the new header.  There are currently two ways to not re-license a file;  use different license header in the file than one specified in 'license-header', or specify the file or directory in 'noprocess' directive.  Using 'noprocess' is not possible if the file needs to be otherwise processed for the distribution.  Future versions of Autodist may provide a mechanism to re-license only part of the distribution.

Example current header:

     --- Start example
       This program is free software; you can redistribute it and/or modify
       it under the terms of the GNU General Public License as published by
       the Free Software Foundation; version 2 of the License.

       This program is distributed in the hope that it will be useful,
       but WITHOUT ANY WARRANTY; without even the implied warranty of
       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       GNU General Public License for more details.
     --- end example

Example new header:

     --- Start example
       All rights reserved.

       Redistribution and use in source and binary forms, with or without
       modification, are permitted provided that the conditions listed in the
       COPYING file are met.

     --- end example

In this example, if the text in the current header file is found in any file in the distribution it will be replaced with the new header file. Notice that, both header files have same amount of lines (8 lines).

Note that, the current header must match exactly the header used in files.  Otherwise the replacement will not be complete.

Directive: prereq <version>
===========================

The 'prereq' may be used to enforce the Autodist version.  If the Autodist version used to process the distribution is older than the version specified with 'prereq' the Autodist will fail.

Example:

     prereq 1.3.2

Will require Autodist 1.3.2 or newer for this distribution.

Directive: inherit <distfile>
=============================

The Autodist provides inheritance of distributions.  The 'inherit' directive is used to define the distribution which will be inherited into the distribution.  The <distfile> specifies the name of the inherited distribution.  If the distribution cannot be inherited Autodist will give an error.

The 'inherit' will inherit the following information from the distribution: distdefs, undefines, includes, excludes and noprocesses. Other information will not be inherited.  If the inherited distribution inherits other distributions, they will also be inherited automatically. User should be careful when inheriting distributions as it may be possible to create an infinite recursion.  The Autodist would allow for this and not detect this error.  Zero or more 'inherit' directives may be set for distribution.

Example:

     inherit common
     inherit client
     inherit toolkit

Will inherit distributions 'common', 'client' and 'toolkit' into this distribution.  All distdefs, undefines, includes, excludes and noprocesses from these distributions are now also part this distribution.

The distribution that is being prepared or packaged take precedence when defining distdefs that were specifically undefined in the inherited distribution.  This means that if the inherited distribution specifically undefines a distdefs but the inheriting distribution (one being prepared or packaged) specifically defines it, the distdef will be defined. Similarly, if the inherited distribution defines a distdef but the inheriting distribution undefines it, the distdef will be undefined. Note that, this precedence works only in the top distribution (the one being prepared or packaged).  If the inherited distribution inherits other distributions, all distdefs (defined and specifically undefined) will be inherited as is.  This means that if one inherited distribution defines a distdef that other inherited distribution distdef undefines, it will be undefined.  However, the top distribution can then override them if needed.

Directive: define <symbol>
==========================

The 'define' directive is used to define the distdef symbols for the distribution.  This directive is optional, however, all distributions should define at least one distdef so that the distribution may be controlled with the distdef conditionals in files in the source tree (see Distdefines).  By default, the distdef prefix is '_DIST_'.  Many software projects will want to set their own prefix for the distdefs for consistency.  The prefix may be defined in the 'autodist.conf' file (see autodist.conf).

Example:

     define _DIST_FOO
     define _DIST_FEATURE_X
     define _DIST_LIBRARY_Y

Will define the following distdefs for the distribution: '_DIST_FOO', '_DIST_FEATURE_X' and '_DIST_LIBRARY_Y'.  These distdefs may then be used in the source tree and source code to control what is included in or excluded from this distribution.

Directive: undef <symbol>
=========================

The 'undef' directive may be used to explicitly undefine a distdef. When inheriting distributions it may be desired to be able undefine certain distdefs.  This directive is optional.

Example:

     undef _DIST_FEATURE_Y

Will undefine '_DIST_FEATURE_Y' distdef.  This distdef will not be part of this distribution anymore, even if it is defined in some inherited distribution.

Directive: option <option> [...]
================================

The 'option' directive is used to define various options for the distribution.  The options can change the behavior of the distribution. This directive is optional.  One or more options may be defined in one 'option' directive.  Zero or more 'option' directives may be set for distribution.  The following options are available.

     template

When set, the distribution is a template distribution.  Templates are special distributions which cannot be prepared or packaged with Autodist. Templates can only be inherited.  Usually, templates are used to define a common template distribution for other distributions.  Templates may set distdefs, undefines, includes, excludes and noprocesses.  A large software project could have several distributions that share a common base.  In this case defining the common base as a template distribution and then inheriting that distribution makes it easier to manage the distfiles.

     no-dist

Distributions with the 'no-dist' option are similar to templates, except that they can be prepared with Autodist, but they cannot be packaged. These are usually used as a common development distribution, such as the 'default' distribution created with 'autodist -i'.

     no-inherit

If this option is set to normal distributions or distributions with 'no-dist' option, the distribution cannot be inherited.  For template this option has no effect.  If distribution with this option is inherited the Autodist will give an error.

Directive: include <source> [<destination>]
===========================================

The 'include' directive can be used to include files or directories into the distribution.  Sometimes it may be desired to specify included files and directories in distribution instead of Makefile.am and EXTRA_DIST, especially if there are many distributions that need to include specific files and directories.  While it would be possible to define them in Makefile.ad and use distdef conditionals to define which will be included in which distribution, if there are many different distributions it may pollute the Makefile.ad unnecessarily.

This directive is optional.  The <source> may be a single file, a  single directory or a regular expression which will match several files and/or directories.  The <destination> is optional.  If it is omitted then the <source> will be copied into the same location in the distribution. If the <destination> is provided the <source> will be copied into the specified location.

Example:

     include apps/foobar/README README
     include lib/libfoo
     include lib/libfoobar lib/foobarlib
     include doc/foo*
     include scripts/foobar.sh foo.sh

Will include the file 'apps/foobar/README' into the top distribution directory in the name 'README', the directory 'lib/libfoo' into same location in distribution, the directory 'lib/libfoobar' into 'lib/foobarlib' changing the name of the directory into 'foobarlib', the files and directories that match 'doc/foo*' into the same locations in distribution, and finally the 'scripts/foobar.sh' into the top distribution directory changing the name of the file into 'foo.sh'.

Note that, the 'include' directives will be processed by the Autodist only when the distribution is packaged (see Creating distribution).  When preparing the source tree for configuration and compilation (see Preparing source tree) the 'include' directives are ignored.  This is same behavior as with Makefile.am's EXTRA_DIST.

If the included file or directory does not exist the Autodist will give an error and stop the distribution creation.  If the destination file exist, it will be replaced with the included file.  If the destination directory already exists, the contents of the source directory will be copied into the directory.  Note that, the directory will not be copied into the directory; if the <destination> is specified, also the name of the <source> file or directory must be specified, otherwise the 'include' will change the name into the one specified.

Example:

     include lib/libfoo lib

In this example the 'lib/libfoo' will be included as 'lib'.  If the 'lib' already exists, this effectively copies the contents of the 'lib/libfoo' into 'lib'.  In order to include the directory with same name, the name must be specified.

Example:

     include lib/libfoo lib/libfoo
     include lib/foobar new_lib/foobar

This will include the 'lib/libfoo' into 'lib/libfoo' in distribution, and 'lib/foobar' into 'new_lib/foobar' in distribution.

Directive: exclude <filename> [...]
===================================

The 'exclude' directive can be used to exclude files and directories from the distribution.  This directive is optional.  This directive is processed before processing the 'include' directive.  The <filename> can be a single file, a single directory or a regular expression that will match several files and/or directories.

Example:

     exclude README
     exclude doc/client*

This will exclude the file 'README' and anything that match 'doc/client*'.

Directive: noprocess <filename> [...]
=====================================

The 'noprocess' directive can be used to tell Autodist specifically not to process files or directories.  The Autodist will not process the files during distribution packaging.  This directive is optional.  One or more files can be specified in the 'noprocess' directive.  Zero or more 'noprocess' directives can be used in distribution.  The <filename> can be a single file, a single directory or a regular expression that will match several files and/or directories.

Example:

     noprocess autodist.texi
     noprocess apps/foo/

Autodist will not process 'autodist.texi' file, and any files and directories under 'apps/foo/'.

Note that, 'noprocess' directive cannot be used to disallow processing of any file with '.ad' suffix.

Directive: pre-hook <filename> [...]
====================================

The 'pre-hook' directive can be used define additional scripts that will be run before the source tree is prepared.  This directive is optional.  One or more scripts may be defined in one 'pre-hook' directive. Zero or more 'pre-hook' directives may be set for distribution.  The 'pre-hook' hook will be run immediately after invoking Autodist to start preparing the source tree for configuration and compilation (see Preparing source tree).

The scripts will get at least three (3) command line arguments when Autodist executes the script: distribution name, distribution version and package name of distribution.  The script may use these arguments if it needs them.  If user passed any extra parameters to autodist in the command line they will also be passed to the script as last arguments.

Directive: post-hook <filename> [...]
=====================================

The 'post-hook' directive can be used define additional scripts that will be run after the source tree is prepared.  This directive is optional.  One or more scripts may be defined in one 'post-hook' directive. Zero or more 'post-hook' directives may be set for distribution.  The 'post-hook' hook will be run immediately after the Autodist has finished preparing the source three for configuration and compilation (see Preparing source tree).  The Autodist will exit after it has run the 'post-hook' scripts.

The scripts will get at least three (3) command line arguments when Autodist executes the script: distribution name, distribution version and package name of distribution.  The script may use these arguments if it needs them.  If user passed any extra parameters to autodist in the command line they will also be passed to the script as last arguments.

Directive: pre-process-dist-hook <filename> [...]
=================================================

The 'pre-process-dist-hook' directive can be used define additional scripts that will be run when Autodist has started distribution creation. This directive is optional.  One or more scripts may be defined in one 'pre-process-dist-hook' directive.  Zero or more 'pre-process-dist-hook' directives may be set for distribution.  The 'pre-process-dist-hook' hook will be run immediately after the Autodist has created the distribution directory but has not yet started any distribution processing.

The scripts will get at least four (4) command line arguments when Autodist executes the script: distribution name, distribution version, package name of distribution and destination distribution directory name. The script may use these arguments if it needs them.  If user passed any extra parameters to autodist in the command line they will also be passed to the script as last arguments.

Directive: post-process-dist-hook <filename> [...]
==================================================

The 'post-process-dist-hook' directive can be used define additional scripts that will be run when Autodist has finished distribution processing.  This directive is optional.  One or more scripts may be defined in one 'post-process-dist-hook' directive.  Zero or more 'post-process-dist-hook' directives may be set for distribution.  The 'post-process-dist-hook' hook will be run immediately after the Autodist has finished processing the destination distribution directory but has not yet created the distribution package.

The scripts will get at least four (4) command line arguments when Autodist executes the script: distribution name, distribution version, package name of distribution and destination distribution directory name. The script may use these arguments if it needs them.  If user passed any extra parameters to autodist in the command line they will also be passed to the script as last arguments.

Directive: pre-dist-hook <filename> [...]
=========================================

The 'pre-dist-hook' directive can be used define additional scripts that will be run when Autodist has started distribution creation.  This directive is optional.  One or more scripts may be defined in one 'pre-dist-hook' directive.  Zero or more 'pre-dist-hook' directives may be set for distribution.  The 'pre-dist-hook' hook will be run immediately after the Autodist has started distribution creation, but has not yet created the distribution directory.  This hook is run before 'pre-process-dist-hook'.

The scripts will get at least four (4) command line arguments when Autodist executes the script: distribution name, distribution version, package name of distribution and destination distribution directory name. The script may use these arguments if it needs them.  If user passed any extra parameters to autodist in the command line they will also be passed to the script as last arguments.

Directive: post-dist-hook <filename> [...]
==========================================

The 'post-dist-hook' directive can be used define additional scripts that will be run when Autodist has finished distribution creation.  This directive is optional.  One or more scripts may be defined in one 'post-dist-hook' directive.  Zero or more 'post-dist-hook' directives may be set for distribution.  The 'post-dist-hook' hook will be run immediately after the Autodist has finished creating the distribution package.  This is the last hook Autodist runs.

The scripts will get at least four (4) command line arguments when Autodist executes the script: distribution name, distribution version, package name of distribution and destination distribution directory name. The script may use these arguments if it needs them.  If user passed any extra parameters to autodist in the command line they will also be passed to the script as last arguments.

Running hooks
=============

The Autodist runs the hooks in the following order:

Preparing source tree for configuration and compilation:

     <...Autodist started...>
     pre-hook
     <...preparation...>
     post-hook
     <...Autodist exits...>

Creating distribution:

     <...Autodist started...>
     pre-dist-hook
     <...distribution directory created...>
     pre-process-dist-hook
     <...processing all files, processing excludes and includes...>
     post-process-dist-hook
     <...creating distribution package...>
     post-dist-hook
     <...Autodist exits...>

When creating distribution the 'pre-hook' and 'post-hook' are not run.

Example distfile
================

The following is a simple distfile example.  The example assumes that the distdefs prefix is 'SILC'.

     # SILC Client distribution
     name SILC Client
     package silc-client
     bug-report silc-client-bugs@silcnet.org
     inherit common
     inherit platform-unix
     inherit platform-win32
     define SILC_DIST_CLIENT
     define SILC_DIST_CLIENTLIB
     define SILC_DIST_IRSSI
     undef SILC_DIST_MPI
     exclude doc/draft*
     pre-hook scripts/client-pre-run
     post-process-dist-hook scripts/client-post-process
     post-dist-hook scripts/client-post-dist-bin

configure.ad files
==================

Autodist creates 'configure.ac' file from the 'configure.ad' file.  The 'configure.ad' file is a rather normal 'configure.ac' except that it accepts also Autodist macros.  Autodist also supports configure script fragments, also named as 'configure.ad'.  Any 'configure.ad' file in the source tree can be incorporated into the the top 'configure.ad' file.  Sometimes it may be useful to split a large configure script into smaller fragments. Especially in multi distribution system where certain libraries or features can be excluded from certain distributions it may be useful to handle their configuration from a configure fragment.  If the library is excluded then also its configuration can be excluded.

If the software project already has a 'configure.ac' or 'configure.in' file, the 'configure.ad' can be created by simply renaming the current file to 'configure.ad'.  In this case the current configure script must be edited to support Autodist.  This is done by replacing the 'AC_INIT' to 'AD_INIT'.  After specifying the 'AD_INIT' as the first macro in the 'configure.ad', the Autodist support has been fully integrated into the software project.

If your software project is going to use configure fragments, then also Autodist macro 'AD_INCLUDE_CONFIGURE' must be used.  Autodist will automatically combine the fragments with the top 'configure.ac' script. To exclude a 'configure.ad' fragment from a distribution use the distdef conditionals inside the 'configure.ad' fragment file.  If the distdef is not defined the fragment will be excluded automatically.

The following macros are available in current Autodist version.

 -- Macro: AD_INIT

     The 'AD_INIT' macro is used in place of Autoconf macro 'AC_INIT'.  The 'AD_INIT' must be the first macro in the 'configure.ad', just like the 'AC_INIT' macro in 'configure.ac'.  The AD_INIT macro is used to deliver the distribution names, distribution version, package name and bug-report email address to the 'configure.ac' file that Autodist will create. The 'AC_INIT' macro must not be used in 'configure.ad' file.

     This macro is mandatory and Autodist will exit with error if it is not specified in 'configure.ad'.  This macro has no arguments.

 -- Macro: AD_INCLUDE_CONFIGURE

     This macro is used to tell Autodist that it should include any other 'configure.ad' fragment that is found from the source tree into the top 'configure.ad' file.  Note that, the 'configure.ad' fragments will be incorporated at the location where this macro is used in the 'configure.ad'.  Usually this macro is placed just before the Autoconf macro 'AC_OUTPUT'.  This macro has no arguments.

     Note that, the 'configure.ad' fragments are not real full featured configure scripts.  They must not use 'AD_INIT', 'AD_INCLUDE_CONFIGURE', 'AC_INIT' or any other initialization macros.

 -- Macro: AD_DISABLE_DEPENDENCIES

     This macro is used to disable Autodist dependencies.  If this macro is used, then after editing 'Makefile.ad' and 'configure.ad' files the Autodist must be run manually.  When dependencies are enabled Autodist is run automatically when source is compiled with 'make'.  Dependencies make the development easier.  This macro has no arguments.

     Note that, the dependencies are enabled only in the prepared source tree. Depedencies are not delivered to distribution, as they would require the presence of 'Makefile.ad' and 'configure.ad' files, which are not delivered to distribution.

Makefile.ad files
=================

Autodist creates 'Makefile.am' files from 'Makefile.ad' files.  A software project do not need to use 'Makefile.ad' files if there is no need to use distdef conditionals inside makefiles.  Usually a multi distribution software project, however will need to define certain things to different distributions.  In these cases 'Makefile.ad' file needs to be created.

Even though it would be possible to use distdef conditionals also inside 'Makefile.am' files, Autodist does not process 'Makefile.am' files when preparing the source tree for configuration and compilation (see Preparing source tree).  Thus, the prepared environment would not be identical to the created distribution package (when the 'Makefile.am' will be processed), and configuration and compilation would be inconsistent. Basic rule is, if you need distdefs (see Distdefines) inside makefiles, put them inside 'Makefile.ad' file.

Other .ad files
===============

Any file in the source tree can have the '.ad' suffix appended.  Autodist will process any file that has the suffix when the source tree is prepared for configuration and compilation (see Preparing source tree).  If the files have distdef conditionals the Autodist will process them. The files will have the '.ad' suffix removed.

Basic rule is, if you need to process some file when preparing the source tree for configuration and compilation, add '.ad' suffix to it. Distdefs (see Distdefines) can be used in any file in source tree but without '.ad' suffix Autodist will not process those files during preparation.  They will be processed when creating the distribution package. If you need processed files during configuration or compilation then they need to have '.ad' suffix.

Note that, the distdef format used in these files must be the non-source format, even if the file is source file.  This is because the distdefs are processed during source tree preparation, and the source file will have all distdefs removed when it is compiled.

Using distribution defines (distdefs)
=====================================

Distribution defines, or distdefs from now on, are used to define inside a file what will be included in the distribution.  Distribution may define many different distdefs, for example, based on feature sets, platforms, or for other similar reasons.  If distdef is not defined for the distribution but is used in a file, anything inside the distdef in that file will be removed when the distribution is packaged (see Creating distribution).  This guarantees that only the files, directories and file content (such as source code) that is supposed to be delivered with the distribution are delivered.  Delivering files or code accidentally in the distribution cannot happen.

All other files, except files ending with '.ad' suffix are processed for distdefs only when the distribution is packaged.  Files ending with '.ad' suffix are processed for distdefs when preparing the source tree for configuration and compilation (see Preparing source tree).

By default the distdefs are named '_DIST_XXX', where 'XXX' is the name of distdef.  However, many projects will want to define their own prefix for distdefs in the 'autodist.conf' configuration file (see autodist.conf). In the following examples a prefix 'SILC' is used, hence the prefix for the distdefs are 'SILC_DIST_'.

The basic format for the distdefs are as follows:

     #ifdef SILC_DIST_DEFINE
     #endif SILC_DIST_DEFINE

     #ifndef SILC_DIST_DEFINE
     #endif SILC_DIST_DEFINE

     #ifdef SILC_DIST_DEFINE
     #else !SILC_DIST_DEFINE
     #endif SILC_DIST_DEFINE

     #ifndef SILC_DIST_DEFINE
     #else SILC_DIST_DEFINE
     #endif SILC_DIST_DEFINE

This format should be used only in non-source files, as for example C and C++ compilers will not like this format inside a file.  In source files a compiler friendly format, defined below, should be used.

     #ifdef SILC_DIST_DEFINE
     #endif /* SILC_DIST_DEFINE */

     #ifndef SILC_DIST_DEFINE
     #endif /* SILC_DIST_DEFINE */

     #ifdef SILC_DIST_DEFINE
     #else /* !SILC_DIST_DEFINE */
     #endif /* SILC_DIST_DEFINE */

     #ifndef SILC_DIST_DEFINE
     #else /* SILC_DIST_DEFINE */
     #endif /* SILC_DIST_DEFINE */

Note that, only the format defined above is supported.  Other more complex use of the preprocessor directives such as using '&&' and '||' in the '#ifdef' or '#ifndef' are not supported, and neither is '#elif'.  Also note, that the name of the distdef in '#else' and '#endif' directives in non-source format and in source format inside C comments (/* */), and the use of '!' character in the '#else' branch of '#ifdef'" are mandatory. Also note, that the distdef conditionals must be placed at the start of the line, they must not be indented.

The following example shows the use of non-source format:

     SUBDIRS =                        \
     #ifdef SILC_DIST_SERVER
            server                    \
            server-foobar             \
     #endif SILC_DIST_SERVER
     #ifndef SILC_DIST_CLIENT
            tests                     \
     #endif SILC_DIST_CLIENT
     #ifdef SILC_DIST_TOOLKIT
            toolkit                   \
            toolkit-docs              \
     #else !SILC_DIST_TOOLKIT
            doc                       \
            lib                       \
     #ifdef SILC_DIST_CLIENT
            client                    \
     #endif SILC_DIST_CLIENT
     #endif SILC_DIST_TOOLKIT

Say, in this example, your distribution has the SILC_DIST_CLIENT and SILC_DIST_SERVER defined, but not the SILC_DIST_TOOLKIT, the end result would be:

     SUBDIRS =                        \
            server                    \
            server-foobar             \
            doc                       \
            lib                       \
            client                    \

The lines defined specifically for the SILC_DIST_TOOLKIT, which in our example was not defined, were removed.  Also lines that specifically expected certain distdefs not to be defined ('#ifndef') were removed. (Note the last remaining '\' in example above would be removed by the Autodist automatically to avoid errors with Automake.)

The following example shows the use of source code format:

       initialize_lib();
     #ifdef SILC_DIST_MPI
       init_mpi();
       mpi = mpi_alloc();
     #else /* !SILC_DIST_MPI */
       init_gmp();
     #endif /* SILC_DIST_MPI */

     #ifndef SILC_DIST_FOOBAR
       foobar_replacement();
       foobar_hack_init();
       foobar_init();
     #else /* SILC_DIST_FOOBAR */
       real_foobar();
     #endif /* SILC_DIST_FOOBAR */

Say, you have both SILC_DIST_MPI and SILC_DIST_FOOBAR defined, the end result would be:

       initialize_lib();
       init_mpi();
       mpi = mpi_alloc();

       real_foobar();

Even before processing the source files with Autodist, the preprocessor will respect the preprocessor directives if the code use '#include' to include the distdef header file created by the Autodist (see 'autodist.conf' (see autodist.conf)).  When the distribution is packaged (see Creating distribution) the Autodist will process the files, and will remove any line not defined to be included. The preprocessor directives will also be removed.

Because the software project includes the header file with '#include' the distdef header file needs to be present in the distribution, unless it is placed inside some other '#ifdef' conditional.  If the distribution is prepared but not compiled (it is packaged after preparation without compilation) then including the distdef header in the source is not necessary.  Including it then in the distribution is not necessary either.

The software project should not use the same name space that distdef conditionals use for other than distribution usage.  The Autodist will process any line that uses the formats above and has the specified prefix (eg. 'SILC_DIST_') in those lines.  Using same prefix for other purposes will produce unexpected results and invalid distributions.

The following suffixes will be considered as source files by the Autodist:

         .c
         .C
         .cc
         .cp
         .cpp
         .CPP
         .cxx
         .CXX
         .c++
         .m
         .h
         .H
         .hh

Also, any file that has '.in' suffix with any of the above source file suffixes, the format inside the file must follow the source code format. Using distdefs in any other file must follow the non-source format.

Example:

         .c.in
         .h.in

In this example, in both of the files the source code format is used.

Autodist dependency support
===========================

Autodist support dependencies for 'Makefile.ad' and 'configure.ad' files. When these files are edited, they are processed by Autodist automatically when the source tree is compiled with 'make'.  This makes development in the source tree easier, when Autodist does not have to be run manually. The dependencies can be disabled by using 'AD_DISABLE_DEPENDENCIES' macro in the 'configure.ad' file.

When editing 'configure.ad' fragments the modifcation is detected when the source tree is compiled with 'make' from the top source directory. Giving 'make' in a subdirectory will not detect a change in 'configure.ad' fragment.

Dependencies are present only in the prepared source tree.  They are not delivered to created distribution, as they depend on 'Makefile.ad' and 'configure.ad' files which are not present in the created distribution. Autodist automatically removes the dependencies when the distribution is created.

Invoking Autodist
*****************

The Autodist has two basic functions:

1. Preparing source tree for configuration and compilation (see Preparing source tree)

2. Creating distribution packages (see Creating distribution)

The 'autodist' accepts the following options:

-h
--help
     Prints the help for the Autodist and exits.

-V
--version
     Prints version number and exits.

-v
--verbose
     Verbosely report processing.

-d
--distdir <dir>
     Search distributions from <dir> instead of default 'distdir'.

-s
--distdefs [<dist>]
     Prints distribution defines of <dist> and exits.

-i
--init
     Initializes Autodist environment.  Creates the default distribution directory 'distdir', 'autodist.conf' configuration file and the default distribution 'default', then exits.

-p
--process <type> <src> <dst>
     Process file <src> into <dst> for distribution, <type> is 'makefile', 'configure', 'non-source' or 'source' and defines the type of <src>, then exits.

-m
--makedist
     Creates and packages distribution

--gzip
     Create package compressed with gzip (default)

--bzip2
     Create also package compressed with bzip2

--compress
     Create also package compressed with compress

--zip
     Create also package compressed with zip

Preparing source tree for configuration and compilation
=======================================================

Before distribution can be created from the source tree, the source tree must be prepared for configuration and compilation.  If your project is not using Autodist, then you would do this by running perhaps 'aclocal', 'autoconf', 'autoheader' and 'automake' tools manually, or you would run an 'autogen.sh' script that prepares your raw source tree.  With Autodist this process is performed by Autodist, and running these tools manually or using 'autogen.sh' script is not necessary.

By default the 'autodist.conf' (see autodist.conf) has defined the tools that will be run by the Autodist when preparing the source tree. These are 'aclocal', 'autoheader', 'autoconf', 'automake' and 'libtoolize'.  If you do not wish that Autodist runs some or any of these tools automatically, do not set them in the 'autodist.conf'.  You would then need to run them manually. However, this is not recommended.  If you need to run additional preparation scripts you may set your scripts either in the 'pre-hook' and/or 'post-hook' where you can run what ever additional processing you may need to prepare your source tree.

By default the Autodist creates a 'default' distribution when you initialize your project by running 'autodist -i'.  The 'default' distribution should be used when you are developing in your source tree.  By default, the 'default' distribution cannot be packaged, however, if your project creates only one distribution you may find it more convenient to define your distribution inside the 'default' distribution and allow it to be packaged also.  If your source tree will create multiple distributions, the 'default' should be used only as development distribution.  You would use it when you, for example, checkout your source tree from CVS and prepare it for configuration and compilation.  To prepare your source tree with the 'default' distribution run Autodist without any arguments.

       autodist

The Autodist will prepare your source tree.  After that you may run './configure' and continue to compile with 'make'.

If you do not wish to use the 'default' distribution, or you wish to do the development in a tree specifically prepared for some specific distribution, or you are preparing to create a new distribution package, you will need to run the Autodist with the distribution you wish to prepare.

       autodist example-distribution 1.0.3

This prepares your source tree for 'example-distribution' of version '1.0.3'.  After that you may run './configure' and continue to compile with 'make'.  If the version is omitted the version will be '0.0'. The 'PACKAGE_VERSION' define delivered by Autoconf will contain this version.

Note that, running Autodist for preparation merely prepares your source tree for the distribution, it does not create an actual distribution package.  When preparing source tree for configuration and compilation the Autodist will process any file that ends with '.ad' suffix.  It will process all 'configure.ad' and 'Makefile.ad' files for that distribution. When you run './configure' your tree will be configured for that distribution, and when you compile with 'make' it will compile for that distribution.

However, the source files, or any other file (except files ending with '.ad' suffix) are not processed by the Autodist.  When compiling your sources the preprocessor, however, will respect your distdef conditionals inside your source files if you '#include' the distdef header file.  This way, even the compiled binaries will be compiled for that distribution, even though the source files have not yet been processed by the Autodist.  Rest of the files in the distribution will be processed when you create the actual distribution package.  It is guaranteed that the distribution you have prepared will behave in your source tree exactly the same way as if it was already packaged with Autodist (providing that you remember to include the distdef header file in your code).

When preparing the source tree Autodist will create a file 'autodist.dist' which will contain information on the prepared distribution.  When Creating the distribution that file will be read by the Autodist automatically.  That file should not be removed or the distribution cannot be packaged.

Autodist also created a log file, 'autodist.log', that will include messages created by Autodist during preparation.

Creating distribution package(s)
================================

Before creating a new distribution package, you will need to prepare the source tree for the distribution you want to create.  After preparing your source tree you will be ready to create a new distribution.  The Autodist package provides a simple helper script 'makedist' that may be used to create the distribution.  However, if you wish, you may run the Autodist yourself, as the 'makedist' will call Autodist anyway.

To create a new distribution for the distribution you have prepared for, run first './configure' and then 'makedist'.

       makedist

This will run the Autodist and create a new distribution package that is archived with 'tar' and compressed with 'gzip'.  If you wish to create packages also compressed with 'bzip2', 'compress' and/or 'zip' you may give one or all of the following options:

       makedist --bzip2 --compress --zip

This example would create, in addition of 'tar.gz' package, also a 'tar.bz2', 'tar.Z' and '.zip' packages.  Current version of Autodist does not support archiving with 'shar'.

If you wish to run additional processing for your distributions when they are being packaged you may set 'pre-process-dist-hook', 'post-process-dist-hook, 'pre-dist-hook' and/or 'post-dist-hook' in your distribution file.  Also note that any hooks provided by Automake in Makefiles will be run in normal manner.

When creating the distribution Autodist creates a log file, 'makedist.log', that will include messages created by Autodist.  It is suggested that this file is checked after distribution is created.  For example, when the 'license-header' directive is used to re-license the distribution, the 'makedist.log' will include list of files that were not re-licensed.  The log file can be used to verify that the distribution was re-licensed correctly, and fix any possible mistakes.

Examples
********

Single distribution tree example, start to finish
=================================================

Lets suppose you have a simple source tree with one application, called 'foozbar' you wish to release.  While you would probably suffice using Autoconf and Automake features you may still use Autodist.

First, you create the default 'distdir' into your software package:

       autodist -i

Then, you create the 'configure.ad' file from your existing 'configure.ac' or 'configure.in' file.  If you don't have configure script written yet, please refer to the Autoconf manual.  In the 'configure.ad' you add as first macro in the file:

       AD_INIT

Then, you create distribution file for your application:

     # Foozbar distribution
     name Foozbar
     package foozbar
     bug-report foozbar-bugs@foo.z.bar
     define _DIST_FOOZBAR

This distribution file go into 'distdir/foozbar'.

And there you go.  You have succesfully integrated Autodist into your source tree.  If you need to do development and you wish to use the 'default' distribution for that, you should inherit the new 'foozbar' distribution in it.  Add the following line in 'distdir/default':

       inherit foozbar

After that, you can prepare the source tree for configuration and compilation by giving:

       autodist

After this command you can give './configure' and 'make'.

If you want to do development directly in a tree prepared for the 'foozbar' distribution, or you are ready to start creating a new distribution package, you give:

       autodist foozbar 1.0

After this command you can give './configure' and 'make'.

To create the distribution package, you will give:

       makedist

The end result will be a 'foozbar-1.0.tar.gz' package.

Multiple distribution tree example, start to finish
===================================================

Lets suppose you have a source tree from which you create multiple distributions, say three.  If you really have a such source tree you must have by now noticed the difficulty of maintaining such a source tree and problems with controlling the distributions.  Maybe you have sufficed with Autoconf and Automake, or perhaps you have created your own scripts that carry out the kludges.  No more, for Autodist is here.

First, you integrate Autodist into your tree by creating the distributions directory 'distdir':

       autodist -i

Then, you create the 'configure.ad' file from your existing 'configure.ac' or 'configure.in' file.  If you don't have configure script written yet, please refer to the Autoconf manual.  In the 'configure.ad' you add as first macro in the file:

       AD_INIT

You then continue with creating the distribution files for your three distributions.  Let's name them 'foozbar', 'libfoozbar' and 'nomad'. We will also create a common template that all distributions inherit.

     # Foozbar distribution
     name Foozbar
     package foozbar
     bug-report foozbar-bugs@foo.z.bar
     inherit common
     define _DIST_FOOZBAR

     # libfoozbar distribution
     name libfoozbar
     bug-report libfoozbar-bugs@foo.z.bar
     inherit common
     define _DIST_LIBFOOZBAR

     # Nomad distribution
     name Nomad
     package nomad-the-server
     bug-report nomad-bugs@foo.z.bar
     inherit common
     include doc/nomad
     define _DIST_NOMAD
     define _DIST_NOMAD_LIB
     undef _DIST_CRYPTO
     pre-dist-hook nomad-pre-dist-hook

     # Common template
     option template
     define _DIST_DOC
     define _DIST_LIB
     define _DIST_MATH
     define _DIST_CRYPTO
     define _DIST_UNIX
     define _DIST_MACOSX
     define _DIST_WIN32

You put the distribution files in the 'distdir' directory.  In addition you will be doing development in the source tree using the 'default' distribution, you will add the new distributions to the 'distdir/default':

     inherit foozbar
     inherit libfoozbar
     inherit nomad

To prepare the source tree for configuration and compilation you would simply give:

     autodist

This will prepare your source tree for configuration and compilation.  Since the 'default' distribution inherits all distributions your development source tree will have all of them included.  If you do not want to do this then don't inherit them in the 'default', but run the autodist specifically for the distributions, for example:

     autodist foozbar

Since all the distributions inherit the 'common' distribution they get all the distdefs that the 'common' defines.  In this example various distdefs have been defined.  You would use them in your code and in your makefiles to control various things.  For example, let's say the 'common' distdefs control what directories distributions have.  An example 'Makefile.ad' file:

     SUBDIRS =                       \
     #ifdef _DIST_LIB
            lib                      \
     #endif _DIST_LIB
     #ifdef _DIST_DOC
            doc                      \
     #endif _DIST_DOC

Perhaps the 'Makefile.ad' in 'lib' subdirectory could define something like this:

     SUBDIRS =                       \
             util                    \
     #ifdef _DIST_MATH
             mathlib                 \
     #endif _DIST_MATH
     #ifdef _DIST_CRYPTO
             cryptolib               \
     #endif _DIST_CRYPTO
     #ifdef _DIST_NOMAD_LIB
             nomadlib                \
     #endif _DIST_NOMAD_LIB
     #ifdef _DIST_LIBFOOZBAR
             foozbarlib               \
     #endif _DIST_LIBFOOZBAR

Since the 'nomad' distribution undefined the '_DIST_CRYPTO' distdef it would not have the 'cryptolib' in its distribution.  Clearly Nomad don't need it.  In addition of using the distdefs just in the makefiles you may want to use them in the source code as well:

          ...some code...

     #ifdef _DIST_MATH
       /* Initialize math library */
       math_init();
     #endif /* _DIST_MATH */

          ...some code...

After an intensive development period you're ready to create new releases. Let's say you're going to release all distributions:

First you release Foozbar 0.5.1:

     autodist foozbar 0.5.1
     makedist --bzip2

The end result is two files: 'foozbar-0.5.1.tar.gz' and 'foozbar-0.5.1.tar.bz2'.

Then you continue with libfoozbar and Nomad:

     autodist libfoozbar 1.0.5
     makedist

Nomad has also an RPM .spec file that you have written and a pre-dist-hook that will replace the RPM release version with sed tool with the one you give as extra parameter to autodist:

     autodist nomad 2.0 0.fc7
     makedist

The end results are: 'libfoozbar-1.0.5.tar.gz' and 'nomad-2.0.tar.gz', and the RPM will have a release version '0.fc7' when you compile the RPM.  Any extra parameter that you pass to autodist will be delivered to your hook scripts.

Download
********

Download latest version of Autodist at http://silcnet.org/download/autodist/