Allow packages to control handling of compiler flags (#4421)
* Initial work on flag trapping using functions called <flag>_handler and default_flag_handler * Update packages so they do not obliterate flags * Added append to EnvironmentModifications class * changed EnvironmentModifications to have append_flags method * changed flag_val to be a tuple * Increased test coverage * added documentation of flag handling
This commit is contained in:
@@ -2390,6 +2390,94 @@ build system.
|
||||
Compiler flags
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
Compiler flags set by the user through the Spec object can be passed to
|
||||
the build in one of two ways. For packages inheriting from the
|
||||
``CmakePackage`` or ``AutotoolsPackage`` classes, the build environment
|
||||
passes those flags to the relevant environment variables (``CFLAGS``,
|
||||
``CXXFLAGS``, etc) that are respected by the build system. For all other
|
||||
packages, the default behavior is to inject the flags directly into the
|
||||
compiler commands using Spack's compiler wrappers.
|
||||
|
||||
Individual packages can override the default behavior for the flag
|
||||
handling. Packages can define a ``default_flag_handler`` method that
|
||||
applies to all sets of flags handled by Spack, or may define
|
||||
individual methods ``cflags_handler``, ``cxxflags_handler``,
|
||||
etc. Spack will apply the individual method for a flag set if it
|
||||
exists, otherwise the ``default_flag_handler`` method if it exists,
|
||||
and fall back on the default for that package class if neither exists.
|
||||
|
||||
These methods are defined on the package class, and take two
|
||||
parameters in addition to the packages itself. The ``env`` parameter
|
||||
is an ``EnvironmentModifications`` object that can be used to change
|
||||
the build environment. The ``flag_val`` parameter is a tuple. Its
|
||||
first entry is the name of the flag (``cflags``, ``cxxflags``, etc.)
|
||||
and its second entry is a list of the values for that flag.
|
||||
|
||||
There are three primary idioms that can be combined to create whatever
|
||||
behavior the package requires.
|
||||
|
||||
1. The default behavior for packages inheriting from
|
||||
``AutotoolsPackage`` or ``CmakePackage``.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def default_flag_handler(self, env, flag_val):
|
||||
env.append_flags(flag_val[0].upper(), ' '.join(flag_val[1]))
|
||||
return []
|
||||
|
||||
2. The default behavior for other packages
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def default_flag_handler(self, env, flag_val):
|
||||
return flag_val[1]
|
||||
|
||||
|
||||
3. Packages may have additional flags to add to the build. These flags
|
||||
can be added to either idiom above. For example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def default_flag_handler(self, env, flag_val):
|
||||
flags = flag_val[1]
|
||||
flags.append('-flag')
|
||||
return flags
|
||||
|
||||
or
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def default_flag_handler(self, env, flag_val):
|
||||
env.append_flags(flag_val[0].upper(), ' '.join(flag_val[1]))
|
||||
env.append_flags(flag_val[0].upper(), '-flag')
|
||||
return []
|
||||
|
||||
Packages may also opt for methods that include aspects of any of the
|
||||
idioms above. E.g.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def default_flag_handler(self, env, flag_val):
|
||||
flags = []
|
||||
if len(flag_val[1]) > 3:
|
||||
env.append_flags(flag_val[0].upper(), ' '.join(flag_val[1][3:]))
|
||||
flags = flag_val[1][:3]
|
||||
else:
|
||||
flags = flag_val[1]
|
||||
flags.append('-flag')
|
||||
return flags
|
||||
|
||||
Because these methods can pass values through environment variables,
|
||||
it is important not to override these variables unnecessarily in other
|
||||
package methods. In the ``setup_environment`` and
|
||||
``setup_dependent_environment`` methods, use the ``append_flags``
|
||||
method of the ``EnvironmentModifications`` class to append values to a
|
||||
list of flags whenever there is no good reason to override the
|
||||
existing value. In the ``install`` method and other methods that can
|
||||
operate on the build environment directly through the ``env``
|
||||
variable, test for environment variable existance before overriding
|
||||
values to add compiler flags.
|
||||
|
||||
In rare circumstances such as compiling and running small unit tests, a
|
||||
package developer may need to know what are the appropriate compiler
|
||||
flags to enable features like ``OpenMP``, ``c++11``, ``c++14`` and
|
||||
|
Reference in New Issue
Block a user