?? bjam.qbk
字號:
for creating compiler response files, and other "internal" files. The expansionworks both during parsing and action execution. Hence it is possible to createfiles during any of the three build phases.[endsect][section:builtins Built-in Variables]This section discusses variables that have special meaning to =bjam=.[section:search SEARCH and LOCATE]These two variables control the binding of file target names to locations inthe file system. Generally, =$(SEARCH)= is used to find existing sourceswhile =$(LOCATE)= is used to fix the location for built targets.Rooted (absolute path) file targets are bound as is. Unrooted file target names are also normally bound as is, and thus relative to the current directory, but the settings of =$(LOCATE)= and =$(SEARCH)= alter this:* If =$(LOCATE)= is set then the target is bound relative to the first directory in =$(LOCATE)=. Only the first element is used for binding.* If =$(SEARCH)= is set then the target is bound to the first directory in =$(SEARCH)= where the target file already exists.* If the =$(SEARCH)= search fails, the target is bound relative to the current directory anyhow. Both =$(SEARCH)= and =$(LOCATE)= should be set target-specific and not globally. If they were set globally, =bjam= would use the same paths for all file binding, which is not likely to produce sane results. When writing your own rules, especially ones not built upon those in Jambase, you may need to set =$(SEARCH)= or =$(LOCATE)= directly. Almost all of the rules defined in Jambase set =$(SEARCH)= and =$(LOCATE)= to sensible values for sources they are looking for and targets they create, respectively.[endsect][section:hdrscan HDRSCAN and HDRRULE]These two variables control header file scanning. =$(HDRSCAN)= is an=egrep(1)= pattern, with ()'s surrounding the file name, used to find fileinclusion statements in source files. =Jambase= uses =$(HDRPATTERN)= as thepattern for =$(HDRSCAN)=. =$(HDRRULE)= is the name of a rule to invoke withthe results of the scan: the scanned file is the target, the found files arethe sources. This is the only place where =bjam= invokes a rule through avariable setting.Both =$(HDRSCAN)= and =$(HDRRULE)= must be set for header file scanning to take place, and they should be set target-specific and not globally. If they were set globally, all files, including executables and libraries, would be scanned for header file include statements.The scanning for header file inclusions is not exact, but it is at least dynamic, so there is no need to run something like =makedepend(GNU)= to create a static dependency file. The scanning mechanism errs on the side of inclusion (i.e., it is more likely to return filenames that are not actually used by the compiler than to miss include files) because it can't tell if `#include` lines are inside `#ifdefs` or other conditional logic. In =Jambase=, =HdrRule= applies the =NOCARE= rule to each header file found during scanning so that if the file isn't present yet doesn't cause the compilation to fail, =bjam= won't care.Also, scanning for regular expressions only works where the included file name is literally in the source file. It can't handle languages that allow including files using variable names (as the =Jam= language itself does). [endsect][section Semaphores]It is sometimes desirable to disallow parallel execution of some actions. For example:* Old versions of yacc use files with fixed names. So, running two yacc actions is dangerous.* One might want to perform parallel compiling, but not do parallel linking, because linking is i/o bound and only gets slower.Craig McPeeters has extended Perforce Jam to solve such problems, and that extension was integrated in Boost.Jam.Any target can be assigned a /semaphore/, by setting a variable called =SEMAPHORE= on that target. The value of the variable is the semaphore name. It must be different from names of any declared target, but is arbitrary otherwise.The semantic of semaphores is that in a group of targets which have the same semaphore, only one can be updated at the moment, regardless of "=-j=" option.[endsect][section Platform Identifier]A number of Jam built-in variables can be used to identify runtime platform:[variablelist[[=OS=] [OS identifier string]][[=OSPLAT=] [Underlying architecture, when applicable]][[=MAC=] [true on MAC platform]][[=NT=] [true on NT platform]][[=OS2=] [true on OS2 platform]][[=UNIX=] [true on Unix platforms]][[=VMS=] [true on VMS platform]]][endsect][section Jam Version][variablelist[[=JAMDATE=] [Time and date at =bjam= start-up as an ISO-8601 UTC value.]][[=JAMUNAME=] [Ouput of uname(1) command (Unix only)]][[=JAMVERSION=] [=bjam= version, currently ":version:"]][[=JAM_VERSION=] [A predefined global variable with two elements indicates the version number of Boost Jam. Boost Jam versions start at "=03=" "=00=". Earlier versions of =Jam= do not automatically define =JAM_VERSION=.]]][endsect][section JAMSHELL]When =bjam= executes a rule's action block, it forks and execs a shell, passing the action block as an argument to the shell. The invocation of the shell can be controlled by =$(JAMSHELL)=. The default on Unix is, for example:[preJAMSHELL = /bin/sh -c % ;]The =%= is replaced with the text of the action block.=BJam= does not directly support building in parallel across multiple hosts, since that is heavily dependent on the local environment. To build in parallel across multiple hosts, you need to write your own shell that provides access to the multiple hosts. You then reset =$(JAMSHELL)= to reference it.Just as =bjam= expands a =%= to be the text of the rule's action block, it expands a =!= to be the multi-process slot number. The slot number varies between 1 and the number of concurrent jobs permitted by the =-j= flag given on the command line. Armed with this, it is possible to write a multiple host shell. For example:[pre#!/bin/sh# This sample JAMSHELL uses the SunOS on(1) command to execute a# command string with an identical environment on another host.# Set JAMSHELL = jamshell ! %## where jamshell is the name of this shell file.## This version handles up to -j6; after that they get executed# locally.case $1 in1|4) on winken sh -c "$2";;2|5) on blinken sh -c "$2";;3|6) on nod sh -c "$2";;*) eval "$2";;esac][endsect][section:actionrule =__TIMING_RULE__= and =__ACTION_RULE__=]The =__TIMING_RULE__= and =__ACTION_RULE__= can be set to the name of a rulefor =bjam= to call *after* an action completes for a target. They both givediagnostic information about the action that completed. For =__TIMING_RULE__=the rule is called as: rule timing-rule ( args * : target : start end user system )And =__ACTION_RULE__= is called as: rule action-rule ( args * : target : command status start end user system : output ? )The arguments for both are:[variablelist [[[^args]] [Any values following the rule name in the =__TIMING_RULE__= or =__ACTION_RULE__= are passed along here.]] [[[^target]] [The =bjam= target that was built.]] [[[^command]] [The text of the executed command in the action body.]] [[[^status]] [The integer result of the executed command.]] [[[^start]] [The starting timestamp of the executed command as a ISO-8601 UTC value.]] [[[^end]] [The completion timestamp of the executed command as a ISO-8601 UTC value.]] [[[^user]] [The number of user CPU seconds the executed command spent as a floating point value.]] [[[^system]] [The number of system CPU seconds the executed command spent as a floating point value.]] [[[^output]] [The output of the command as a single string. The content of the output reflects the use of the =-pX= option.]]][note If both variables are set for a target both are called, first =__TIMING_RULE__= then =__ACTION_RULE__=. ][endsect][endsect][endsect][section Modules]Boost Jam introduces support for modules, which provide some rudimentary namespace protection for rules and variables. A new keyword, "=module=" was also introduced. The features described in this section are primitives, meaning that they are meant to provide the operations needed to write Jam rules which provide a more elegant module interface.[section Declaration][premodule /expression/ { ... }]Code within the [^{ ... }] executes within the module named by evaluating expression. Rule definitions can be found in the module's own namespace, and in the namespace of the global module as /module-name/./rule-name/, so within a module, other rules in that module may always be invoked without qualification:[pre*module my_module**{* rule salute ( x ) { ECHO $(x), world ; } rule greet ( ) { salute hello ; } greet ;*}**my_module.salute* goodbye ;]When an invoked rule is not found in the current module's namespace, it is looked up in the namespace of the global module, so qualified calls work across modules:[premodule your_module{ rule bedtime ( ) { *my_module.salute* goodnight ; }}][endsect][section Variable Scope]Each module has its own set of dynamically nested variable scopes. When execution passes from module A to module B, all the variable bindings from A become unavailable, and are replaced by the bindings that belong to B. This applies equally to local and global variables:[premodule A{ x = 1 ; rule f ( ) { local y = 999 ; # becomes visible again when B.f calls A.g B.f ; } rule g ( ) { ECHO $(y) ; # prints "999" }}module B{ y = 2 ; rule f ( ) { ECHO $(y) ; # always prints "2" A.g ; }}]The only way to access another module's variables is by entering that module:[prerule peek ( module-name ? : variables + ){ module $(module-name) { return $($(>)) ; }}]Note that because existing variable bindings change whenever a new module scope is entered, argument bindings become unavailable. That explains the use of "=$(>)=" in the peek rule above.[endsect][section Local Rules][prelocal rule /rulename/...]The rule is declared locally to the current module. It is not entered in the global module with qualification, and its name will not appear in the result of:[pre\[ RULENAMES /module-name/ \]][endsect][section The =RULENAMES= Rule][prerule RULENAMES ( /module/ ? )]Returns a list of the names of all non-local rules in the given module. If /module/ is omitted, the names of all non-local rules in the global module are returned.[endsect][section The =VARNAMES= Rule][prerule VARNAMES ( /module/ ? )]Returns a list of the names of all variable bindings in the given module. If /module/ is omitted, the names of all variable bindings in the global module are returned.[note This includes any local variables in rules from the call stack which have not returned at the time of the =VARNAMES= invocation.][endsect][section The =IMPORT= Rule]=IMPORT= allows rule name aliasing across modules:[prerule IMPORT ( /source_module/ ? : /source_rules/ * : /target_module/ ? : /target_rules/ * )]The =IMPORT= rule copies rules from the /source_module/ into the /target_module/ as local rules. If either /source_module/ or /target_module/ is not supplied, it refers to the global module. /source_rules/ specifies which rules from the /source_module/ to import; /target_rules/ specifies the names to give those rules in /target_module/. If /source_rules/ contains a name which doesn't correspond to a rule in /source_module/, or if it contains a different number of items than /target_rules/, an error is issued. For example,[pre# import m1.rule1 into m2 as local rule m1-rule1.IMPORT m1 : rule1 : m2 : m1-rule1 ;# import all non-local rules from m1 into m2IMPORT m1 : \[ RULENAMES m1 \] : m2 : \[ RULENAMES m1 \] ;][endsect][section The =EXPORT= Rule]=EXPORT= allows rule name aliasing across modules:[prerule EXPORT ( /module/ ? : /rules/ * )]The =EXPORT= rule marks /rules/ from the =source_module= as non-local (and thus exportable). If an element of /rules/ does not name a rule in /module/, an error is issued. For example,[premodule X { local rule r { ECHO X.r ; }}IMPORT X : r : : r ; # error - r is local in XEXPORT X : r ;IMPORT X : r : : r ; # OK.][endsect][section The =CALLER_MODULE
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -