summaryrefslogtreecommitdiff
path: root/lib/spack/docs/build_systems/autotoolspackage.rst
diff options
context:
space:
mode:
Diffstat (limited to 'lib/spack/docs/build_systems/autotoolspackage.rst')
-rw-r--r--lib/spack/docs/build_systems/autotoolspackage.rst305
1 files changed, 305 insertions, 0 deletions
diff --git a/lib/spack/docs/build_systems/autotoolspackage.rst b/lib/spack/docs/build_systems/autotoolspackage.rst
new file mode 100644
index 0000000000..ce22fd832b
--- /dev/null
+++ b/lib/spack/docs/build_systems/autotoolspackage.rst
@@ -0,0 +1,305 @@
+.. Copyright 2013-2018 Lawrence Livermore National Security, LLC and other
+ Spack Project Developers. See the top-level COPYRIGHT file for details.
+
+ SPDX-License-Identifier: (Apache-2.0 OR MIT)
+
+.. _autotoolspackage:
+
+----------------
+AutotoolsPackage
+----------------
+
+Autotools is a GNU build system that provides a build-script generator.
+By running the platform-independent ``./configure`` script that comes
+with the package, you can generate a platform-dependent Makefile.
+
+^^^^^^
+Phases
+^^^^^^
+
+The ``AutotoolsPackage`` base class comes with the following phases:
+
+#. ``autoreconf`` - generate the configure script
+#. ``configure`` - generate the Makefiles
+#. ``build`` - build the package
+#. ``install`` - install the package
+
+Most of the time, the ``autoreconf`` phase will do nothing, but if the
+package is missing a ``configure`` script, ``autoreconf`` will generate
+one for you.
+
+The other phases run:
+
+.. code-block:: console
+
+ $ ./configure --prefix=/path/to/installation/prefix
+ $ make
+ $ make check # optional
+ $ make install
+ $ make installcheck # optional
+
+
+Of course, you may need to add a few arguments to the ``./configure``
+line.
+
+^^^^^^^^^^^^^^^
+Important files
+^^^^^^^^^^^^^^^
+
+The most important file for an Autotools-based package is the ``configure``
+script. This script is automatically generated by Autotools and generates
+the appropriate Makefile when run.
+
+.. warning::
+
+ Watch out for fake Autotools packages!
+
+ Autotools is a very popular build system, and many people are used to the
+ classic steps to install a package:
+
+ .. code-block:: console
+
+ $ ./configure
+ $ make
+ $ make install
+
+
+ For this reason, some developers will write their own ``configure``
+ scripts that have nothing to do with Autotools. These packages may
+ not accept the same flags as other Autotools packages, so it is
+ better to use the ``Package`` base class and create a
+ :ref:`custom build system <custompackage>`. You can tell if a package
+ uses Autotools by running ``./configure --help`` and comparing the output
+ to other known Autotools packages. You should also look for files like:
+
+ * ``configure.ac``
+ * ``configure.in``
+ * ``Makefile.am``
+
+ Packages that don't use Autotools aren't likely to have these files.
+
+^^^^^^^^^^^^^^^^^^^^^^^^^
+Build system dependencies
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Whether or not your package requires Autotools to install depends on
+how the source code is distributed. Most of the time, when developers
+distribute tarballs, they will already contain the ``configure`` script
+necessary for installation. If this is the case, your package does not
+require any Autotools dependencies.
+
+However, a basic rule of version control systems is to never commit
+code that can be generated. The source code repository itself likely
+does not have a ``configure`` script. Developers typically write
+(or auto-generate) a ``configure.ac`` script that contains configuration
+preferences and a ``Makefile.am`` script that contains build instructions.
+Then, ``autoconf`` is used to convert ``configure.ac`` into ``configure``,
+while ``automake`` is used to convert ``Makefile.am`` into ``Makefile.in``.
+``Makefile.in`` is used by ``configure`` to generate a platform-dependent
+``Makefile`` for you. The following diagram provides a high-level overview
+of the process:
+
+.. figure:: Autoconf-automake-process.*
+ :target: https://commons.wikimedia.org/w/index.php?curid=15581407
+
+ `GNU autoconf and automake process for generating makefiles <https://commons.wikimedia.org/wiki/File:Autoconf-automake-process.svg>`_
+ by `Jdthood` under `CC BY-SA 3.0 <https://creativecommons.org/licenses/by-sa/3.0/deed.en>`_
+
+If a ``configure`` script is not present in your tarball, you will
+need to generate one yourself. Luckily, Spack already has an ``autoreconf``
+phase to do most of the work for you. By default, the ``autoreconf``
+phase runs:
+
+.. code-block:: console
+
+ $ libtoolize
+ $ aclocal
+ $ autoreconf --install --verbose --force
+
+All you need to do is add a few Autotools dependencies to the package.
+Most stable releases will come with a ``configure`` script, but if you
+check out a commit from the ``develop`` branch, you would want to add:
+
+.. code-block:: python
+
+ depends_on('autoconf', type='build', when='@develop')
+ depends_on('automake', type='build', when='@develop')
+ depends_on('libtool', type='build', when='@develop')
+ depends_on('m4', type='build', when='@develop')
+
+In some cases, developers might need to distribute a patch that modifies
+one of the files used to generate ``configure`` or ``Makefile.in``.
+In this case, these scripts will need to be regenerated. It is
+preferable to regenerate these manually using the patch, and then
+create a new patch that directly modifies ``configure``. That way,
+Spack can use the secondary patch and additional build system
+dependencies aren't necessary.
+
+""""""""""""""""
+force_autoreconf
+""""""""""""""""
+
+If for whatever reason you really want to add the original patch
+and tell Spack to regenerate ``configure``, you can do so using the
+following setting:
+
+.. code-block:: python
+
+ force_autoreconf = True
+
+This line tells Spack to wipe away the existing ``configure`` script
+and generate a new one. If you only need to do this for a single
+version, this can be done like so:
+
+.. code-block:: python
+
+ @property
+ def force_autoreconf(self):
+ return self.version == Version('1.2.3'):
+
+^^^^^^^^^^^^^^^^^^^^^^^
+Finding configure flags
+^^^^^^^^^^^^^^^^^^^^^^^
+
+Once you have a ``configure`` script present, the next step is to
+determine what option flags are available. These flags can be found
+by running:
+
+.. code-block:: console
+
+ $ ./configure --help
+
+``configure`` will display a list of valid flags separated into
+some or all of the following sections:
+
+* Configuration
+* Installation directories
+* Fine tuning of the installation directories
+* Program names
+* X features
+* System types
+* **Optional Features**
+* **Optional Packages**
+* **Some influential environment variables**
+
+For the most part, you can ignore all but the last 3 sections.
+The "Optional Features" sections lists flags that enable/disable
+features you may be interested in. The "Optional Packages" section
+often lists dependencies and the flags needed to locate them. The
+"environment variables" section lists environment variables that the
+build system uses to pass flags to the compiler and linker.
+
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+Addings flags to configure
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+For most of the flags you encounter, you will want a variant to
+optionally enable/disable them. You can then optionally pass these
+flags to the ``configure`` call by overriding the ``configure_args``
+function like so:
+
+.. code-block:: python
+
+ def configure_args(self):
+ args = []
+
+ if '+mpi' in self.spec:
+ args.append('--enable-mpi')
+ else:
+ args.append('--disable-mpi')
+
+ return args
+
+Note that we are explicitly disabling MPI support if it is not
+requested. This is important, as many Autotools packages will enable
+options by default if the dependencies are found, and disable them
+otherwise. We want Spack installations to be as deterministic as possible.
+If two users install a package with the same variants, the goal is that
+both installations work the same way. See `here <https://www.linux.com/news/best-practices-autotools>`__
+and `here <https://wiki.gentoo.org/wiki/Project:Quality_Assurance/Automagic_dependencies>`__
+for a rationale as to why these so-called "automagic" dependencies
+are a problem.
+
+By default, Autotools installs packages to ``/usr``. We don't want this,
+so Spack automatically adds ``--prefix=/path/to/installation/prefix``
+to your list of ``configure_args``. You don't need to add this yourself.
+
+^^^^^^^^^^^^^^^^
+Helper functions
+^^^^^^^^^^^^^^^^
+
+You may have noticed that most of the Autotools flags are of the form
+``--enable-foo``, ``--disable-bar``, ``--with-baz=<prefix>``, or
+``--without-baz``. Since these flags are so common, Spack provides a
+couple of helper functions to make your life easier.
+
+TODO: document ``with_or_without`` and ``enable_or_disable``.
+
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Configure script in a sub-directory
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Occasionally, developers will hide their source code and ``configure``
+script in a subdirectory like ``src``. If this happens, Spack won't
+be able to automatically detect the build system properly when running
+``spack create``. You will have to manually change the package base
+class and tell Spack where the ``configure`` script resides. You can
+do this like so:
+
+.. code-block:: python
+
+ configure_directory = 'src'
+
+^^^^^^^^^^^^^^^^^^^^^^
+Building out of source
+^^^^^^^^^^^^^^^^^^^^^^
+
+Some packages like ``gcc`` recommend building their software in a
+different directory than the source code to prevent build pollution.
+This can be done using the ``build_directory`` variable:
+
+.. code-block:: python
+
+ build_directory = 'spack-build'
+
+By default, Spack will build the package in the same directory that
+contains the ``configure`` script
+
+^^^^^^^^^^^^^^^^^^^^^^^^^
+Build and install targets
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+For most Autotools packages, the usual:
+
+.. code-block:: console
+
+ $ configure
+ $ make
+ $ make install
+
+is sufficient to install the package. However, if you need to run
+make with any other targets, for example, to build an optional
+library or build the documentation, you can add these like so:
+
+.. code-block:: python
+
+ build_targets = ['all', 'docs']
+ install_targets = ['install', 'docs']
+
+^^^^^^^
+Testing
+^^^^^^^
+
+Autotools-based packages typically provide unit testing via the
+``check`` and ``installcheck`` targets. If you build your software
+with ``spack install --test=root``, Spack will check for the presence
+of a ``check`` or ``test`` target in the Makefile and run
+``make check`` for you. After installation, it will check for an
+``installcheck`` target and run ``make installcheck`` if it finds one.
+
+^^^^^^^^^^^^^^^^^^^^^^
+External documentation
+^^^^^^^^^^^^^^^^^^^^^^
+
+For more information on the Autotools build system, see:
+https://www.gnu.org/software/automake/manual/html_node/Autotools-Introduction.html