From a863cc65d7be15eb4db70ff802009ad003d8be97 Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Fri, 12 Aug 2005 09:17:33 +0000 Subject: [PATCH] Some doc changes. Most notably, initial description of jam language. The changes were done quite some time ago, so can't provide more detailed changelog. [SVN r30533] --- v2/doc/src/advanced.xml | 670 ++++++++++++++++------------------------ v2/doc/src/tutorial.xml | 11 + 2 files changed, 281 insertions(+), 400 deletions(-) diff --git a/v2/doc/src/advanced.xml b/v2/doc/src/advanced.xml index f3d4c45af..6d632b132 100644 --- a/v2/doc/src/advanced.xml +++ b/v2/doc/src/advanced.xml @@ -74,17 +74,149 @@ +
+ Boost.Jam language + + This section will describe the basics of the Boost.Jam + language—just enough for writing Jamfiles. For more information, + please see the Boost.Jam + and Classic + Jam documentation. + + Boost.Jam has an interpreted, procedural language. + On the lowest level, a Boost.Jam program consists of variables and + rule + rules (the Jam term for function). They are grouped + in modules—there's one global module and a number of named + modules. Besides that, a Boost.Jam program contains classes and class + instances. + + + Syntantically, a Boost.Jam program consists of two kind of + elements—keywords (which have a special meaning to Boost.Jam) and + literals. + + Consider this code: + +a = b ; + which assigns the value b to the variable + a. Here, = and + ; are keywords, while a and + b are literals. + + All syntax elements, even keywords, must be separated by + spaces. For example, omitting the space character before + ; will lead to a syntax error. + + + If you want to use a literal value that is the same as some keyword, the + value can be quoted: + +a = "=" ; + + + All variables in Boost.Jam have the same type—list of + strings. To define a variable one assigns a value to it, like in the + previous example. An undefined variable is the same as a variable with + an empty value. Variables can be accessed with the + $(variable) syntax. For example: + +a = $(b) $(c) ; + + + + Rules are defined by specifying the rule name, the parameter names, + and the allowed size of the list value for each parameter. + +rule example + ( + parameter1 : + parameter2 ? : + parameter3 + : + parameter4 * + ) + { + // body + } + When this rule is called, the list passed as the first argument must + have exactly one value. The list passed as the second argument can + either have one value of be empty. The two remaining arguments can + be arbitrary long, but the third argument may not be empty. + + + The overview of Boost.Jam language statements is given below: + +helper 1 : 2 : 3 ; +x = [ helper 1 : 2 : 3 ] ; + This code calls the named rule with the specified arguments. When the + result of the call must be used inside some expression, you need to add + brackets around the call, like shown on the second line. + +if cond { statements } [ else statement ] + Regular if-statement. The condition is composed of: + + Literals (true if at least one string is not empty) + Comparisons: a + operator b where + operator is one of =, + !=, <, >, + <=, >=. The comparison is done + pairwise between each string in the left and the right arguments. + + + Logical operations: ! a, a && + b, a || b + Grouping: ( cond ) + + +for var in list { statements } + Executes statements for each element in list, setting the variable + var to the element value. + +while cond { statements } + Repeatedly execute statements while cond remains true upon entry. + +return values ; + This statement should be used only inside a + rule and assigns values to the return value of the + rule. + + The return statement does not exit the rule. For example: + +rule test ( ) +{ + if 1 = 1 { + return "resonable" ; + } + return "strange" ; +} will return strange, not +resonable. + + + +import module ; +import module : rule ; + The first form imports the specified bjam module. All rules from + that module are made available using the qualified name: + module.rule. + The second form imports the specified rules only, and they can be called + using unqualified names. + +
Configuration The Boost.Build configuration is specified in the file - user-config.jam. You can edit the one that comes with Boost.Build, or - - create a copy in your home directory and edit that. (See the reference for the exact search - paths.) The primary function of that file is to declare which compilers - and other tools are available. The simplest syntax to configure a tool is: + user-config.jam. You can edit the one in top-level + directory of Boost.Build installation create a copy in your home directory + and edit that. (See for the + exact search paths.) The primary function of that file is to declare which + compilers and other tools are available. The simplest syntax to configure + a tool is: + using tool-name ; @@ -163,12 +295,13 @@ using msvc : : Z:/Programs/Microsoft Visual Studio/vc98/bin/cl ; Some Boost.Build toolsets will use that path to take additional actions required before invoking the compiler, such as calling vendor-supplied scripts to set up its required environment variables. - +When compiler executables for C and C++ are different, path to the C++ +compiler executable must be specified. The “invocation command” +can be any command allowed by the operating system. For example: + +using msvc : : echo Compiling && foo/bar/baz/cl ; + +will work. To configure several versions of a toolset, simply invoke @@ -220,184 +353,23 @@ using gcc : 3.4 : : <compileflags>-m64 <linkflags>-m64 ;
-
- Writing Jamfiles - -
- Overview - - Jamfiles are the thing that is most important to the user, - - bacause they declare the targets that should be built. - - Jamfiles are also used for organizing targets— - - each Jamfile is a separate project - - that can be built independently from the other projects. - - - - Jamfiles mostly contain calls to Boost.Build functions that do - all the work, specifically: - - - - declare main - targets - - - define - project properties - - - do various other - things - - - - - - - - - - - -
- - - -
- Main targets + Declaring targets A Main target is a user-defined named - entity that can be built, for example an executable file. - + entity that can be built, for example an executable file. Declaring a main target is usually done using one of the main target rules described in . The user can also declare custom main target rules as shown in . - - - Most main target rules in Boost.Build can be invoked with - a common syntax: + + + main targetdeclaration + syntax + Most main target rules in Boost.Build have the same common + signature: +common signature -rule-namemain-target-name - : sources... - : requirements... - : default-build... - : usage-requirements... - ; +rule rule-name ( + main-target-name : + sources + : + requirements * : + default-build * : + usage-requirements * ) @@ -465,12 +438,11 @@ boost-build /path/to/boost.build ; Some main target rules have a shorter list of parameters; consult their documentation for details. - Note that the actual requirements, default-build and - usage-requirements attributes for a target are obtained by - combining the explicitly specified ones with those specified for - the project where a target is declared. - + The actual requirements for a target are obtained by refining + requirements of the project where a target is declared with the + explicitly specified requirements. The same is true for + usage-requirements. More details can be found in + The list of sources specifies what should be processed to @@ -483,53 +455,47 @@ boost-build /path/to/boost.build ; exe a : a.cpp ; # a.cpp is the only source file exe b : [ glob *.cpp ] ; # all .cpp files in this directory are sources - Unless you specify a files with absolute path, the name is - considered relative to the source directory -- which is typically + Unless you specify a file with an absolute path, the name is + considered relative to the source directory—which is typically the directory where the Jamfile is located, but can be changed as described in . + The list of sources can also refer to other main targets. Targets in the same project can be referred to by name, while - targets in other projects need to be qualified with a directory or a symbolic - project name. For example: + targets in other projects must be qualified with a directory or a + symbolic project name. The directory/project name is separated from + the target name by double slash. There's no special syntax to + distinguish directory name from project name—the part before + double slash is first looked up as project name, and then as directory + name. For example: lib helper : helper.cpp ; exe a : a.cpp helper ; -exe b : b.cpp ..//utils ; +# Since all project ids start with slash, ".." is directory name. +exe b : b.cpp ..//utils ; exe c : c.cpp /boost/program_options//program_options ; The first exe uses the library defined in the same project. The second one uses some target (most likely library) defined by Jamfile one level higher. Finally, the third target uses some C++ Boost - library, referring to it by its absolute symbolic name. More - information about it can be found in and . - Requirements are the properties that should always be present when building a target. Typically, they are includes and defines: exe hello : hello.cpp : <include>/opt/boost <define>MY_DEBUG ; - In special circumstances, - - other properties can be used, for example if + There is a number of other feature, listed in + . For example if a library can only be built statically, or a file can't be compiled with optimization due to a compiler bug, one can use @@ -538,33 +504,7 @@ obj main : main.cpp : <optimization>off ; - Sometimes requirements are necessary only for a specific - compiler or build variant. Conditional - properties can be used in that case: - - -lib util : util.cpp : <toolset>msvc:<link>static ; - - - Whenever <toolset>msvc property is - in build properties, the <link>static property will - be included as well. Conditional requirements can be “chained”: - -lib util : util.cpp : <toolset>msvc:<link>static - <link>static:<define>STATIC_LINK ; - - will set of static link - - and the STATIC_LINK define on the - msvc toolset. - - - The default-build parameter - is a set of properties to be used if the build request does not otherwise specify a value for features in the set. For example: @@ -573,79 +513,71 @@ exe hello : hello.cpp : : <threading>multi ; would build a multi-threaded target in unless the user explicitly requests a single-threaded version. The difference between requirements and default-build is that requirements cannot be - overriden in any way. + overriden in any way. - A target of the same name can be declared several times, in which - case each declaration is called an - alternative. When the target is built, one of - the alternatives will be selected and used. Alternatives need not be - defined by the same main target rule. For example, - -lib helpers : helpers.hpp ; # a header-only library -alias helpers : helpers.lib : <toolset>msvc ; # except on msvc + Sometimes, particular relationships need to be maintained + among a target's build properties. This can be achieved with + conditional + requirement. For example, you might want to set + specific #defines when a library is built as shared, + or when a target's release variant is built in + release mode. + +lib network : network.cpp + : <link>shared:<define>NEWORK_LIB_SHARED + <variant>release:<define>EXTRA_FAST + ; - - - - The actual commands used to build any given main target can differ greatly from - platform to platform. For example, you might have different lists - of sources for different compilers, or different options for those - compilers. Two approaches to this are explained in the - tutorial. - - - - Sometimes a main target is really needed only by some other main - target. For example, a rule that declares a test-suite uses a main - target - - that represent test, but those main targets are rarely needed - by themselves. - - + + The ways a target is built can be so different that + describing them using conditional requirements would be + hard. For example, imagine that a library actually uses + different source files depending on the toolset used to build + it. We can express this situation using target + alternatives: + +lib demangler : dummy_demangler.cpp ; # alternative 1 +lib demangler : demangler_gcc.cpp : <toolset>gcc ; # alternative 2 +lib demangler : demangler_msvc.cpp : <toolset>msvc ; # alternative 3 + + In the example above, when built with gcc + or msvc, demangler + will use a source file specific to the toolset. Otherwise, it + will use a generic source file, + dummy_demangler.cpp. + It is possible to declare a target inline, i.e. the "sources" parameter may include calls to other main rules. For example: exe hello : hello.cpp - [ obj helpers : helpers.cpp : <optimization>off ] ; - + [ obj helpers : helpers.cpp : <optimization>off ] ; Will cause "helpers.cpp" to be always compiled without - optimization. - - When referring to an inline main target, its declared name - must be prefixed by its parent target's name and two dots. In + optimization. When referring to an inline main target, its declared + name must be prefixed by its parent target's name and two dots. In the example above, to build only helpers, one should run bjam hello..helpers. + When no target is requested on the command line, all targets in the + current project will be built. If a target should be built only by + explicit request, this can be expressed by the + explicit rule: + +explicit install_programs ; + +
@@ -667,9 +599,7 @@ project id : attributes ; Here, attributes is a sequence of rule arguments, each of which begins with an attribute-name - and is followed by any number of build properties. - The list + and is followed by any number of build properties. The list of attribute names along with its handling is also shown in the table below. For example, it is possible to write: @@ -721,15 +651,13 @@ project tennis Attribute - Name for the 'project' rule - + Name Default value - Handling by the 'project' rule + Handling by the project + rule + @@ -932,60 +860,7 @@ bjam --help project.rulename
- - - - - - -
- +
The Build Process @@ -1009,8 +884,6 @@ should be absolute project id. each metatarget will produce a set of real targets corresponding to the requested properties. It is quite possible that the same metatarget is built several times with different properties, - producing different files. @@ -1040,7 +913,6 @@ bjam app1 lib1//lib1 gcc debug optimization=full The complete syntax, which has some additional shortcuts, is described in . -
@@ -1167,11 +1039,17 @@ explicit hello_test ;
Builtin target types - + This section describes main targets types that Boost.Build supports + of-of-the-box. Unless otherwise noted, all mentioned main target rules + have the common signature, described in . + +
Programs + Builtin + rulesexe Programs are created using the exe rule, which follows the common syntax. For example: @@ -1345,25 +1223,20 @@ lib a : a.cpp : <use>b : : <library>b ;
Alias - The alias rule follows the common syntax. For - example: - -alias core : im reader writer ; - - will build the sources - - and return - - the generated source targets - without modification. + + The alias rule gives alternative name to + a group of targets. For example, to give name + core to a group of three other targets with the + following code: + +alias core : im reader writer ; + Using core on the command line, or in source list + of any other target is the same as explicitly using + im, reader, and + writer, just more convenient. + - - The alias rule is a convenience tool. If you often build - the same group of targets at the same time, you can define an alias - to save typing. - Another use of the alias rule is to change build @@ -1604,16 +1477,20 @@ unit-test helpers_test : helpers_test.cpp helpers ; - Introduces a dependency on the target named by the value of this feature (so it will be brought - up-to-date whenever the target being declared is), and + up-to-date whenever the target being declared is). + The dependency is not used in any other way. For example, in + application with plugins, the plugins are not used when linking + the application, + application might have dependency on its plugins, even though + + + , and adds its usage requirements to the build properties - - of the target being declared. The dependency is not used - in any other way. The primary use case is when you want + of the target being declared. + + The primary use case is when you want the usage requirements (such as #include paths) of some library to be applied, but don't want to link to it. - Another method was to create a new toolset module that would set - the variables and then invoke the base toolset. Neither method - is necessary now: the using rule provides a consistent way to - initialize a toolset, - - including several versions. See In V1, toolsets were configured by environment variables. If you + wanted to use two versions of the same toolset, you had to create a new + toolset module that would set the variables and then invoke the base + toolset. In V2, toolsets are configured by the + using, and you can easily configure several + versions of a toolset. See for details. @@ -1801,7 +1672,6 @@ bjam msvc release some_target
- + This section will guide you though the most basic features of + Boost.Build V2. We will start with the “Hello, world” example, + learn how to use libraries, and finish with testing and installing features. + +
Hello, world @@ -436,6 +441,12 @@ project
+
+ Testing + + +
+
Static and shared libaries