<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-html40"> <head> <meta http-equiv=Content-Type content="text/html; charset=windows-1252"> <meta name=ProgId content=Word.Document> <meta name=Generator content="Microsoft Word 9"> <meta name=Originator content="Microsoft Word 9"> <link rel=File-List href="./JamUseI_files/filelist.xml"> <title>Using Jam in a dynamic automated build enviroment</title> <!--[if gte mso 9]><xml> <o:DocumentProperties> <o:Author>Neal R. Firth</o:Author> <o:Template>Normal</o:Template> <o:LastAuthor>Neal R. Firth</o:LastAuthor> <o:Revision>3</o:Revision> <o:TotalTime>398</o:TotalTime> <o:Created>2002-12-17T01:17:00Z</o:Created> <o:LastSaved>2002-12-17T01:23:00Z</o:LastSaved> <o:Pages>2</o:Pages> <o:Words>708</o:Words> <o:Characters>4037</o:Characters> <o:Company>The Infrastructure Group, Inc.</o:Company> <o:Lines>33</o:Lines> <o:Paragraphs>8</o:Paragraphs> <o:CharactersWithSpaces>4957</o:CharactersWithSpaces> <o:Version>9.3821</o:Version> </o:DocumentProperties> </xml><![endif]--> <style> <!-- /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0in; margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:12.0pt; font-family:"Times New Roman"; mso-fareast-font-family:"Times New Roman";} p.Script, li.Script, div.Script {mso-style-name:Script; margin-top:0in; margin-right:0in; margin-bottom:0in; margin-left:.3in; margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:12.0pt; font-family:courier,monospace; mso-fareast-font-family:"Times New Roman"; mso-bidi-font-family:"Times New Roman";} @page Section1 {size:8.5in 11.0in; margin:1.0in 1.25in 1.0in 1.25in; mso-header-margin:.5in; mso-footer-margin:.5in; mso-paper-source:0;} div.Section1 {page:Section1;} --> </style> </head> <body lang=EN-US style='tab-interval:.5in'> <div class=Section1> <p class=MsoNormal>This example demonstrates the power of Jam as an integral component of an automated build environment with dynamic generation requirements.</p> <p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p> <p class=MsoNormal>A user had a build process that used a manual pre-operation configuration and typically ran for most of a day because their default dependency rule was build it just in case we missed it during configuration. Moreover, because of differences in generation environments, the development build process was different from the release engineering build process, which was in turn different from the build process used by support. The primary initial project goal was to automate the entire build process. A secondary goal was to make the build process common for all users. Combining Jam with some glue scripts achieved both of these goals, and more, in a relatively short period of time.</p> <p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p> <p class=MsoNormal>The primary glue script scans the current working directory and all of its subdirectories looking for either custom control or Jam files. Custom control and Jam files are uniquely identifiable through naming conventions. Custom control files are dynamically resolved into Jam files. Jam files are referenced directly. All of these Jam files are then referenced by a common include file that forms the input control for a Jam based build master.</p> <p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p> <p class=MsoNormal>The general form of the Jam based build master is:</p> <p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p> <p class=Script># Expected argument sequence:</p> <p class=Script>#<span style="mso-spacerun: yes"> </span>$1 - File to be generated</p> <p class=Script>#<span style="mso-spacerun: yes"> </span>$2 - Primary source for file being generated</p> <p class=Script>#<span style="mso-spacerun: yes"> </span>$3 - Configuration control files for source</p> <p class=Script>#<span style="mso-spacerun: yes"> </span>$4 - Generation program (with options)</p> <p class=Script><![if !supportEmptyParas]> <![endif]><o:p></o:p></p> <p class=Script>rule Generate {</p> <p class=Script><span style='mso-tab-count:1'> </span>GENERATOR on $(1) = $(4) ;</p> <p class=Script><span style='mso-tab-count:1'> </span>CONTROLS on $(1) = "-c "$(3) ;</p> <p class=Script><![if !supportEmptyParas]> <![endif]><o:p></o:p></p> <p class=Script><span style='mso-tab-count:1'> </span>Depends all : $(1) ;</p> <p class=Script><span style='mso-tab-count:1'> </span>Depends $(1) : $(2) $(3) $(4) ;</p> <p class=Script><![if !supportEmptyParas]> <![endif]><o:p></o:p></p> <p class=Script><span style='mso-tab-count:1'> </span>Generator $(1) : $(2) ;</p> <p class=Script>}</p> <p class=Script><![if !supportEmptyParas]> <![endif]><o:p></o:p></p> <p class=Script>actions ignore Generator {</p> <p class=Script><span style='mso-tab-count:1'> </span>$(GENERATOR) $(CONTROLS) -o $(1) $(2)</p> <p class=Script>}</p> <p class=Script><![if !supportEmptyParas]> <![endif]><o:p></o:p></p> <p class=Script># What has the script found this time??</p> <p class=Script><![if !supportEmptyParas]> <![endif]><o:p></o:p></p> <p class=Script>{</p> <p class=Script><span style='mso-tab-count:1'> </span>include ThisRun ;</p> <p class=Script>}</p> <p class=Script><![if !supportEmptyParas]> <![endif]><o:p></o:p></p> <p class=MsoNormal>The contents of ThisRun would reference Jam files that ultimately specified instructions such as this:</p> <p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p> <p class=Script>Generate O : Y : c1 c2 : bin\\gen ;</p> <p class=Script>Generate c1 : Z : c2 : bin\\cgen ;</p> <p class=Script>Generate c2 : Z : : bin\\cgen ;</p> <p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p> <p class=MsoNormal>Using this straightforward structure, all users can use the same build process because the process adapts to the users environment. A user only needs to populate their environment with the files being worked on. Instead of a manual, and often error prone, specification process the tools dynamically adapt to the users environment. Missing environmental dependencies are quickly identified as part of the Jam output. For example, if the cgen generator was missing from your environment in the example above, youd see something like this as output from Jam and youd know you were missing the generator program:</p> <p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p> <p class=Script>don't know how to make bin\cgen</p> <p class=Script>found 8 target(s)...</p> <p class=Script>can't find 1 target(s)...</p> <p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p> <p class=MsoNormal>And there were other benefits to using Jam in this process. Prior to this process, build times were not particularly predictable. Some types of generators typically ran for seconds, others for minutes, and others for tens of minutes. Evaluating build times or the impact of what if scenarios required significant effort. Jams o option presented a solution to this problem. For the example above, running Jam with the o option would generate output that looked like this:</p> <p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p> <p class=Script>bin\cgen<span style="mso-spacerun: yes"> </span>-o c2<span style="mso-spacerun: yes"> </span>Z </p> <p class=Script>bin\cgen<span style="mso-spacerun: yes"> </span>-c c2<span style="mso-spacerun: yes"> </span>-o c1<span style="mso-spacerun: yes"> </span>Z </p> <p class=Script>bin\gen<span style="mso-spacerun: yes"> </span>-c c1 -c c2<span style="mso-spacerun: yes"> </span>-o O<span style="mso-spacerun: yes"> </span>Y</p> <p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p> <p class=MsoNormal>The results are scanned for the presence of specific generators. Each instance of a specific generator is associated with a processing time estimate and thus build times can be predicted. Even for complex environments involving thousands of generated objects the processing time for the glue scanner, Jam, and the o evaluator was typically minutes.</p> <p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p> <p class=MsoNormal>Output from Jams o option was also used as input to a pre-generation validation of build results. This was very important in an environment where release build cycles were typically measured in significant fractions of a day. The output from running Jam with o could be scanned for important build elements. If an expected element build was not going to happen, you knew in minutes rather than in hours. This simple technique had a dramatic impact on release engineering productivity and the usability of releases.</p> <p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p> <p class=MsoNormal>This process has adapted and evolved over time to include new elements of the environment. Initially, the process encompassed the users custom generation needs. Eventually, the glue scanner was enhanced to scan Microsoft Visual Studio VBP and DSP files for dependencies that were used as input to a generator compilation rule.</p> <p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p> <p class=MsoNormal>Jams inherent separation of platform-dependent issues was also a benefit. Initially, this process was developed and debugged in a Windows environment. Having used Jam as the build manager made adapting these processes to MAC and UNIX systems a straightforward task. The generated Jam scripts transported as is. The most complex part of the porting task was adapting the glue scanners.</p> </div> </body> </html>
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#2 | 2588 | Neal Firth | Update for Jam example. | ||
#1 | 2510 | Neal Firth |
Revised for internal information consistency and use of fixed space fonts in the code/output text. |