xref: /petsc/doc/developers/buildsystem.md (revision a982d5546cc9bcf96044945e3157033f4bde0259)
1*4bcd95a3SBarry Smith(ch_buildsystem)=
2*4bcd95a3SBarry Smith
3*4bcd95a3SBarry Smith# BuildSystem
4*4bcd95a3SBarry Smith
5*4bcd95a3SBarry Smith`BuildSystem` (located in `config/BuildSystem`) configures PETSc before PETSc is compiled with make.
6*4bcd95a3SBarry SmithIt is much like [GNU Autoconf (configure)](https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.71/html_node/index.html#Top)
7*4bcd95a3SBarry Smithbut written in Python especially for PETSc.
8*4bcd95a3SBarry Smith
9*4bcd95a3SBarry Smith## What is a build?
10*4bcd95a3SBarry Smith
11*4bcd95a3SBarry SmithThe build stage compiles source to object files, stores them
12*4bcd95a3SBarry Smith(usually in archives), and links shared libraries and executables. These
13*4bcd95a3SBarry Smithare mechanical operations that reduce to applying a construction rule to
14*4bcd95a3SBarry Smithsets of files. The [Make](http://www.gnu.org/software/make/) tool is
15*4bcd95a3SBarry Smithgreat at this job.
16*4bcd95a3SBarry Smith
17*4bcd95a3SBarry Smith## Why is configure necessary?
18*4bcd95a3SBarry Smith
19*4bcd95a3SBarry SmithThe `configure` program is designed to assemble all information and preconditions
20*4bcd95a3SBarry Smithnecessary for the build stage. This is a far more complicated task, heavily dependent on
21*4bcd95a3SBarry Smiththe local hardware and software environment. It is also the source of nearly every build
22*4bcd95a3SBarry Smithproblem. The most crucial aspect of a configure system is not performance, scalability, or
23*4bcd95a3SBarry Smitheven functionality, but *debuggability*. Configuration failure is at least as common as
24*4bcd95a3SBarry Smithsuccess, due to broken tools, operating system upgrades, hardware incompatibilities, user
25*4bcd95a3SBarry Smitherror, and a host of other reasons. Problem diagnosis is the single biggest bottleneck for
26*4bcd95a3SBarry Smithdevelopment and maintenance time. Unfortunately, current systems are built to optimize the
27*4bcd95a3SBarry Smithsuccessful case rather than the unsuccessful. In PETSc, we have developed the
28*4bcd95a3SBarry Smith`BuildSystem` package to remedy the shortcomings of configuration systems such as
29*4bcd95a3SBarry SmithAutoconf, CMake, and SCons.
30*4bcd95a3SBarry Smith
31*4bcd95a3SBarry Smith## Why use PETSc BuildSystem?
32*4bcd95a3SBarry Smith
33*4bcd95a3SBarry SmithAs several configuration tools
34*4bcd95a3SBarry Smithcurrently exist, it is instructive to consider why PETSc would choose to create another
35*4bcd95a3SBarry Smithfrom scratch. Below we list features and design considerations which lead us to prefer
36*4bcd95a3SBarry Smith`BuildSystem` to the alternatives.
37*4bcd95a3SBarry Smith
38*4bcd95a3SBarry Smith### Namespacing
39*4bcd95a3SBarry Smith
40*4bcd95a3SBarry Smith`BuildSystem` wraps collections of related tests in Python modules, which also hold
41*4bcd95a3SBarry Smiththe test results. Thus results are accessed using normal Python
42*4bcd95a3SBarry Smithnamespacing. As rudimentary as this sounds, no namespacing beyond the
43*4bcd95a3SBarry Smithuse of variable name prefixes is present in Autoconf, CMake, and SCons.
44*4bcd95a3SBarry SmithInstead, a flat namespace is used. This
45*4bcd95a3SBarry Smithtendency appears again when composing command lines for external tools,
46*4bcd95a3SBarry Smithsuch as the compiler and linker. In the traditional configure tools,
47*4bcd95a3SBarry Smithoptions are aggregated in a single bucket variable, such as `INCLUDE`
48*4bcd95a3SBarry Smithor `LIBS`, whereas in `BuildSystem` one can trace the provenance of a flag before it
49*4bcd95a3SBarry Smithis added to the command line. CMake also makes the unfortunate decision
50*4bcd95a3SBarry Smithto force all link options to resolve to full paths, which causes havoc
51*4bcd95a3SBarry Smithwith compiler-private libraries.
52*4bcd95a3SBarry Smith
53*4bcd95a3SBarry Smith### Explicit control flow
54*4bcd95a3SBarry Smith
55*4bcd95a3SBarry SmithThe `BuildSystem` configure modules mentioned above, containing one `Configure` object
56*4bcd95a3SBarry Smithper module, are organized explicitly into a directed acyclic graph
57*4bcd95a3SBarry Smith(DAG). The user indicates dependence, an *edge* in the dependence graph,
58*4bcd95a3SBarry Smithwith a single call, `requires('path.to.other.test', self)`, which not
59*4bcd95a3SBarry Smithonly structures the DAG, but returns the `Configure` object. The caller
60*4bcd95a3SBarry Smithcan then use this object to access the results of the tests run by the
61*4bcd95a3SBarry Smithdependency, achieving test and result encapsulation simply.
62*4bcd95a3SBarry Smith
63*4bcd95a3SBarry Smith### Multi-language tests
64*4bcd95a3SBarry Smith
65*4bcd95a3SBarry Smith`BuildSystem` maintains an explicit language stack, so that the current language
66*4bcd95a3SBarry Smithcan be manipulated by the test environment. A compile or link can be run
67*4bcd95a3SBarry Smithusing any language, complete with the proper compilers, flags,
68*4bcd95a3SBarry Smithlibraries, etc., with a single call. This automation is crucial
69*4bcd95a3SBarry Smithfor cross-language tests, which are thinly supported in current
70*4bcd95a3SBarry Smithtools. In fact, the design of these tools inhibits this kind of check.
71*4bcd95a3SBarry SmithThe `check_function_exists()` call in Autoconf and CMake looks only
72*4bcd95a3SBarry Smithfor the presence of a particular symbol in a library, and fails in C++
73*4bcd95a3SBarry Smithand on Microsoft Windows, whereas the equivalent `BuildSystem` test can also take a
74*4bcd95a3SBarry Smithdeclaration. The `try_compile()` test in Autoconf and CMake requires
75*4bcd95a3SBarry Smiththe entire list of libraries be present in the `LIBS` variable,
76*4bcd95a3SBarry Smithproviding no good way to obtain libraries from other tests in a modular
77*4bcd95a3SBarry Smithfashion. As another example, if the user has a dependent library that
78*4bcd95a3SBarry Smithrequires `libstdc++`, but they are working with a C project, no
79*4bcd95a3SBarry Smithstraightforward method exists to add this dependency.
80*4bcd95a3SBarry Smith
81*4bcd95a3SBarry Smith### Subpackages
82*4bcd95a3SBarry Smith
83*4bcd95a3SBarry SmithThe most complicated, yet perhaps most useful, part of `BuildSystem` is
84*4bcd95a3SBarry Smithsupport for dependent packages. It provides an object scaffolding for
85*4bcd95a3SBarry Smithincluding a 3rd party package (more than 100 are now available) so that
86*4bcd95a3SBarry SmithPETSc downloads and builds the package for use by PETSc. The native
87*4bcd95a3SBarry Smithconfigure and build system for the package is used, and special support
88*4bcd95a3SBarry Smithexists for Autoconf and CMake packages. No similar system exists in the other
89*4bcd95a3SBarry Smithtools, which rely on static declarations, such as `pkg-config` or
90*4bcd95a3SBarry Smith`FindPackage.cmake` files, that are not tested and often become
91*4bcd95a3SBarry Smithobsolete.
92*4bcd95a3SBarry Smith
93*4bcd95a3SBarry Smith### Batch environments
94*4bcd95a3SBarry Smith
95*4bcd95a3SBarry SmithMost systems, such as Autoconf and CMake, do not actually run tests in a
96*4bcd95a3SBarry Smithbatch environment, but rather require a direct specification, in CMake a
97*4bcd95a3SBarry Smith"platform file". This requires a human expert to write and maintain the
98*4bcd95a3SBarry Smithplatform file. Alternatively, `BuildSystem` submits a dynamically
99*4bcd95a3SBarry Smithgenerated set of tests to the batch system, enabling automatic
100*4bcd95a3SBarry Smithcross-configuration and cross-compilation.
101*4bcd95a3SBarry Smith
102*4bcd95a3SBarry Smith### Caching
103*4bcd95a3SBarry Smith
104*4bcd95a3SBarry SmithCaching often seems like an attractive option since configuration can be
105*4bcd95a3SBarry Smithquite time-consuming, and both Autoconf and CMake enable caching by
106*4bcd95a3SBarry Smithdefault. However, no system has the ability to reliably invalidate the
107*4bcd95a3SBarry Smithcache when the environment for the configuration changes. For example, a
108*4bcd95a3SBarry Smithcompiler or library dependency may be upgraded on the system. Moreover,
109*4bcd95a3SBarry Smithdependencies between cached variables are not tracked, so that even if
110*4bcd95a3SBarry Smithsome variables are correctly updated after an upgrade, others which
111*4bcd95a3SBarry Smithdepend on them may not be. Moreover, CMake mixes together information
112*4bcd95a3SBarry Smithwhich is discovered automatically with that explicitly provided by the
113*4bcd95a3SBarry Smithuser, which is often not tested.
114*4bcd95a3SBarry Smith
115*4bcd95a3SBarry Smith### Concision
116*4bcd95a3SBarry Smith
117*4bcd95a3SBarry SmithThe cognitive load is usually larger for larger code bases,
118*4bcd95a3SBarry Smithand our observation is that the addition of logic to Autoconf
119*4bcd95a3SBarry Smithand CMake is often quite cumbersome and verbose as they do not employ a modern,
120*4bcd95a3SBarry Smithhigher level language. Although `BuildSystem` itself is not widely used,
121*4bcd95a3SBarry Smithit has the advantage of being written in Python, a widely-understood, high-level
122*4bcd95a3SBarry Smithlanguage.
123*4bcd95a3SBarry Smith
124*4bcd95a3SBarry Smith## High level organization
125*4bcd95a3SBarry Smith
126*4bcd95a3SBarry SmithA minimal `BuildSystem` setup consists of a `config` directory off the
127*4bcd95a3SBarry Smithpackage root, which contains all the Python necessary to run (in addition
128*4bcd95a3SBarry Smithto the `BuildSystem` source). At minimum, the `config` directory contains
129*4bcd95a3SBarry Smith`configure.py`, which is executed to run the configure process, and a
130*4bcd95a3SBarry Smithmodule for the package itself. For example, PETSc contains
131*4bcd95a3SBarry Smith`config/PETSc/petsc.py`. It is also common to include a top level
132*4bcd95a3SBarry Smith`configure` file to execute the configure, as this looks like
133*4bcd95a3SBarry SmithAutotools,
134*4bcd95a3SBarry Smith
135*4bcd95a3SBarry Smith```python
136*4bcd95a3SBarry Smith#!/usr/bin/env python3
137*4bcd95a3SBarry Smithimport os
138*4bcd95a3SBarry Smithexecfile(os.path.join(os.path.dirname(__file__), 'config', 'configure.py'))
139*4bcd95a3SBarry Smith```
140*4bcd95a3SBarry Smith
141*4bcd95a3SBarry SmithThe `configure.py` script constructs a tree of configure modules and
142*4bcd95a3SBarry Smithexecutes the configure process over it. A minimal version of this would
143*4bcd95a3SBarry Smithbe
144*4bcd95a3SBarry Smith
145*4bcd95a3SBarry Smith```python
146*4bcd95a3SBarry Smithpackage = 'PETSc'
147*4bcd95a3SBarry Smith
148*4bcd95a3SBarry Smithdef configure(configure_options):
149*4bcd95a3SBarry Smith  # Command line arguments take precedence (but don't destroy argv[0])
150*4bcd95a3SBarry Smith  sys.argv = sys.argv[:1] + configure_options + sys.argv[1:]
151*4bcd95a3SBarry Smith  framework = config.framework.Framework(['--configModules='+package+'.Configure', '--optionsModule='+package+'.compilerOptions']+sys.argv[1:], loadArgDB = 0)
152*4bcd95a3SBarry Smith  framework.setup()
153*4bcd95a3SBarry Smith  framework.configure(out = sys.stdout)
154*4bcd95a3SBarry Smith  framework.storeSubstitutions(framework.argDB)
155*4bcd95a3SBarry Smith  framework.printSummary()
156*4bcd95a3SBarry Smith  framework.argDB.save(force = True)
157*4bcd95a3SBarry Smith  framework.logClear()
158*4bcd95a3SBarry Smith  framework.closeLog()
159*4bcd95a3SBarry Smith
160*4bcd95a3SBarry Smithif __name__ == '__main__':
161*4bcd95a3SBarry Smith  configure([])
162*4bcd95a3SBarry Smith```
163*4bcd95a3SBarry Smith
164*4bcd95a3SBarry SmithThe PETSc `configure.py` is quite a bit longer than this, as it
165*4bcd95a3SBarry Smithperforms specialized command line processing, error handling, and
166*4bcd95a3SBarry Smithintegrating logging with the rest of PETSc.
167*4bcd95a3SBarry Smith
168*4bcd95a3SBarry SmithThe `config/package/Configure.py` module determines how the tree of
169*4bcd95a3SBarry Smith`Configure` objects is built and how the configure information is output.
170*4bcd95a3SBarry SmithThe `configure()` method of the module will be run by the `Framework`
171*4bcd95a3SBarry Smithobject created at the top level. A minimal `configure()` method would look
172*4bcd95a3SBarry Smithlike
173*4bcd95a3SBarry Smith
174*4bcd95a3SBarry Smith```python
175*4bcd95a3SBarry Smithdef configure(self):
176*4bcd95a3SBarry Smith  self.framework.header          = self.arch.arch+'/include/'+self.project+'conf.h'
177*4bcd95a3SBarry Smith  self.framework.makeMacroHeader = self.arch.arch+'/conf/'+self.project+'variables'
178*4bcd95a3SBarry Smith  self.framework.makeRuleHeader  = self.arch.arch+'/conf/'+self.project+'rules'
179*4bcd95a3SBarry Smith
180*4bcd95a3SBarry Smith  self.Dump()
181*4bcd95a3SBarry Smith  self.logClear()
182*4bcd95a3SBarry Smith  return
183*4bcd95a3SBarry Smith```
184*4bcd95a3SBarry Smith
185*4bcd95a3SBarry SmithThe `Dump` method runs over the tree of configure modules, and outputs
186*4bcd95a3SBarry Smiththe data necessary for building, usually employing the
187*4bcd95a3SBarry Smith`addMakeMacro()`, `addMakeRule()` and `addDefine()` methods. These
188*4bcd95a3SBarry Smithmethods funnel output to the include and make files defined by the
189*4bcd95a3SBarry Smithframework object, and set at the beginning of this `configure()`
190*4bcd95a3SBarry Smithmethod. There is also some simple information that is often used, which
191*4bcd95a3SBarry Smithwe define in the initializer,
192*4bcd95a3SBarry Smith
193*4bcd95a3SBarry Smith```python
194*4bcd95a3SBarry Smithdef __init__(self, framework):
195*4bcd95a3SBarry Smith  config.base.Configure.__init__(self, framework)
196*4bcd95a3SBarry Smith  self.Project      = 'PETSc'
197*4bcd95a3SBarry Smith  self.project      = self.Project.lower()
198*4bcd95a3SBarry Smith  self.PROJECT      = self.Project.upper()
199*4bcd95a3SBarry Smith  self.headerPrefix = self.PROJECT
200*4bcd95a3SBarry Smith  self.substPrefix  = self.PROJECT
201*4bcd95a3SBarry Smith  self.framework.Project = self.Project
202*4bcd95a3SBarry Smith  return
203*4bcd95a3SBarry Smith```
204*4bcd95a3SBarry Smith
205*4bcd95a3SBarry SmithMore sophisticated configure assemblies, like PETSc, output some other
206*4bcd95a3SBarry Smithcustom information, such as information about the machine, configure
207*4bcd95a3SBarry Smithprocess, and a script to recreate the configure run.
208*4bcd95a3SBarry Smith
209*4bcd95a3SBarry SmithThe `Package` configure module has two other main functions. First, top
210*4bcd95a3SBarry Smithlevel options can be defined in the `setupHelp()` method,
211*4bcd95a3SBarry Smith
212*4bcd95a3SBarry Smith```python
213*4bcd95a3SBarry Smithdef setupHelp(self, help):
214*4bcd95a3SBarry Smith  import nargs
215*4bcd95a3SBarry Smith  help.addArgument(self.Project, '-prefix=<path>', nargs.Arg(None, '', 'Specify location to install '+self.Project+' (eg. /usr/local)'))
216*4bcd95a3SBarry Smith  help.addArgument(self.Project, '-load-path=<path>', nargs.Arg(None, os.path.join(os.getcwd(), 'modules'), 'Specify location of auxiliary modules'))
217*4bcd95a3SBarry Smith  help.addArgument(self.Project, '-with-shared-libraries', nargs.ArgBool(None, 0, 'Make libraries shared'))
218*4bcd95a3SBarry Smith  help.addArgument(self.Project, '-with-dynamic-loading', nargs.ArgBool(None, 0, 'Make libraries dynamic'))
219*4bcd95a3SBarry Smith  return
220*4bcd95a3SBarry Smith```
221*4bcd95a3SBarry Smith
222*4bcd95a3SBarry SmithThis uses the `BuildSystem` help facility that is used to define options
223*4bcd95a3SBarry Smithfor all configure modules. The first argument groups these options into
224*4bcd95a3SBarry Smitha section named for the package. The second task is to build the tree of
225*4bcd95a3SBarry Smithmodules for the configure run, using the `setupDependencies()` method.
226*4bcd95a3SBarry SmithA simple way to do this is by explicitly declaring dependencies,
227*4bcd95a3SBarry Smith
228*4bcd95a3SBarry Smith```python
229*4bcd95a3SBarry Smithdef setupDependencies(self, framework):
230*4bcd95a3SBarry Smith    config.base.Configure.setupDependencies(self, framework)
231*4bcd95a3SBarry Smith    self.setCompilers  = framework.require('config.setCompilers',                self)
232*4bcd95a3SBarry Smith    self.arch          = framework.require(self.Project+'.utilities.arch',       self.setCompilers)
233*4bcd95a3SBarry Smith    self.projectdir    = framework.require(self.Project+'.utilities.projectdir', self.arch)
234*4bcd95a3SBarry Smith    self.compilers     = framework.require('config.compilers',                   self)
235*4bcd95a3SBarry Smith    self.types         = framework.require('config.types',                       self)
236*4bcd95a3SBarry Smith    self.headers       = framework.require('config.headers',                     self)
237*4bcd95a3SBarry Smith    self.functions     = framework.require('config.functions',                   self)
238*4bcd95a3SBarry Smith    self.libraries     = framework.require('config.libraries',                   self)
239*4bcd95a3SBarry Smith
240*4bcd95a3SBarry Smith    self.compilers.headerPrefix  = self.headerPrefix
241*4bcd95a3SBarry Smith    self.types.headerPrefix      = self.headerPrefix
242*4bcd95a3SBarry Smith    self.headers.headerPrefix    = self.headerPrefix
243*4bcd95a3SBarry Smith    self.functions.headerPrefix  = self.headerPrefix
244*4bcd95a3SBarry Smith    self.libraries.headerPrefix  = self.headerPrefix
245*4bcd95a3SBarry Smith```
246*4bcd95a3SBarry Smith
247*4bcd95a3SBarry SmithThe `projectdir` and `arch` modules define the project root
248*4bcd95a3SBarry Smithdirectory and a build name so that multiple independent builds can be
249*4bcd95a3SBarry Smithmanaged. The `Framework.require()` method creates an edge in the
250*4bcd95a3SBarry Smithdependency graph for configure modules, and returns the module object so
251*4bcd95a3SBarry Smiththat it can be queried after the configure information is determined.
252*4bcd95a3SBarry SmithSetting the header prefix routes all the defines made inside those
253*4bcd95a3SBarry Smithmodules to our package configure header. We can also automatically
254*4bcd95a3SBarry Smithcreate configure modules based upon what we see on the filesystem,
255*4bcd95a3SBarry Smith
256*4bcd95a3SBarry Smith```python
257*4bcd95a3SBarry Smithfor utility in os.listdir(os.path.join('config', self.Project, 'utilities')):
258*4bcd95a3SBarry Smith  (utilityName, ext) = os.path.splitext(utility)
259*4bcd95a3SBarry Smith  if not utilityName.startswith('.') and not utilityName.startswith('#') and ext == '.py' and not utilityName == '__init__':
260*4bcd95a3SBarry Smith    utilityObj                    = self.framework.require(self.Project+'.utilities.'+utilityName, self)
261*4bcd95a3SBarry Smith    utilityObj.headerPrefix       = self.headerPrefix
262*4bcd95a3SBarry Smith    utilityObj.archProvider       = self.arch
263*4bcd95a3SBarry Smith    utilityObj.languageProvider   = self.languages
264*4bcd95a3SBarry Smith    utilityObj.precisionProvider  = self.scalartypes
265*4bcd95a3SBarry Smith    utilityObj.installDirProvider = self.installdir
266*4bcd95a3SBarry Smith    utilityObj.externalPackagesDirProvider = self.externalpackagesdir
267*4bcd95a3SBarry Smith    setattr(self, utilityName.lower(), utilityObj)
268*4bcd95a3SBarry Smith```
269*4bcd95a3SBarry Smith
270*4bcd95a3SBarry SmithThe provider modules customize the information given to the module based
271*4bcd95a3SBarry Smithupon settings for our package. For example, PETSc can be compiled with a
272*4bcd95a3SBarry Smithscalar type that is single, double, or quad precision, and thus has a
273*4bcd95a3SBarry Smith`precisionProvider`. If a package does not have this capability, the
274*4bcd95a3SBarry Smithprovider setting can be omitted.
275*4bcd95a3SBarry Smith
276*4bcd95a3SBarry Smith## Main objects
277*4bcd95a3SBarry Smith
278*4bcd95a3SBarry Smith### Framework
279*4bcd95a3SBarry Smith
280*4bcd95a3SBarry SmithThe `config.framework.Framework` object serves as the central control
281*4bcd95a3SBarry Smithfor a configure run. It maintains a graph of all the configure modules
282*4bcd95a3SBarry Smithinvolved, which is also used to track dependencies between them. It
283*4bcd95a3SBarry Smithinitiates the run, compiles the results, and handles the final output.
284*4bcd95a3SBarry SmithIt maintains the help list for all options available in the run. The
285*4bcd95a3SBarry Smith`setup()` method performs generic `Script` setup and then is called
286*4bcd95a3SBarry Smithrecursively on all the child modules. The `cleanup()` method performs
287*4bcd95a3SBarry Smiththe final output and logging actions,
288*4bcd95a3SBarry Smith
289*4bcd95a3SBarry Smith- Substitute files
290*4bcd95a3SBarry Smith- Output configure header
291*4bcd95a3SBarry Smith- Log filesystem actions
292*4bcd95a3SBarry Smith
293*4bcd95a3SBarry SmithChildren may be added to the Framework using `addChild()` or
294*4bcd95a3SBarry Smith`getChild()`, but the far more frequent method is to use
295*4bcd95a3SBarry Smith`require()`. Here a module is requested, as in `getChild()`, but it
296*4bcd95a3SBarry Smithis also required to run before another module, usually the one executing
297*4bcd95a3SBarry Smiththe `require()`. This provides a simple local interface to establish
298*4bcd95a3SBarry Smithdependencies between the child modules, and provides a partial order on
299*4bcd95a3SBarry Smiththe children to the Framework.
300*4bcd95a3SBarry Smith
301*4bcd95a3SBarry SmithA backwards compatibility mode is provided for which the user specifies
302*4bcd95a3SBarry Smitha configure header and set of files to experience substitution,
303*4bcd95a3SBarry Smithmirroring the common usage of Autoconf. Slight improvements have been
304*4bcd95a3SBarry Smithmade in that all defines are now guarded, various prefixes are allowed
305*4bcd95a3SBarry Smithfor defines and substitutions, and C specific constructs such as
306*4bcd95a3SBarry Smithfunction prototypes and typedefs are removed to a separate header.
307*4bcd95a3SBarry SmithHowever, this is not the intended future usage. The use of configure
308*4bcd95a3SBarry Smithmodules by other modules in the same run provides a model for the
309*4bcd95a3SBarry Smithsuggested interaction of a new build system with the Framework. If a
310*4bcd95a3SBarry Smithmodule requires another, it merely executes a `require()`. For
311*4bcd95a3SBarry Smithinstance, the PETSc configure module for hypre requires information
312*4bcd95a3SBarry Smithabout MPI, and thus contains
313*4bcd95a3SBarry Smith
314*4bcd95a3SBarry Smith```python
315*4bcd95a3SBarry Smithself.mpi = self.framework.require("config.packages.MPI", self)
316*4bcd95a3SBarry Smith```
317*4bcd95a3SBarry Smith
318*4bcd95a3SBarry SmithNotice that passing self for the last arguments means that the MPI
319*4bcd95a3SBarry Smithmodule will run before the hypre module. Furthermore, we save the
320*4bcd95a3SBarry Smithresulting object as `self.mpi` so that we may interrogate it later.
321*4bcd95a3SBarry Smithhypre can initially test whether MPI was indeed found using
322*4bcd95a3SBarry Smith`self.mpi.found`. When hypre requires the list of MPI libraries in
323*4bcd95a3SBarry Smithorder to link a test object, the module can use `self.mpi.lib`.
324*4bcd95a3SBarry Smith
325*4bcd95a3SBarry Smith### Base
326*4bcd95a3SBarry Smith
327*4bcd95a3SBarry SmithThe `config.base.Configure` is the base class for all configure
328*4bcd95a3SBarry Smithobjects. It handles several types of interaction. First, it has hooks
329*4bcd95a3SBarry Smiththat allow the Framework to initialize it correctly. The Framework will
330*4bcd95a3SBarry Smithfirst instantiate the object and call `setupDependencies()`. All
331*4bcd95a3SBarry Smith`require()` calls should be made in that method. The Framework will
332*4bcd95a3SBarry Smiththen call `configure()`. If it succeeds, the object will be marked as
333*4bcd95a3SBarry Smithconfigured. Second, all configure tests should be run using
334*4bcd95a3SBarry Smith`executeTest()` which formats the output and adds metadata for the
335*4bcd95a3SBarry Smithlog.
336*4bcd95a3SBarry Smith
337*4bcd95a3SBarry SmithThird, all tests that involve preprocessing, compiling, linking, and
338*4bcd95a3SBarry Smithrunning operator through `base`. Two forms of this check are provided
339*4bcd95a3SBarry Smithfor each operation. The first is an "output" form which is intended to
340*4bcd95a3SBarry Smithprovide the status and complete output of the command. The second, or
341*4bcd95a3SBarry Smith"check" form will return a success or failure indication based upon the
342*4bcd95a3SBarry Smithstatus and output. The routines are
343*4bcd95a3SBarry Smith
344*4bcd95a3SBarry Smith```python
345*4bcd95a3SBarry SmithoutputPreprocess(), checkPreprocess(), preprocess()
346*4bcd95a3SBarry SmithoutputCompile(),    checkCompile()
347*4bcd95a3SBarry SmithoutputLink(),       checkLink()
348*4bcd95a3SBarry SmithoutputRun(),        checkRun()
349*4bcd95a3SBarry Smith```
350*4bcd95a3SBarry Smith
351*4bcd95a3SBarry SmithThe language used for these operation is managed with a stack, similar
352*4bcd95a3SBarry Smithto Autoconf, using `pushLanguage()` and `popLanguage()`. We also
353*4bcd95a3SBarry Smithprovide special forms used to check for valid compiler and linker flags,
354*4bcd95a3SBarry Smithoptionally adding them to the defaults.
355*4bcd95a3SBarry Smith
356*4bcd95a3SBarry Smith```python
357*4bcd95a3SBarry SmithcheckCompilerFlag(), addCompilerFlag()
358*4bcd95a3SBarry SmithcheckLinkerFlag(),   addLinkerFlag()
359*4bcd95a3SBarry Smith```
360*4bcd95a3SBarry Smith
361*4bcd95a3SBarry SmithYou can also use `getExecutable()` to search for executables.
362*4bcd95a3SBarry Smith
363*4bcd95a3SBarry SmithAfter configure tests have been run, various kinds of output can be
364*4bcd95a3SBarry Smithgenerated.A #define statement can be added to the configure header using
365*4bcd95a3SBarry Smith`addDefine()`, and `addTypedef()` and `addPrototype()` also put
366*4bcd95a3SBarry Smithinformation in this header file. Using `addMakeMacro()` and
367*4bcd95a3SBarry Smith`addMakeRule()` will add make macros and rules to the output makefiles
368*4bcd95a3SBarry Smithspecified in the framework. In addition we provide `addSubstitution()`
369*4bcd95a3SBarry Smithand `addArgumentSubstitution()` to mimic the behavior of Autoconf if
370*4bcd95a3SBarry Smithnecessary. The object may define a `headerPrefix` member, which will
371*4bcd95a3SBarry Smithbe appended, followed by an underscore, to every define which is output
372*4bcd95a3SBarry Smithfrom it. Similarly, a `substPrefix` can be defined which applies to
373*4bcd95a3SBarry Smithevery substitution from the object. Typedefs and function prototypes are
374*4bcd95a3SBarry Smithplaced in a separate header in order to accommodate languages such as
375*4bcd95a3SBarry SmithFortran whose preprocessor can sometimes fail at these statements.
376