1*179860b2SJed Brown<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"> 2*179860b2SJed Brown<book id="BuildSystemManual" lang="en"> 3*179860b2SJed Brown 4*179860b2SJed Brown<bookinfo> 5*179860b2SJed Brown<title>ASE BuildSystem Manual</title> 6*179860b2SJed Brown<authorgroup> 7*179860b2SJed Brown<author> 8*179860b2SJed Brown<firstname>Matthew</firstname> 9*179860b2SJed Brown<othername>G.</othername> 10*179860b2SJed Brown<surname>Knepley</surname> 11*179860b2SJed Brown</author> 12*179860b2SJed Brown</authorgroup> 13*179860b2SJed Brown<date>July, 2005</date> 14*179860b2SJed Brown<releaseinfo>Release tag ???</releaseinfo> 15*179860b2SJed Brown</bookinfo> 16*179860b2SJed Brown 17*179860b2SJed Brown<chapter id="Introduction"> 18*179860b2SJed Brown<title>Introduction</title> 19*179860b2SJed Brown 20*179860b2SJed Brown<para>The BuildSystem from ASE is intended to be a Python replacement for the GNU autotools. It actually encompasses 21*179860b2SJed Brownsomewhat more, as it supports integrated version control and automatic code generation. However, the most useful 22*179860b2SJed Browncomparisons will come from <command>autoconf</command>, <command>make</command>, and <command>libtool</command>. The 23*179860b2SJed Brownsystem is not designed to be monolithic. Thus each component may be used independently, meaning logging, configuration, 24*179860b2SJed Brownand build are all separate modules which do not require each other. This allows a user to incremenetally adopt the most 25*179860b2SJed Brownuseful portions of the package.</para> 26*179860b2SJed Brown 27*179860b2SJed Brown</chapter> 28*179860b2SJed Brown 29*179860b2SJed Brown<chapter id="Configure"> 30*179860b2SJed Brown<title>Configure</title> 31*179860b2SJed Brown 32*179860b2SJed Brown<sect1 id="Configure-Design-Sketch"> 33*179860b2SJed Brown<title>Configure Design Sketch</title> 34*179860b2SJed Brown 35*179860b2SJed Brown<para>The system is based upon an autonomous unit, objects of class <classname>config.base.Configure</classname>, which 36*179860b2SJed Brownare responsible for discovering configuration information for a particular package or purpose. The only interface which 37*179860b2SJed Brownmust be supported is the <methodname>configure</methodname> method, as shown below. Support for lower-level operations 38*179860b2SJed Brownsuch as compiling and linking will be discussed in section ???.</para> 39*179860b2SJed Brown 40*179860b2SJed Brown<classsynopsis language="python"> 41*179860b2SJed Brown<ooclass> 42*179860b2SJed Brown<classname>Configure</classname> 43*179860b2SJed Brown</ooclass> 44*179860b2SJed Brown<methodsynopsis> 45*179860b2SJed Brown<void/><methodname>configure</methodname><methodparam><parameter>self</parameter></methodparam> 46*179860b2SJed Brown</methodsynopsis> 47*179860b2SJed Brown</classsynopsis> 48*179860b2SJed Brown 49*179860b2SJed Brown<para>This collection of configure objects is managed by a <classname>config.base.Framework</classname> object. As we 50*179860b2SJed Brownwill see in section ???, the framework manages all dependecies between modules and output of configure information. The 51*179860b2SJed Brownframework is itself a subclass of <classname>config.base.Configure</classname> for which the 52*179860b2SJed Brown<methodname>configure</methodname> method manages the entire configuration process. In order to associate a module with 53*179860b2SJed Brownthe given framework, it also provides the <methodname>require</methodname> method, discussed in section ???. Thus, the 54*179860b2SJed Brownminimal framework interface is given by:</para> 55*179860b2SJed Brown 56*179860b2SJed Brown<classsynopsis language="python"> 57*179860b2SJed Brown<ooclass> 58*179860b2SJed Brown<classname>Framework</classname> 59*179860b2SJed Brown</ooclass> 60*179860b2SJed Brown<ooclass> 61*179860b2SJed Brown<classname>config.base.Configure</classname> 62*179860b2SJed Brown</ooclass> 63*179860b2SJed Brown<methodsynopsis> 64*179860b2SJed Brown<void/><methodname>require</methodname> 65*179860b2SJed Brown <methodparam><parameter>self</parameter></methodparam> 66*179860b2SJed Brown <methodparam><parameter>moduleName</parameter></methodparam> 67*179860b2SJed Brown <methodparam><parameter>depChild</parameter></methodparam> 68*179860b2SJed Brown <methodparam><parameter>keywordArgs</parameter><initializer>{}</initializer></methodparam> 69*179860b2SJed Brown</methodsynopsis> 70*179860b2SJed Brown<methodsynopsis> 71*179860b2SJed Brown<void/><methodname>configure</methodname><methodparam><parameter>self</parameter></methodparam> 72*179860b2SJed Brown</methodsynopsis> 73*179860b2SJed Brown</classsynopsis> 74*179860b2SJed Brown 75*179860b2SJed Brown<para>This design allows user modules to be seamlessly integrated into the framework without changing the paradigm, or 76*179860b2SJed Browneven any of the original code. Modules can be specified on the command line, or left in special directories. Although it 77*179860b2SJed Brownis common to derive from <classname>config.base.Configure</classname>, the only necessity is that the user provide a 78*179860b2SJed Brown<methodname>configure</methodname> method for the framework to execute.</para> 79*179860b2SJed Brown 80*179860b2SJed Brown<para>The framework does provide the traditional output mechanisms from <command>autoconf</command>, namely 81*179860b2SJed Brown<methodname>#define</methodname> statements and file substitutions, to which we add make variables and 82*179860b2SJed Brownrules. However, the preferred interaction mechanism is to use member variables directly from the configure objects. This 83*179860b2SJed Brownis illustrated in section ???</para> 84*179860b2SJed Brown 85*179860b2SJed Brown</sect1> 86*179860b2SJed Brown 87*179860b2SJed Brown<sect1 id="Running-configure"> 88*179860b2SJed Brown<title>Running configure</title> 89*179860b2SJed Brown 90*179860b2SJed Brown<para>The first step in running configure is to show the help: 91*179860b2SJed Brown<screen> 92*179860b2SJed Brown<prompt>bash$</prompt> <command>framework.py -help</command> 93*179860b2SJed Brown<computeroutput> 94*179860b2SJed BrownPython Configure Help 95*179860b2SJed Brown Comma seperated lists should be given between [] (use \[ \] in tcsh/csh) 96*179860b2SJed Brown For example: --with-mpi-lib=\[/usr/local/lib/libmpich.a,/usr/local/lib/libpmpich.a\] 97*179860b2SJed Brown---------------------------------------------------------------------------------------- 98*179860b2SJed BrownScript: 99*179860b2SJed Brown --help : Print this help message current: 1 100*179860b2SJed Brown --h : Print this help message current: 0 101*179860b2SJed BrownFramework: 102*179860b2SJed Brown --configModules : A list of Python modules with a Configure class current: [] 103*179860b2SJed Brown --ignoreCompileOutput : Ignore compiler output current: 1 104*179860b2SJed Brown --ignoreLinkOutput : Ignore linker output current: 1 105*179860b2SJed Brown --ignoreWarnings : Ignore compiler and linker warnings current: 0 106*179860b2SJed Brown --doCleanup : Delete any configure generated files (turn off for debugging) current: 1 107*179860b2SJed Brown --with-alternatives : Provide a choice among alternative package installations current: 0 108*179860b2SJed Brown --search-dirs : A list of directories used to search for executables current: [] 109*179860b2SJed Brown --package-dirs : A list of directories used to search for packages current: [] 110*179860b2SJed Brown --with-batch : Machine uses a batch system to submit jobs current: 0 111*179860b2SJed Brown</computeroutput> 112*179860b2SJed Brown</screen> 113*179860b2SJed BrownThe options shown will depend upon the modules loaded with <option>-configModules</option>. For instance, we will 114*179860b2SJed Brownnormally load the compiler module, which reveals the host of optios controlling preprocessors, compilers, and linkers. 115*179860b2SJed Brown<screen> 116*179860b2SJed Brown<prompt>bash$</prompt> <command>framework.py -configModules=[config.compilers] -help</command> 117*179860b2SJed Brown<computeroutput> 118*179860b2SJed BrownPython Configure Help 119*179860b2SJed Brown Comma seperated lists should be given between [] (use \[ \] in tcsh/csh) 120*179860b2SJed Brown For example: --with-mpi-lib=\[/usr/local/lib/libmpich.a,/usr/local/lib/libpmpich.a\] 121*179860b2SJed Brown---------------------------------------------------------------------------------------- 122*179860b2SJed BrownScript: 123*179860b2SJed Brown --help : Print this help message current: 1 124*179860b2SJed Brown --h : Print this help message current: 0 125*179860b2SJed BrownFramework: 126*179860b2SJed Brown --configModules : A list of Python modules with a Configure class current: [] 127*179860b2SJed Brown --ignoreCompileOutput : Ignore compiler output current: 1 128*179860b2SJed Brown --ignoreLinkOutput : Ignore linker output current: 1 129*179860b2SJed Brown --ignoreWarnings : Ignore compiler and linker warnings current: 0 130*179860b2SJed Brown --doCleanup : Delete any configure generated files (turn off for debugging) current: 1 131*179860b2SJed Brown --with-alternatives : Provide a choice among alternative package installations current: 0 132*179860b2SJed Brown --search-dirs : A list of directories used to search for executables current: [] 133*179860b2SJed Brown --package-dirs : A list of directories used to search for packages current: [] 134*179860b2SJed Brown --with-batch : Machine uses a batch system to submit jobs current: 0 135*179860b2SJed BrownCompilers: 136*179860b2SJed Brown --with-cpp=<prog> : Specify the C preprocessor 137*179860b2SJed Brown --with-cc=<prog> : Specify the C compiler 138*179860b2SJed Brown --with-cxx=<prog> : Specify the C++ compiler 139*179860b2SJed Brown --with-fc=<prog> : Specify the Fortran compiler 140*179860b2SJed Brown --with-gnu-compilers=<bool> : Try to use GNU compilers current: 1 141*179860b2SJed Brown --with-vendor-compilers=<vendor> : Try to use vendor compilers (no argument all vendors, 0 no vendors) current: 142*179860b2SJed Brown --with-64-bit-pointers=<bool> : Use 64 bit compilers and libraries current: 0 143*179860b2SJed Brown --CPP=<prog> : Specify the C preprocessor 144*179860b2SJed Brown --CPPFLAGS=<string> : Specify the C preprocessor options current: 145*179860b2SJed Brown --CXXPP=<prog> : Specify the C++ preprocessor 146*179860b2SJed Brown --CC=<prog> : Specify the C compiler 147*179860b2SJed Brown --CFLAGS=<string> : Specify the C compiler options current: 148*179860b2SJed Brown --CXX=<prog> : Specify the C++ compiler 149*179860b2SJed Brown --CXXFLAGS=<string> : Specify the C++ compiler options current: 150*179860b2SJed Brown --CXX_CXXFLAGS=<string> : Specify the C++ compiler-only options current: 151*179860b2SJed Brown --FC=<prog> : Specify the Fortran compiler 152*179860b2SJed Brown --FFLAGS=<string> : Specify the Fortran compiler options current: 153*179860b2SJed Brown --LD=<prog> : Specify the default linker 154*179860b2SJed Brown --CC_LD=<prog> : Specify the linker for C only 155*179860b2SJed Brown --CXX_LD=<prog> : Specify the linker for C++ only 156*179860b2SJed Brown --FC_LD=<prog> : Specify the linker for Fortran only 157*179860b2SJed Brown --LDFLAGS=<string> : Specify the linker options current: 158*179860b2SJed Brown --with-ar : Specify the archiver 159*179860b2SJed Brown -AR : Specify the archiver flags 160*179860b2SJed Brown -AR_FLAGS : Specify the archiver flags 161*179860b2SJed Brown --with-ranlib : Specify ranlib 162*179860b2SJed Brown --with-shared-libraries : Enable shared libraries current: 1 163*179860b2SJed Brown --with-shared-ld=<prog> : Specify the shared linker 164*179860b2SJed Brown --with-f90-header=<file> : Specify the C header for the F90 interface, e.g. f90_intel.h 165*179860b2SJed Brown --with-f90-source=<file> : Specify the C source for the F90 interface, e.g. f90_intel.c 166*179860b2SJed Brown</computeroutput> 167*179860b2SJed Brown</screen> 168*179860b2SJed BrownThe syntax for list and dictionary option values is identical to Python syntax. However, in some shells (like 169*179860b2SJed Brown<command>csh</command>), brackets must be escaped, and braces will usually have to be enclosed in quotes.</para> 170*179860b2SJed Brown 171*179860b2SJed Brown<para>The modules indicated with <option>-configModules</option> are located using <envar>PYTHONPATH</envar>. Since 172*179860b2SJed Brownspecifying environment variables can be inconvenient and error prone, it is common to provide a driver which alters 173*179860b2SJed Brown<varname>sys.path</varname>, as is done for PETSc. In fact, the PETSc driver 174*179860b2SJed Brown<itemizedlist> 175*179860b2SJed Brown <listitem><para>Verifies <envar>PETSC_ARCH</envar></para></listitem> 176*179860b2SJed Brown <listitem><para>Checks for invalid Cygwin versions</para></listitem> 177*179860b2SJed Brown <listitem><para>Checks for RedHat 9, which has a threads bug</para></listitem> 178*179860b2SJed Brown <listitem><para>Augments <envar>PYTHONPATH</envar></para></listitem> 179*179860b2SJed Brown <listitem><para>Adds the default PETSc configure module</para></listitem> 180*179860b2SJed Brown <listitem><para>Persists the configuration in <filename>RDict.db</filename></para></listitem> 181*179860b2SJed Brown <listitem><para>Handles exceptions</para></listitem> 182*179860b2SJed Brown</itemizedlist> 183*179860b2SJed Brown</para> 184*179860b2SJed Brown 185*179860b2SJed Brown</sect1> 186*179860b2SJed Brown 187*179860b2SJed Brown<sect1 id="Adding-a-module"> 188*179860b2SJed Brown<title>Adding a module</title> 189*179860b2SJed Brown 190*179860b2SJed Brown<para>As we discussed in the introduction, all that is strictly necessary for a configure module, is to provide a class 191*179860b2SJed Brownnamed <classname>Configure</classname> with a method <methodname>configure</methodname> taking no arguments. However, 192*179860b2SJed Brownthere are a variety of common operations, which will be illustrated in the sections below.</para> 193*179860b2SJed Brown 194*179860b2SJed Brown <sect2 id="Using-other-modules"> 195*179860b2SJed Brown <title>Using other modules</title> 196*179860b2SJed Brown 197*179860b2SJed Brown <para>We will often want to use the methods or results of other configure modules in order to perform checks in our 198*179860b2SJed Brownown. The framework provides a mechanism for retrieving the object for any given configure module. As an example, 199*179860b2SJed Brownconsider checking for the <methodname>ddot</methodname> function in the BLAS library. The relevant Python code would 200*179860b2SJed Brownbe 201*179860b2SJed Brown<programlisting> 202*179860b2SJed Brownimport config.base 203*179860b2SJed Brown 204*179860b2SJed Brownclass Configure(config.base.Configure): 205*179860b2SJed Brown def __init__(self, framework): 206*179860b2SJed Brown config.base.Configure.__init__(self, framework) 207*179860b2SJed Brown self.compilers = self.framework.require('config.compilers', self) 208*179860b2SJed Brown self.libraries = self.framework.require('config.libraries', self) 209*179860b2SJed Brown return 210*179860b2SJed Brown 211*179860b2SJed Brown def configure(self): 212*179860b2SJed Brown return self.libraries.check('libblas.a', 'ddot', otherLibs = self.compilers.flibs, 213*179860b2SJed Brown fortranMangle = 1) 214*179860b2SJed Brown</programlisting> 215*179860b2SJed BrownThe <methodname>require</methodname> call will return the configure object from the given module, creating it if 216*179860b2SJed Brownnecessary. If the second argument is given, the framework will ensure that the returned configure object runs 217*179860b2SJed Brown<emphasis>before</emphasis> the passed configure object. Notice that we can use the returned object either to call 218*179860b2SJed Brownmethods, like <methodname>check</methodname> from <classname>config.libraries</classname>, or use member variables, such 219*179860b2SJed Brownas the list of Fortran compatibility libraries <methodname>flibs</methodname> from 220*179860b2SJed Brown<classname>config.compilers</classname>. 221*179860b2SJed Brown</para> 222*179860b2SJed Brown 223*179860b2SJed Brown<para>The underlying implementation in the framework uses a directed acyclic graph to indicate dependencies among 224*179860b2SJed Brownmodules. The vertices of this graph, configure objects, are topologically sorted and then executed. Moreover, child 225*179860b2SJed Brownobjects can be added to the framework without respecting the dependency structure, but this is discouraged.</para> 226*179860b2SJed Brown 227*179860b2SJed Brown </sect2> 228*179860b2SJed Brown 229*179860b2SJed Brown <sect2 id="Adding-a-test"> 230*179860b2SJed Brown <title>Adding a test</title> 231*179860b2SJed Brown 232*179860b2SJed Brown <para>A user could of course perform all tests in the object's <methodname>configure</methodname> method, but the base 233*179860b2SJed Brownclass provides useful logging support for this purpose. Consider again the BLAS example, which will now become, 234*179860b2SJed Brown<programlisting> 235*179860b2SJed Brown def checkDot(self): 236*179860b2SJed Brown '''Verify that the ddot() function is contained in the BLAS library''' 237*179860b2SJed Brown return self.libraries.check('libblas.a', 'ddot', otherLibs = self.compilers.flibs, 238*179860b2SJed Brown fortranMangle = 1) 239*179860b2SJed Brown 240*179860b2SJed Brown def configure(self): 241*179860b2SJed Brown self.executeTest(self.checkDot) 242*179860b2SJed Brown return 243*179860b2SJed Brown</programlisting> 244*179860b2SJed BrownPassing our test module to the framework, 245*179860b2SJed Brown<screen> 246*179860b2SJed Brown<prompt>docs$</prompt> <command>PYTHONPATH=`pwd` ../config/framework.py --configModules=[examples.blasTest]</command> 247*179860b2SJed Brown</screen> 248*179860b2SJed 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, 249*179860b2SJed Brownall shell calls, and any output actions as well.</para> 250*179860b2SJed Brown<screen> 251*179860b2SJed Brown<computeroutput> 252*179860b2SJed Brown================================================================================ 253*179860b2SJed BrownTEST checkDot from examples.blasTest(/PETSc3/sidl/BuildSystem/docs/examples/blasTest.py:10) 254*179860b2SJed BrownTESTING: checkDot from examples.blasTest(/PETSc3/sidl/BuildSystem/docs/examples/blasTest.py:10) 255*179860b2SJed Brown Verify that the ddot() function is contained in the BLAS library 256*179860b2SJed Brown Checking for functions ['ddot'] in library ['libblas.a'] ['-lfrtbegin', '-lg2c', '-lm', 257*179860b2SJed Brown '-L/usr/lib/gcc-lib/i486-linux/3.3.5', '-L/usr/lib/gcc-lib/i486-linux/3.3.5/../../..', 258*179860b2SJed Brown '-lm', '-lgcc_s'] 259*179860b2SJed Brownsh: gcc -c -o conftest.o -fPIC conftest.c 260*179860b2SJed BrownExecuting: gcc -c -o conftest.o -fPIC conftest.c 261*179860b2SJed Brownsh: 262*179860b2SJed Brownsh: gcc -o conftest -fPIC conftest.o -lblas -lfrtbegin -lg2c -lm 263*179860b2SJed Brown -L/usr/lib/gcc-lib/i486-linux/3.3.5 -L/usr/lib/gcc-lib/i486-linux/3.3.5/../../.. -lm -lgcc_s 264*179860b2SJed BrownExecuting: gcc -o conftest -fPIC conftest.o -lblas -lfrtbegin -lg2c -lm 265*179860b2SJed Brown -L/usr/lib/gcc-lib/i486-linux/3.3.5 -L/usr/lib/gcc-lib/i486-linux/3.3.5/../../.. -lm -lgcc_s 266*179860b2SJed Brownsh: 267*179860b2SJed BrownDefined HAVE_LIBBLAS to 1 in config.libraries 268*179860b2SJed Brown</computeroutput> 269*179860b2SJed Brown</screen> 270*179860b2SJed Brown 271*179860b2SJed Brown </sect2> 272*179860b2SJed Brown 273*179860b2SJed Brown <sect2 id="Checking-for-headers"> 274*179860b2SJed Brown <title>Checking for headers</title> 275*179860b2SJed Brown 276*179860b2SJed Brown <para>Often, we would like to test for the presence of certain headers. This is done is a completely analogous way to 277*179860b2SJed Brownthe library case, using instead the <classname>config.headers</classname> module. Below, we test for the presence of the 278*179860b2SJed Brown<command>curses</command> header. 279*179860b2SJed Brown<programlisting> 280*179860b2SJed Brownimport config.base 281*179860b2SJed Brown 282*179860b2SJed Brownclass Configure(config.base.Configure): 283*179860b2SJed Brown def __init__(self, framework): 284*179860b2SJed Brown config.base.Configure.__init__(self, framework) 285*179860b2SJed Brown self.headers = self.framework.require('config.headers, self) 286*179860b2SJed Brown return 287*179860b2SJed Brown 288*179860b2SJed Brown def checkCurses(self): 289*179860b2SJed Brown 'Verify that we have the curses header' 290*179860b2SJed Brown return self.headers.check('curses.h') 291*179860b2SJed Brown 292*179860b2SJed Brown def configure(self): 293*179860b2SJed Brown self.executeTest(self.checkCurses) 294*179860b2SJed Brown return 295*179860b2SJed Brown</programlisting> 296*179860b2SJed BrownRunning this test 297*179860b2SJed Brown<screen> 298*179860b2SJed Brown<prompt>docs$</prompt> <command>PYTHONPATH=`pwd` ../config/framework.py --configModules=[examples.cursesTest]</command> 299*179860b2SJed Brown</screen> 300*179860b2SJed Brownproduces the following log output.</para> 301*179860b2SJed Brown<screen> 302*179860b2SJed Brown<computeroutput> 303*179860b2SJed Brown================================================================================ 304*179860b2SJed BrownTEST checkCurses from examples.cursesTest(/PETSc3/sidl/BuildSystem/docs/examples/cursesTest.py:9) 305*179860b2SJed BrownTESTING: checkCurses from examples.cursesTest(/PETSc3/sidl/BuildSystem/docs/examples/cursesTest.py:9) 306*179860b2SJed Brown Verify that we have the curses header 307*179860b2SJed BrownChecking for header: curses.h 308*179860b2SJed Brownsh: gcc -E conftest.c 309*179860b2SJed BrownExecuting: gcc -E conftest.c 310*179860b2SJed Brownsh: # 1 "conftest.c" 311*179860b2SJed Brown# 1 "<built-in>" 312*179860b2SJed Brown# 1 "<command line>" 313*179860b2SJed Brown# 1 "conftest.c" 314*179860b2SJed Brown# 1 "confdefs.h" 1 315*179860b2SJed Brown# 2 "conftest.c" 2 316*179860b2SJed Brown# 1 "conffix.h" 1 317*179860b2SJed Brown# 3 "conftest.c" 2 318*179860b2SJed Brown# 1 "/usr/include/curses.h" 1 3 4 319*179860b2SJed Brown# 58 "/usr/include/curses.h" 3 4 320*179860b2SJed Brown# 1 "/usr/include/ncurses_dll.h" 1 3 4 321*179860b2SJed Brown# 59 "/usr/include/curses.h" 2 3 4 322*179860b2SJed Brown# 99 "/usr/include/curses.h" 3 4 323*179860b2SJed Browntypedef unsigned long chtype; 324*179860b2SJed Brown# 1 "/usr/include/stdio.h" 1 3 4 325*179860b2SJed Brown# 28 "/usr/include/stdio.h" 3 4 326*179860b2SJed Brown# 1 "/usr/include/features.h" 1 3 4 327*179860b2SJed Brown# 295 "/usr/include/features.h" 3 4 328*179860b2SJed Brown# 1 "/usr/include/sys/cdefs.h" 1 3 4 329*179860b2SJed Brown# 296 "/usr/include/features.h" 2 3 4 330*179860b2SJed Brown# 318 "/usr/include/features.h" 3 4 331*179860b2SJed Brown#... 332*179860b2SJed Brown... W* win,int* y, int* x, _Bool to_screen); 333*179860b2SJed Brownextern _Bool mouse_trafo (int*, int*, _Bool); 334*179860b2SJed Brownextern int mcprint (char *, int); 335*179860b2SJed Brownextern int has_key (int); 336*179860b2SJed Brownextern void _tracef (const char *, ...) ; 337*179860b2SJed Brownextern void _tracedump (const char *, WINDOW *); 338*179860b2SJed Brownextern char * _traceattr (attr_t); 339*179860b2SJed Brownextern char * _traceattr2 (int, chtype); 340*179860b2SJed Brownextern char * _nc_tracebits (void); 341*179860b2SJed Brownextern char * _tracechar (int); 342*179860b2SJed Brownextern char * _tracechtype (chtype); 343*179860b2SJed Brownextern char * _tracechtype2 (int, chtype); 344*179860b2SJed Brown# 1203 "/usr/include/curses.h" 3 4 345*179860b2SJed Brownextern char * _tracemouse (const MEVENT *); 346*179860b2SJed Brownextern void trace (const unsigned int); 347*179860b2SJed Brown# 4 "conftest.c" 2 348*179860b2SJed Brown 349*179860b2SJed BrownDefined HAVE_CURSES_H to 1 in config.headers 350*179860b2SJed Brown</computeroutput> 351*179860b2SJed Brown</screen> 352*179860b2SJed Brown 353*179860b2SJed Brown<para>Alternatively, we could have specified that this header be included in the list of header files checked by default.</para> 354*179860b2SJed Brown<programlisting> 355*179860b2SJed Brownimport config.base 356*179860b2SJed Brown 357*179860b2SJed Brownclass Configure(config.base.Configure): 358*179860b2SJed Brown def __init__(self, framework): 359*179860b2SJed Brown config.base.Configure.__init__(self, framework) 360*179860b2SJed Brown self.headers = self.framework.require('config.headers, self) 361*179860b2SJed Brown self.headers.headers.append('curses.h') 362*179860b2SJed Brown return 363*179860b2SJed Brown 364*179860b2SJed Brown def checkCurses(self): 365*179860b2SJed Brown 'Verify that we have the curses header' 366*179860b2SJed Brown return self.headers.haveHeader('curses.h') 367*179860b2SJed Brown 368*179860b2SJed Brown def configure(self): 369*179860b2SJed Brown self.executeTest(self.checkCurses) 370*179860b2SJed Brown return 371*179860b2SJed Brown</programlisting> 372*179860b2SJed Brown 373*179860b2SJed Brown<para>In addition, the base class does include lower level support for preprocessing files. The 374*179860b2SJed Brown<methodname>preprocess</methodname> method takes a code string as input and return a tuple of the 375*179860b2SJed Brown<command>(stdout,stderr,error code)</command> for the run. The <methodname>outputPreprocess</methodname> method returns 376*179860b2SJed Brownonly the standard output, and <methodname>checkPreprocess</methodname> returns true if no error occurs.</para> 377*179860b2SJed Brown 378*179860b2SJed Brown </sect2> 379*179860b2SJed Brown 380*179860b2SJed Brown <sect2 id="Checking-for-libraries"> 381*179860b2SJed Brown <title>Checking for libraries</title> 382*179860b2SJed Brown 383*179860b2SJed Brown <para>We have already demonstrated a test for the existence of a function in a library. However the 384*179860b2SJed Brown<methodname>check</methodname> method is much more general. It allows the specification of multiple libraries and 385*179860b2SJed Brownmultiple functions, as well as auxiliary libraries. For instance, to check for the <methodname>MPI_Init</methodname> and 386*179860b2SJed Brown<methodname>MPI_Comm_create</methodname> functions in MPICH when the Fortran bindings are active, we would use: 387*179860b2SJed Brown<programlisting> 388*179860b2SJed Brown self.libraries.check(['libmpich.so', 'libpmpich.so'], ['MPI_Init', 'MPI_Comm_create'], 389*179860b2SJed Brown otherLibs = self.compilers.flibs) 390*179860b2SJed Brown</programlisting> 391*179860b2SJed BrownAs in the BLAS example, we can also turn on Fortran name mangling. The caller may also supply a function prototype and 392*179860b2SJed Browncalling sequence, which are necessary if the current language is C++. 393*179860b2SJed Brown</para> 394*179860b2SJed Brown 395*179860b2SJed Brown<para>It is also necessary at some times to determine whether a given library is a shared object. This can be 396*179860b2SJed Brownaccomplished using the <methodname>checkShared</methodname> method, as we demonstrate with the MPICH library in a call 397*179860b2SJed Browntaken from the MPI configure module in PETSc. 398*179860b2SJed Brown<programlisting> 399*179860b2SJed Brown self.libraries.checkShared('#include <mpi.h>\n', 'MPI_Init', 'MPI_Initialized', 400*179860b2SJed Brown 'MPI_Finalize', checkLink = self.checkMPILink, 401*179860b2SJed Brown libraries = self.lib) 402*179860b2SJed Brown</programlisting> 403*179860b2SJed BrownThe theory for the check is that a shared object will have only one copy of any global variable. Thus functions such as 404*179860b2SJed Brown<methodname>MPI_Initialized</methodname> will render consistent results across other libraries. The test begins by 405*179860b2SJed Browncreating two dynamic libraries, both of which link the given library. Then an executable is constructed which loads the 406*179860b2SJed Brownlibraries in turn. The first library calls the initizlization functions, here <methodname>MPI_Init</methodname>, and the 407*179860b2SJed Brownsecond library calls the initialization check function, here <methodname>MPI_Initialized</methodname>. The check 408*179860b2SJed Brownfunction will return true if the given library is a shared object. This organization is shown in figure ???</para> 409*179860b2SJed Brown<para> 410*179860b2SJed Brown<inlinemediaobject> 411*179860b2SJed Brown<imageobject><imagedata fileref="sharedLibraryCheck" format="EPS"/></imageobject> 412*179860b2SJed Brown<imageobject><imagedata fileref="sharedLibraryCheck" format="JPG"/></imageobject> 413*179860b2SJed Brown<!-- <textobject><phrase>A diagram of the link structure for the shared library test</phrase></textobject> --> 414*179860b2SJed Brown</inlinemediaobject> 415*179860b2SJed Brown</para> 416*179860b2SJed Brown 417*179860b2SJed Brown <para>The lower level interface to compiling and linking in the base class mirrors that for preprocessing. The 418*179860b2SJed Brown<methodname>outputCompile</methodname> and <methodname>checkCompile</methodname> methods function in the same way. The 419*179860b2SJed Browncode is now broken up into four distinct sections. There are includes, the body of <methodname>main</methodname>, and a 420*179860b2SJed Brownpossible replacement for the beginning and end of the <methodname>main</methodname> declaration. The linking methods, 421*179860b2SJed Brown<methodname>outputLink</methodname> and <methodname>checkLink</methodname>, are exactly analogous.</para> 422*179860b2SJed Brown 423*179860b2SJed Brown <para>There are also some convenience methods provided to handle compiler and linker flags. The 424*179860b2SJed Brown<methodname>checkCompilerFlag</methodname> and <methodname>checkLinkerFlag</methodname> try to determine whether a given 425*179860b2SJed Brownflag is accepted by the processor, while <methodname>addCompilerFlag</methodname> and 426*179860b2SJed Brown<methodname>addLinkerFlag</methodname> will do that check and add any valid flag to the list of default flags.</para> 427*179860b2SJed Brown 428*179860b2SJed Brown </sect2> 429*179860b2SJed Brown 430*179860b2SJed Brown <sect2 id="Checking-for-executables"> 431*179860b2SJed Brown <title>Checking for executables</title> 432*179860b2SJed Brown 433*179860b2SJed Brown <para>The <methodname>getExecutable</methodname> method is used to locate executable files. For instance, this code 434*179860b2SJed Brownwould allow us to locate the <command>valgrind</command> binary. 435*179860b2SJed Brown<programlisting> 436*179860b2SJed Brown self.getExecutable('valgrind') 437*179860b2SJed Brown</programlisting> 438*179860b2SJed 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 439*179860b2SJed Brownmacro defined to it as well. We can opt for these to contain the full path by using the <option>getFullPath</option> 440*179860b2SJed Brownargument. In addition, we can change the name of the member variable and macro using the <option>resultName</option> 441*179860b2SJed Brownargument. 442*179860b2SJed Brown</para> 443*179860b2SJed Brown 444*179860b2SJed Brown<para>We also have control over the search path used. If we give no arguments, the default path from the environment is 445*179860b2SJed Brownused. This can be overridden with a new path using the <option>path</option> argument, either as a Python list or a 446*179860b2SJed Browncolon separated string. Furthermore, the default path can be added to this custom path using the 447*179860b2SJed Brown<option>useDefaultPath</option> argument. For instance, this call 448*179860b2SJed Brown<programlisting> 449*179860b2SJed Brown self.getExecutable('valgrind', path=['/opt/valgrind-1.0'], getFullPath=1, 450*179860b2SJed Brown useDefaultPath=1, resultName='grinder') 451*179860b2SJed Brown</programlisting> 452*179860b2SJed Brownwill check for <command>valgrind</command> first in <filename>/opt/valgrind-1.0</filename> and then along the default 453*179860b2SJed Brownpath. If found in the first location, it will set <varname>self.grinder</varname> to 454*179860b2SJed Brown<filename>/opt/valgrind-1.0/valgrind</filename> as well as define <envar>GRINDER</envar> to the same value in makefiles. 455*179860b2SJed Brown</para> 456*179860b2SJed Brown 457*179860b2SJed Brown <para>As in the cases of preprocessing, compiling, and linking, the lower level operations are also exposed. The 458*179860b2SJed Brown<methodname>checkRun</methodname> method takes in a code string and returns true if the executable runs without 459*179860b2SJed Brownerror. The <methodname>outputRun</methodname> method returns the output and status code. Both methods us the safe 460*179860b2SJed Brownexecution routine <methodname>config.base.Configure.executeShellCommand</methodname> which accepts a timeout. Moreover, 461*179860b2SJed Brownthere commands can run in the special batch mode described in section ???.</para> 462*179860b2SJed Brown 463*179860b2SJed Brown </sect2> 464*179860b2SJed Brown 465*179860b2SJed Brown <sect2 id="Output-results"> 466*179860b2SJed Brown <title>Output results</title> 467*179860b2SJed Brown 468*179860b2SJed Brown <para>The BuildSystem configure includes the traditional output methods employed by <command>autoconf</command> to 469*179860b2SJed Brownenable communication with <command>make</command>. Individual configure modules use the 470*179860b2SJed Brown<methodname>addDefine</methodname> method to add C <methodname>#define</methodname> statements to a configuration header 471*179860b2SJed Brownand the <methodname>addSubstitution</methodname> to setup substitution rules for specified files. For instance, to 472*179860b2SJed Brownactivate the ParMetis package, we might provide 473*179860b2SJed Brown<programlisting> 474*179860b2SJed Brown self.addDefine('HAVE_PARMETIS', 1) 475*179860b2SJed Brown</programlisting> 476*179860b2SJed Brownand then for the make process 477*179860b2SJed Brown<programlisting> 478*179860b2SJed Brown self.addSubstitution('PARMETIS_INCLUDE', ' '.join([self.libraries.getIncludeArgument(i) 479*179860b2SJed Brown for i in self.include])) 480*179860b2SJed Brown self.addSubstitution('PARMETIS_LIB, ' '.join([self.libraries.getLibArgument(l) 481*179860b2SJed Brown for l in self.lib])) 482*179860b2SJed Brown</programlisting> 483*179860b2SJed Brown</para> 484*179860b2SJed Brown 485*179860b2SJed Brown<para>The actual output of this data is controlled by the framework. The user specifies the header file using the 486*179860b2SJed Brown<varname>header</varname> field of the framework, and then the file is created automatically during the configure 487*179860b2SJed Brownprocess, but can be output at any time using the <methodname>outputHeader</methodname> method. Furthermore, the 488*179860b2SJed Brown<methodname>addSubstitutionFile</methodname> method can be used to tag a file for substitution, and also specify a 489*179860b2SJed Browndifferent file for the result of the substitution.</para> 490*179860b2SJed Brown 491*179860b2SJed Brown<para>In the <command>autoconf</command> approach, separating the the defines and substitutions for different packages 492*179860b2SJed Brownbecomes troublesome, and in some cases impossible to maintain. To help with this, we have introduced 493*179860b2SJed Brown<emphasis>prefixes</emphasis> for the defines and substitutions. The are strings, unique to each module, which are 494*179860b2SJed Brownprepended with an underscore to each identifier defined or substituted. These are set on a per object basis using the 495*179860b2SJed Brown<varname>headerPrefix</varname> and <varname>substPrefix</varname> members. For instance, in our 496*179860b2SJed BrownParMetis example, if we instead used the code 497*179860b2SJed Brown<programlisting> 498*179860b2SJed Brown self.headerPrefix = 'MATT' 499*179860b2SJed Brown self.addDefine('HAVE_PARMETIS', 1) 500*179860b2SJed Brown</programlisting> 501*179860b2SJed Brownin our configuration header we would see 502*179860b2SJed Brown<programlisting> 503*179860b2SJed Brown #ifndef MATT_HAVE_PARMETIS 504*179860b2SJed Brown #define MATT_HAVE_PARMETIS 1 505*179860b2SJed Brown #endif 506*179860b2SJed Brown</programlisting> 507*179860b2SJed BrownNote that the value of the prefix is used at output time, not at the time that the define or substitution is set. 508*179860b2SJed Brown</para> 509*179860b2SJed Brown 510*179860b2SJed Brown<para>Another extension of the old-style output mechanisms adds more C structure to the interface. The 511*179860b2SJed Brown<methodname>addTypedef</methodname> method allows a typedef from one typename to another, which in 512*179860b2SJed Brown<command>autoconf</command> is handled by a define. Likewise <methodname>addPrototype</methodname> can add a missing 513*179860b2SJed Brownfunction prototype to a header. Since these are C specific structures, they are output into a separate configuration 514*179860b2SJed Brownheader file, which is controlled by the <varname>cHeader</varname> member variable.</para> 515*179860b2SJed Brown 516*179860b2SJed Brown<para>Extending in a different direction, we allow makefile structures to be specified directly rather than through 517*179860b2SJed Brownsubstitutions. Using <methodname>addMakeMacro</methodname>, we can add variable definitions to the configuration 518*179860b2SJed Brownmakefile, whereas <methodname>addMakeRule</methodname> allows the user to specify a make target, complete with 519*179860b2SJed Browndependencies and action. As an example, we will replace our ParMetis example from above with the following code 520*179860b2SJed Brown<programlisting> 521*179860b2SJed Brown self.addMakeMacro('PARMETIS_INCLUDE', ' '.join([self.libraries.getIncludeArgument(i) 522*179860b2SJed Brown for i in self.include])) 523*179860b2SJed Brown self.addMakeMacro('PARMETIS_LIB, ' '.join([self.libraries.getLibArgument(l) 524*179860b2SJed Brown for l in self.lib])) 525*179860b2SJed Brown self.addMakeRule('.c.o', '', ['${CC} -c -o $@ -I${PARMETIS_INCLUDE} $<']) 526*179860b2SJed Brown self.addMakeRule('myApp', '${.c=.o:SOURCE}', ['${CC} -o $@ $< ${PARMETIS_LIB}']) 527*179860b2SJed Brown</programlisting> 528*179860b2SJed Brownwhich will produce 529*179860b2SJed Brown<programlisting> 530*179860b2SJed Brown PARMETIS_INCLUDE = -I/home/knepley/petsc-dev/externalpackages/ParMetis/include 531*179860b2SJed Brown PARMETIS_LIB = -L/home/knepley/petsc-dev/externalpackages/ParMetis/lib/linux-gnu -lparmetis -lmetis 532*179860b2SJed Brown</programlisting> 533*179860b2SJed Brownin the file specified by the <varname>makeMacroHeader</varname> member variable, and 534*179860b2SJed Brown<programlisting> 535*179860b2SJed Brown myApp: ${.c=.o:SOURCE} 536*179860b2SJed Brown ${CC} -i $@ $< ${PARMETIS_LIB} 537*179860b2SJed Brown</programlisting> 538*179860b2SJed Brownin the file specified by the <varname>makeRuleHeader</varname> member variable.</para> 539*179860b2SJed Brown 540*179860b2SJed Brown<para>The above output methods are all specified on a per configure object basis, however this may become confusing in a 541*179860b2SJed Brownlarge project. All the prefixes and output filenames would have to be coordinated. A common strategy is to use the 542*179860b2SJed Brownframework for coordination, putting all the output into the framework object itself. For instance, we might have 543*179860b2SJed Brown<programlisting> 544*179860b2SJed Brown self.framework.addDefine('HAVE_PARMETIS', 1) 545*179860b2SJed Brown</programlisting> 546*179860b2SJed Brownwhich would allow the define to appear in the headre specified by the framework with the framework prefix. 547*179860b2SJed Brown</para> 548*179860b2SJed Brown 549*179860b2SJed Brown </sect2> 550*179860b2SJed Brown 551*179860b2SJed Brown</sect1> 552*179860b2SJed Brown 553*179860b2SJed Brown<sect1 id="Configuring-batch-systems"> 554*179860b2SJed Brown<title>Configuring batch systems</title> 555*179860b2SJed Brown 556*179860b2SJed Brown<para>It is not uncommon for large clusters or supercomputing centers to have a batch execution policy, making it 557*179860b2SJed Browndifficult for configure to execute the few tests that depend on executing code, rather than compiling and linking it. To 558*179860b2SJed Brownhandle this case, we provide the <option>--with-batch</option> argument. The code to be run is collected in a single 559*179860b2SJed Brownexecutable which the user must submit to the system. This executable produces a <emphasis>reconfigure</emphasis> script 560*179860b2SJed Brownwhich may then be run to fully configure the system.</para> 561*179860b2SJed Brown 562*179860b2SJed Brown<para>When configure is run with the <option>--with-batch</option> option, the following message will appear. 563*179860b2SJed Brown<screen> 564*179860b2SJed Brown<prompt>petsc-dev$</prompt> <command>./config/configure.py --with-batch</command> 565*179860b2SJed Brown</screen> 566*179860b2SJed Brownproduces the following log output. 567*179860b2SJed Brown<screen> 568*179860b2SJed Brown<computeroutput> 569*179860b2SJed Brown================================================================================= 570*179860b2SJed Brown Since your compute nodes require use of a batch system or mpirun you must: 571*179860b2SJed Brown 1) Submit ./conftest to your batch system (this will generate the file reconfigure) 572*179860b2SJed Brown 2) Run "python reconfigure" (to complete the configure process). 573*179860b2SJed Brown================================================================================= 574*179860b2SJed Brown</computeroutput> 575*179860b2SJed Brown</screen> 576*179860b2SJed BrownThe user must then execute the <filename>conftest</filename> binary, and then run the <command>python 577*179860b2SJed Brownreconfigure</command> command. 578*179860b2SJed Brown</para> 579*179860b2SJed Brown 580*179860b2SJed Brown<para>If a user defined test relies upon running code, he may make it suitable for a batch system. The 581*179860b2SJed Brown<methodname>checkRun</methodname> method takes the <option>defaultArg</option> argument which names a configure option 582*179860b2SJed Brownwhose value may substitute for the outcome of the test, allowing a user to preempt the run. For instance, the 583*179860b2SJed Brown<methodname>config.types.checkEndian</methodname> method contains the code 584*179860b2SJed Brown<programlisting> 585*179860b2SJed Brown if self.checkRun('', body, defaultArg = 'isLittleEndian'): 586*179860b2SJed Brown</programlisting> 587*179860b2SJed Brownwhich means the <option>isLittleEndian</option> option can be given to replace the output of the run. However, this does 588*179860b2SJed Brownthe require the user to supply the missing option.</para> 589*179860b2SJed Brown 590*179860b2SJed Brown<para>To automate this process, the test should first check for batch mode. Using the 591*179860b2SJed Brown<methodname>addBatchInclude</methodname> and <methodname>addBatchBody</methodname> methods, code can be included in the 592*179860b2SJed Brownbatch executable. We return to the endian test to illustrate this usage. 593*179860b2SJed Brown<programlisting> 594*179860b2SJed Brown if not self.framework.argDB['with-batch']: 595*179860b2SJed Brown body = ''' 596*179860b2SJed Brown /* Are we little or big endian? From Harbison & Steele. */ 597*179860b2SJed Brown union 598*179860b2SJed Brown { 599*179860b2SJed Brown long l; 600*179860b2SJed Brown char c[sizeof(long)]; 601*179860b2SJed Brown } u; 602*179860b2SJed Brown u.l = 1; 603*179860b2SJed Brown exit(u.c[sizeof(long) - 1] == 1); 604*179860b2SJed Brown ''' 605*179860b2SJed Brown if self.checkRun('', body, defaultArg = 'isLittleEndian'): 606*179860b2SJed Brown endian = 'little' 607*179860b2SJed Brown else: 608*179860b2SJed Brown endian = 'big' 609*179860b2SJed Brown else: 610*179860b2SJed Brown self.framework.addBatchBody( 611*179860b2SJed Brown ['{', 612*179860b2SJed Brown ' union {long l; char c[sizeof(long)];} u;', 613*179860b2SJed Brown ' u.l = 1;', 614*179860b2SJed Brown ' fprintf(output, " \'--with-endian=%s\',\\n",\ 615*179860b2SJed Brown (u.c[sizeof(long) - 1] == 1) ? "little" : "big");', 616*179860b2SJed Brown '}']) 617*179860b2SJed Brown # Dummy value 618*179860b2SJed Brown endian = 'little' 619*179860b2SJed Brown</programlisting> 620*179860b2SJed BrownThe batch body code should output configure options to the <varname>output</varname> file descriptor. These are 621*179860b2SJed Browncollected for the new configure run in the <filename>reconfigure</filename> script. 622*179860b2SJed Brown</para> 623*179860b2SJed Brown 624*179860b2SJed Brown</sect1> 625*179860b2SJed Brown 626*179860b2SJed Brown</chapter> 627*179860b2SJed Brown 628*179860b2SJed Brown<chapter id="Build"> 629*179860b2SJed Brown<title>Build</title> 630*179860b2SJed Brown 631*179860b2SJed Brown<para>The build operation now encompasses the configure, compile, link, install, and update operations.</para> 632*179860b2SJed Brown 633*179860b2SJed Brown<sect1 id="Running-make"> 634*179860b2SJed Brown<title>Running make</title> 635*179860b2SJed Brown 636*179860b2SJed Brown<para>All options for both configuration and build are given to <filename>make.py</filename>. Thus, the simplest build 637*179860b2SJed Brownis merely 638*179860b2SJed Brown<screen> 639*179860b2SJed Brown<prompt>petsc-dev$</prompt> <command>./make.py</command> 640*179860b2SJed Brown</screen> 641*179860b2SJed BrownThe help is also given by <option>-help</option>, but this time it will also include build switches. 642*179860b2SJed Brown<screen> 643*179860b2SJed Brown<prompt>petsc-dev$</prompt> <command>./make.py -help</command> 644*179860b2SJed Brown<computeroutput> 645*179860b2SJed BrownScript Help 646*179860b2SJed Brown----------- 647*179860b2SJed BrownScript: 648*179860b2SJed Brown --help : Print this help message current: 1 649*179860b2SJed Brown --h : Print this help message current: 0 650*179860b2SJed BrownMake: 651*179860b2SJed Brown -forceConfigure : Force a reconfiguration current: 0 652*179860b2SJed Brown -ignoreCompileOutput : Ignore compiler output current: 1 653*179860b2SJed Brown -defaultRoot : Directory root for all packages current: ../.. 654*179860b2SJed Brown -prefix : Root for installation of libraries and binaries 655*179860b2SJed BrownSIDLMake: 656*179860b2SJed Brown -bootstrap : Generate the boostrap client current: 0 657*179860b2SJed Brown -outputSIDLFiles : Write generated files to disk current: 1 658*179860b2SJed Brown -excludeLanguages=<languages> : Do not load configurations from RDict for the given languages current: [] 659*179860b2SJed Brown -excludeBasenames=<names> : Do not load configurations from RDict for these SIDL base names current: [] 660*179860b2SJed Brown</computeroutput> 661*179860b2SJed Brown</screen> 662*179860b2SJed Brown</para> 663*179860b2SJed Brown 664*179860b2SJed Brown</sect1> 665*179860b2SJed Brown 666*179860b2SJed Brown<sect1 id="Makers"> 667*179860b2SJed Brown<title>Makers</title> 668*179860b2SJed Brown 669*179860b2SJed Brown<para>The build operation now encompasses configure, compile, and link operations, which are coordinated by objects of 670*179860b2SJed Brownclass <classname>maker.Maker</classname>. This object manages: 671*179860b2SJed Brown<itemizedlist> 672*179860b2SJed Brown <listitem><para>configuration,</para></listitem> 673*179860b2SJed Brown <listitem><para>build,</para></listitem> 674*179860b2SJed Brown <listitem><para>install, and</para></listitem> 675*179860b2SJed Brown <listitem><para>project dependencies</para></listitem> 676*179860b2SJed Brown</itemizedlist> 677*179860b2SJed BrownAll options, no matter which component they are intended for, are given uniformly to <filename>make.py</filename>. 678*179860b2SJed Brown</para> 679*179860b2SJed Brown 680*179860b2SJed Brown <sect2 id="SIDLMaker"> 681*179860b2SJed Brown <title>SIDLMaker</title> 682*179860b2SJed Brown 683*179860b2SJed Brown<para>This is a subclass which handles source generation from SIDL.</para> 684*179860b2SJed Brown 685*179860b2SJed Brown </sect2> 686*179860b2SJed Brown 687*179860b2SJed Brown</sect1> 688*179860b2SJed Brown 689*179860b2SJed Brown<sect1 id="Builders"> 690*179860b2SJed Brown<title>Builders</title> 691*179860b2SJed Brown 692*179860b2SJed Brown<para>The build operation now encompasses the configure, compile, and link operations.</para> 693*179860b2SJed Brown 694*179860b2SJed Brown</sect1> 695*179860b2SJed Brown 696*179860b2SJed Brown<sect1 id="LanguageProcessors"> 697*179860b2SJed Brown<title>LanguageProcessors</title> 698*179860b2SJed Brown 699*179860b2SJed Brown<para>The build operation now encompasses the configure, compile, and link operations.</para> 700*179860b2SJed Brown 701*179860b2SJed Brown</sect1> 702*179860b2SJed Brown 703*179860b2SJed Brown<sect1 id="Interaction-with-Configure"> 704*179860b2SJed Brown<title>Interaction with Configure</title> 705*179860b2SJed Brown 706*179860b2SJed Brown<para>The pickled configure is loaded by Maker, and then the config.compile objects are jacked into the Builder.</para> 707*179860b2SJed Brown 708*179860b2SJed Brown</sect1> 709*179860b2SJed Brown 710*179860b2SJed Brown</chapter> 711*179860b2SJed Brown 712*179860b2SJed Brown</book> 713