The PyTrilinos Build System
===========================

The move by Trilinos to the CMake build system has had many advantages
for PyTrilinos.  The two primary advantages being that shared
libraries and python extension libraries can now both be built
automatically by the host build system.  Previously, shared libraries
were built by the PyTrilinos package in an ad-hoc manner, and the
python extension libraries were built using the python distutils
module, which has some reports of portability issues.  The move to
CMake has improved the reliability and robustness of the PyTrilinos
build system.

From a build-system point of view, there are two types of Trilinos
packages that are supported by PyTrilinos: those that are contained
within a single namespace, like Teuchos, Epetra and AztecOO; and those
that are contained within nested namespaces, such as NOX.  These two
types are detailed below, in addition to the ``pytrilinos`` library
and package-specific configuration options.

Single Namespace Packages
-------------------------

Make sure you package is properly listed in the
``TrilinosPackageDependencies.xml`` file, as described above.

The PyTrilinos build system maintains two variables,
``PyTrilnos_PACKAGES`` and ``PyTrilinos_MODULES``, both set in the
top-level PyTrilinos ``CMakeLists.txt`` file, to keep track of what to
build.  (Note that these variables are referenced as
``${PACKAGE_NAME}_PACKAGES`` and ``${PACKAGE_NAME}_MODULES`` within
``CMakeLists.txt``.)  For single namespace packages, the entries in
these two variables is the same.  For example, ::

    IF(PyTrilinos_ENABLE_Teuchos)
      APPEND_SET(${PACKAGE_NAME}_PACKAGES Teuchos)
      APPEND_SET(${PACKAGE_NAME}_MODULES  Teuchos)
    ENDIF(PyTrilinos_ENABLE_Teuchos)

In this instance, the build system now expects to find a SWIG
interface file in the source directory ``src/Teuchos.i`` that defines
module ``PyTrilinos.Teuchos``.  The end products will be placed in the
build directory ``src/PyTrilinos``::

    src/PyTrilinos/Teuchos.py
    src/PyTrilinos/Teuchos.pyc
    src/PyTrilinos/_Teuchos.so

SWIG will generate ``Teuchos.py`` and ``TeuchosPYTHON_wrap.cpp``. The
latter will be compiled to create ``_Teuchos.so``. ``Teuchos.py`` has
an ``import _Teuchos`` command that imports the compiled
extension. The ``Teuchos.pyc`` file is obtained when the build system
byte-compiles ``Teuchos.py``.

Nested Namespace Packages
-------------------------

Using ``NOX`` as an example, the ``LIB_OPTIONAL_DEP_PACKAGES``
attribute of the ``PyTrilinos`` element of type ``Package`` in the
``TrilinosPackageDependencies.xml`` file should contain the entry
``NOX`` and it should be listed in build order.

In the top-level PyTrilinos ``CMakeLists.txt`` file, the variable
``PyTrilinos_PACKAGES`` should be appended as before, with a single
entry.  But ``PyTrilinos_MODULES`` should contain an entry for each
nested namespace::

    IF(PyTrilinos_ENABLE_NOX)
      APPEND_SET(${PACKAGE_NAME}_PACKAGES NOX)
      APPEND_SET(${PACKAGE_NAME}_MODULES  NOX           )
      APPEND_SET(${PACKAGE_NAME}_MODULES  NOX.Abstract  )
      APPEND_SET(${PACKAGE_NAME}_MODULES  NOX.StatusTest)
      APPEND_SET(${PACKAGE_NAME}_MODULES  NOX.Solver    )
      IF(NOX_ENABLE_Epetra)
        APPEND_SET(${PACKAGE_NAME}_MODULES NOX.Epetra          )
        APPEND_SET(${PACKAGE_NAME}_MODULES NOX.Epetra.Interface)
      ENDIF(NOX_ENABLE_Epetra)
      IF(NOX_ENABLE_ABSTRACT_IMPLEMENTATION_PETSC)
        APPEND_SET(PyTrilinos_MODULES NOX.PETSc          )
        APPEND_SET(PyTrilinos_MODULES NOX.PETSc.Interface)
      ENDIF(NOX_ENABLE_ABSTRACT_IMPLEMENTATION_PETSC)
    ENDIF(PyTrilinos_ENABLE_NOX)

For every entry in ``PyTrilnos_MODULES``, there should be a
corresponding SWIG file in the source directory::

    src/NOX.i
    src/NOX.Abstract.i
    src/NOX.StatusTest.i
    src/NOX.Solver.i
    src/NOX.Epetra.i
    src/NOX.Epetra.Interface.i
    src/NOX.PETSc.i
    src/NOX.PETSc.Interface.i

which will generate the following build products::

    src/PyTrilinos/NOX/__init__.py
    src/PyTrilinos/NOX/__init__.pyc
    src/PyTrilinos/NOX/Base.py
    src/PyTrilinos/NOX/Base.pyc
    src/PyTrilinos/NOX/_Base.py
    src/PyTrilinos/NOX/Abstract.py
    src/PyTrilinos/NOX/Abstract.pyc
    src/PyTrilinos/NOX/_Abstract.so
    src/PyTrilinos/NOX/StatusTest.py
    src/PyTrilinos/NOX/StatusTest.pyc
    src/PyTrilinos/NOX/_StatusTest.so
    src/PyTrilinos/NOX/Solver.py
    src/PyTrilinos/NOX/Solver.pyc
    src/PyTrilinos/NOX/_Solver.so
    src/PyTrilinos/NOX/Epetra/__init__.py
    src/PyTrilinos/NOX/Epetra/__init__.pyc
    src/PyTrilinos/NOX/Epetra/Base.py
    src/PyTrilinos/NOX/Epetra/Base.pyc
    src/PyTrilinos/NOX/Epetra/_Base.py
    src/PyTrilinos/NOX/Epetra/Interface.py
    src/PyTrilinos/NOX/Epetra/Interface.pyc
    src/PyTrilinos/NOX/Epetra/_Interface.so
    src/PyTrilinos/NOX/PETSc/__init__.py
    src/PyTrilinos/NOX/PETSc/__init__.pyc
    src/PyTrilinos/NOX/PETSc/Base.py
    src/PyTrilinos/NOX/PETSc/Base.pyc
    src/PyTrilinos/NOX/PETSc/_Base.py
    src/PyTrilinos/NOX/PETSc/Interface.py
    src/PyTrilinos/NOX/PETSc/Interface.pyc
    src/PyTrilinos/NOX/PETSc/_Interface.so

The ``pytrilinos`` Library
--------------------------

If you develop a module that requires compiled code not generated by
SWIG (i.e., source code you develop), it should be put in the
``pytrilinos`` library.  Simply append entries the the ``HEADERS`` and
``SOURCES`` variables in ``src/CMakeLists.txt`` file.

Package-Specific Configuration Options
--------------------------------------

If you need package-specific configuration options set, they should be
done so in ``src/CMakeLists.txt`` prior to the call to
``PACKAGE_CONFIGURE_FILE()`` and in ``cmake/PyTrilinos_config.h.in``.
Currently, the following variables are set depending upon the
top-level Trilinos configuration::

    HAVE_EPETRA
    HAVE_TPETRA
    HAVE_DOMI
    HAVE_STK
    HAVE_NOX_EPETRA
    HAVE_NOX_EPETRAEXT
    HAVE_NOX_PETSC
    HAVE_MPI
    HAVE_MPI4PY
