source: LMDZ5/trunk/tools/fcm/doc/design/build.html @ 4014

Last change on this file since 4014 was 1578, checked in by jghattas, 13 years ago
  • Add fcm in LMDZ5/tools directory

It is no longer needed to have fcm in your environement PATH variable.
Now makelmdz_fcm takes by default this fcm. It is still possible to use
another fcm, using -fcm_path argument in makelmdz_fcm.

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