From 8ce62ba51334f0f9e4b62f795923d81514229013 Mon Sep 17 00:00:00 2001 From: "Adam J. Stewart" Date: Tue, 17 Jul 2018 13:28:38 -0500 Subject: Add documentation on build systems (#5015) Spack provides a number of classes based on commonly-used build systems that users can extend when writing packages; the classes provide functionality to perform the actions relevant to the build system (e.g. running "configure" for an Autotools-based package). This adds documentation for classes supporting the following build systems: * Makefile * Autotools * CMake * QMake * SCons * Waf This includes build systems for managing extensions of the following packages: * Perl * Python * R * Octave This also adds documentation on implementing packages that use a custom build system (e.g. Perl/CMake). Spack also provides extendable classes which aggregate functionality for related sets of packages, e.g. those using CUDA. Documentation is added for CudaPackage. --- lib/spack/docs/build_systems/sconspackage.rst | 301 ++++++++++++++++++++++++++ 1 file changed, 301 insertions(+) create mode 100644 lib/spack/docs/build_systems/sconspackage.rst (limited to 'lib/spack/docs/build_systems/sconspackage.rst') diff --git a/lib/spack/docs/build_systems/sconspackage.rst b/lib/spack/docs/build_systems/sconspackage.rst new file mode 100644 index 0000000000..6be41ee0d8 --- /dev/null +++ b/lib/spack/docs/build_systems/sconspackage.rst @@ -0,0 +1,301 @@ +.. _sconspackage: + +------------ +SConsPackage +------------ + +SCons is a general-purpose build system that does not rely on +Makefiles to build software. SCons is written in Python, and handles +all building and linking itself. + +As far as build systems go, SCons is very non-uniform. It provides a +common framework for developers to write build scripts, but the build +scripts themselves can vary drastically. Some developers add subcommands +like: + +.. code-block:: console + + $ scons clean + $ scons build + $ scons test + $ scons install + + +Others don't add any subcommands. Some have configuration options that +can be specified through variables on the command line. Others don't. + +^^^^^^ +Phases +^^^^^^ + +As previously mentioned, SCons allows developers to add subcommands like +``build`` and ``install``, but by default, installation usually looks like: + +.. code-block:: console + + $ scons + $ scons install + + +To facilitate this, the ``SConsPackage`` base class provides the +following phases: + +#. ``build`` - build the package +#. ``install`` - install the package + +Package developers often add unit tests that can be invoked with +``scons test`` or ``scons check``. Spack provides a ``test`` method +to handle this. Since we don't know which one the package developer +chose, the ``test`` method does nothing by default, but can be easily +overridden like so: + +.. code-block:: python + + def test(self): + scons('check') + + +^^^^^^^^^^^^^^^ +Important files +^^^^^^^^^^^^^^^ + +SCons packages can be identified by their ``SConstruct`` files. These +files handle everything from setting up subcommands and command-line +options to linking and compiling. + +One thing to look for is the ``EnsureSConsVersion`` function: + +.. code-block:: none + + EnsureSConsVersion(2, 3, 0) + + +This means that SCons 2.3.0 is the earliest release that will work. +You should specify this in a ``depends_on`` statement. + +^^^^^^^^^^^^^^^^^^^^^^^^^ +Build system dependencies +^^^^^^^^^^^^^^^^^^^^^^^^^ + +At the bare minimum, packages that use the SCons build system need a +``scons`` dependency. Since this is always the case, the ``SConsPackage`` +base class already contains: + +.. code-block:: python + + depends_on('scons', type='build') + + +If you want to specify a particular version requirement, you can override +this in your package: + +.. code-block:: python + + depends_on('scons@2.3.0:', type='build') + + +^^^^^^^^^^^^^^^^^^^^^^^^^ +Finding available options +^^^^^^^^^^^^^^^^^^^^^^^^^ + +The first place to start when looking for a list of valid options to +build a package is ``scons --help``. Some packages like +`kahip `_ +don't bother overwriting the default SCons help message, so this isn't +very useful, but other packages like +`serf `_ +print a list of valid command-line variables: + +.. code-block:: console + + $ scons --help + scons: Reading SConscript files ... + Checking for GNU-compatible C compiler...yes + scons: done reading SConscript files. + + PREFIX: Directory to install under ( /path/to/PREFIX ) + default: /usr/local + actual: /usr/local + + LIBDIR: Directory to install architecture dependent libraries under ( /path/to/LIBDIR ) + default: $PREFIX/lib + actual: /usr/local/lib + + APR: Path to apr-1-config, or to APR's install area ( /path/to/APR ) + default: /usr + actual: /usr + + APU: Path to apu-1-config, or to APR's install area ( /path/to/APU ) + default: /usr + actual: /usr + + OPENSSL: Path to OpenSSL's install area ( /path/to/OPENSSL ) + default: /usr + actual: /usr + + ZLIB: Path to zlib's install area ( /path/to/ZLIB ) + default: /usr + actual: /usr + + GSSAPI: Path to GSSAPI's install area ( /path/to/GSSAPI ) + default: None + actual: None + + DEBUG: Enable debugging info and strict compile warnings (yes|no) + default: False + actual: False + + APR_STATIC: Enable using a static compiled APR (yes|no) + default: False + actual: False + + CC: Command name or path of the C compiler + default: None + actual: gcc + + CFLAGS: Extra flags for the C compiler (space-separated) + default: None + actual: + + LIBS: Extra libraries passed to the linker, e.g. "-l -l" (space separated) + default: None + actual: None + + LINKFLAGS: Extra flags for the linker (space-separated) + default: None + actual: + + CPPFLAGS: Extra flags for the C preprocessor (space separated) + default: None + actual: None + + Use scons -H for help about command-line options. + + +More advanced packages like +`cantera `_ +use ``scons --help`` to print a list of subcommands: + +.. code-block:: console + + $ scons --help + scons: Reading SConscript files ... + + SCons build script for Cantera + + Basic usage: + 'scons help' - print a description of user-specifiable options. + + 'scons build' - Compile Cantera and the language interfaces using + default options. + + 'scons clean' - Delete files created while building Cantera. + + '[sudo] scons install' - Install Cantera. + + '[sudo] scons uninstall' - Uninstall Cantera. + + 'scons test' - Run all tests which did not previously pass or for which the + results may have changed. + + 'scons test-reset' - Reset the passing status of all tests. + + 'scons test-clean' - Delete files created while running the tests. + + 'scons test-help' - List available tests. + + 'scons test-NAME' - Run the test named "NAME". + + 'scons dump' - Dump the state of the SCons environment to the + screen instead of doing , e.g. + 'scons build dump'. For debugging purposes. + + 'scons samples' - Compile the C++ and Fortran samples. + + 'scons msi' - Build a Windows installer (.msi) for Cantera. + + 'scons sphinx' - Build the Sphinx documentation + + 'scons doxygen' - Build the Doxygen documentation + + +You'll notice that cantera provides a ``scons help`` subcommand. Running +``scons help`` prints a list of valid command-line variables. + +^^^^^^^^^^^^^^^^^^^^^^^^^^ +Passing arguments to scons +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Now that you know what arguments the project accepts, you can add them to +the package build phase. This is done by overriding ``build_args`` like so: + +.. code-block:: python + + def build_args(self, spec, prefix): + args = [ + 'PREFIX={0}'.format(prefix), + 'ZLIB={0}'.format(spec['zlib'].prefix), + ] + + if '+debug' in spec: + args.append('DEBUG=yes') + else: + args.append('DEBUG=no') + + return args + + +``SConsPackage`` also provides an ``install_args`` function that you can +override to pass additional arguments to ``scons install``. + +^^^^^^^^^^^^^^^^^ +Compiler wrappers +^^^^^^^^^^^^^^^^^ + +By default, SCons builds all packages in a separate execution environment, +and doesn't pass any environment variables from the user environment. +Even changes to ``PATH`` are not propagated unless the package developer +does so. + +This is particularly troublesome for Spack's compiler wrappers, which depend +on environment variables to manage dependencies and linking flags. In many +cases, SCons packages are not compatible with Spack's compiler wrappers, +and linking must be done manually. + +First of all, check the list of valid options for anything relating to +environment variables. For example, cantera has the following option: + +.. code-block:: none + + * env_vars: [ string ] + Environment variables to propagate through to SCons. Either the + string "all" or a comma separated list of variable names, e.g. + 'LD_LIBRARY_PATH,HOME'. + - default: 'LD_LIBRARY_PATH,PYTHONPATH' + + +In the case of cantera, using ``env_vars=all`` allows us to use +Spack's compiler wrappers. If you don't see an option related to +environment variables, try using Spack's compiler wrappers by passing +``spack_cc``, ``spack_cxx``, and ``spack_fc`` via the ``CC``, ``CXX``, +and ``FC`` arguments, respectively. If you pass them to the build and +you see an error message like: + +.. code-block:: none + + Spack compiler must be run from Spack! Input 'SPACK_PREFIX' is missing. + + +you'll know that the package isn't compatible with Spack's compiler +wrappers. In this case, you'll have to use the path to the actual +compilers, which are stored in ``self.compiler.cc`` and friends. +Note that this may involve passing additional flags to the build to +locate dependencies, a task normally done by the compiler wrappers. +serf is an example of a package with this limitation. + +^^^^^^^^^^^^^^^^^^^^^^ +External documentation +^^^^^^^^^^^^^^^^^^^^^^ + +For more information on the SCons build system, see: +http://scons.org/documentation.html -- cgit v1.2.3-60-g2f50