ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/doc/tex/manual/BuildSystem.tex
Revision: 1.7
Committed: Wed Feb 28 12:41:28 2007 UTC (18 years, 2 months ago) by sashby
Content type: application/x-tex
Branch: MAIN
CVS Tags: HEAD_SM_071214, V1_1_0, v110p1, V110p6, V110p5, V110p4
Branch point for: HEAD_BRANCH_SM_071214
Changes since 1.6: +2 -2 lines
Log Message:
Updates to doc.

File Contents

# Content
1 %%____________________________________________________________________
2 %% File: BuildSystem.tex
3 %%____________________________________________________________________
4 %%
5 %% Author: Shaun ASHBY <Shaun.Ashby@cern.ch>
6 %% Update: 2005-11-02 17:07:01+0100
7 %% Revision: $Id: BuildSystem.tex,v 1.6 2007/02/27 16:16:01 sashby Exp $
8 %%
9 %% Copyright: 2005 (C) Shaun ASHBY
10 %%
11 %%--------------------------------------------------------------------
12 \chapter{The SCRAM Build System}\label{ch:buildsystem}
13
14 The primary function of the \scram\ build system is to allow efficient,
15 ordered compilation of source code of different types (\eg \texttt{C},
16 \texttt{C++}, \texttt{FORTRAN}) into libraries, binary executables or
17 other build products and to make it possible to easily extend the
18 supported product types, as dictated by changing project requirements,
19 and manage external and internal dependencies between software units
20 in a transparent and uniform way.
21
22 \ni In previous versions of \scram, much of the build system functionality
23 was hard-coded in parts of the \scram\ source tree making it difficult
24 to make changes to adapt to changing software development patterns.
25 Any such change often meant a new release of \scram\ and the
26 subsequent delays entailed by a release sequence. In addition, the
27 actual algorithm for determining what build actions should be
28 activated for each software unit was not optimum with many
29 configuration documents needlessly being parsed multiple times,
30 greatly adding to project build times. This fundamental problem
31 stemmed from the fact there was never a clear separation between
32 parsing of configuration documents and the creation of a
33 \texttt{Makefile}- the two were run on the fly. Supporting the
34 building a project for a new architecture, particularly where the
35 syntax of the \texttt{Makefile} is very different (\eg
36 \texttt{WIN32}), was also practically impossible within the old
37 design.
38
39 \ni In \scram~\scramvx, a new approach is taken by separating the
40 collection of build metadata from the generation of the
41 \texttt{Makefile} and compilation of the software units. Metadata in
42 this context refers to all information needed to build all products.
43 This includes package-level dependency requirements and all
44 information needed to use external tools (\eg libraries to link
45 against, compilation flags, pre-processor macros, library directories,
46 header file locations and runtime requirements).
47 Having parsed all necessary project documents, and the metadata
48 obtained and processed as required, data elements are substituted
49 into text templates to create the project \texttt{Makefile}. The data
50 elements include directory names, library names and names of
51 build targets all of which must be generated by \scram.
52 Of course, the text templates can be written so that the output is in
53 some other format than that for a \texttt{Makefile}.
54
55 \section{BuildFiles and Build System Control}
56
57 The \buildfile\ is the configuration document for the build system. For
58 each software unit, a \buildfile\ defines the external dependencies, the
59 internal dependencies (\ie the other software units that are used by
60 this one) and the interface. This interface supplies the product
61 provided by this software unit and the external/internal dependencies
62 required by it to any other software unit that requires it.
63 A software unit can be thought of as a product entity which is self-contained
64 and can be used either in linking to satisfy the dependencies of
65 a build product, or can be used to participate in some way on the
66 build process (for example, an executable used to process a source
67 file template to generate soucre files in a particular package).
68 Most of the time, a software unit is synonymous with a package (and
69 hence a shared library).
70
71 \subsection{The Markup Syntax}
72 \index{\buildfile}\index{SCRAM!build files}
73
74 Differing from other configuration documents in which the document
75 class defines the parse type, \scram\ knows about build files only
76 from their name, which must be \buildfile.xml\footnote{\textit{note the uppercase letters!}.}.
77 A \buildfile\ only has a significance in a project area. The
78 valid tags that can be used in a \buildfile\ are listed below.
79 \index{\buildfile!valid basic markup tags}
80
81 \begin{description}
82
83 \item[\lbkt\texttt{use} name=\textit{"unit"}$/$\rbkt]\mbox{}\\
84 Specify that there is a dependency on an external tool or a
85 local/external package \texttt{unit} (\eg a library, or everything the package
86 exports). External tools and packages are treated in the same way.
87 The interface to \textit{unit} must be defined via the
88 \lbkt\texttt{export}\rbkt\tagend{export} tag.
89
90 \item[\lbkt\texttt{export}\rbkt\tagend{export}]\mbox{}\\
91 A software unit can be declared and exported to be used inside the
92 project or externally by another \scram\ project using the current
93 project as an external tool. The interface is defined by listing
94 the libraries (this can include those corresponding to a subset of a
95 subsystem) that are to be exported when the package (or subsystem)
96 is used. Typically, a package will export its' library, all
97 dependencies and specific compiler flags.
98
99 \item[\lbkt\texttt{lib} name=\textit{"libname"} {[}\texttt{position}=\textit{"first"}{]}$/$\rbkt]\mbox{}\\
100 Add a library to the list of libraries passed to the linker. The
101 optional \texttt{position} argument will move the library to the
102 front of the list of libraries as received by the linker (this
103 bypasses the automatic library ordering as determined by depth-first
104 sorting of the package metadata).
105
106 \item[\lbkt\texttt{group} name=\textit{"groupname"}$/$\rbkt]\mbox{}\\
107 Specify that all dependencies defined within the group
108 \textit{groupname} should be used by the current software unit.
109
110 \item[\lbkt\texttt{include\_path} path=\textit{"path"}$/$\rbkt]\mbox{}\\
111 Add the path \textit{path} to the global \texttt{INCLUDE} path
112 passed to the compiler. The include paths of individual
113 tools/packages will be ordered according to their dependency order
114 when added to the project or package \texttt{INCLUDE}.
115
116 \item[\lbkt\texttt{libtype} type=\textit{"type"}$/$\rbkt]\mbox{}\\
117 Specify the type of library that should be built.
118 This option overrides the project defaults but is currently unused
119 since libraries are \texttt{shared} only.
120
121 \item[\lbkt\texttt{flags} \texttt{NAME}="definition"$/$\rbkt]\mbox{}\\
122 Extra compiler flags can be added either in a tool description or in
123 a package. These flags will be added to the global compiler flags
124 and propageted to the build product defined in the \buildfile\ where
125 the declaration was made.
126 \end{description}
127
128 \ni There are also tags for the supported build products:
129 \index{\buildfile!valid product markup tags}
130 \begin{description}
131
132 \item[\lbkt\texttt{bin} file=\textit{"filename"} {[}name=\textit{"name"}{]}\rbkt\tagend{bin}]\mbox{}\\
133 Specify an executable to build. The name of the executable can be
134 changed using the optional \textit{name} argument, otherwise the
135 name will be the same as \textit{filename}, less the file ending
136 (typically `.cpp'). More than one file can be compiled and linked to
137 make the executable. The file list can be specified like "main.cpp,
138 *.cc", "*.cpp" or "main.cpp, file.cc" (\ie file globs are
139 supported in a minimal way).
140
141 All dependencies are contained between the opening and closing tags:
142 these dependencies are specific \textit{only} to this binary
143 executable. Dependencies or other metadata listed outside the
144 individual product tag will be passed to all products defined in the
145 \buildfile.
146
147 \item[\lbkt\texttt{module} file=\textit{"filename"} {[}name=\textit{"name"}{]}\rbkt\tagend{module}]\mbox{}\\
148 Specify a plug-in module to build. The name of the module can be
149 changed using the optional \textit{name} argument. How the plug-in
150 is defined can be customised within the project. By default (\ie
151 when using initial templates provided with \scram, copied to a
152 project \texttt{config} directory), a plug-in module is just a shared
153 library with all dependencies fully resolved when it is loaded (in
154 fact, there is not much difference between a plug-in module and a
155 shared library built by default in package \texttt{src} directories).
156
157 \item[\lbkt\texttt{library} file=\textit{"filename"} {[}name=\textit{"name"}{]}\rbkt\tagend{library}]\mbox{}\\
158 Define an additional library to build (in addition to the library
159 built automatically from the contents of \texttt{src} in the parent
160 package directory). This is usually used to build libraries for unit tests.
161
162 \item[\lbkt\texttt{application} file=\textit{"filename"} {[}name=\textit{"name"}{]}\rbkt\tagend{application}]\mbox{}\\
163 Define an application. How one defines an application is
164 project-specific: it could be that an application differs from a
165 binary executable in only the compiler flags or the storage
166 location when released. This product type could also be used to
167 inject custom rules into the build system.
168
169 \item[\lbkt\texttt{plugin} file=\textit{"filename"} {[}name=\textit{"name"}{]}\rbkt\tagend{plugin}]\mbox{}\\
170 Specify a plugin module to build. This type of product is for a
171 specific kind of plugin where certain actions must be performed to
172 register the plugin to a manager. Templates for this product type
173 can be implemented to handle any such actions without developers
174 having to remember what those actions are. Otherwise, this product
175 is the same as a \texttt{module}.
176
177 \item[\lbkt\texttt{unittest} file=\textit{"filename"} {[}name=\textit{"name"}{]}\rbkt\tagend{unittest}]\mbox{}\\
178 Specify a unit test executable to build. Customisations are handled
179 inside the generic build templates. Otherwise, this is basically a
180 \texttt{bin} product.
181
182 % Not yet advertised: <<FIXME
183 %\item[\lbkt\texttt{skip}\rbkt\tagend{skip}]\mbox{}\\
184 % Indicate that a directory should be skipped. Comments can be entered
185 % between the tags which will be printed to STDOUT during building.
186 % \textit{Work in progress!!}.
187 %
188 \end{description}
189
190
191
192 \subsection{The Project BuildFile}\label{sec:projectbuildfile}
193 \index{\buildfile!project}
194
195 Global behaviour is controlled by the project \buildfile\ which is
196 located in the \texttt{config} directory in all \scram-managed
197 projects. This file is parsed first, before all others. The
198 storage areas for build products are defined in this \buildfile. More
199 importantly, instructions on what actions to perform throughout the
200 source code tree occur here using \texttt{classpath} directives.
201 The directives indicate which templates to apply at each directory
202 location based on matching the directory structure to the class path.
203 There are three keywords which refer to certain levels in a directory
204 tree and the definitions of these are fixed. The keywords are
205 \texttt{Project}, which refers to the top-level source directory
206 (usually \texttt{src}), \texttt{SubSystem}, which refers to the
207 directory one level up, and \texttt{Package}, which refers to a
208 subdirectory of a \texttt{SubSystem}. A project is not bound to a
209 structure in which there are always subsystems: in fact, it is
210 possible to have only a package level under the project \texttt{src}
211 directory. The advantage to having subsystems is that it becomes
212 possible to group packages together according to some common task (for
213 example): groups can then be defined which allow several independent
214 packages to become a single dependency unit which can be used by other
215 packages or executables at link-time.
216
217 \ni Each directory which is an exact match to a keyword location will be
218 flagged as such and \textit{structure templates}\index{structure templates}
219 will be used to create the rules for compiling in these locations.
220 Of course, it is possible to redefine what actions to apply at the
221 subsystem, package or even project level, just by supplying a different
222 template or overriding an action in the project class path.
223 For libraries and executables (in general, build products), which are
224 associated to a subdirectory inside a package, \textit{product
225 templates} define the build targets.
226 Generated build rules for directories that do not fully match any
227 \texttt{classpath} will simply print a message that no action is required
228 at that location (\eg for an \texttt{include} or \texttt{interface} directory).
229 Complex build operations can be activated by modifying the
230 structure templates to do specific things for specific directories.
231 This could be for a \texttt{Documentation} subsystem, for example,
232 where the source code happens to be \texttt{html} or \LaTeX\
233 sources, or for single packages where source code must be generated
234 first before normal package build actions.
235
236 \ni The syntax of the \texttt{classpath} tag is \index{\texttt{classpath}
237 tag}%
238 \begin{tagprint}
239 \lbkt\texttt{classpath}
240 path="{[}\textit{pattern\_match}{]}+\textit{template\_type}/\ldots"$/$\rbkt
241 \end{tagprint}
242
243 \ni In the above case, the \texttt{template\_type} could be
244 \texttt{library}, \texttt{binary} \texttt{module} \etc. (the build
245 products). The template file name corresponding to the
246 \texttt{library} template type would be
247 \texttt{library\_template.tmpl} and this would be located in the
248 \texttt{config} directory of the project. Note that where there are
249 multiple \lbkt\texttt{classpath}\rbkt tags defined, it is always the
250 last tag that matches the current location that will be used.
251 See examples in Chapter~\ref{ch:examples}.
252
253 \subsubsection{Product Storage Locations}
254 \index{\texttt{productstore} tag}%
255
256 The storage locations are defined using
257 \begin{tagprint}
258 \lbkt\texttt{productstore} name=\textit{"name"} {[}type=\textit{"type"}
259 swap=\textit{"t"}{]} {[}path=\textit{"path"}{]}$/$\rbkt
260 \end{tagprint}
261
262 \ni The name \textit{name} is the name of the directory to be created
263 and the option \textit{type} can be set to \texttt{arch} so that an
264 architecture-dependent subdirectory for platform-specific products
265 will be added in the project area with the product directory
266 \textit{name} underneath. Without this type option the directory
267 \textit{name} will be created in the project area. Using the
268 \textit{swap} option reverses the order of the architecture-dependent
269 sub-directory and the name of the storage directory. That is, setting
270 swap to \textit{true} or \textit{t} will create the product directory
271 first with an architecture-dependent sub-directory
272 underneath.\footnote{This is the fixed behaviour for all SCRAM
273 releases prior to \scramvx.}
274
275 \ni The path \texttt{path} can be specified as the location where all
276 products corresponding to \textit{name} will be installed: a symbolic
277 link will be created in the project area which points to this
278 directory.
279
280 \ni When \scram\ finds a \tagstart{productstore} tag,
281 a \texttt{Makefile} variable is set which can be used anywhere in a project makefile
282 when writing custom rules:
283 \begin{description}
284 \item[\texttt{SCRAMSTORENAME\_name}]\mbox{}\\
285 The path to the storage location \texttt{name} from the project area
286 directory (\eg \texttt{lib} or \texttt{lib/slc3\_ia32\_gcc323}).
287 \end{description}
288
289 \ni This could be used, for example, where there may be a default rule for
290 copying all \texttt{include} files to a single location after building
291 all libraries. By default, all build products are copied to their
292 storage areas once built.
293
294 \subsection{Local Metadata}\index{local metadata}\index{config/self}
295
296 In order to propagate metadata from the local area to the source tree
297 at compile time, the local settings like \texttt{INCLUDE} or library paths in the
298 project templates plus the runtime environment, are defined in a local
299 file called \texttt{Self.xml} found in the \texttt{config} directory\footnote{Note that this is unlike \scram\ V0 where
300 such settings were hard-coded in the top-level \buildfile.}.
301 This file behaves like a tool description file and is set up when the project
302 area is bootstrapped: all of the information defined within it is
303 automatically propagated to the whole tree.
304 In addition, all \texttt{scram} commands used to query tools
305 can also be used to inspect the local settings and changes can be made
306 at will with the tool set up by hand to propagate new settings.
307
308 \subsection{Defining Groups}\label{sec:defininggroups}
309 \index{software units!defining a group}
310 A group can be used by adding a a \lbkt\texttt{group}\dots\rbkt statement
311 giving the name of the group to be included.
312
313 \ni A group can be defined like this
314
315 \small{
316 \begin{verbatim}
317 <define_group name="GA">
318 <use name="D"/>
319 <use name="zlib"/>
320 <group name="XY"/>
321 <Flags CPPFLAGS="-DGROUP_GA"/>
322 </define_group>
323 \end{verbatim}
324 }\normalsize
325
326 \ni in a subsystem \buildfile.
327
328 \ni Note that it is not necessary to declare where the group can be
329 found (for example in another \scram\ project included as an
330 external product in the local configuration environment) since \scram\
331 determines this automatically. Duplicated/overridden groups will raise
332 a warning when \scram\ parses the \buildfile.
333
334 \section{Configuring a New Package}
335 \label{sec:exportingsoftwareunits}
336 \index{software units}
337 \index{software units!defining the interface to}
338
339 When a new package is added to a project, it is important that the
340 directory contains a \buildfile\ (note that it must be the package
341 directory and \textit{not} the \texttt{src} directory where the
342 sources are located that contains the \buildfile).
343 This \buildfile\ should have the following components:
344 \begin{description}
345 \item[\textbf{Declarations for all compile-time/link-time dependencies}]\mbox{}\\
346 The dependencies should be deduced from the \texttt{include}
347 statements in the package sources and a \lbkt\texttt{use}
348 name=\textit{"unit"}$/$\rbkt should be added for each required unit
349 (external/internal package or external software product) which
350 provides a library needed at link-time.
351 \item[\textbf{Export of the dependencies and package product}]\mbox{}\\
352 Every package providing a shared library should permit client software
353 units to use it at compile or link time. The
354 \lbkt\texttt{export}\rbkt\tagend{export} tag is used to define the
355 interface to the package and contains the full list of
356 \lbkt\texttt{use} name=\textit{"unit"}$/$\rbkt statements (as required
357 by the package) and a \lbkt\texttt{lib} name=\textit{"PackageName"}$/$\rbkt
358 statement with the name of the library provided by the package.
359 \end{description}
360
361 \ni A typical package \buildfile\ will look like this:
362 \index{example of using \texttt{export} tag}%
363 \index{software units!exporting}%
364 \small{
365 \begin{verbatim}
366 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
367 <doc type="BuildSystem::BuildFile" version="1.0">
368 <export>
369 <lib name="PX"/>
370 <use name="S/A"/>
371 <use name="B"/>
372 </export>
373
374 <use name="S/A"/>
375 <use name="B"/>
376 </doc>
377 \end{verbatim}
378 }\normalsize
379 \index{defining a set of libraries for a package}
380 \ni Any other package or executable requiring this package would have
381 a statement \lbkt\texttt{use} name=\texttt{"PX"}$/$\rbkt
382 in the \buildfile\ of the package/executable, where
383 \texttt{"PX"} is a path to the package in the
384 project (and hence could actually look like \lbkt\texttt{use}
385 name=\texttt{"Subsystem/PX"}$/$\rbkt if the package is located in
386 a subsystem).
387
388 \ni External projects and external tools can be used in the same way
389 using the \texttt{use} statement, \ie it is not necessary to qualify
390 the statement with a project name as with the older \scram\ syntax.
391
392 \section{Build System Caches}
393 \label{sec:bscaches}
394 \index{Build system!caches}
395
396 Tracking changes to files in the source tree is achieved by caching
397 file timestamps and this is especially important for files that are
398 part of the project configuration. Caching is also extensively used
399 to store metadata as it is read from the \buildfile s
400 and tool description documents and to minimise subsequent re-parsing of
401 build data when the dependencies of a target change.
402
403 \subsection{File Timestamp Cache}
404 \label{sec:bstscache}
405 \index{File Timestamp Cache}
406
407 Build tools like \texttt{Make} keep track of relationships between
408 targets and the source files or headers needed to build those targets.
409 When a timestamp on a source file or header changes, \texttt{Make}
410 knows how to rebuild the target having determined that the target is
411 out of date with respect to those modified files. A limitation arises
412 when code is retrieved from a code repository such as one based on
413 \texttt{CVS}. Often, the timestamps on checked-out files are in the
414 past (usually the time of the commit) which implies that a target will
415 not be rebuilt if these files are added to the source code tree since
416 they will be older than the target.
417
418 \ni To cope with situations like this, \scram\ employs a cache mechanism
419 which stores the timestamps of the \buildfile s and the directories in
420 the source code tree. Note that it is not necessary to store the
421 timestamp of every source file since it is the change of timestamp of
422 the parent directory that will change when files are added or removed.
423 Once populated (when \scram\ first performs a build), the existing
424 cache will be used to determine when the status of a directory or a
425 file has changed. Such a change to the status can be found by using
426 the \texttt{stat} command and comparing information like access mode
427 in addition to the timestamp. Changes in timestamp provoke a rebuild
428 of the updated package. If a \buildfile\ changes then the package is
429 rebuilt automatically, otherwise \scram\ will trigger a rebuild by
430 modifying the timestamp of the \buildfile\ of the package where the
431 files were added or removed first.
432
433 \subsection{Metadata Cache}
434 \label{sec:bsmdcache}
435 \index{Metadata Cache}
436
437 The actions to be taken by the build system when compiling and the
438 relationships between project software units are described in
439 \buildfile s located in the package directories in the source
440 code tree and the project configuration directory. Since it is
441 important to discover when metadata has changed, the timestamps of all
442 templates and the tool cache are also monitored. Since a change in a
443 tool setting or a template could affect the whole project, these
444 changes force a reparse of all \buildfile s and a complete rebuild of
445 the project.
446
447 \section{Understanding the Build Templates}
448 \label{sec:bstemplates}
449 \index{Build system!buildtemplates}
450
451 Many open source and commercial software projects use \texttt{make} to manage rebuilds
452 of large programs or collections of programs. Each build action is
453 defined using a rule which describes the steps that should be executed
454 to build the program. The rules are written in a file called a
455 \texttt{Makefile}. In very large projects, a \texttt{Makefile} can typically be
456 thousands of lines long and is very difficult to write
457 from scratch and manage manually; it is preferable to generate it
458 automatically using a more abstract process. Since \scram\ projects can
459 contain many occurrences of the same class of build object (\eg shared
460 libraries, executables), a complete \texttt{Makefile} can be
461 generated from templates which implement the rules for these different classes.
462 Thus, \scram\ can generate a \texttt{Makefile} for a complex project structure easily.
463
464 \subsection{What is a Template?}
465
466 A template is a file which is written in the same way as a
467 \texttt{Makefile} except that some parts of the rules or environment
468 variables are inserted at the time of generation.
469
470 %%\begin{center}
471 %% \textit{More to be added here over time. Check snapshots pages!}
472 %%\end{center}
473
474 % An Example Rule: <<FIXME
475
476
477
478
479 %% Build System
480 %% ------------
481
482 %% The SCRAM version 1.0 build system consists of two stages. Firstly,
483 %% all external requirements and build actions are determined and cached
484 %% for every location in the project. Secondly, the processed metadata
485 %% (lists of libraries used, INCLUDE/LIBDIR paths and compiler flags) are
486 %% used by the template engine to produce Makefile fragments used by
487 %% gmake in the usual way. Templates can easily be adapted to support
488 %% both different kinds of compilations (e.g. using java) or different
489 %% architectures.
490
491 %% The project data and the state of the project area are made persistent
492 %% so that, by checking the current state relative to the last cached
493 %% state, any new actions (e.g. a rebuild after a modification to a BuildFile)
494 %% can be affected very quickly without resorting to a traversal of the
495 %% entire directory tree.
496
497
498 %% - The Directory Cache
499
500 %% In an empty project area, the first step is to populate the directory
501 %% cache with the timestamp and content information for the project
502 %% directory tree. All timestamps and file modes are stored for parent
503 %% and subdirectories in the ``src'' tree. Parameters for important files
504 %% used in the build system, such as templates and other files in
505 %% ``config'' are also recorded. The timestamps of other directories in
506 %% the project area (tmp and build product stores for example), are not
507 %% stored.
508 %% Once the timestamp information is stored, the cache (simply a Perl
509 %% object of type ``Cache::Cache'') is converted to a data structure
510 %% using the CPAN module ``Data::Dumper'' and written to a file
511 %% called ``.SCRAM/DirCache.db''. This is the directory cache.
512 %% Removing this file will result in a re-read of the directory tree and
513 %% repopulation of the cache on a subsequent ``scram build''. This can
514 %% happen intentionally via a ``scram build distclean''.
515
516
517
518 %% - The Build Metadata Cache
519
520 %% The next step is to collect the build metadata and store it in a cache
521 %% that is separate to the directory cache. This cache is also a Perl
522 %% object (the same methods are used for reading and writing caches in
523 %% all cache handling operations in SCRAM version 1.0) which is written
524 %% to a file called ``.SCRAM/ProjectCache.db''. The object is of type
525 %% ``BuildSystem::BuildDataStorage''.
526
527 %% After checking that there is a project BuildFile in the config
528 %% directory, which is essential for obtaining the ClassPath data which
529 %% directs all build operations, each directory known to the directory
530 %% cache is scanned. Every path is assigned a ``BuildSystem::TreeItem''
531 %% object which is used to store all metadata required by the template
532 %% engine which will be used to generate a Makefile.
533
534 %% Two main actions are performed for each path:
535 %% ---------------------------------------------
536
537 %% i. if a BuildFile exists under ``path/Buildfile'', it is parsed and
538 %% this raw data is stored in the TreeItem object. Any groups defined in
539 %% the BuildFile are recorded in the build cache as a KNOWNGROUPS hash
540 %% with the name of the group as the key and the path to the buildFile
541 %% defining it as the value. This is required so that later the
542 %% KNOWNGROUPS hash can be used as a lookup table when resolving
543 %% <group name=X> type tags.
544 %% The raw metadata is itself stored as an object of type
545 %% ``BuildSystem::BuildFile'' in the TreeItem.
546
547 %% ii. the path is compared to each known ClassPath (as obtained from
548 %% config/BuildFile) to establish what build actions should be applied
549 %% there. The directory is assigned the following based on a best match to a
550 %% ClassPath:
551
552 %% - a class, i.e. a type of template to apply (Project, SubSystem,
553 %% Package, Library, Binary, etc..)
554
555 %% - a classdir, the part of the path that matched the ClassPath
556
557 %% - a suffix, the part of the path that dir *not* match
558
559 %% Because package dependencies are in general stated in <use name=X>
560 %% tags as ``subsystem/package''and not ``src/subsystem/package'', the
561 %% path is converted to a DATAPATH by removing the ``src'', or rather,
562 %% by removing the start of the path that matches \$ENV{SCRAM\_SOURCEDIR}.
563 %% This data is stored in the TreeItem which is itself stored in the
564 %% build cache, accessed using the DATAPATH as the key. This provides an
565 %% efficient lookup table for accessing package-level metadata when
566 %% resolving build requirements.
567
568 %% The parent directory and subdirectories (children) are recorded in
569 %% each TreeItem: this allows traversal from parent to children (a
570 %% directory ``branch'') and when coupled with the class information, can
571 %% permit simple determination of proper locations for build actions
572 %% (i.e. the actual path where the build of a certain class should be
573 %% applied) and greatly facilitates updating of build data when a
574 %% BuildFile somewhere in the branch has been modified. Thus it is not
575 %% necessary to reparse all BuildFiles after an modification to only one
576 %% of them.
577
578
579 %% Updating Metadata
580 %% -----------------
581
582 %% At the start of a build, the directory cache is scanned and files that
583 %% are new or have newer timestamps are updated. Any BuildFiles that have
584 %% been updated are passed to the update routines of the
585 %% ``BuildSystem::BuildDataStorage'' object which is responsible for
586 %% collecting and managing the metadata.
587 %% The BuildFiles are re-parsed and the TreeItem for the path and any
588 %% subdirectories is updated. Only the BuildFiles that have been
589 %% modified are re-processed in this way and thus, only the relevant
590 %% makefile fragments, are remade. After updating, the directory cache is
591 %% marked as up-to-date and the build proceeds as normal.
592
593
594 %% From Metadata to Makefile
595 %% -------------------------
596
597 %% Once all metadata is available, the template engine takes over. The
598 %% TemplateInterface object, which is a global, handles the interfacing
599 %% to the templates and their plugin modules.
600 %% The templates know how to obtain the metadata from the collected data
601 %% via the methods in the plugins. The TreeItem object provides all
602 %% needed metadata for a particular path: once the template engine has a
603 %% TreeItem, it uses methods in the PluginCore object to obtain
604
605 %% - lists of libraries in link order;
606 %% - LIBDIR and INCLUDEDIR lists in link order;
607 %% - compiler flags and makefile text, correctly formatted;
608 %% - package dependencies
609
610
611
612
613 %% Using Private Plugins
614 %% ---------------------
615
616
617 %% Customizations can be provided by way of project Template plugin
618 %% modules. These modules are standard Perl modules, inheriting from the
619 %% SCRAM base plugin module class.
620
621 %% For example, to override the main PluginCore module, one could do the
622 %% following:
623
624 %% - Write a module called SCRAM::Plugins::MyPluginCore inheriting from
625 %% BuildSystem::Template::Plugins::PluginCore;
626
627 %% - Add
628 %% [% USE MyPluginCore %]
629
630 %% to the project templates. The build system will then have access to
631 %% customized build metadata.
632
633 %% NB: Custom base class MUST be SCRAM::Plugins....
634
635
636
637
638
639
640 %% \section{Brief Description of the Build Process}\label{sec:buildprocess}
641 %% \index{description of the SCRAM build process}
642
643 %% Assuming that the build area is clean (no builds have already been
644 %% performed) and that all tools are correctly set up, the actions taken
645 %% by \scram are as follows:
646
647 %% \begin{itemize}
648 %% \item Initially, \scram checks the current location to test if it is a
649 %% project area. If it isn't, an error message like
650
651 %% %% \small{\begin{verbatim}
652 %% %% SCRAM error: Unable to locate the top of local release. Exitting.
653 %% %% \end{verbatim}}\normalsize
654
655 %% \ni will appear on \texttt{STDERR}.
656
657
658 %% \item Tool settings are read and a makefile stub is created which
659 %% contains all relevant path information for all tools in makefile
660 %% syntax. The makefile stub is called \texttt{clientmakefile} and
661 %% is located in the directory \texttt{tmp} in the project area.
662
663 %% \item \scram parses the project \texttt{BuildFile}, creating a
664 %% corresponding makefile called \texttt{BuildFile.mk} located
665 %% under \texttt{tmp/config}. The \texttt{ClassPath} settings are
666 %% parsed to determine the appropriate build actions.
667
668 %% \item A makefile is created according to the current directory.
669 %% The makefile is located in a directory under \texttt{tmp/src}
670 %% which has the same name as the current directory. This makefile
671 %% will be merged with appropriate makefiles determined from the
672 %% \texttt{ClassPath} and will include the makefile generated from
673 %% the project \texttt{BuildFile}. A list of subdirectories in
674 %% which build actions should occur is stored in a make variable
675 %% \texttt{\$(SUBDIRS)}-- the build order of various packages is
676 %% the same as the order in which the package directories appear in
677 %% this variable. To view the order, type \texttt{scram b echo\_SUBDIRS}.
678
679 %% \item Before running \texttt{gmake}, the generated makefiles are
680 %% merged with \texttt{basics.mk} from the \scram sources (which
681 %% also includes \texttt{toolrules.mk} which contains the rules
682 %% for compiling different file types and how to create libraries,
683 %% binaries or modules).
684
685 %% \item The build runs: any extra makefile statements or compiler
686 %% flags are passed directly to \texttt{gmake}. The working directory for
687 %% compilation is \texttt{/tmp/\$(SCRAM\_ARCH)}. Errors and warnings
688 %% are reported directly to standard output.
689
690 %% \item The build products are moved from the working directory to
691 %% the product storage areas.
692
693 %% \end{itemize}
694
695
696 %%% Local Variables:
697 %%% mode: latex
698 %%% TeX-master: "SCRAM-manual"
699 %%% End:
700
701 %%____________________________________________________________________
702 %% End of BuildSystem.tex
703 %%____________________________________________________________________
704 %%