source: OFFICIAL/FCM_V1.3/doc/design/build.html @ 1

Last change on this file since 1 was 1, checked in by fcm, 15 years ago

creation de larborescence

File size: 33.3 KB
Line 
1<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2
3<html>
4<head>
5  <title>FCM Detailed Design: Build System</title>
6  <meta name="author" content="FCM development team">
7  <meta name="descriptions" content="FCM Detailed Design: Build System">
8  <meta name="keywords" content="FCM, design">
9  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
10  <link rel="stylesheet" type="text/css" href="style.css">
11<script type="text/javascript" src="maintain.js">
12</script>
13</head>
14
15<body>
16  <address>
17    <a href="index.html">FCM Detailed Design</a> &gt; Build System
18  </address>
19
20  <h1>Build System</h1>
21 
22  <p>In this chapter, we shall discuss in detail the design of the build
23  system. For information of how to use the build system, please see: <a
24  href="../user_guide/build.html">FCM System User Guide &gt; The Build
25  System</a>.</p>
26
27  <p>The build system analyses the directory tree containing a set of source
28  code, processes the configuration, and invokes <em>make</em> to compile/build
29  the source code into the project executables. The system is written in a set
30  of Perl modules. It is designed to work with GNU <em>make</em>. It creates
31  the <em>Makefile</em> and many other dependent files automcatically. The
32  build system uses a similar interface to the extract system. Its
33  configuration file can be produced through the extract system. It also
34  shares the same command line interface and many other utilities with the
35  code management system and the extract system.</p>
36
37  <h2><a name="io">Input and Output</a></h2>
38
39  <p>The build system has the following input:</p>
40
41  <ul class="pad">
42    <li>a directory tree populated with a set of Fortran and C source files,
43    and scripts written in Perl, Python, TCL, PVWave or a Unix shell.</li>
44
45    <li>the location of the root directory of the build.</li>
46
47    <li>the tools/commands (and their options) to be used for the build.</li>
48
49    <li>the locations of previous builds, if the current build is to base on
50    them.</li>
51
52    <li>other build options.</li>
53  </ul>
54
55  <p>Output from the build system includes:</p>
56
57  <ul class="pad">
58    <li>the targets of the build and their dependencies.</li>
59
60    <li>other files used by the system to build the targets.</li>
61  </ul>
62
63  <h2><a name="component">Components</a></h2>
64
65  <p>The build system uses the following commands, modules and tools:</p>
66
67  <table class="pad" summary="build system components" border="1">
68    <tr>
69      <th>Name</th>
70
71      <th>Category</th>
72
73      <th>Description</th>
74    </tr>
75
76    <tr>
77      <th>fcm</th>
78
79      <td>Perl executable</td>
80
81      <td>Top level command line interface of the FCM system.</td>
82    </tr>
83
84    <tr>
85      <th>fcm_internal</th>
86
87      <td>Perl executable</td>
88
89      <td>Command wrapper for the compiler and linker.</td>
90    </tr>
91
92    <tr>
93      <th>Fcm::Build</th>
94
95      <td>Perl module</td>
96
97      <td>Main class that controls the running of the build system.</td>
98    </tr>
99
100    <tr>
101      <th>Fcm::BuildTask</th>
102
103      <td>Perl module</td>
104
105      <td>A class that performs various "tasks" (such as pre-process and
106      generate interface) for the build system.</td>
107    </tr>
108
109    <tr>
110      <th>Fcm::CfgFile</th>
111
112      <td>Perl module</td>
113
114      <td>A class for reading from and writing to configuration files.</td>
115    </tr>
116
117    <tr>
118      <th>Fcm::Compiler</th>
119
120      <td>Perl module</td>
121
122      <td>A class for wrapping the compiler and linker commands.</td>
123    </tr>
124
125    <tr>
126      <th>Fcm::Config</th>
127
128      <td>Perl module</td>
129
130      <td>A class that contains the configuration settings shared by all
131      FCM components.</td>
132    </tr>
133
134    <tr>
135      <th>Fcm::SrcFile</th>
136
137      <td>Perl module</td>
138
139      <td>A class that controls the actions on a source file.</td>
140    </tr>
141
142    <tr>
143      <th>Fcm::SrcPackage</th>
144
145      <td>Perl module</td>
146
147      <td>A class that deals with the actions on a source directory
148      sub-package.</td>
149    </tr>
150
151    <tr>
152      <th>Fcm::Util</th>
153
154      <td>Perl module</td>
155
156      <td>A collection of utilities shared by all FCM components.</td>
157    </tr>
158
159    <tr>
160      <th>Ecmwf::Fortran90_stuff</th>
161
162      <td>Perl module</td>
163
164      <td>A utility originally developed by the ECMWF for generating interface
165      blocks for Fortran 9X source files. Modified for adoptation by the FCM
166      system.</td>
167    </tr>
168
169    <tr>
170      <th>make</th>
171
172      <td>Unix utility</td>
173
174      <td>The <em>make</em> build utility. FCM is designed to work with the
175      GNU version of <em>make</em>.</td>
176    </tr>
177
178    <tr>
179      <th>sh</th>
180
181      <td>Unix shell</td>
182
183      <td>The following shell commands are used: "cp", "rm", "mv", "cd" and
184      "touch".</td>
185    </tr>
186
187    <tr>
188      <th>f90aib</th>
189
190      <td>Fortran utility</td>
191
192      <td>Formerly used by the GEN system as the generator for Fortran 9X
193      interface blocks. It is a freeware developed by Michel Olagnon at the
194      French Research Institute for Exploitation of the Sea. Its use is still
195      supported by FCM, but the ECMWF interface generator is now
196      preferred.</td>
197    </tr>
198  </table>
199
200  <h2><a name="command">The Build Command</a></h2>
201
202  <p>There are several options that can be supplied to the build command.
203  These options are implemented as follows:</p>
204
205  <ul>
206    <li><strong>Archive mode</strong>: the build system generates many files,
207    which are placed in various sub-directories according to their categories.
208    Most of these files are not used in the runtime environment. To prevent a
209    clutter up of disk space, it may be desirable to archive these
210    sub-directories. The system implements this by using the "tar" command to
211    archive each sub-directory. For an incremental build in the same
212    directory, the archived "tar" files are extracted back into the
213    sub-directories so that they can be re-used. It is worth noting that the
214    archive mode should not be used if a build is going to be re-used as a
215    pre-compiled build, as it will not be possible to extract the "tar" archives
216    back to their original forms. The default is not to archive
217    sub-directories.</li>
218
219    <li><strong>Full mode</strong>: on an incremental build, the system removes
220    all sub-directories created by the previous build, so that a new build can
221    be performed. The default is to perform an incremental build.</li>
222
223    <li><strong>Parallel jobs</strong>: this is implemented via the option in
224    GNU <em>make</em>. The generated <em>Makefile</em> is written with
225    parallel <em>make</em> in mind. The default is to perform a serial
226    build.</li>
227
228    <li><strong>Stage</strong>: this is implemented by running the build
229    system up to and including a named or a numbered stage. The default is to
230    go through all the stages.</li>
231
232    <li><strong>Targets</strong>: if targets are specified in the build
233    command, overrides the default targets supplied to the <em>make</em>
234    command. The default is to build the "all" target.</li>
235
236    <li><strong>Verbose</strong>: the verbose setting is a variable in the
237    Fcm::Config module. If the option is specified in the build command, it
238    sets this variable to the value supplied to the option. At various places
239    in the build process, it may be useful to print out diagnostic
240    information. This variable contols whether the information will get
241    printed.</li>
242  </ul>
243
244  <h2><a name="fcm-cfg">The Central/User Configuration File</a></h2>
245
246  <p>When we invoke the FCM command, it creates a new instance of Fcm::Config,
247  which reads, processes and stores information from the central and user
248  configuration file. The default settings in Fcm::Config is overwritten by
249  the information provided by the central configuration file. If a user
250  configuration file is found, its settings will take overall precedence.
251  These settings are stored in the Fcm::Config instance, which are parsed to
252  all other modules used by the build system. By convention, the reference to
253  the Fcm::Config instance can normally be fetched by the "config" method for
254  all OO "Fcm::" modules.</p>
255
256  <h2><a name="bld-cfg">The Build Configuration File</a></h2>
257
258  <p>When we invoke the build command, it creates a new instance of Fcm::Build,
259  which automatically creates a new instance of Fcm::CfgFile. If an argument
260  is specified in the build command, it is used as the build configuration
261  file if it is a regular file. Otherwise, it is used to search for the build
262  configuration file. If no argument is specified, the current working directory
263  is searched. Fcm::CfgFile will attempt to locate a file called "bld.cfg"
264  under this directory. If such a file is not found, it will attempt to locate
265  it under "cfg/bld.cfg".</p>
266 
267  <p>Once a file is located, Fcm::CfgFile will attempt to parse it. This is
268  done by reading and processing each line of the configuration file into
269  separate label, value and comment fields. Each line is then pushed into an
270  array that can be fetched using the "lines" method of the Fcm::CfgFile
271  instance. Internally, each line is recorded as a reference to a hash table
272  with the following keys:</p>
273
274  <ul class="pad">
275    <li>LABEL: the label of a declaration.</li>
276
277    <li>VALUE: the value of a declaration.</li>
278
279    <li>COMMENT: the comment following a declaration or the comment in a
280    comment line.</li>
281
282    <li>NUMBER: the line number of the current line in the source file.</li>
283
284    <li>SRC: the name of the source file.</li>
285  </ul>
286 
287  <p>The information given by each line is "deciphered" by Fcm::Build. The
288  information is processed in the following ways:</p>
289
290  <ul class="pad">
291    <li>The configuration file type "CFG::TYPE" and version "CFG::VERSION"
292    declarations are stored as properties of the Fcm::CfgFile instance.
293    Fcm::Build uses the information to ensure that it is reading a build
294    configuration file.</li>
295
296    <li>Build target(s) declarations "TARGET" are delimited by space
297    characters. Each target is pushed into the array reference "TARGET".</li>
298
299    <li>The location of the build root directory "DIR::ROOT" and its
300    sub-directories are stored in the "DIR" hash reference in the Fcm::Build
301    instance.  The keys of the hash table are the internal names of the
302    sub-directories, and the values are the locations of the
303    sub-directories.</li>
304
305    <li>The source directories "SRC::&lt;pcks&gt;" are stored in the "SRCDIR"
306    hash reference under the Fcm::Build instance. The keys of the hash table
307    are the names of the sub-packages. (If package names are delimited by the
308    double colons "::", they are turned into the double underscores "__" at
309    this stage.) The values of the "SRCDIR" hash reference are new instances
310    of Fcm::SrcPackage. When initialised, Each Fcm::SrcPackage creates a list
311    of source files in its source directory. For each source file in the list,
312    a new instance of Fcm::SrcFile is created, and pushed into the the
313    "SRCFILE" array reference under the Fcm::SrcPackage instance. When
314    initialised, each Fcm::SrcFile instance will attempt to determine the type
315    associated with the source file. This information can be fetched using the
316    "type" method of the Fcm::SrcFile instance.</li>
317
318    <li>Pre-processor switches "PP[::&lt;pcks&gt;]" declarations are stored in
319    the "PP" hash reference under the Fcm::Build instance. The keys of this hash
320    table are the names of the sub-packages, prefix with PP and a pair of
321    underscores, i.e. "PP__&lt;pcks&gt;". The declaration to switch on/off
322    pre-processing globally is stored using the key "PP". The values in the
323    hash table is either true (1) or false (0).</li>
324
325    <li>A tool declaration "TOOL::&lt;name&gt;[::&lt;pcks&gt;]" is stored as
326    a setting in Fcm::Config as ("TOOL", &lt;name&gt;[__&lt;pcks&gt;]. The
327    value of the declaration can then be fetched using the "setting" method of
328    the Fcm::Config instance.</li>
329
330    <li>An exclude dependency declaration "EXCL_DEP[::&lt;pcks&gt;]" is stored
331    as a setting in Fcm::Config as ("EXCL_DEP", &lt;value&gt;, &lt;pcks&gt;,
332    where &lt;value&gt; is the value of the declaration. For an exclude
333    dependency declaration that applies globally, &lt;pcks&gt; is set to a
334    null string "".) The value of an exclude dependency setting is always set
335    to 1.</li>
336
337    <li>Input file extension declaration "INFILE_EXT::&lt;ext&gt;" is stored
338    as a setting in Fcm::Config as ("INFILE_EXT", &lt;ext&gt;). The value of
339    the setting can then be fetched using the "setting" method of the
340    Fcm::Config instance.</li>
341
342    <li>Output file extension declaration "OUTFILE_EXT::&lt;type&gt;" is
343    stored as a in Fcm::Config as ("OUTFILE_EXT", &lt;type&gt;). The value of
344    the setting can then be fetched using the "setting" method of the
345    Fcm::Config instance.</li>
346
347    <li>For each "USE" declaration to use a pre-compiled build, a new instance of
348    Fcm::Build is created. The instance Fcm::Build for the previous build
349    creates a new instance of Fcm::CfgFile for its configuration file. The
350    configuration of the previous build is read and processed as described
351    above. The current instance of Fcm::Build will then attempt to inherit the
352    settings of the previous build where appropriate. The Fcm::Build instance
353    for the pre-compiled build is pushed into the "USE" array reference under
354    the current Fcm::Build.</li>
355
356    <li>The inherit flags for targets "INHERIT::TARGET", source directories
357    "INHERIT::SRC[::&lt;pcks&gt;]" and pre-processor switches
358    "INHERIT::PP[::&lt;pcks&gt;]" are stored in the "INHERIT" hash reference
359    under the Fcm::Build instance. For declarations that apply globally, the
360    keys to the hash table are "TARGET", "SRCDIR" or "PP". If the declarations
361    apply to &lt;pcks&gt;, the keys are "SRCDIR__&lt;pcks&gt;" or
362    "PP__&lt;pcks&gt;". (The inherit target flag always applies globally.)</li>
363  </ul>
364
365  <p>Unless the search source flag "SEARCH_SRC" is switched off (0) in the build
366  configuration, Fcm::Build will attempt to search the source sub-directory
367  "src/" of the build root recursively for source directory sub-packages. The
368  source directories obtained in the search are treated as if they are
369  declared using "SRC::&lt;pcks&gt;" in the build configuration file.</p>
370
371  <h2><a name="flags">Compiler Flags</a></h2>
372
373  <p>As discussed in the user guide, if you declare the Fortran compiler flags
374  without specifying a sub-package, the declaration applies globally.
375  Otherwise, it only applies to the Fortran source files within the
376  sub-package. This is implemented via a simple "tool selection" mechanism. You
377  may have noticed that all TOOL declarations (and TOOL settings in
378  Fcm::Config) are turned into an environemnt variable declaration in the
379  generated <em>Makefile</em>. For example, if we have a
380  "FFLAGS__bar__egg__ham__foo" declaration, it will be declared as an
381  environment variable in the generated <em>Makefile</em>. Suppose we have a
382  source file "foo.f90" under the sub-package "bar::egg::ham". When we invoke
383  the compiler wrapper (i.e. "fcm_internal" and "Fcm::Compile") to compile the
384  source file, the system will first attempt to select from the FFLAGS
385  environment variable that matches the sub-package of the source file, which
386  is "FFLAGS__bar__egg__ham__foo" in this case. If the environment variable
387  does not exist, it will attempt to go one sub-package up, i.e.
388  "FFLAGS__bar__egg__ham", and so on until it reaches the global "FFLAGS"
389  declaration, (which should always exists).</p>
390
391  <p>For changes in compiler flags declaration, the build system should
392  trigger re-compilation of required targets only. This is implemented using a
393  "flags" file system. These "flags" files are dummy files created in the
394  "flags/" sub-directory of the build root. They are updated by the "touch"
395  command.  The following dependencies are followed:</p>
396
397  <ul>
398    <li>Source files are dependent on its own "flags" file. E.g. the file
399    Ops_Switch in sub-package ":ops::code::OpsMod_Control" is dependent
400    on "FFLAGS__ops__code__OpsMod_Control__Ops_Switch.flags".</li>
401
402    <li>The "flags" file of a source file is dependent on the "flags" file
403    of its container sub-package. E.g. the above flags file is dependent
404    on "FFLAGS__ops__code__OpsMod_Control.flags".</li>
405
406    <li>The "flags" file of a sub-package is dependent on the "flags"
407    file of its container sub-package. E.g. the above is dependent on
408    "FFLAGS__ops__code.flags", which is dependent on
409    "FFLAGS__ops.flags".</li>
410
411    <li>The "flags" file of a top-level package is dependent on the
412    "flags" file of the global flags. E.g. "FFLAGS__ops.flags" is
413    dependent on "FFLAGS.flags".</li>
414
415    <li>The "flags" file of the global "flags" file is dependent on the
416    "flags" file of the compiler command. E.g. "FFLAGS.flags" is
417    dependent on "FC.flags".</li>
418  </ul>
419 
420  <p>The system records changes in declared tools using a cache file, (called
421  ".bld_tool", located at the ".cache/" sub-directory of the built root). It
422  is basically a list of "TOOL::" declarations for the latest build.  When an
423  incremental build is invoked, the list is compared against the current set.
424  If there are changes (modification, addition and deletion) in any
425  declarations, the timestamp of the corresponding "flags" files will be
426  updated. Files depending on the updated "flags" file will then be considered
427  out of date by <em>make</em>, triggering a re-build of those files.</p>
428
429  <h2><a name="interface">Fortran 9X Interface Block Generator</a></h2>
430
431  <p>The build system generates an interface block file for each Fortran 9X
432  source file. If the original source file has been pre-processed, the system
433  uses the pre-processed source file. Otherwise, the system uses the original
434  source file. For each source file containing standalone subroutines and
435  functions, the system will generate an interface file containing the
436  interfaces for the subroutines and functions. The interface files for other
437  Fortran 9X source files are empty.</p>
438
439  <p>Fcm::Build controls the creation of interface files by searching for a
440  list of Fcm::SrcFile instances containing Fortran 9X source files, by
441  calling the "is_type ('FORTRAN9X')" method of each Fcm::SrcFile instance.
442  For each of Fortran 9X source file, a Fcm::BuildTask is created to "build"
443  the interface file. The build task is dependent on the interface
444  generator. The interface files will be re-generated if we change the
445  interface generator. The generated interface is held in an array initially.
446  If an old file exists, it is read into an array so that it can be compared
447  with the current one. The current interface is written to the interface file
448  if it is not the same as the old one, or if an old one does not already
449  exist.</p>
450
451  <p>FCM supports the use of <em>f90aib</em> and the ECMWF interface
452  generator. The latter is the default.</p>
453
454  <h2><a name="dependency">Depdendency Scanner</a></h2>
455
456  <p>For each source directory sub-package, the build system scans its source
457  files for dependency information. The dependency scanner uses a pre-defined
458  set of patterns and rules in Fcm::Config to determine whether a line in a
459  source file contains a dependency. Only source files of supported types are
460  scanned. The dependency information of a sub-package is stored in the memory
461  as well as a cache file. The latter can be re-used by subsequent incremental
462  builds. In an incremntal build, only those source files newer than the cache
463  file is re-scanned for dependency. The cache file is read/written using
464  temporary instances of Fcm::CfgFile.</p>
465
466  <p>The control of the source file selection process is handled by the
467  Fcm::SrcPackage instances, while the actual dependency scans are performed
468  via the scan_dependency method of the Fcm::SrcFile instances.</p>
469
470  <p>A dependency has a type. For example, it can be a Fortran module or an
471  include file. The type of a dependency determines how it will be used by the
472  source file during the <em>make</em> stage, and so it affects how the
473  <em>make</em> rule will be written for the source file. In memory, the
474  dependency information is stored in a hash table, which can be retrieved as
475  a property of the Fcm::SrcFile instance. The keys of the hash table are the
476  dependency items, and the values are their types.</p>
477
478  <p>A dependency is not added to the hash table if it matches with an exclude
479  dependency declaration for the current sub-package.</p>
480
481  <p>While the dependency scanner is scanning through each line of a Fortran
482  source file, the system also attempt to determine its internal name. This is
483  normally the name of the first compilable program unit defined in the
484  Fortran source file. The internal name is converted into lowercase (bearing
485  in mind that Fortran is case insensitive), and will be used to name the
486  compiled object file of the source file.</p>
487
488  <p>The package configuration file is a system to bypass the automatic
489  dependency scanner. It can also be used to add extra dependencies to a
490  source file in the package. The configuration file is a special file in a
491  source package. The lines in the file is read using a temporary instance of
492  Fcm::CfgFile created by Fcm::SrcPackage. All declarations in a package
493  configuration file apply to named source files. The declarations set the
494  properties of the Fcm::SrcFile instance associated with the source file. It
495  can be used to add dependencies to a source file, and to tell the system to
496  bypass automatic dependency scanning of the source file. Other modifications
497  such as the internal name (object file name) of a source file, or the target
498  name of the executable can also be set using the package configuration file
499  in the package containing the source file.</p>
500
501  <h2><a name="rule">Make Rule Generator</a></h2>
502
503  <p>The dependency information is used to create the <em>Makefile</em>
504  fragments for the source directory sub-packages. A <em>Makefile</em> fragment
505  is updated if it is older than its corresponding dependency cache file.</p>
506
507  <p>The following is a list of file types and their <em>make</em> rule
508  targets:</p>
509
510  <table class="pad" summary="list of file types and thier make rules"
511  border="1">
512    <tr>
513      <th colspan="2">File type</th>
514
515      <th>Targets</th>
516    </tr>
517
518    <tr>
519      <th rowspan="5">SOURCE</th>
520
521      <th>all</th>
522
523      <td>
524        <ul>
525          <li>compile: object file</li>
526
527          <li>touch: flags file for compiler flags</li>
528        </ul>
529      </td>
530    </tr>
531
532    <tr>
533      <th>FPP and C</th>
534
535      <td>
536        <p>If the original source has not been pre-processed:</p>
537
538        <ul>
539          <li>touch: flags file for pre-processor definition macros</li>
540        </ul>
541      </td>
542    </tr>
543
544    <tr>
545      <th>PROGRAM</th>
546
547      <td>
548        <ul>
549          <li>load: executable binary file</li>
550
551          <li>touch: flags file for loader (linker) flags</li>
552        </ul>
553      </td>
554    </tr>
555
556    <tr>
557      <th>all except PROGRAM</th>
558
559      <td>
560        <ul>
561          <li>touch: "done" file to denote the resolution of all external
562          objects.</li>
563        </ul>
564      </td>
565    </tr>
566
567    <tr>
568      <th>all FORTRAN except PROGRAM and MODULE</th>
569
570      <td>
571        <ul>
572          <li>interface: "interface" file to denote that all dependent module
573          information files are up to date.</li>
574        </ul>
575      </td>
576    </tr>
577
578    <tr>
579      <th colspan="2">INCLUDE</th>
580
581      <td>
582        <ul>
583          <li>cp: "include" file to "inc/" sub-directory</li>
584
585          <li>touch: "idone" file to denote the resolution of all external
586          objects.</li>
587        </ul>
588      </td>
589    </tr>
590
591    <tr>
592      <th colspan="2">EXE and SCRIPT</th>
593
594      <td>
595        <ul>
596          <li>cp: executable file to "bin/" sub-directory</li>
597        </ul>
598      </td>
599    </tr>
600
601    <tr>
602      <th colspan="2">LIB</th>
603
604      <td>
605        <ul>
606          <li>ar: archive object library file</li>
607        </ul>
608      </td>
609    </tr>
610  </table>
611
612  <p>The resulting <em>Makefile</em> is made up of a top level
613  <em>Makefile</em> and a list of include ".mk" files, (one for each
614  sub-package). The toplevel <em>Makefile</em> consists of useful environment
615  variables, including the search path of each sub-directory, the build tools,
616  the verbose mode and the VPATH directives for different file types. It has
617  two top level build targets, "all" and "clean". The "all" target is the
618  default target, and the "clean" target is for removing the previous build
619  from the current build root. It also has a list of targets for building the
620  top level and the container sub-package "flags" files. At the end of the
621  file is a list of "include" statements to include the ".mk" files.</p>
622
623  <p>A the top of each of ".mk" files are local variables for locating the
624  source directories of the sub-package. Below that are the rules for building
625  source files in the sub-package.</p>
626
627  <h2><a name="pp">Pre-processing</a></h2>
628
629  <p>As discussed in the user guide, the PP switch can be used to switch on
630  pre-processing. The PP switch can be specified globally or for individual
631  sub-packages. (However, it does not go down to the level of individual
632  source files.) The "inheritance" relationship is similar to that of the
633  compiler flags.</p>
634
635  <p>Currently, only Fortran source files with uppercase file extensions and C
636  source files are considered to be source files requiring pre-processing. If
637  a sub-package source directory contains such files and has its PP switch set
638  to ON, the system will attempt to pre-process these files.</p>
639
640  <p>The system allows header files to be located anywhere in the source tree.
641  Therefore, a dependency scan is performed on all files requiring
642  pre-processing as well as all header files to obtain a list of "#include"
643  header file dependencies. For each header file or source file requiring
644  pre-processing, a new instance of Fcm::BuildTask is created to represent a
645  "target". Similar to the logic in <em>make</em>, a "target" is only up to
646  date if all its dependencies are up to date. The Fcm::BuildTask instance
647  uses this logic to pre-process its files. Dependent header files are updated
648  by copying them to the "inc/" sub-directory of the build root. The "inc/"
649  sub-directory is automatically placed in the search path of the
650  pre-processor command, usually by the "-I" option. Pre-processing is
651  performed by a method of the Fcm::SrcFile instance. The method builds the
652  command by selecting the correct set of pre-processor definition macros and
653  pre-processor flags, using an inheritance relationship similar to that used
654  by the compiler flags. Unlike <em>make</em>, however, Fcm::BuildTask only
655  updates the target if both the timestamp and the content are out of date.
656  Therefore, if the target already exists, the pre-processing command is only
657  invoked if the timestamp of the target is out of date. The output from the
658  pre-processor will then be compared with the content in the target. The
659  target is only updated if the content has changed.</p>
660
661  <p>Once a source file is pre-processed, subsequent build system operations
662  such as Fortran 9X interface block generation and dependency scan (for
663  creating the <em>Makefile</em>) will be based on the pre-processed source,
664  and not the original source file. If a source file requires pre-processing
665  and is not pre-processed at the pre-processing stage, it will be left to the
666  compiler to perform the task.</p>
667
668  <h2><a name="file-type">File Type Register</a></h2>
669
670  <p>The build system file type register is a simple interface for modifying
671  the default settings in the Fcm::Config module. There are two registers, one
672  for output file type and one for input file type.</p>
673
674  <p>The output file register is the simpler of the two. It is implemented as
675  a hash table, with the keys being the names of the file types as known by the
676  system internally, and the values being the suffices that will be added to
677  those output files. Therefore, the output file register allows us to modify
678  the suffix added to an output file of a particular type.</p>
679
680  <p>The input file register allows us to modify the type flags of a file
681  named with a particular extension. The type flags are keywords used by the
682  build system to determine what type of input files it is dealing with. It is
683  implemented as a list of uppercase keywords delimited by a pair of colons.
684  The order of the keywords in the string is insignificant. Internally, the
685  build system determines the action on a file by looking at whether it
686  belongs to a type that is tied with that particular action. For example, a
687  file that has the keyword "SOURCE" in its type flag will be treated as a
688  compilable source file, and so it will be written to the <em>Makefile</em>
689  with a rule to compile it.</p>
690
691  <h2><a name="makefile">The <em>Makefile</em></a></h2>
692
693  <p>The following items are automatically written to the <em>Makefile</em>:</p>
694
695  <ul>
696    <li>The root directory and sub-directories of the current build, as
697    environment variables FCM_ROOTDIR, etc.</li>
698
699    <li>The search path of the different types of output file, using a set of
700    "vpath" directives.</li>
701
702    <li>TOOL declarations in the build configuration file are exported as
703    environment variables.</li>
704
705    <li>The diagnostic verbose mode information.</li>
706
707    <li>The default build targets.</li>
708
709    <li>The rules for building the targets for all the source files.</li>
710  </ul>
711
712  <h2><a name="wrapper">The Compiler/Linker Wrapper</a></h2>
713
714  <p>Compile and link are handled by the <em>fcm_internal</em> wrapper script.
715  The wrapper script uses the environment variables exported by the
716  <em>Makefile</em> to generate the correct compiler (or linker) command for the
717  current source (or object) file. Depending on the diagnistic verbose level,
718  it also prints out various amount of diagnostic output.</p>
719
720  <p>For compilation, the wrapper does the following:</p>
721
722  <ol>
723    <li>Select the correct compiler for the current source file.</li>
724
725    <li>Specify the output file name for the current source file.</li>
726
727    <li>If pre-processing is left to the compiler, specify the definition
728    macros, if any, for the pre-processor.</li>
729
730    <li>Specify the "include" path, in case the source file has dependencies
731    on include files.</li>
732
733    <li>Specify the "compile only" option, if it is not already set.</li>
734
735    <li>Add any other user defined flags to the compiler command.</li>
736
737    <li>Run the command, sending the output to a temporary directory.</li>
738
739    <li>If the compile succeeded, move the output from the temporary directory
740    to the output object directory.</li>
741
742    <li>Otherwise, delete the output from the temporary directory.</li>
743
744    <li>If there are Fortran module definition files (*.mod, *.MOD, etc), move
745    them to the "inc/" sub-directory.</li>
746  </ol>
747
748  <p>For linking, the wrapper does the following:</p>
749
750  <ol>
751    <li>Create a temporary object archive library with all the object files
752    currently residing in the output object sub-directory.</li>
753
754    <li>Select the correct linker for the current main program object
755    file.</li>
756
757    <li>Specify the output file name for the main program.</li>
758
759    <li>Specify the main program object file.</li>
760
761    <li>Specify the link library search path and the temporary link
762    library.</li>
763
764    <li>Add any other user defined flags to the linker command.</li>
765
766    <li>Run the command, sending the output to a temporary directory.</li>
767
768    <li>If the link succeeded, move the output from the temporary directory to
769    the "bin/" sub-directory of the build root.</li>
770
771    <li>Otherwise, delete the output from the temporary directory.</li>
772
773    <li>Remove the temporary object archive library.</li>
774  </ol>
775
776  <h2><a name="inheritance">Inheriting from a Pre-compiled Build</a></h2>
777
778  <p>A build can inherit configurations, source files and other items from a
779  previous build. At the Perl source code level, this is implemented via hash
780  tables and search paths. At the <em>Makefile</em> level, this is implemented
781  using the "vpath" directives. The following is a summary:</p>
782
783  <ul>
784    <li>Build targets are stored in a list. Targets that are specified in the
785    configuration file in the previous build are pushed into the list first.
786    A target that is specified in the current configuration file is pushed
787    into the list if it has not already been specified.</li>
788
789    <li>Each source directory has a unique sub-package identifier and a path
790    location. If a source directory in the previous build has the same
791    sub-package identifier, its location as specified in the previous build
792    will be placed in the search path of the source directory. The directory
793    specified in the current build is searched for files before the directory
794    specified in the previous build.</li>
795
796    <li>Tool settings such as compiler flags are set via the configuration
797    hash table. Settings declared in the previous build overrides those of the
798    default, and settings declared in the current build overrides those
799    declared in the previous build.</li>
800
801    <li>Ditto for exclude dependency, input file extension and output file
802    extension declarations.</li>
803
804    <li>Build items such as object files, executable files and other dummy
805    files are inherited via search path (and/or "vpath"). For example, the
806    system searches the "obj/" sub-directory of the current build for object
807    files before looking at that of the previous build. The system does not
808    re-build an item that exists in the previous build and is up to date.</li>
809  </ul>
810 
811  <script type="text/javascript">
812<!--
813document.body.appendChild(document.createElement('hr'))
814document.body.appendChild(displayMaintenanceInfo('doc/design/'))
815//-->
816</script>
817</body>
818</html>
Note: See TracBrowser for help on using the repository browser.