xref: /petsc/config/BuildSystem/docs/manual.xml (revision bebe2cf65d55febe21a5af8db2bd2e168caaa2e7)
1179860b2SJed Brown<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN">
2179860b2SJed Brown<book id="BuildSystemManual" lang="en">
3179860b2SJed Brown
4179860b2SJed Brown<bookinfo>
5179860b2SJed Brown<title>ASE BuildSystem Manual</title>
6179860b2SJed Brown<authorgroup>
7179860b2SJed Brown<author>
8179860b2SJed Brown<firstname>Matthew</firstname>
9179860b2SJed Brown<othername>G.</othername>
10179860b2SJed Brown<surname>Knepley</surname>
11179860b2SJed Brown</author>
12179860b2SJed Brown</authorgroup>
13179860b2SJed Brown<date>July, 2005</date>
14179860b2SJed Brown<releaseinfo>Release tag ???</releaseinfo>
15179860b2SJed Brown</bookinfo>
16179860b2SJed Brown
17179860b2SJed Brown<chapter id="Introduction">
18179860b2SJed Brown<title>Introduction</title>
19179860b2SJed Brown
20179860b2SJed Brown<para>The BuildSystem from ASE is intended to be a Python replacement for the GNU autotools. It actually encompasses
21179860b2SJed Brownsomewhat more, as it supports integrated version control and automatic code generation. However, the most useful
22179860b2SJed Browncomparisons will come from <command>autoconf</command>, <command>make</command>, and <command>libtool</command>. The
23179860b2SJed Brownsystem is not designed to be monolithic. Thus each component may be used independently, meaning logging, configuration,
24179860b2SJed Brownand build are all separate modules which do not require each other. This allows a user to incremenetally adopt the most
25179860b2SJed Brownuseful portions of the package.</para>
26179860b2SJed Brown
27179860b2SJed Brown</chapter>
28179860b2SJed Brown
29179860b2SJed Brown<chapter id="Configure">
30179860b2SJed Brown<title>Configure</title>
31179860b2SJed Brown
32179860b2SJed Brown<sect1 id="Configure-Design-Sketch">
33179860b2SJed Brown<title>Configure Design Sketch</title>
34179860b2SJed Brown
35179860b2SJed Brown<para>The system is based upon an autonomous unit, objects of class <classname>config.base.Configure</classname>, which
36179860b2SJed Brownare responsible for discovering configuration information for a particular package or purpose. The only interface which
37179860b2SJed Brownmust be supported is the <methodname>configure</methodname> method, as shown below. Support for lower-level operations
38179860b2SJed Brownsuch as compiling and linking will be discussed in section ???.</para>
39179860b2SJed Brown
40179860b2SJed Brown<classsynopsis language="python">
41179860b2SJed Brown<ooclass>
42179860b2SJed Brown<classname>Configure</classname>
43179860b2SJed Brown</ooclass>
44179860b2SJed Brown<methodsynopsis>
45179860b2SJed Brown<void/><methodname>configure</methodname><methodparam><parameter>self</parameter></methodparam>
46179860b2SJed Brown</methodsynopsis>
47179860b2SJed Brown</classsynopsis>
48179860b2SJed Brown
49179860b2SJed Brown<para>This collection of configure objects is managed by a <classname>config.base.Framework</classname> object. As we
50179860b2SJed Brownwill see in section ???, the framework manages all dependecies between modules and output of configure information. The
51179860b2SJed Brownframework is itself a subclass of <classname>config.base.Configure</classname> for which the
52179860b2SJed Brown<methodname>configure</methodname> method manages the entire configuration process. In order to associate a module with
53179860b2SJed Brownthe given framework, it also provides the <methodname>require</methodname> method, discussed in section ???. Thus, the
54179860b2SJed Brownminimal framework interface is given by:</para>
55179860b2SJed Brown
56179860b2SJed Brown<classsynopsis language="python">
57179860b2SJed Brown<ooclass>
58179860b2SJed Brown<classname>Framework</classname>
59179860b2SJed Brown</ooclass>
60179860b2SJed Brown<ooclass>
61179860b2SJed Brown<classname>config.base.Configure</classname>
62179860b2SJed Brown</ooclass>
63179860b2SJed Brown<methodsynopsis>
64179860b2SJed Brown<void/><methodname>require</methodname>
65179860b2SJed Brown  <methodparam><parameter>self</parameter></methodparam>
66179860b2SJed Brown  <methodparam><parameter>moduleName</parameter></methodparam>
67179860b2SJed Brown  <methodparam><parameter>depChild</parameter></methodparam>
68179860b2SJed Brown  <methodparam><parameter>keywordArgs</parameter><initializer>{}</initializer></methodparam>
69179860b2SJed Brown</methodsynopsis>
70179860b2SJed Brown<methodsynopsis>
71179860b2SJed Brown<void/><methodname>configure</methodname><methodparam><parameter>self</parameter></methodparam>
72179860b2SJed Brown</methodsynopsis>
73179860b2SJed Brown</classsynopsis>
74179860b2SJed Brown
75179860b2SJed Brown<para>This design allows user modules to be seamlessly integrated into the framework without changing the paradigm, or
76179860b2SJed Browneven any of the original code. Modules can be specified on the command line, or left in special directories. Although it
77179860b2SJed Brownis common to derive from <classname>config.base.Configure</classname>, the only necessity is that the user provide a
78179860b2SJed Brown<methodname>configure</methodname> method for the framework to execute.</para>
79179860b2SJed Brown
80179860b2SJed Brown<para>The framework does provide the traditional output mechanisms from <command>autoconf</command>, namely
81179860b2SJed Brown<methodname>#define</methodname> statements and file substitutions, to which we add make variables and
82179860b2SJed Brownrules. However, the preferred interaction mechanism is to use member variables directly from the configure objects. This
83179860b2SJed Brownis illustrated in section ???</para>
84179860b2SJed Brown
85179860b2SJed Brown</sect1>
86179860b2SJed Brown
87179860b2SJed Brown<sect1 id="Running-configure">
88179860b2SJed Brown<title>Running configure</title>
89179860b2SJed Brown
90179860b2SJed Brown<para>The first step in running configure is to show the help:
91179860b2SJed Brown<screen>
92179860b2SJed Brown<prompt>bash$</prompt> <command>framework.py -help</command>
93179860b2SJed Brown<computeroutput>
94179860b2SJed BrownPython Configure Help
95*bebe2cf6SSatish Balay   Comma separated lists should be given between [] (use \[ \] in tcsh/csh)
96179860b2SJed Brown    For example: --with-mpi-lib=\[/usr/local/lib/libmpich.a,/usr/local/lib/libpmpich.a\]
97179860b2SJed Brown----------------------------------------------------------------------------------------
98179860b2SJed BrownScript:
99179860b2SJed Brown  --help                : Print this help message                                         current: 1
100179860b2SJed Brown  --h                   : Print this help message                                         current: 0
101179860b2SJed BrownFramework:
102179860b2SJed Brown  --configModules       : A list of Python modules with a Configure class                 current: []
103179860b2SJed Brown  --ignoreCompileOutput : Ignore compiler output                                          current: 1
104179860b2SJed Brown  --ignoreLinkOutput    : Ignore linker output                                            current: 1
105179860b2SJed Brown  --ignoreWarnings      : Ignore compiler and linker warnings                             current: 0
106179860b2SJed Brown  --doCleanup           : Delete any configure generated files (turn off for debugging)   current: 1
107179860b2SJed Brown  --with-alternatives   : Provide a choice among alternative package installations        current: 0
108179860b2SJed Brown  --search-dirs         : A list of directories used to search for executables            current: []
109179860b2SJed Brown  --package-dirs        : A list of directories used to search for packages               current: []
110179860b2SJed Brown  --with-batch          : Machine uses a batch system to submit jobs                      current: 0
111179860b2SJed Brown</computeroutput>
112179860b2SJed Brown</screen>
113179860b2SJed BrownThe options shown will depend upon the modules loaded with <option>-configModules</option>. For instance, we will
114179860b2SJed Brownnormally load the compiler module, which reveals the host of optios controlling preprocessors, compilers, and linkers.
115179860b2SJed Brown<screen>
116179860b2SJed Brown<prompt>bash$</prompt> <command>framework.py -configModules=[config.compilers] -help</command>
117179860b2SJed Brown<computeroutput>
118179860b2SJed BrownPython Configure Help
119*bebe2cf6SSatish Balay   Comma separated lists should be given between [] (use \[ \] in tcsh/csh)
120179860b2SJed Brown    For example: --with-mpi-lib=\[/usr/local/lib/libmpich.a,/usr/local/lib/libpmpich.a\]
121179860b2SJed Brown----------------------------------------------------------------------------------------
122179860b2SJed BrownScript:
123179860b2SJed Brown  --help                           : Print this help message                                               current: 1
124179860b2SJed Brown  --h                              : Print this help message                                               current: 0
125179860b2SJed BrownFramework:
126179860b2SJed Brown  --configModules                  : A list of Python modules with a Configure class                       current: []
127179860b2SJed Brown  --ignoreCompileOutput            : Ignore compiler output                                                current: 1
128179860b2SJed Brown  --ignoreLinkOutput               : Ignore linker output                                                  current: 1
129179860b2SJed Brown  --ignoreWarnings                 : Ignore compiler and linker warnings                                   current: 0
130179860b2SJed Brown  --doCleanup                      : Delete any configure generated files (turn off for debugging)         current: 1
131179860b2SJed Brown  --with-alternatives              : Provide a choice among alternative package installations              current: 0
132179860b2SJed Brown  --search-dirs                    : A list of directories used to search for executables                  current: []
133179860b2SJed Brown  --package-dirs                   : A list of directories used to search for packages                     current: []
134179860b2SJed Brown  --with-batch                     : Machine uses a batch system to submit jobs                            current: 0
135179860b2SJed BrownCompilers:
136179860b2SJed Brown  --with-cpp=&lt;prog&gt;                : Specify the C preprocessor
137179860b2SJed Brown  --with-cc=&lt;prog&gt;                 : Specify the C compiler
138179860b2SJed Brown  --with-cxx=&lt;prog&gt;                : Specify the C++ compiler
139179860b2SJed Brown  --with-fc=&lt;prog&gt;                 : Specify the Fortran compiler
140179860b2SJed Brown  --with-gnu-compilers=&lt;bool&gt;      : Try to use GNU compilers                                              current: 1
141179860b2SJed Brown  --with-vendor-compilers=&lt;vendor&gt; : Try to use vendor compilers (no argument all vendors, 0 no vendors)   current:
142179860b2SJed Brown  --with-64-bit-pointers=&lt;bool&gt;    : Use 64 bit compilers and libraries                                    current: 0
143179860b2SJed Brown  --CPP=&lt;prog&gt;                     : Specify the C preprocessor
144179860b2SJed Brown  --CPPFLAGS=&lt;string&gt;              : Specify the C preprocessor options                                    current:
145179860b2SJed Brown  --CXXPP=&lt;prog&gt;                   : Specify the C++ preprocessor
146179860b2SJed Brown  --CC=&lt;prog&gt;                      : Specify the C compiler
147179860b2SJed Brown  --CFLAGS=&lt;string&gt;                : Specify the C compiler options                                        current:
148179860b2SJed Brown  --CXX=&lt;prog&gt;                     : Specify the C++ compiler
149179860b2SJed Brown  --CXXFLAGS=&lt;string&gt;              : Specify the C++ compiler options                                      current:
150179860b2SJed Brown  --CXX_CXXFLAGS=&lt;string&gt;          : Specify the C++ compiler-only options                                 current:
151179860b2SJed Brown  --FC=&lt;prog&gt;                      : Specify the Fortran compiler
152179860b2SJed Brown  --FFLAGS=&lt;string&gt;                : Specify the Fortran compiler options                                  current:
153179860b2SJed Brown  --LD=&lt;prog&gt;                      : Specify the default linker
154179860b2SJed Brown  --CC_LD=&lt;prog&gt;                   : Specify the linker for C only
155179860b2SJed Brown  --CXX_LD=&lt;prog&gt;                  : Specify the linker for C++ only
156179860b2SJed Brown  --FC_LD=&lt;prog&gt;                   : Specify the linker for Fortran only
157179860b2SJed Brown  --LDFLAGS=&lt;string&gt;               : Specify the linker options                                            current:
158179860b2SJed Brown  --with-ar                        : Specify the archiver
159179860b2SJed Brown  -AR                              : Specify the archiver flags
160179860b2SJed Brown  -AR_FLAGS                        : Specify the archiver flags
161179860b2SJed Brown  --with-ranlib                    : Specify ranlib
162179860b2SJed Brown  --with-shared-libraries                : Enable shared libraries                                               current: 1
163179860b2SJed Brown  --with-shared-ld=&lt;prog&gt;          : Specify the shared linker
164179860b2SJed Brown  --with-f90-header=&lt;file&gt;         : Specify the C header for the F90 interface, e.g. f90_intel.h
165179860b2SJed Brown  --with-f90-source=&lt;file&gt;         : Specify the C source for the F90 interface, e.g. f90_intel.c
166179860b2SJed Brown</computeroutput>
167179860b2SJed Brown</screen>
168179860b2SJed BrownThe syntax for list and dictionary option values is identical to Python syntax. However, in some shells (like
169179860b2SJed Brown<command>csh</command>), brackets must be escaped, and braces will usually have to be enclosed in quotes.</para>
170179860b2SJed Brown
171179860b2SJed Brown<para>The modules indicated with <option>-configModules</option> are located using <envar>PYTHONPATH</envar>. Since
172179860b2SJed Brownspecifying environment variables can be inconvenient and error prone, it is common to provide a driver which alters
173179860b2SJed Brown<varname>sys.path</varname>, as is done for PETSc. In fact, the PETSc driver
174179860b2SJed Brown<itemizedlist>
175179860b2SJed Brown  <listitem><para>Verifies <envar>PETSC_ARCH</envar></para></listitem>
176179860b2SJed Brown  <listitem><para>Checks for invalid Cygwin versions</para></listitem>
177179860b2SJed Brown  <listitem><para>Checks for RedHat 9, which has a threads bug</para></listitem>
178179860b2SJed Brown  <listitem><para>Augments <envar>PYTHONPATH</envar></para></listitem>
179179860b2SJed Brown  <listitem><para>Adds the default PETSc configure module</para></listitem>
180179860b2SJed Brown  <listitem><para>Persists the configuration in <filename>RDict.db</filename></para></listitem>
181179860b2SJed Brown  <listitem><para>Handles exceptions</para></listitem>
182179860b2SJed Brown</itemizedlist>
183179860b2SJed Brown</para>
184179860b2SJed Brown
185179860b2SJed Brown</sect1>
186179860b2SJed Brown
187179860b2SJed Brown<sect1 id="Adding-a-module">
188179860b2SJed Brown<title>Adding a module</title>
189179860b2SJed Brown
190179860b2SJed Brown<para>As we discussed in the introduction, all that is strictly necessary for a configure module, is to provide a class
191179860b2SJed Brownnamed <classname>Configure</classname> with a method <methodname>configure</methodname> taking no arguments. However,
192179860b2SJed Brownthere are a variety of common operations, which will be illustrated in the sections below.</para>
193179860b2SJed Brown
194179860b2SJed Brown  <sect2 id="Using-other-modules">
195179860b2SJed Brown  <title>Using other modules</title>
196179860b2SJed Brown
197179860b2SJed Brown  <para>We will often want to use the methods or results of other configure modules in order to perform checks in our
198179860b2SJed Brownown. The framework provides a mechanism for retrieving the object for any given configure module. As an example,
199179860b2SJed Brownconsider checking for the <methodname>ddot</methodname> function in the BLAS library. The relevant Python code would
200179860b2SJed Brownbe
201179860b2SJed Brown<programlisting>
202179860b2SJed Brownimport config.base
203179860b2SJed Brown
204179860b2SJed Brownclass Configure(config.base.Configure):
205179860b2SJed Brown  def __init__(self, framework):
206179860b2SJed Brown    config.base.Configure.__init__(self, framework)
207179860b2SJed Brown    self.compilers = self.framework.require('config.compilers', self)
208179860b2SJed Brown    self.libraries = self.framework.require('config.libraries', self)
209179860b2SJed Brown    return
210179860b2SJed Brown
211179860b2SJed Brown  def configure(self):
212179860b2SJed Brown    return self.libraries.check('libblas.a', 'ddot', otherLibs = self.compilers.flibs,
213179860b2SJed Brown                                fortranMangle = 1)
214179860b2SJed Brown</programlisting>
215179860b2SJed BrownThe <methodname>require</methodname> call will return the configure object from the given module, creating it if
216179860b2SJed Brownnecessary. If the second argument is given, the framework will ensure that the returned configure object runs
217179860b2SJed Brown<emphasis>before</emphasis> the passed configure object. Notice that we can use the returned object either to call
218179860b2SJed Brownmethods, like <methodname>check</methodname> from <classname>config.libraries</classname>, or use member variables, such
219179860b2SJed Brownas the list of Fortran compatibility libraries <methodname>flibs</methodname> from
220179860b2SJed Brown<classname>config.compilers</classname>.
221179860b2SJed Brown</para>
222179860b2SJed Brown
223179860b2SJed Brown<para>The underlying implementation in the framework uses a directed acyclic graph to indicate dependencies among
224179860b2SJed Brownmodules. The vertices of this graph, configure objects, are topologically sorted and then executed. Moreover, child
225179860b2SJed Brownobjects can be added to the framework without respecting the dependency structure, but this is discouraged.</para>
226179860b2SJed Brown
227179860b2SJed Brown  </sect2>
228179860b2SJed Brown
229179860b2SJed Brown  <sect2 id="Adding-a-test">
230179860b2SJed Brown  <title>Adding a test</title>
231179860b2SJed Brown
232179860b2SJed Brown  <para>A user could of course perform all tests in the object's <methodname>configure</methodname> method, but the base
233179860b2SJed Brownclass provides useful logging support for this purpose. Consider again the BLAS example, which will now become,
234179860b2SJed Brown<programlisting>
235179860b2SJed Brown  def checkDot(self):
236179860b2SJed Brown    '''Verify that the ddot() function is contained in the BLAS library'''
237179860b2SJed Brown    return self.libraries.check('libblas.a', 'ddot', otherLibs = self.compilers.flibs,
238179860b2SJed Brown                                fortranMangle = 1)
239179860b2SJed Brown
240179860b2SJed Brown  def configure(self):
241179860b2SJed Brown    self.executeTest(self.checkDot)
242179860b2SJed Brown    return
243179860b2SJed Brown</programlisting>
244179860b2SJed BrownPassing our test module to the framework,
245179860b2SJed Brown<screen>
246179860b2SJed Brown<prompt>docs$</prompt> <command>PYTHONPATH=`pwd` ../config/framework.py --configModules=[examples.blasTest]</command>
247179860b2SJed Brown</screen>
248179860b2SJed Brownwe produce the following log output in <filename>configure.log</filename>. Notice that it not only records the method and module, but the method doc string,
249179860b2SJed Brownall shell calls, and any output actions as well.</para>
250179860b2SJed Brown<screen>
251179860b2SJed Brown<computeroutput>
252179860b2SJed Brown================================================================================
253179860b2SJed BrownTEST checkDot from examples.blasTest(/PETSc3/sidl/BuildSystem/docs/examples/blasTest.py:10)
254179860b2SJed BrownTESTING: checkDot from examples.blasTest(/PETSc3/sidl/BuildSystem/docs/examples/blasTest.py:10)
255179860b2SJed Brown  Verify that the ddot() function is contained in the BLAS library
256179860b2SJed Brown      Checking for functions ['ddot'] in library ['libblas.a'] ['-lfrtbegin', '-lg2c', '-lm',
257179860b2SJed Brown       '-L/usr/lib/gcc-lib/i486-linux/3.3.5', '-L/usr/lib/gcc-lib/i486-linux/3.3.5/../../..',
258179860b2SJed Brown       '-lm', '-lgcc_s']
259179860b2SJed Brownsh: gcc -c -o conftest.o  -fPIC  conftest.c
260179860b2SJed BrownExecuting: gcc -c -o conftest.o  -fPIC  conftest.c
261179860b2SJed Brownsh:
262179860b2SJed Brownsh: gcc  -o conftest   -fPIC  conftest.o  -lblas -lfrtbegin -lg2c -lm
263179860b2SJed Brown  -L/usr/lib/gcc-lib/i486-linux/3.3.5 -L/usr/lib/gcc-lib/i486-linux/3.3.5/../../.. -lm -lgcc_s
264179860b2SJed BrownExecuting: gcc  -o conftest   -fPIC  conftest.o  -lblas -lfrtbegin -lg2c -lm
265179860b2SJed Brown  -L/usr/lib/gcc-lib/i486-linux/3.3.5 -L/usr/lib/gcc-lib/i486-linux/3.3.5/../../.. -lm -lgcc_s
266179860b2SJed Brownsh:
267179860b2SJed BrownDefined HAVE_LIBBLAS to 1 in config.libraries
268179860b2SJed Brown</computeroutput>
269179860b2SJed Brown</screen>
270179860b2SJed Brown
271179860b2SJed Brown  </sect2>
272179860b2SJed Brown
273179860b2SJed Brown  <sect2 id="Checking-for-headers">
274179860b2SJed Brown  <title>Checking for headers</title>
275179860b2SJed Brown
276179860b2SJed Brown  <para>Often, we would like to test for the presence of certain headers. This is done is a completely analogous way to
277179860b2SJed Brownthe library case, using instead the <classname>config.headers</classname> module. Below, we test for the presence of the
278179860b2SJed Brown<command>curses</command> header.
279179860b2SJed Brown<programlisting>
280179860b2SJed Brownimport config.base
281179860b2SJed Brown
282179860b2SJed Brownclass Configure(config.base.Configure):
283179860b2SJed Brown  def __init__(self, framework):
284179860b2SJed Brown    config.base.Configure.__init__(self, framework)
285179860b2SJed Brown    self.headers = self.framework.require('config.headers, self)
286179860b2SJed Brown    return
287179860b2SJed Brown
288179860b2SJed Brown  def checkCurses(self):
289179860b2SJed Brown    'Verify that we have the curses header'
290179860b2SJed Brown    return self.headers.check('curses.h')
291179860b2SJed Brown
292179860b2SJed Brown  def configure(self):
293179860b2SJed Brown    self.executeTest(self.checkCurses)
294179860b2SJed Brown    return
295179860b2SJed Brown</programlisting>
296179860b2SJed BrownRunning this test
297179860b2SJed Brown<screen>
298179860b2SJed Brown<prompt>docs$</prompt> <command>PYTHONPATH=`pwd` ../config/framework.py --configModules=[examples.cursesTest]</command>
299179860b2SJed Brown</screen>
300179860b2SJed Brownproduces the following log output.</para>
301179860b2SJed Brown<screen>
302179860b2SJed Brown<computeroutput>
303179860b2SJed Brown================================================================================
304179860b2SJed BrownTEST checkCurses from examples.cursesTest(/PETSc3/sidl/BuildSystem/docs/examples/cursesTest.py:9)
305179860b2SJed BrownTESTING: checkCurses from examples.cursesTest(/PETSc3/sidl/BuildSystem/docs/examples/cursesTest.py:9)
306179860b2SJed Brown  Verify that we have the curses header
307179860b2SJed BrownChecking for header: curses.h
308179860b2SJed Brownsh: gcc -E   conftest.c
309179860b2SJed BrownExecuting: gcc -E   conftest.c
310179860b2SJed Brownsh: # 1 "conftest.c"
311179860b2SJed Brown# 1 "&lt;built-in&gt;"
312179860b2SJed Brown# 1 "&lt;command line&gt;"
313179860b2SJed Brown# 1 "conftest.c"
314179860b2SJed Brown# 1 "confdefs.h" 1
315179860b2SJed Brown# 2 "conftest.c" 2
316179860b2SJed Brown# 1 "conffix.h" 1
317179860b2SJed Brown# 3 "conftest.c" 2
318179860b2SJed Brown# 1 "/usr/include/curses.h" 1 3 4
319179860b2SJed Brown# 58 "/usr/include/curses.h" 3 4
320179860b2SJed Brown# 1 "/usr/include/ncurses_dll.h" 1 3 4
321179860b2SJed Brown# 59 "/usr/include/curses.h" 2 3 4
322179860b2SJed Brown# 99 "/usr/include/curses.h" 3 4
323179860b2SJed Browntypedef unsigned long chtype;
324179860b2SJed Brown# 1 "/usr/include/stdio.h" 1 3 4
325179860b2SJed Brown# 28 "/usr/include/stdio.h" 3 4
326179860b2SJed Brown# 1 "/usr/include/features.h" 1 3 4
327179860b2SJed Brown# 295 "/usr/include/features.h" 3 4
328179860b2SJed Brown# 1 "/usr/include/sys/cdefs.h" 1 3 4
329179860b2SJed Brown# 296 "/usr/include/features.h" 2 3 4
330179860b2SJed Brown# 318 "/usr/include/features.h" 3 4
331179860b2SJed Brown#...
332179860b2SJed Brown... W* win,int* y, int* x, _Bool to_screen);
333179860b2SJed Brownextern _Bool mouse_trafo (int*, int*, _Bool);
334179860b2SJed Brownextern int mcprint (char *, int);
335179860b2SJed Brownextern int has_key (int);
336179860b2SJed Brownextern void _tracef (const char *, ...) ;
337179860b2SJed Brownextern void _tracedump (const char *, WINDOW *);
338179860b2SJed Brownextern char * _traceattr (attr_t);
339179860b2SJed Brownextern char * _traceattr2 (int, chtype);
340179860b2SJed Brownextern char * _nc_tracebits (void);
341179860b2SJed Brownextern char * _tracechar (int);
342179860b2SJed Brownextern char * _tracechtype (chtype);
343179860b2SJed Brownextern char * _tracechtype2 (int, chtype);
344179860b2SJed Brown# 1203 "/usr/include/curses.h" 3 4
345179860b2SJed Brownextern char * _tracemouse (const MEVENT *);
346179860b2SJed Brownextern void trace (const unsigned int);
347179860b2SJed Brown# 4 "conftest.c" 2
348179860b2SJed Brown
349179860b2SJed BrownDefined HAVE_CURSES_H to 1 in config.headers
350179860b2SJed Brown</computeroutput>
351179860b2SJed Brown</screen>
352179860b2SJed Brown
353179860b2SJed Brown<para>Alternatively, we could have specified that this header be included in the list of header files checked by default.</para>
354179860b2SJed Brown<programlisting>
355179860b2SJed Brownimport config.base
356179860b2SJed Brown
357179860b2SJed Brownclass Configure(config.base.Configure):
358179860b2SJed Brown  def __init__(self, framework):
359179860b2SJed Brown    config.base.Configure.__init__(self, framework)
360179860b2SJed Brown    self.headers = self.framework.require('config.headers, self)
361179860b2SJed Brown    self.headers.headers.append('curses.h')
362179860b2SJed Brown    return
363179860b2SJed Brown
364179860b2SJed Brown  def checkCurses(self):
365179860b2SJed Brown    'Verify that we have the curses header'
366179860b2SJed Brown    return self.headers.haveHeader('curses.h')
367179860b2SJed Brown
368179860b2SJed Brown  def configure(self):
369179860b2SJed Brown    self.executeTest(self.checkCurses)
370179860b2SJed Brown    return
371179860b2SJed Brown</programlisting>
372179860b2SJed Brown
373179860b2SJed Brown<para>In addition, the base class does include lower level support for preprocessing files. The
374179860b2SJed Brown<methodname>preprocess</methodname> method takes a code string as input and return a tuple of the
375179860b2SJed Brown<command>(stdout,stderr,error code)</command> for the run. The <methodname>outputPreprocess</methodname> method returns
376179860b2SJed Brownonly the standard output, and <methodname>checkPreprocess</methodname> returns true if no error occurs.</para>
377179860b2SJed Brown
378179860b2SJed Brown  </sect2>
379179860b2SJed Brown
380179860b2SJed Brown  <sect2 id="Checking-for-libraries">
381179860b2SJed Brown  <title>Checking for libraries</title>
382179860b2SJed Brown
383179860b2SJed Brown  <para>We have already demonstrated a test for the existence of a function in a library. However the
384179860b2SJed Brown<methodname>check</methodname> method is much more general. It allows the specification of multiple libraries and
385179860b2SJed Brownmultiple functions, as well as auxiliary libraries. For instance, to check for the <methodname>MPI_Init</methodname> and
386179860b2SJed Brown<methodname>MPI_Comm_create</methodname> functions in MPICH when the Fortran bindings are active, we would use:
387179860b2SJed Brown<programlisting>
388179860b2SJed Brown  self.libraries.check(['libmpich.so', 'libpmpich.so'], ['MPI_Init', 'MPI_Comm_create'],
389179860b2SJed Brown                       otherLibs = self.compilers.flibs)
390179860b2SJed Brown</programlisting>
391179860b2SJed BrownAs in the BLAS example, we can also turn on Fortran name mangling. The caller may also supply a function prototype and
392179860b2SJed Browncalling sequence, which are necessary if the current language is C++.
393179860b2SJed Brown</para>
394179860b2SJed Brown
395179860b2SJed Brown<para>It is also necessary at some times to determine whether a given library is a shared object. This can be
396179860b2SJed Brownaccomplished using the <methodname>checkShared</methodname> method, as we demonstrate with the MPICH library in a call
397179860b2SJed Browntaken from the MPI configure module in PETSc.
398179860b2SJed Brown<programlisting>
399179860b2SJed Brown  self.libraries.checkShared('#include &lt;mpi.h&gt;\n', 'MPI_Init', 'MPI_Initialized',
400179860b2SJed Brown                             'MPI_Finalize', checkLink = self.checkMPILink,
401179860b2SJed Brown                             libraries = self.lib)
402179860b2SJed Brown</programlisting>
403179860b2SJed BrownThe theory for the check is that a shared object will have only one copy of any global variable. Thus functions such as
404179860b2SJed Brown<methodname>MPI_Initialized</methodname> will render consistent results across other libraries. The test begins by
405179860b2SJed Browncreating two dynamic libraries, both of which link the given library. Then an executable is constructed which loads the
406179860b2SJed Brownlibraries in turn. The first library calls the initizlization functions, here <methodname>MPI_Init</methodname>, and the
407179860b2SJed Brownsecond library calls the initialization check function, here <methodname>MPI_Initialized</methodname>. The check
408179860b2SJed Brownfunction will return true if the given library is a shared object. This organization is shown in figure ???</para>
409179860b2SJed Brown<para>
410179860b2SJed Brown<inlinemediaobject>
411179860b2SJed Brown<imageobject><imagedata fileref="sharedLibraryCheck" format="EPS"/></imageobject>
412179860b2SJed Brown<imageobject><imagedata fileref="sharedLibraryCheck" format="JPG"/></imageobject>
413179860b2SJed Brown<!-- <textobject><phrase>A diagram of the link structure for the shared library test</phrase></textobject> -->
414179860b2SJed Brown</inlinemediaobject>
415179860b2SJed Brown</para>
416179860b2SJed Brown
417179860b2SJed Brown  <para>The lower level interface to compiling and linking in the base class mirrors that for preprocessing. The
418179860b2SJed Brown<methodname>outputCompile</methodname> and <methodname>checkCompile</methodname> methods function in the same way. The
419179860b2SJed Browncode is now broken up into four distinct sections. There are includes, the body of <methodname>main</methodname>, and a
420179860b2SJed Brownpossible replacement for the beginning and end of the <methodname>main</methodname> declaration. The linking methods,
421179860b2SJed Brown<methodname>outputLink</methodname> and <methodname>checkLink</methodname>, are exactly analogous.</para>
422179860b2SJed Brown
423179860b2SJed Brown  <para>There are also some convenience methods provided to handle compiler and linker flags. The
424179860b2SJed Brown<methodname>checkCompilerFlag</methodname> and <methodname>checkLinkerFlag</methodname> try to determine whether a given
425179860b2SJed Brownflag is accepted by the processor, while <methodname>addCompilerFlag</methodname> and
426179860b2SJed Brown<methodname>addLinkerFlag</methodname> will do that check and add any valid flag to the list of default flags.</para>
427179860b2SJed Brown
428179860b2SJed Brown  </sect2>
429179860b2SJed Brown
430179860b2SJed Brown  <sect2 id="Checking-for-executables">
431179860b2SJed Brown  <title>Checking for executables</title>
432179860b2SJed Brown
433179860b2SJed Brown  <para>The <methodname>getExecutable</methodname> method is used to locate executable files. For instance, this code
434179860b2SJed Brownwould allow us to locate the <command>valgrind</command> binary.
435179860b2SJed Brown<programlisting>
436179860b2SJed Brown  self.getExecutable('valgrind')
437179860b2SJed Brown</programlisting>
438179860b2SJed BrownIf the program is found, a member variable of the same name will be set in the object to the program name, and a make
439179860b2SJed Brownmacro defined to it as well. We can opt for these to contain the full path by using the <option>getFullPath</option>
440179860b2SJed Brownargument. In addition, we can change the name of the member variable and macro using the <option>resultName</option>
441179860b2SJed Brownargument.
442179860b2SJed Brown</para>
443179860b2SJed Brown
444179860b2SJed Brown<para>We also have control over the search path used. If we give no arguments, the default path from the environment is
445179860b2SJed Brownused. This can be overridden with a new path using the <option>path</option> argument, either as a Python list or a
446179860b2SJed Browncolon separated string. Furthermore, the default path can be added to this custom path using the
447179860b2SJed Brown<option>useDefaultPath</option> argument. For instance, this call
448179860b2SJed Brown<programlisting>
449179860b2SJed Brown  self.getExecutable('valgrind', path=['/opt/valgrind-1.0'], getFullPath=1,
450179860b2SJed Brown                     useDefaultPath=1, resultName='grinder')
451179860b2SJed Brown</programlisting>
452179860b2SJed Brownwill check for <command>valgrind</command> first in <filename>/opt/valgrind-1.0</filename> and then along the default
453179860b2SJed Brownpath. If found in the first location, it will set <varname>self.grinder</varname> to
454179860b2SJed Brown<filename>/opt/valgrind-1.0/valgrind</filename> as well as define <envar>GRINDER</envar> to the same value in makefiles.
455179860b2SJed Brown</para>
456179860b2SJed Brown
457179860b2SJed Brown  <para>As in the cases of preprocessing, compiling, and linking, the lower level operations are also exposed. The
458179860b2SJed Brown<methodname>checkRun</methodname> method takes in a code string and returns true if the executable runs without
459179860b2SJed Brownerror. The <methodname>outputRun</methodname> method returns the output and status code. Both methods us the safe
460179860b2SJed Brownexecution routine <methodname>config.base.Configure.executeShellCommand</methodname> which accepts a timeout. Moreover,
461179860b2SJed Brownthere commands can run in the special batch mode described in section ???.</para>
462179860b2SJed Brown
463179860b2SJed Brown  </sect2>
464179860b2SJed Brown
465179860b2SJed Brown  <sect2 id="Output-results">
466179860b2SJed Brown  <title>Output results</title>
467179860b2SJed Brown
468179860b2SJed Brown  <para>The BuildSystem configure includes the traditional output methods employed by <command>autoconf</command> to
469179860b2SJed Brownenable communication with <command>make</command>. Individual configure modules use the
470179860b2SJed Brown<methodname>addDefine</methodname> method to add C <methodname>#define</methodname> statements to a configuration header
471179860b2SJed Brownand the <methodname>addSubstitution</methodname> to setup substitution rules for specified files. For instance, to
47215ac2963SJed Brownactivate the parmetis package, we might provide
473179860b2SJed Brown<programlisting>
474179860b2SJed Brown  self.addDefine('HAVE_PARMETIS', 1)
475179860b2SJed Brown</programlisting>
476179860b2SJed Brownand then for the make process
477179860b2SJed Brown<programlisting>
478179860b2SJed Brown  self.addSubstitution('PARMETIS_INCLUDE', ' '.join([self.libraries.getIncludeArgument(i)
479179860b2SJed Brown                                                     for i in self.include]))
480179860b2SJed Brown  self.addSubstitution('PARMETIS_LIB, ' '.join([self.libraries.getLibArgument(l)
481179860b2SJed Brown                                                for l in self.lib]))
482179860b2SJed Brown</programlisting>
483179860b2SJed Brown</para>
484179860b2SJed Brown
485179860b2SJed Brown<para>The actual output of this data is controlled by the framework. The user specifies the header file using the
486179860b2SJed Brown<varname>header</varname> field of the framework, and then the file is created automatically during the configure
487179860b2SJed Brownprocess, but can be output at any time using the <methodname>outputHeader</methodname> method. Furthermore, the
488179860b2SJed Brown<methodname>addSubstitutionFile</methodname> method can be used to tag a file for substitution, and also specify a
489179860b2SJed Browndifferent file for the result of the substitution.</para>
490179860b2SJed Brown
491179860b2SJed Brown<para>In the <command>autoconf</command> approach, separating the the defines and substitutions for different packages
492179860b2SJed Brownbecomes troublesome, and in some cases impossible to maintain. To help with this, we have introduced
493179860b2SJed Brown<emphasis>prefixes</emphasis> for the defines and substitutions. The are strings, unique to each module, which are
494179860b2SJed Brownprepended with an underscore to each identifier defined or substituted. These are set on a per object basis using the
495179860b2SJed Brown<varname>headerPrefix</varname> and <varname>substPrefix</varname> members. For instance, in our
49615ac2963SJed Brownparmetis example, if we instead used the code
497179860b2SJed Brown<programlisting>
498179860b2SJed Brown  self.headerPrefix = 'MATT'
499179860b2SJed Brown  self.addDefine('HAVE_PARMETIS', 1)
500179860b2SJed Brown</programlisting>
501179860b2SJed Brownin our configuration header we would see
502179860b2SJed Brown<programlisting>
503179860b2SJed Brown  #ifndef MATT_HAVE_PARMETIS
504179860b2SJed Brown  #define MATT_HAVE_PARMETIS 1
505179860b2SJed Brown  #endif
506179860b2SJed Brown</programlisting>
507179860b2SJed BrownNote that the value of the prefix is used at output time, not at the time that the define or substitution is set.
508179860b2SJed Brown</para>
509179860b2SJed Brown
510179860b2SJed Brown<para>Another extension of the old-style output mechanisms adds more C structure to the interface. The
511179860b2SJed Brown<methodname>addTypedef</methodname> method allows a typedef from one typename to another, which in
512179860b2SJed Brown<command>autoconf</command> is handled by a define. Likewise <methodname>addPrototype</methodname> can add a missing
513179860b2SJed Brownfunction prototype to a header. Since these are C specific structures, they are output into a separate configuration
514179860b2SJed Brownheader file, which is controlled by the <varname>cHeader</varname> member variable.</para>
515179860b2SJed Brown
516179860b2SJed Brown<para>Extending in a different direction, we allow makefile structures to be specified directly rather than through
517179860b2SJed Brownsubstitutions. Using <methodname>addMakeMacro</methodname>, we can add variable definitions to the configuration
518179860b2SJed Brownmakefile, whereas <methodname>addMakeRule</methodname> allows the user to specify a make target, complete with
51915ac2963SJed Browndependencies and action. As an example, we will replace our parmetis example from above with the following code
520179860b2SJed Brown<programlisting>
521179860b2SJed Brown  self.addMakeMacro('PARMETIS_INCLUDE', ' '.join([self.libraries.getIncludeArgument(i)
522179860b2SJed Brown                                                  for i in self.include]))
523179860b2SJed Brown  self.addMakeMacro('PARMETIS_LIB, ' '.join([self.libraries.getLibArgument(l)
524179860b2SJed Brown                                             for l in self.lib]))
525179860b2SJed Brown  self.addMakeRule('.c.o', '', ['${CC} -c -o $@ -I${PARMETIS_INCLUDE} $&lt;'])
526179860b2SJed Brown  self.addMakeRule('myApp', '${.c=.o:SOURCE}', ['${CC} -o $@ $&lt; ${PARMETIS_LIB}'])
527179860b2SJed Brown</programlisting>
528179860b2SJed Brownwhich will produce
529179860b2SJed Brown<programlisting>
53015ac2963SJed Brown  PARMETIS_INCLUDE = -I/home/knepley/petsc-dev/externalpackages/parmetis/build/Darwin-x86_64/include
53115ac2963SJed Brown  PARMETIS_LIB = -L/home/knepley/petsc-dev/externalpackages/parmetis/build/Darwin-x86_64/lib -lparmetis -lmetis
532179860b2SJed Brown</programlisting>
533179860b2SJed Brownin the file specified by the <varname>makeMacroHeader</varname> member variable, and
534179860b2SJed Brown<programlisting>
535179860b2SJed Brown  myApp: ${.c=.o:SOURCE}
536179860b2SJed Brown        ${CC} -i $@ $&lt; ${PARMETIS_LIB}
537179860b2SJed Brown</programlisting>
538179860b2SJed Brownin the file specified by the <varname>makeRuleHeader</varname> member variable.</para>
539179860b2SJed Brown
540179860b2SJed Brown<para>The above output methods are all specified on a per configure object basis, however this may become confusing in a
541179860b2SJed Brownlarge project. All the prefixes and output filenames would have to be coordinated. A common strategy is to use the
542179860b2SJed Brownframework for coordination, putting all the output into the framework object itself. For instance, we might have
543179860b2SJed Brown<programlisting>
544179860b2SJed Brown  self.framework.addDefine('HAVE_PARMETIS', 1)
545179860b2SJed Brown</programlisting>
546179860b2SJed Brownwhich would allow the define to appear in the headre specified by the framework with the framework prefix.
547179860b2SJed Brown</para>
548179860b2SJed Brown
549179860b2SJed Brown  </sect2>
550179860b2SJed Brown
551179860b2SJed Brown</sect1>
552179860b2SJed Brown
553179860b2SJed Brown<sect1 id="Configuring-batch-systems">
554179860b2SJed Brown<title>Configuring batch systems</title>
555179860b2SJed Brown
556179860b2SJed Brown<para>It is not uncommon for large clusters or supercomputing centers to have a batch execution policy, making it
557179860b2SJed Browndifficult for configure to execute the few tests that depend on executing code, rather than compiling and linking it. To
558179860b2SJed Brownhandle this case, we provide the <option>--with-batch</option> argument. The code to be run is collected in a single
559179860b2SJed Brownexecutable which the user must submit to the system. This executable produces a <emphasis>reconfigure</emphasis> script
560179860b2SJed Brownwhich may then be run to fully configure the system.</para>
561179860b2SJed Brown
562179860b2SJed Brown<para>When configure is run with the <option>--with-batch</option> option, the following message will appear.
563179860b2SJed Brown<screen>
564179860b2SJed Brown<prompt>petsc-dev$</prompt> <command>./config/configure.py --with-batch</command>
565179860b2SJed Brown</screen>
566179860b2SJed Brownproduces the following log output.
567179860b2SJed Brown<screen>
568179860b2SJed Brown<computeroutput>
569179860b2SJed Brown=================================================================================
570179860b2SJed Brown    Since your compute nodes require use of a batch system or mpirun you must:
571179860b2SJed Brown 1) Submit ./conftest to your batch system (this will generate the file reconfigure)
572179860b2SJed Brown 2) Run "python reconfigure" (to complete the configure process).
573179860b2SJed Brown=================================================================================
574179860b2SJed Brown</computeroutput>
575179860b2SJed Brown</screen>
576179860b2SJed BrownThe user must then execute the <filename>conftest</filename> binary, and then run the <command>python
577179860b2SJed Brownreconfigure</command> command.
578179860b2SJed Brown</para>
579179860b2SJed Brown
580179860b2SJed Brown<para>If a user defined test relies upon running code, he may make it suitable for a batch system. The
581179860b2SJed Brown<methodname>checkRun</methodname> method takes the <option>defaultArg</option> argument which names a configure option
582179860b2SJed Brownwhose value may substitute for the outcome of the test, allowing a user to preempt the run. For instance, the
583179860b2SJed Brown<methodname>config.types.checkEndian</methodname> method contains the code
584179860b2SJed Brown<programlisting>
585179860b2SJed Brown  if self.checkRun('', body, defaultArg = 'isLittleEndian'):
586179860b2SJed Brown</programlisting>
587179860b2SJed Brownwhich means the <option>isLittleEndian</option> option can be given to replace the output of the run. However, this does
588179860b2SJed Brownthe require the user to supply the missing option.</para>
589179860b2SJed Brown
590179860b2SJed Brown<para>To automate this process, the test should first check for batch mode. Using the
591179860b2SJed Brown<methodname>addBatchInclude</methodname> and <methodname>addBatchBody</methodname> methods, code can be included in the
592179860b2SJed Brownbatch executable. We return to the endian test to illustrate this usage.
593179860b2SJed Brown<programlisting>
594179860b2SJed Brown  if not self.framework.argDB['with-batch']:
595179860b2SJed Brown    body = '''
596179860b2SJed Brown    /* Are we little or big endian?  From Harbison &amp; Steele. */
597179860b2SJed Brown    union
598179860b2SJed Brown    {
599179860b2SJed Brown      long l;
600179860b2SJed Brown      char c[sizeof(long)];
601179860b2SJed Brown    } u;
602179860b2SJed Brown    u.l = 1;
603179860b2SJed Brown    exit(u.c[sizeof(long) - 1] == 1);
604179860b2SJed Brown    '''
605179860b2SJed Brown    if self.checkRun('', body, defaultArg = 'isLittleEndian'):
606179860b2SJed Brown      endian = 'little'
607179860b2SJed Brown    else:
608179860b2SJed Brown      endian = 'big'
609179860b2SJed Brown  else:
610179860b2SJed Brown    self.framework.addBatchBody(
611179860b2SJed Brown      ['{',
612179860b2SJed Brown       '  union {long l; char c[sizeof(long)];} u;',
613179860b2SJed Brown       '  u.l = 1;',
614179860b2SJed Brown       '  fprintf(output, " \'--with-endian=%s\',\\n",\
615179860b2SJed Brown            (u.c[sizeof(long) - 1] == 1) ? "little" : "big");',
616179860b2SJed Brown       '}'])
617179860b2SJed Brown    # Dummy value
618179860b2SJed Brown    endian = 'little'
619179860b2SJed Brown</programlisting>
620179860b2SJed BrownThe batch body code should output configure options to the <varname>output</varname> file descriptor. These are
621179860b2SJed Browncollected for the new configure run in the <filename>reconfigure</filename> script.
622179860b2SJed Brown</para>
623179860b2SJed Brown
624179860b2SJed Brown</sect1>
625179860b2SJed Brown
626179860b2SJed Brown</chapter>
627179860b2SJed Brown
628179860b2SJed Brown<chapter id="Build">
629179860b2SJed Brown<title>Build</title>
630179860b2SJed Brown
631179860b2SJed Brown<para>The build operation now encompasses the configure, compile, link, install, and update operations.</para>
632179860b2SJed Brown
633179860b2SJed Brown<sect1 id="Running-make">
634179860b2SJed Brown<title>Running make</title>
635179860b2SJed Brown
636179860b2SJed Brown<para>All options for both configuration and build are given to <filename>make.py</filename>. Thus, the simplest build
637179860b2SJed Brownis merely
638179860b2SJed Brown<screen>
639179860b2SJed Brown<prompt>petsc-dev$</prompt> <command>./make.py</command>
640179860b2SJed Brown</screen>
641179860b2SJed BrownThe help is also given by <option>-help</option>, but this time it will also include build switches.
642179860b2SJed Brown<screen>
643179860b2SJed Brown<prompt>petsc-dev$</prompt> <command>./make.py -help</command>
644179860b2SJed Brown<computeroutput>
645179860b2SJed BrownScript Help
646179860b2SJed Brown-----------
647179860b2SJed BrownScript:
648179860b2SJed Brown  --help                        : Print this help message                                           current: 1
649179860b2SJed Brown  --h                           : Print this help message                                           current: 0
650179860b2SJed BrownMake:
651179860b2SJed Brown  -forceConfigure               : Force a reconfiguration                                           current: 0
652179860b2SJed Brown  -ignoreCompileOutput          : Ignore compiler output                                            current: 1
653179860b2SJed Brown  -defaultRoot                  : Directory root for all packages                                   current: ../..
654179860b2SJed Brown  -prefix                       : Root for installation of libraries and binaries
655179860b2SJed BrownSIDLMake:
656179860b2SJed Brown  -bootstrap                    : Generate the boostrap client                                      current: 0
657179860b2SJed Brown  -outputSIDLFiles              : Write generated files to disk                                     current: 1
658179860b2SJed Brown  -excludeLanguages=&lt;languages&gt; : Do not load configurations from RDict for the given languages     current: []
659179860b2SJed Brown  -excludeBasenames=&lt;names&gt;     : Do not load configurations from RDict for these SIDL base names   current: []
660179860b2SJed Brown</computeroutput>
661179860b2SJed Brown</screen>
662179860b2SJed Brown</para>
663179860b2SJed Brown
664179860b2SJed Brown</sect1>
665179860b2SJed Brown
666179860b2SJed Brown<sect1 id="Makers">
667179860b2SJed Brown<title>Makers</title>
668179860b2SJed Brown
669179860b2SJed Brown<para>The build operation now encompasses configure, compile, and link operations, which are coordinated by objects of
670179860b2SJed Brownclass <classname>maker.Maker</classname>. This object manages:
671179860b2SJed Brown<itemizedlist>
672179860b2SJed Brown  <listitem><para>configuration,</para></listitem>
673179860b2SJed Brown  <listitem><para>build,</para></listitem>
674179860b2SJed Brown  <listitem><para>install, and</para></listitem>
675179860b2SJed Brown  <listitem><para>project dependencies</para></listitem>
676179860b2SJed Brown</itemizedlist>
677179860b2SJed BrownAll options, no matter which component they are intended for, are given uniformly to <filename>make.py</filename>.
678179860b2SJed Brown</para>
679179860b2SJed Brown
680179860b2SJed Brown  <sect2 id="SIDLMaker">
681179860b2SJed Brown  <title>SIDLMaker</title>
682179860b2SJed Brown
683179860b2SJed Brown<para>This is a subclass which handles source generation from SIDL.</para>
684179860b2SJed Brown
685179860b2SJed Brown  </sect2>
686179860b2SJed Brown
687179860b2SJed Brown</sect1>
688179860b2SJed Brown
689179860b2SJed Brown<sect1 id="Builders">
690179860b2SJed Brown<title>Builders</title>
691179860b2SJed Brown
692179860b2SJed Brown<para>The build operation now encompasses the configure, compile, and link operations.</para>
693179860b2SJed Brown
694179860b2SJed Brown</sect1>
695179860b2SJed Brown
696179860b2SJed Brown<sect1 id="LanguageProcessors">
697179860b2SJed Brown<title>LanguageProcessors</title>
698179860b2SJed Brown
699179860b2SJed Brown<para>The build operation now encompasses the configure, compile, and link operations.</para>
700179860b2SJed Brown
701179860b2SJed Brown</sect1>
702179860b2SJed Brown
703179860b2SJed Brown<sect1 id="Interaction-with-Configure">
704179860b2SJed Brown<title>Interaction with Configure</title>
705179860b2SJed Brown
706179860b2SJed Brown<para>The pickled configure is loaded by Maker, and then the config.compile objects are jacked into the Builder.</para>
707179860b2SJed Brown
708179860b2SJed Brown</sect1>
709179860b2SJed Brown
710179860b2SJed Brown</chapter>
711179860b2SJed Brown
712179860b2SJed Brown</book>
713