diff options
Diffstat (limited to 'lib/spack/docs/build_systems/autotoolspackage.rst')
-rw-r--r-- | lib/spack/docs/build_systems/autotoolspackage.rst | 305 |
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 |