📄 jamfile.html
字号:
<HTML><TITLE>Jamfiles and Jambase</TITLE><BODY><CENTER><A HREF=http://www.perforce.com/jam/jam.html>Jam</a><A NAME="TOP"><H2>Using Jamfiles and Jambase</H2></A></CENTER><P>This document describes how to write Jamfiles using the Jam Jambase rules to build software products. Related documents of interest are:<UL><LI> <a href="Jam.html">The Jam Executable Program</A>, which describes using the <b>jam</b> command and the langauge used in Jambase<LI> <A href="Jambase.html">Jambase Reference</A>, which summarizes the Jambase rules and variables</UL><P>Jam documentation and source are available from the<A HREF=http://public.perforce.com/public/index.html>Perforce Public Depot</a>.<HR><P><H2>Overview</H2><P> <B>jam,</B> the Jam executable program, recursively builds target files from source files using dependency and build specifications defined in Jam rules files. <B>jam</B> parses the rules files to identify targets and sources, examines the filesystem to determine which targets need updating, and issues OS commands to update targets.<P> A base rules file called "Jambase" is provided with the Jam distribution. The Jambase file defines rules and variables which support standard software build operations, like compiling, linking, etc.<P> When the Jambase rules are used, <B>jam</B> reads Jambase, then reads a file called "Jamfile" in the current directory. The Jamfile describes what to do with the source files in its directory. It may also cause Jamfiles in other directories to be read. <P> Under certain circumstances, the first Jamfile read also causes a site-specific "Jamrules" file to be read. The Jamrules file is an optional set of rule and variable definitions used to define site-specific processing.<P><H4>The Basic Jamfile</H4><P>Jamfiles contain rule invocations, which usually look like:<PRE> <I>RuleName</I> <I>targets</I> : <I>targets</I> ;</PRE>The target(s) to the left of the colon usually indicatewhat gets built, and the target(s) to the right of thecolon usually indicate what it is built from.<P><P>A Jamfile can be as simple as this:<PRE> Main myprog : main.c util.c ;</PRE>This specifies that there is a main.c and util.c file in the samedirectory as the Jamfile, and that those source files should becompiled and linked into an executable called myprog.If you cd to the directory where this Jamfile lives,you can see the exactly how <b>jam</b> would build myprog with:<PRE> jam -n</PRE>Or, you can actually build myprog with the command:<PRE> jam</PRE><P><H4>Whitespace</H4>Jamfile elements are delimited by whitespace (blanks, tabs, ornewlines). Elements to be delimited include rule names, targets,colons, and semicolons. A common mistake users make is to forget thewhitespace, e.g.,<PRE> Main myprog: main.c util.c ; #<I>WRONG!</I></PRE>Jam doesn't distinguish between a typo and a target called "myprog:", so if you get strange results, the first thingyou should check for in your Jamfile is missing whitespace.<P><H4>Filenames, Target Identifiers, and Buildable Targets</H4><P>Consider this Jamfile:<PRE> Main myprog : main.c util.c ; LinkLibraries myprog : libtree ; Library libtree : treemake.c treetrav.c ; </PRE><P>The Main rule specifies that an executable called myprog will be built.The compiled main.c and util.c objects will be linked to producemyprog. The LinkLibraries rule specifies that libtree willbe linked into myprog as well.The Library rule specifies which source files will be compiled andarchived into the libtree library.<P>The Jamfile above refers to targets like "myprog" and "libtree". However, depending on the platform you're building on, the actualfilenames of those targets could be "myprog.exe" and "libtree.lib".Most Jambase rules supply the actual filenames of targets,so that Jamfiles themselves need not make anyplatform-specific filename references.<P>The <b>jam</b> program builds up a list of unique target identifiers.Unless you are using the SubDir rules (described later),the default identifier for a file target is its filename. In the aboveexample, the target identifiers are the filenames: myprog.exe,libtree.lib, main.obj, etc.<P>While all Jambase rules refer to "targets",not all targets are buildable.There are two kinds of buildable targets: file targets and pseudotargets.File targets are objects that can be found in the filesystem.Pseudotargets are symbolic, and represent other targets.<P>You can use any buildable target on the <b>jam</b> command line tobuild a subset of defined targets. For example:<PRE> jam libtree.a </PRE>on Unix builds the libtree library and all the compiled objectsthat go in it.<P><H4>Pseudotargets</H4><P>Most Jambase rules that define file targets also define pseudotargetswhich are dependent on types of file targets.For example, Jambase defines a pseudotarget called "lib", which is dependent on file targets created by the Library rule. So the command: <PRE> jam lib</PRE> used with the above example would cause the libtree library to be built.Also, there is one pseudotarget built into <b>jam</b> itself, called"all". Jambase sets "all" dependent on (almost) all other targets.<P>In the unfortunate case where you have a buildable target whose nameis the same as one of the Jambase pseudotargets, you'll have problemswith the conflicting target name.Your workaround choices are:<P><ol><lI>Change the name of your buildable file or directory that conflicts.<p><li>Modify your Jambase and change the name of the conflicting pseudotarget.(Pseudotargets are defined in Jambase using the NOTFILE rule.)<p><li>Use grist on the conflicting target name in your Jamfile. E.g., instead of <PRE> File lib : libfoo.a ; </PRE> try <PRE> File <dir>lib : libfoo.a ; </PRE></ol><P><H4>Dependencies</H4><P>Jambase rules set dependencies on targets, so that if you update asource file, all the file targets that depend on that sourcefile, and only the ones that depend on that source file, will be updated (rebuilt) the next time you run <b>jam</b>. <P>Here are some of the dependencies that get set when <b>jam</b> runs on NT using the example Jamfile above:<CENTER><TABLE> <TR><TD><B>Target</B><TD> <TD><B>Depends on</B></TD><TR><TD>myprog.exe<TD><TD>main.obj, util.obj, libtree.lib<TR><TD>libtree.lib<TD><TD>treemake.obj, treetrav.obj<TR><TD>treetrav.obj<TD><TD>treetrav.c</TABLE></CENTER><P>Furthermore, the Main and Library rules set up recursiveheader scanning on their source targets.So after <b>jam</b> has finished parsing the Jamfile andsetting the rule-driven dependencies, it scans the source files for "#include" lines. All #include files found duringthis scan become dependencies of the compiled object.E.g., all header files used to compile treetrav.c wouldbe made dependencies of treetrav.obj.<P>As a result, when you run <b>jam</b>, it will rebuild targetsif either the source files change or the header files change. You can't tell by looking at a Jamfilewhich header files are dependencies, but you can easilydisplay those dependencies with:<PRE> jam -nd+3</PRE><H4>Rule Ordering</H4><P>Rules which specify dependencies, like the Main, Library, andLinkLibrary rules, can be invoked in any order. <b>jam</b>figures out the order in which targets are built from their dependencies.<P>Some rules, however, set variables which are used by subsequentrule invocations, and their ordering is important. For example, the SubDir* rules (discussedlater) must be invoked in a particular order.<P><H4>Detailed Jambase Specifications</H4><P>This document describes how to use various Jambase rulesfrom a functional point of view.You can see the summary of available Jambase rules in the<a href="Jambase.html">Jambase Reference</A>.The detailed specifications for any Jambase rulecan be found by reading the rule definition itselfin the Jambase file.<P><HR><H2>Handling Directory Trees</H2> The SubDir* rules are used to define source code directory hierarchies. With SubDir and SubInclude, you can use <b>jam</b> to build software from source files and Jamfiles spread across many directories, as is typical for large projects. The SubDir* rules unify an entire source code tree so that <b>jam</b> can read in all the Jamfiles in one pass and compute dependencies across the entire project.<P> To use the SubDir* rules, you must:<P><OL> <LI> Preface the Jamfile in each directory with an invocation of the SubDir rule.<P> <LI> Place at the root of the tree a file named Jamrules. This file could be empty, but in practice it contains user-provided rules and variable definitions that are shared throughout the tree. Examples of such definitions are library names, header directories, install directories, compiler flags, etc. This file is good candidate for automatic customizing with autoconf(GNU).<P> <LI> Optionally, set an environment variable pointing to the root directory of the srouce tree. The variable's name is left up to you, but in these examples, we use TOP.</OL><P><H4> SubDir Rule</H4><P> The SubDir rule must be invoked before any rules that refer to the contents of the directory - it is best to put it at the top of each Jamfile. For example:<PRE> # Jamfile in $(TOP)/src/util directory. SubDir TOP src util ; Main myprog : main.c util.c ; LinkLibraries myprog : libtree ; Library libtree : treemake.c treetrav.c ; </PRE> This compiles four files in $(TOP)/src/util, archives two of the objects into libtree, and links the whole thing into myprog. Outputs are placed in the $(TOP)/src/util directory. <P> This doesn't appear to be any different from the previous example that didn't have a SubDir rule, but two things are happening behind the scenes: <OL> <LI>The SubDir rule causes <b>jam</b> to read in the $(TOP)/Jamrules file. (The Jamrules file can alternately be named by the variable $(xxxRULES), where xxx is the name of the root variable, e.g., $(TOPRULES)). <P> The Jamrules file can contain variable definitions and rule definitions specific to your codeline. It allows you to completely customize your build environment without having to rewrite Jambase. Jamrules is only read in once, at the first SubDir invocation. <P> <LI> The SubDir rule initializes a set of variables that are used by Main and other rules to uniquely identify the source files in this directory and assign locations to the targets built from files in this directory. <P> When you have set a root variable, e.g., $(TOP), SubDir constructs path names rooted with $(TOP), e.g., $(TOP)/src/util. Otherwise, SubDir constructs relative pathnames to the root directory, computed from the number of arguments to the first SubDir rule, e.g., ../../src/util. In either case, the SubDir rule constructs the path names that locate source files. You'll see how this is useful later. <P> </UL><P> The SubDir rule takes as its first argument the root variable's name and takes as subsequent arguments the directory names leading from the root to the directory of the current Jamfile. Note that the name of the subdirectory is given as individual elements: the SubDir rule does not use system-specific directory name syntax.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -