diff --git a/doc/Jamfile.v2 b/doc/jamfile.jam
similarity index 100%
rename from doc/Jamfile.v2
rename to doc/jamfile.jam
diff --git a/doc/src/advanced.xml b/doc/src/advanced.xml
index 598848d1d..76800ae0b 100644
--- a/doc/src/advanced.xml
+++ b/doc/src/advanced.xml
@@ -5,60 +5,78 @@
Overview
- This section will provide the information necessary to create your own
- projects using Boost.Build. The information provided here is relatively
- high-level, and as well as the on-line help
- system must be used to obtain low-level documentation (see ).
+
+ This section will provide the information necessary to create your own
+ projects using Boost.Build. The information provided here is relatively
+ high-level, and as well as the on-line
+ help system must be used to obtain low-level documentation (see ).
+
- Boost.Build actually consists of two parts - Boost.Jam, a build engine
- with its own interpreted language, and Boost.Build itself, implemented in
- Boost.Jam's language. The chain of events when you type
- bjam on the command line is:
+
+ Boost.Build actually consists of two parts - Boost.Jam, a build engine
+ with its own interpreted language, and Boost.Build itself, implemented in
+ Boost.Jam's language. The chain of events when you type
+ bjam on the command line is as follows:
- Boost.Jam tries to find Boost.Build and loads the top-level
- module. The exact process is described in
-
-
- The top-level module loads user-defined configuration files,
- user-config.jam and
- site-config.jam, which define available toolsets.
+
+ Boost.Jam tries to find Boost.Build and loads the top-level module.
+ The exact process is described in
- The Jamfile in the current directory is read. That in turn
- might cause reading of further Jamfiles. As a result, a tree of
- projects is created, with targets inside projects.
+
+ The top-level module loads user-defined configuration files,
+ user-config.jam and site-config.jam
+ , which define available toolsets.
+
- Finally, using the build request specified on the command line,
- Boost.Build decides which targets should be built, and how. That
- information is passed back to Boost.Jam, which takes care of
- actually running commands.
+
+ The Jamfile in the current directory is read. That in turn might
+ cause reading of further Jamfiles. As a result, a tree of projects
+ is created, with targets inside projects.
+
+
+
+
+ Finally, using the build request specified on the command line,
+ Boost.Build decides which targets should be built and how. That
+ information is passed back to Boost.Jam, which takes care of
+ actually running the scheduled build action commands.
+
- So, to be able to successfully use Boost.Build, you need to know only
- four things:
+
+ So, to be able to successfully use Boost.Build, you need to know only four
+ things:
-
- How to configure Boost.Build
+
+ How to configure
+ Boost.Build
+
-
- How to write declares targets in Jamfiles
+
+ How to declare targets in
+ Jamfiles
+
-
- How the build process works
+
+ How the build process
+ works
+
- Some Basics about the Boost.Jam language. See
- .
+
+ Some Basics about the Boost.Jam language. See .
@@ -67,153 +85,187 @@
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 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 using the
- $(variable) syntax. For example:
-
-a = $(b) $(c) ;
+
+ This section will describe the basics of the Boost.Jam language—
+ just enough for writing Jamfiles. For more information, please see the
+ Boost.Jam documentation.
- Rules are defined by specifying the rule name, the parameter names,
- and the allowed size of the list value for each parameter.
-
+ Boost.Jam has an interpreted, procedural
+ language. On the lowest level, a Boost.Jam
+ program consists of variables and rule
+ rules (Jam term for
+ function). They are grouped into modules—there is 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 using the
+ $(variable) syntax. For example:
+
+a = $(b) $(c) ;
+
+
+
+
+ Rules are defined by specifying the rule name, the parameter names, and
+ the allowed value list size for each parameter.
+
rule example
- (
- parameter1 :
- parameter2 ? :
- parameter3 + :
- parameter4 *
- )
- {
- // body
- }
+ (
+ parameter1 :
+ parameter2 ? :
+ parameter3 + :
+ parameter4 *
+ )
+ {
+ # rule 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
arbitrarily long, but the third argument may not be empty.
- The overview of Boost.Jam language
- statements is given below:
-
+
+ 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 { statements } ]
- This is a 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.
-
+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 { statements } ]
+
+ This is a 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
+ =, !=, <,
+ >, <= or >=. 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:
-
+
+ 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 {
+ if 1 = 1
+ {
return "reasonable" ;
}
return "strange" ;
-} will return strange, not
-reasonable.
-
-
-
+}
+
+ will return strange, not
+ reasonable.
+
+
+
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.
+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.
Sometimes, you'd need to specify the actual command lines to be used
- when creating targets. In jam language, you use named actions to do this.
- For example:
+ when creating targets. In jam language, you use named actions to do
+ this. For example:
actions create-file-from-another
{
create-file-from-another $(<) $(>)
}
- This specifies a named action called
- create-file-from-another. The text inside braces is
- the command to invoke. The $(<) variable will be
- expanded to a list of generated files, and the
- $(>) variable will be expanded to a list of
- source files.
+ This specifies a named action called
+ create-file-from-another. The text inside braces is the
+ command to invoke. The $(<) variable will be
+ expanded to a list of generated files, and the $(>)
+ variable will be expanded to a list of source files.
- To flexibly adjust command line, you can define a rule with the same
- name as the action, and taking three parameters -- targets, sources and
- properties. For example:
+
+ To flexibly adjust the command line, you can define a rule with the same
+ name as the action and taking three parameters -- targets, sources and
+ properties. For example:
rule create-file-from-another ( targets * : sources * : properties * )
{
@@ -227,18 +279,18 @@ actions create-file-from-another
create-file-from-another $(OPTIONS) $(<) $(>)
}
- In this example, the rule checks if certain build property is specified.
- If so, it sets variable OPIONS that is then used inside
- the action. Note that the variables set "on a target" will be visible only
- inside actions building that target, not globally. Were they set globally,
- using variable named OPTIONS in two unrelated actions
- would be impossible.
+ In this example, the rule checks if certain build property is specified.
+ If so, it sets variable OPIONS that is then used
+ inside the action. Note that the variables set "on a target" will be
+ visible only inside actions building that target, not globally. Were
+ they set globally, using variable named OPTIONS in
+ two unrelated actions would be impossible.
- More details can be found in Jam reference,
-
+
+ More details can be found in Jam reference, .
-
@@ -265,7 +317,7 @@ using tool-name ;
default settings. For example, it will use the gcc
executable found in the PATH, or look in some known
installation locations. In most cases, this strategy works automatically.
- In case you have several versions of a compiler, it's installed in some
+ In case you have several versions of a compiler, it is installed in some
unusual location, or you need to tweak its configuration, you'll need to
pass additional parameters to the using rule.
The parameters to using can be different for
@@ -310,39 +362,39 @@ bjam --help tool-name.init
using msvc : 7.1 ;
using gcc ;
-If the compiler can be found in the PATH but only by a
-nonstandard name, you can just supply that name:
+ If the compiler can be found in the PATH but only by a
+ nonstandard name, you can just supply that name:
using gcc : : g++-3.2 ;
-Otherwise, it might be necessary to supply the complete path to the
-compiler executable:
+ Otherwise, it might be necessary to supply the complete path to the
+ compiler executable:
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:
+ 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.
+ will work.
- To configure several versions of a toolset, simply invoke
- the using rule multiple times:
+
+ To configure several versions of a toolset, simply invoke the
+ using rule multiple times:
using gcc : 3.3 ;
using gcc : 3.4 : g++-3.4 ;
using gcc : 3.2 : g++-3.2 ;
- Note that in the first call to
- using, the compiler found in the
- PATH will be used, and there's no need to
- explicitly specify the command.
+ Note that in the first call to using, the
+ compiler found in the PATH will be used, and there is no
+ need to explicitly specify the command.
As shown above, both the
- 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 must be qualified with a directory or a
- symbolic project name. The directory/project name is separated from
- the target name by a double forward slash. There's no special syntax to
- distinguish the directory name from the project name—the part before
- the double slash is first looked up as project name, and then as directory
- name. For example:
+ 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 must be qualified with a directory or a symbolic project
+ name. The directory/project name is separated from the target name by
+ a double forward slash. There is no special syntax to distinguish the
+ directory name from the project name—the part before the 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 ;
-# Since all project ids start with slash, ".." is directory name.
+# Since all project ids start with slash, ".." is a 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 absolute symbolic name. More
- information about target references can be found in and C++ Boost library, referring to it using
+ its absolute symbolic name. More information about target references
+ can be found in and .
-
diff --git a/doc/src/faq.xml b/doc/src/faq.xml
index 4172479c1..fe1bd5a81 100644
--- a/doc/src/faq.xml
+++ b/doc/src/faq.xml
@@ -2,191 +2,232 @@
-
- Frequently Asked Questions
+
+ Frequently Asked Questions
-
-
- How do I get the current value of feature in Jamfile?
-
+
+
+ How do I get the current value of feature in Jamfile?
+
-
- This is not possible, since Jamfile does not have "current" value of any
- feature, be it toolset, build variant or anything else. For a single invocation of
- bjam, any given main target can be built with several property sets.
- For example, user can request two build variants on the command line. Or one library
- is built as shared when used from one application, and as static when used from another.
- Obviously, Jamfile is read only once, so generally, there's no single value of a feature
- you can access in Jamfile.
-
+
+ This is not possible, since Jamfile does not have "current" value of any
+ feature, be it toolset, build variant or anything else. For a single
+ invocation of bjam, any given main target can be
+ built with several property sets. For example, user can request two build
+ variants on the command line. Or one library is built as shared when used
+ from one application, and as static when used from another. Each Jamfile
+ is read only once so generally there is no single value of a feature you
+ can access in Jamfile.
+
- A feature has a specific value only when building a target, and there are two ways how you
- can use that value:
-
- Use conditional requirements or indirect conditional requirements. See
- .
-
- Define a custom generator and a custom main target type. The custom generator can do arbitrary processing
- or properties. See the extender manual.
-
-
+
+ A feature has a specific value only when building a target, and there are
+ two ways you can use that value:
+
-
+
+
+
+ Use conditional requirements or indirect conditional requirements. See
+ .
+
+
+
+ Define a custom generator and a custom main target type. The custom
+ generator can do arbitrary processing or properties. See the extender manual.
+
+
+
-
-
- I'm getting "Duplicate name of actual target" error. What
- does it mean?
-
-
-
- The most likely case is that you're trying to
- compile the same file twice, with almost the same,
- but differing properties. For example:
+
+
+ I am getting a "Duplicate name of actual target" error. What does that
+ mean?
+
+
+ The most likely case is that you are trying to compile the same file
+ twice, with almost the same, but differing properties. For example:
exe a : a.cpp : <include>/usr/local/include ;
exe b : a.cpp ;
-
-
+
- The above snippet requires two different compilations
- of 'a.cpp', which differ only in 'include' property.
- Since the 'include' property is free, Boost.Build
- can't generate two objects files into different directories.
- On the other hand, it's dangerous to compile the file only
- once -- maybe you really want to compile with different
- includes.
+ The above snippet requires two different compilations of
+ a.cpp, which differ only in their include
+ property. Since the include feature is declared as
+ free Boost.Build does not create a separate build
+ directory for each of its values and those two builds would both produce
+ object files generated in the same build directory. Ignoring this and
+ compiling the file only once would be dangerous as different includes
+ could potentially cause completely different code to be compiled.
- To solve this issue, you need to decide if file should
- be compiled once or twice.
+ To solve this issue, you need to decide if the file should be compiled
+ once or twice.
+
-
- Two compile file only once, make sure that properties
- are the same:
-
+
+
+ To compile the file only once, make sure that properties are the same
+ for both target requests:
exe a : a.cpp : <include>/usr/local/include ;
exe b : a.cpp : <include>/usr/local/include ;
-
-
-
- If changing the properties is not desirable, for example
- if 'a' and 'b' target have other sources which need
- specific properties, separate 'a.cpp' into it's own target:
-
+
+ or:
-obj a_obj : a.cpp : <include>/usr/local/include ;
-exe a : a_obj ;
-
-
-
- To compile file twice, you can make the object file local
- to the main target:
-
+alias a-with-include : a.cpp : <include>/usr/local/include ;
+exe a : a-with-include ;
+exe b : a-with-include ;
+
+ or if you want the includes property not to affect
+ how any other sources added for the built a and
+ b executables would be compiled:
- exe a : [ obj a_obj : a.cpp ] : <include>/usr/local/include ;
+obj a-obj : a.cpp : <include>/usr/local/include ;
+exe a : a-obj ;
+exe b : a-obj ;
+
+
+
+ Note that in both of these cases the include
+ property will be applied only for building these object files and not
+ any other sources that might be added for targets a and
+ b.
+
+
+
+
+
+ To compile the file twice, you can tell Boost.Build to compile it to
+ two separate object files like so:
+
+ obj a_obj : a.cpp : <include>/usr/local/include ;
+ obj b_obj : a.cpp ;
+ exe a : a_obj ;
+ exe b : b_obj ;
+
+ or you can make the object file targets local to the main target:
+
+ exe a : [ obj a_obj : a.cpp : <include>/usr/local/include ] ;
exe b : [ obj a_obj : a.cpp ] ;
-
+
+ which will cause Boost.Build to actually change the generated object
+ file names a bit for you and thus avoid any conflicts.
+
+
+ Note that in both of these cases the include
+ property will be applied only for building these object files and not
+ any other sources that might be added for targets a and
+ b.
+
+
+
-
+
+ A good question is why Boost.Build can not use some of the above
+ approaches automatically. The problem is that such magic would only help
+ in half of the cases, while in the other half it would be silently doing
+ the wrong thing. It is simpler and safer to ask the user to clarify his
+ intention in such cases.
+
+
-
- A good question is why Boost.Build can't use some of the above
- approaches automatically. The problem is that such magic would
- require additional implementation complexities and would only
- help in half of the cases, while in other half we'd be silently
- doing the wrong thing. It's simpler and safe to ask user to
- clarify his intention in such cases.
-
-
-
-
-
-
+
+
Accessing environment variables
-
+
-
+
Many users would like to use environment variables in Jamfiles, for
- example, to control location of external libraries. In many cases you
- better declare those external libraries in the site-config.jam file, as
- documented in the recipes
- section. However, if the users already have the environment variables set
- up, it's not convenient to ask them to set up site-config.jam files as
- well, and using environment variables might be reasonable.
+ example, to control the location of external libraries. In many cases it
+ is better to declare those external libraries in the site-config.jam file,
+ as documented in the recipes
+ section. However, if the users already have the environment
+ variables set up, it may not be convenient for them to set up their
+ site-config.jam files as well and using the environment variables might be
+ reasonable.
- In Boost.Build V2, each Jamfile is a separate namespace, and the
- variables defined in environment is imported into the global
- namespace. Therefore, to access environment variable from Jamfile, you'd
- need the following code:
+
+ Boost.Jam automatically imports all environment variables into its
+ built-in .ENVIRON module so user can read them from there directly or by
+ using the helper os.environ rule. For example:
+
+import os ;
+local unga-unga = [ os.environ UNGA_UNGA ] ;
+ECHO $(unga-unga) ;
+
+ or a bit more realistic:
import os ;
local SOME_LIBRARY_PATH = [ os.environ SOME_LIBRARY_PATH ] ;
exe a : a.cpp : <include>$(SOME_LIBRARY_PATH) ;
-
-
-
-
- How to control properties order?
-
-
- For internal reasons, Boost.Build sorts all the properties
- alphabetically. This means that if you write:
-
-exe a : a.cpp : <include>b <include>a ;
-
- then the command line with first mention the "a" include directory, and
- then "b", even though they are specified in the opposite order. In most
- cases, the user doesn't care. But sometimes the order of includes, or
- other properties, is important. For example, if one uses both the C++
- Boost library and the "boost-sandbox" (libraries in development), then
- include path for boost-sandbox must come first, because some headers may
- override ones in C++ Boost. For such cases, a special syntax is
- provided:
-
-exe a : a.cpp : <include>a&&b ;
-
-
-
- The && symbols separate values of an
- property, and specify that the order of the values should be preserved. You
- are advised to use this feature only when the order of properties really
- matters, and not as a convenient shortcut. Using it everywhere might
- negatively affect performance.
-
-
- How to control the library order on Unix?
+ How to control properties order?
- On the Unix-like operating systems, the order in which static
- libraries are specified when invoking the linker is important, because by
- default, the linker uses one pass though the libraries list. Passing the
- libraries in the incorrect order will lead to a link error. Further, this
- behaviour is often used to make one library override symbols from
- another. So, sometimes it's necessary to force specific order of
- libraries.
+
+ For internal reasons, Boost.Build sorts all the properties alphabetically.
+ This means that if you write:
+
+exe a : a.cpp : <include>b <include>a ;
+
+ then the command line with first mention the a include
+ directory, and then b, even though they are specified in the
+ opposite order. In most cases, the user does not care. But sometimes the
+ order of includes, or other properties, is important. For such cases, a
+ special syntax is provided:
+
+exe a : a.cpp : <include>a&&b ;
+
- Boost.Build tries to automatically compute the right order. The
- primary rule is that if library a "uses" library b, then library a will
- appear on the command line before library b. Library a is considered to
- use b is b is present either in the sources of a or in its
- requirements. To explicitly specify the use relationship one can use the
- <use> feature. For example, both of the following lines will cause
- a to appear before b on the command line:
+
+ The && symbols separate property values and specify
+ that their order should be preserved. You are advised to use this feature
+ only when the order of properties really matters and not as a convenient
+ shortcut. Using it everywhere might negatively affect performance.
+
+
+
+
+
+ How to control the library linking order on Unix?
+
+
+
+ On Unix-like operating systems, the order in which static libraries are
+ specified when invoking the linker is important, because by default, the
+ linker uses one pass though the libraries list. Passing the libraries in
+ the incorrect order will lead to a link error. Further, this behaviour is
+ often used to make one library override symbols from another. So,
+ sometimes it is necessary to force specific library linking order.
+
+
+
+ Boost.Build tries to automatically compute the right order. The primary
+ rule is that if library a "uses" library b, then
+ library a will appear on the command line before library
+ b. Library a is considered to use b
+ if b is present either in the a library's
+ sources or its usage is listed in its requirements. To explicitly specify
+ the use relationship one can use the
+ <use> feature. For example, both of the following
+ lines will cause a to appear before b on the
+ command line:
lib a : a.cpp b ;
lib a : a.cpp : <use>b ;
@@ -194,21 +235,22 @@ lib a : a.cpp : <use>b ;
- The same approach works for searched libraries, too:
+ The same approach works for searched libraries as well:
lib z ;
lib png : : <use>z ;
exe viewer : viewer png z ;
-
- Can I get output of external program as a variable in a Jamfile?
+
+ Can I get capture external program output using a Boost.Jam variable?
- The SHELL builtin can be used for the purpose:
+
+ The SHELL builtin rule may be used for this purpose:
local gtk_includes = [ SHELL "gtk-config --cflags" ] ;
@@ -216,7 +258,8 @@ local gtk_includes = [ SHELL "gtk-config --cflags" ] ;
- How to get the project root (a.k.a. Jamroot.jam) location?
+
+ How to get the project root (a.k.a. Jamroot) location?
@@ -230,18 +273,20 @@ path-constant TOP : . ;
- How to change compilation flags for one file?
+
+ How to change compilation flags for one file?
- If one file must be compiled with special options, you need to
- explicitly declare an obj target for that file and then use
- that target in your exe or lib target:
+
+ If one file must be compiled with special options, you need to explicitly
+ declare an obj target for that file and then use that target
+ in your exe or lib target:
exe a : a.cpp b ;
obj b : b.cpp : <optimization>off ;
Of course you can use other properties, for example to specify specific
- compiler options:
+ C/C++ compiler options:
exe a : a.cpp b ;
obj b : b.cpp : <cflags>-g ;
@@ -252,149 +297,162 @@ obj b : b.cpp : <cflags>-g ;
exe a : a.cpp b ;
obj b : b.cpp : <variant>release:<optimization>off ;
-
- Why are the dll-path and
- hardcode-dll-paths properties useful?
+
+ Why are the dll-path and hardcode-dll-paths
+ properties useful?
-
- (This entry is specific to Unix system.)Before answering the
- questions, let's recall a few points about shared libraries. Shared
- libraries can be used by several applications, or other libraries,
- without physically including the library in the application. This can
- greatly decrease the total size of applications. It's also possible to
- upgrade a shared library when the application is already
- installed. Finally, shared linking can be faster.
-
-
- However, the shared library must be found when the application is
- started. The dynamic linker will search in a system-defined list of
- paths, load the library and resolve the symbols. Which means that you
- should either change the system-defined list, given by the
- LD_LIBRARY_PATH environment variable, or install the
- libraries to a system location. This can be inconvenient when
- developing, since the libraries are not yet ready to be installed, and
- cluttering system paths is undesirable. Luckily, on Unix there's another
- way.
-
-
- An executable can include a list of additional library paths, which
- will be searched before system paths. This is excellent for development,
- because the build system knows the paths to all libraries and can include
- them in executables. That's done when the hardcode-dll-paths
- feature has the true value, which is the
- default. When the executables should be installed, the story is
- different.
+
+
+ This entry is specific to Unix systems.
+
+
+
+ Before answering the questions, let us recall a few points about shared
+ libraries. Shared libraries can be used by several applications, or other
+ libraries, without physically including the library in the application
+ which can greatly decrease the total application size. It is also possible
+ to upgrade a shared library when the application is already installed.
- Obviously, installed executable should not hardcode paths to your
- development tree. (The stage rule explicitly disables the
- hardcode-dll-paths feature for that reason.) However, you
- can use the dll-path feature to add explicit paths
+ However, in order for application depending on shared libraries to be
+ started the OS may need to find the shared library when the application is
+ started. The dynamic linker will search in a system-defined list of paths,
+ load the library and resolve the symbols. Which means that you should
+ either change the system-defined list, given by the LD_LIBRARY_PATH
+ environment variable, or install the libraries to a system
+ location. This can be inconvenient when developing, since the libraries
+ are not yet ready to be installed, and cluttering system paths may be
+ undesirable. Luckily, on Unix there is another way.
+
+
+
+ An executable can include a list of additional library paths, which will
+ be searched before system paths. This is excellent for development because
+ the build system knows the paths to all libraries and can include them in
+ the executables. That is done when the hardcode-dll-paths
+ feature has the true value, which is the
+ default. When the executables should be installed, the story is different.
+
+
+
+ Obviously, installed executable should not contain hardcoded paths to your
+ development tree. (The install rule explicitly disables the
+ hardcode-dll-paths feature for that reason.) However,
+ you can use the dll-path feature to add explicit paths
manually. For example:
-stage installed : application : <dll-path>/usr/lib/snake
- <location>/usr/bin ;
+install installed : application : <dll-path>/usr/lib/snake
+ <location>/usr/bin ;
- will allow the application to find libraries placed to
- /usr/lib/snake.
+ will allow the application to find libraries placed in the
+ /usr/lib/snake directory.
- If you install libraries to a nonstandard location and add an
- explicit path, you get more control over libraries which will be used. A
- library of the same name in a system location will not be inadvertently
- used. If you install libraries to a system location and do not add any
- paths, the system administrator will have more control. Each library can
- be individually upgraded, and all applications will use the new library.
+
+ If you install libraries to a nonstandard location and add an explicit
+ path, you get more control over libraries which will be used. A library of
+ the same name in a system location will not be inadvertently used. If you
+ install libraries to a system location and do not add any paths, the
+ system administrator will have more control. Each library can be
+ individually upgraded, and all applications will use the new library.
- Which approach is best depends on your situation. If the libraries
- are relatively standalone and can be used by third party applications,
- they should be installed in the system location. If you have lots of
- libraries which can be used only by your application, it makes sense to
- install it to a nonstandard directory and add an explicit path, like the
- example above shows. Please also note that guidelines for different
- systems differ in this respect. The Debian guidelines prohibit any
- additional search paths, and Solaris guidelines suggest that they should
+
+ Which approach is best depends on your situation. If the libraries are
+ relatively standalone and can be used by third party applications, they
+ should be installed in the system location. If you have lots of libraries
+ which can be used only by your application, it makes sense to install them
+ to a nonstandard directory and add an explicit path, like the example
+ above shows. Please also note that guidelines for different systems differ
+ in this respect. For example, the Debian GNU guidelines prohibit any
+ additional search paths while Solaris guidelines suggest that they should
always be used.
-
Targets in site-config.jam
- It is desirable to declare standard libraries available on a
- given system. Putting target declaration in Jamfile is not really
- good, since locations of the libraries can vary. The solution is
- to declare the targets in site-config.jam:
+
+ It is desirable to declare standard libraries available on a given system.
+ Putting target declaration in a specific project's Jamfile is not really
+ good, since locations of the libraries can vary between different
+ development machines and then such declarations would need to be
+ duplicated in different projects. The solution is to declare the targets
+ in Boost.Build's site-config.jam configuration file:
project site-config ;
lib zlib : : <name>z ;
+
- Recall that both site-config.jam and
- user-config.jam are projects, and everything
- you can do in a Jamfile you can do in those files. So, you declare
- a project id and a target. Now, one can write:
+
+ Recall that both site-config.jam and
+ user-config.jam are projects, and everything you can
+ do in a Jamfile you can do in those files as well. So, you declare a
+ project id and a target. Now, one can write:
exe hello : hello.cpp /site-config//zlib ;
- in any Jamfile.
-
+ in any Jamfile.
+ Header-only libraries
- In modern C++, libraries often consist of just header files, without
- any source files to compile. To use such libraries, you need to add proper
- includes and, maybe, defines, to your project. But with large number of
- external libraries it becomes problematic to remember which libraries are
- header only, and which are "real" ones. However, with Boost.Build a
- header-only library can be declared as Boost.Build target and all
- dependents can use such library without remebering if it's header-only or not.
-
-
- Header-only libraries are declared using the alias rule,
- that specifies only usage requirements, for example:
-
-alias mylib
- : # no sources
- : # no build requirements
- : # no default build
- : <include>whatever
- ;
-
- The includes specified in usage requirements of mylib are
- automatically added to build properties of all dependents. The dependents
- need not care if mylib is header-only or not, and it's possible
- to later make mylib into a regular compiled library.
+
+ In modern C++, libraries often consist of just header files, without any
+ source files to compile. To use such libraries, you need to add proper
+ includes and possibly defines to your project. But with a large number of
+ external libraries it becomes problematic to remember which libraries are
+ header only, and which ones you have to link to. However, with Boost.Build
+ a header-only library can be declared as Boost.Build target and all
+ dependents can use such library without having to remeber whether it is a
+ header-only library or not.
- If you already have proper usage requirements declared for project where
- header-only library is defined, you don't need to duplicate them for
+ Header-only libraries may be declared using the alias rule,
+ specifying their include path as a part of its usage requirements, for
+ example:
+
+alias my-lib
+ : # no sources
+ : # no build requirements
+ : # no default build
+ : <include>whatever ;
+
+ The includes specified in usage requirements of my-lib are
+ automatically added to all of its dependants' build properties. The
+ dependants need not care if my-lib is a header-only or not,
+ and it is possible to later make my-lib into a regular
+ compiled library without having to that its dependants' declarations.
+
+
+
+ If you already have proper usage requirements declared for a project where
+ a header-only library is defined, you do not need to duplicate them for
the alias target:
project my : usage-requirements <include>whatever ;
alias mylib ;
-
+
-
+
-
-
\ No newline at end of file
+-->
diff --git a/doc/src/reference.xml b/doc/src/reference.xml
index 7f16230e0..449f6925c 100644
--- a/doc/src/reference.xml
+++ b/doc/src/reference.xml
@@ -420,41 +420,55 @@ path-constant DATA : data/a.txt ;
- A feature that combines several low-level features, making
- it easy to request common build configurations.
+ A feature combining several low-level features, making it easy to
+ request common build configurations.
- Allowed values:debug, release,
- profile.
+
+ Allowed values:
+ debug, release,
+ profile.
+
- The value debug expands to
+
+ The value debug expands to
+
<optimization>off <debug-symbols>on <inlining>off <runtime-debugging>on
- The value release expands to
+
+ The value release expands to
+
<optimization>speed <debug-symbols>off <inlining>full <runtime-debugging>off
- The value profile expands to the same as
- release, plus:
+
+ The value profile expands to the same as
+ release, plus:
+
<profiling>on <debug-symbols>on
- User can define his own build variants using the variant rule from the common
- module.
-
- Notee: Runtime
- debugging is on in debug builds to suit the expectations of
- people used to various IDEs.
-
+
+ Users can define their own build variants using the
+ variant rule from the common module.
-
+
+
+ Note: Runtime debugging is on in
+ debug builds to suit the expectations of people used to various
+ IDEs.
+
+
+
+
link
@@ -465,10 +479,11 @@ path-constant DATA : data/a.txt ;
static
- A feature that controls how libraries are built.
+ A feature controling how libraries are built.
-
+
+
runtime linking
@@ -720,7 +735,10 @@ path-constant DATA : data/a.txt ;
instruction-setinstruction-set
- Allowed values for this feature depend on used toolset.
+
+ Allowed values: depend on the used
+ toolset.
+ The instruction-set specifies for which
specific instruction set the code should be generated. The
@@ -751,6 +769,31 @@ path-constant DATA : data/a.txt ;
+ c++-template-depth
+
+
+ Allowed values: Any positive
+ integer.
+
+
+
+ This feature allows configuring a C++ compiler with the maximal
+ template instantiation depth parameter. Specific toolsets may or may
+ not provide support for this feature depending on whether their
+ compilers provide a corresponding command-line option.
+
+
+
+ Note: Due to some internal details
+ in the current Boost Build implementation it is not possible to have
+ features whose valid values are all positive integer. As a
+ workaround a large set of allowed values has been defined for this
+ feature and, if a different one is needed, user can easily add it by
+ calling the feature.extend rule.
+
+
+
+
@@ -970,9 +1013,9 @@ using msvc : &toolset_ops; ;
- setup-amd64>
- setup-i386>
- setup-ia64>
+ setup-amd64
+ setup-i386
+ setup-ia64The filename of the target platform specific
environment setup script to run before invoking any of the tools
diff --git a/doc/src/tasks.xml b/doc/src/tasks.xml
index c6889b49e..6ae6f4c58 100644
--- a/doc/src/tasks.xml
+++ b/doc/src/tasks.xml
@@ -9,328 +9,339 @@
Common tasks
- This section describes main targets types that Boost.Build supports
- out-of-the-box. Unless otherwise noted, all mentioned main target rules have
- the common signature, described in .
+
+ This section describes main targets types that Boost.Build supports
+ out-of-the-box. Unless otherwise noted, all mentioned main target rules have
+ the common signature, described in .
Programs
- exe
- Programs are created using the exe rule, which follows
- the common syntax.
- For example:
+ exe
+
+ Programs are created using the exe rule, which follows the
+ common syntax. For
+ example:
exe hello : hello.cpp some_library.lib /some_project//library
: <threading>multi
;
- This will create an executable file from the sources -- in this case,
- one C++ file, one library file present in the same directory, and
- another library that is created by Boost.Build. Generally, sources
- can include C and C++ files, object files and libraries. Boost.Build
- will automatically try to convert targets of other types.
+ This will create an executable file from the sources -- in this case, one
+ C++ file, one library file present in the same directory, and another
+ library that is created by Boost.Build. Generally, sources can include C
+ and C++ files, object files and libraries. Boost.Build will automatically
+ try to convert targets of other types.
+
+
+
+
+ On Windows, if an application uses shared libraries, and both the
+ application and the libraries are built using Boost.Build, it is not
+ possible to immediately run the application, because the PATH
+ environment variable should include the path to the
+ libraries. It means you have to either add the paths manually, or have
+ the build place the application and the libraries into the same
+ directory. See .
+
+
+
-
-
- On Windows, if an application uses dynamic libraries, and both
- the application and the libraries are built by Boost.Build, its not
- possible to immediately run the application, because the
- PATH environment variable should include the path
- to the libraries. It means you have to either add the paths
- manually, or place the application and the libraries to the same
- directory. See .
-
-
-
-
+
+ Libraries
-
- Libraries
-
- Libraries are created using the lib rule, which
- follows the common
- syntax. For example:
+
+ Library targets are created using the lib rule, which
+ follows the common syntax
+ . For example:
-lib helpers : helpers.cpp : <include>boost : : <include>. ;
+lib helpers : helpers.cpp ;
-
-
-
- In the most common case, the lib creates a library from the
- specified sources. Depending on the value of <link> feature the
- library will be either static or shared. There are two other cases.
- First is when the library is installed somewhere in compiler's search
- paths, and should be searched by the compiler (typically, using the
- option). The second case is where the library is
- available as a prebuilt file and the full path is known.
-
-
+ This will define a library target named helpers built from
+ the helpers.cpp source file.
+
+
+ Depending on the given <link> feature value the library will be
+ either static or shared.
+
+
+ Library targets may be used to represent:
+
+
+
+ Built libraries that get built from specified sources,
+ as is the one in the example above.
+
+
+
+
+ Prebuilt libraries which already exist on the system
+ and are just supposed to be used by the build system. Such
+ libraries may be searched for by the tools using them (typically
+ linkers referencing the library using the
+ option) or their path may be known in advance by the build system.
+
+
+
+
+
-
- The syntax for these case is given below:
+
+ The syntax for these case is given below:
lib z : : <name>z <search>/home/ghost ;
lib compress : : <file>/opt/libs/compress.a ;
- The name property specifies the name that should be
- passed to the option, and the file
- property specifies the file location. The search feature
- specifies paths in which to search for the library. That feature can
- be specified several times, or it can be omitted, in which case only
- default compiler paths will be searched.
-
+ The name property specifies the name that should be passed to
+ the option, and the file property
+ specifies the file location. The search feature
+ specifies paths in which to search for the library. That feature can be
+ specified several times or it can be omitted, in which case only the
+ default compiler paths will be searched.
+
- The difference between using the file feature as
- opposed to the name feature together with the
- search feature is that file is more
- precise. A specific file will be used. On the other hand, the
- search feature only adds a library path, and the
- name feature gives the basic name of the library. The
- search rules are specific to the linker. For example, given these
- definition:
+
+ The difference between using the file feature as
+ opposed to the name feature together with the
+ search feature is that file is more precise.
+ A specific file will be used as opposed to the search
+ feature only adding a library path, or the name feature
+ giving only the basic name of the library. The search rules are specific
+ to the linker used. For example, given these definition:
lib a : : <variant>release <file>/pool/release/a.so ;
lib a : : <variant>debug <file>/pool/debug/a.so ;
lib b : : <variant>release <file>/pool/release/b.so ;
lib b : : <variant>debug <file>/pool/debug/b.so ;
- It's possible to use release version of a and debug
- version of b. Had we used the name and
- search features, the linker would always pick either
- release or debug versions.
-
-
+ It is possible to use a release version of a and debug
+ version of b. Had we used the name and
+ search features, the linker would have always picked
+ either the release or the debug versions.
+
+
-
- For convenience, the following syntax is allowed:
+
+ For convenience, the following syntax is allowed:
lib z ;
lib gui db aux ;
- and is does exactly the same as:
+ which has exactly the same effect as:
lib z : : <name>z ;
lib gui : : <name>gui ;
lib db : : <name>db ;
lib aux : : <name>aux ;
-
+
-
- When a library uses another library you should put that other library in
- the list of sources. This will do the right thing in all cases. For
- portability, you should specify library dependencies even for searched
- and prebuilt libraries, othewise, static linking on Unix will not work.
- For example:
+
+ When a library references another library you should put that other
+ library in its list of sources. This will do the right thing in all cases.
+ For portability, you should specify
+ library dependencies even for searched and prebuilt libraries, othewise,
+ static linking on Unix will not work. For example:
lib z ;
lib png : z : <name>png ;
-
-
-
-
- When a library (say, a), that has another library, (say,
- b)
-
- is linked dynamically, the b
- library will be incorporated
-
- in a. (If b
- is dynamic library as well, then a will only refer to it,
- and not include any extra code.)
-
- When the a
- library is linked statically, Boost.Build will assure that all
- executables that link to a will also link to
- b.
-
-
+
+
- One feature of Boost.Build that is very important for libraries is usage
- requirements.
-
- For example, if you write:
-
-lib helpers : helpers.cpp : : : <include>. ;
-
- then the compiler include path for all targets that use
- helpers will contain the directory
-
- where the target is defined.path to "helpers.cpp". The user
- only needs to add helpers to the list of sources,
- and needn't consider the requirements its use imposes on a
- dependent target. This feature greatly simplifies Jamfiles.
-
+ When a library has a shared library defined as its source, or a static
+ library has another static library defined as its source then any target
+ linking to the first library with automatically link to its source
+ library as well.
-
-
- If you don't want shared libraries to include all libraries
- that are specified in sources (especially statically linked ones),
- you'd need to use the following:
+
+ On the other hand, when a shared library has a static library defined as
+ its source then the first library will be built so that it completely
+ includes the second one.
+
+
+ If you do not want shared libraries to include all libraries specified
+ in its sources (especially statically linked ones), you would need to
+ use the following:
lib b : a.cpp ;
lib a : a.cpp : <use>b : : <library>b ;
- This specifies that a uses b, and causes
- all executables that link to a also link to
- b. In this case, even for shared linking, the
- a library won't even refer to b.
-
-
-
-
-
-
- Alias
-
-
- The alias rule gives an alternative name to
- a group of targets. For example, to give the 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 the source
- list of any other target is the same as explicitly using
- im, reader, and
- writer, but it is just more convenient.
+ This specifies that library a uses library b,
+ and causes all executables that link to a also link to
+ b. In this case, even for shared linking, the
+ a library will not even refer to b.
+
+
+ One Boost.Build feature that is often very useful for defining library
+ targets are usage requirements. For example, imagine that
+ you want you build a helpers library and its interface is
+ described in its helpers.hpp header file located in the same
+ directory as the helpers.cpp source file. Then you could add
+ the following to the Jamfile located in that same directory:
+
+lib helpers : helpers.cpp : : : <include>. ;
+
+ which would automatically add the directory where the target has been
+ defined (and where the library's header file is located) to the compiler's
+ include path for all targets using the helpers library. This
+ feature greatly simplifies Jamfiles.
+
+
-
- Another use of the alias rule is to change build
- properties. For example, if you always want static linking for a
- specific C++ Boost library, you can write the following:
+
+ Alias
+
+
+ The alias rule gives an alternative name to a
+ group of targets. For example, to give the 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 the source list
+ of any other target is the same as explicitly using im
+ , reader, and writer.
+
+
+
+ Another use of the alias rule is to change build properties.
+ For example, if you want to use link statically to the Boost Threads
+ library, you can write the following:
alias threads : /boost/thread//boost_thread : <link>static ;
- and use only the threads alias in your Jamfiles.
-
+ and use only the threads alias in your Jamfiles.
+
-
- You can also specify usage requirements for the
- alias target. If you write the following:
+
+ You can also specify usage requirements for the alias target.
+ If you write the following:
alias header_only_library : : : : <include>/usr/include/header_only_library ;
- then using header_only_library in sources will only add an
- include path. Also note that when an alias has sources, their usage
- requirements are propagated as well. For example:
+ then using header_only_library in sources will only add an
+ include path. Also note that when an alias has sources, their usage
+ requirements are propagated as well. For example:
lib library1 : library1.cpp : : : <include>/library/include1 ;
lib library2 : library2.cpp : : : <include>/library/include2 ;
alias static_libraries : library1 library2 : <link>static ;
exe main : main.cpp static_libraries ;
- will compile main.cpp with additional includes
- required for using the specified static libraries.
-
+ will compile main.cpp with additional includes
+ required for using the specified static libraries.
+
+
-
+
+ Installing
-
- Installing
+
+ This section describes various ways to install built target and arbitrary
+ files.
+
- This section describes various ways to install built target
- and arbitrary files.
+ Basic install
- Basic install
-
- For installing a built target you should use the
- install rule, which follows the common syntax. For
- example:
+
+ For installing a built target you should use the install
+ rule, which follows the
+ common syntax. For example:
install dist : hello helpers ;
- will cause the targets hello and helpers to
- be moved to the dist directory, relative to
- Jamfile's directory. The directory can
- be changed with the location property:
+ will cause the targets hello and helpers to be
+ moved to the dist directory, relative to the
+ Jamfile's directory. The directory can be changed using the
+ location property:
install dist : hello helpers : <location>/usr/bin ;
- While you can achieve the same effect by changing the target name to
- /usr/bin, using the location
- property is better, because it allows you to use a mnemonic target
- name.
-
+ While you can achieve the same effect by changing the target name to
+ /usr/bin, using the location property is
+ better as it allows you to use a mnemonic target name.
+
- The location property is especially handy when the location
- is not fixed, but depends on build variant or environment variables:
+
+ The location property is especially handy when the location
+ is not fixed, but depends on the build variant or environment variables:
-install dist : hello helpers : <variant>release:<location>dist/release
- <variant>debug:<location>dist/debug ;
+install dist : hello helpers :
+ <variant>release:<location>dist/release
+ <variant>debug:<location>dist/debug ;
install dist2 : hello helpers : <location>$(DIST) ;
- See also conditional
- properties and environment variables
-
+ See also conditional
+ properties and environment
+ variables
+
- Installing with all dependencies
+ Installing with all dependencies
-
- Specifying the names of all libraries to install can be boring. The
- install allows you to specify only the top-level executable
- targets to install, and automatically install all dependencies:
+
+ Specifying the names of all libraries to install can be boring. The
+ install allows you to specify only the top-level executable
+ targets to install, and automatically install all dependencies:
install dist : hello
: <install-dependencies>on <install-type>EXE
<install-type>LIB
;
- will find all targets that hello depends on, and install
- all of those which are either executables or libraries. More
- specifically, for each target, other targets that were specified as
- sources or as dependency properties, will be recursively found. One
- exception is that targets referred with the use feature
- are not considered, because that feature is typically used to refer to
- header-only libraries.
- If the set of target types is specified, only targets of that type
- will be installed, otherwise, all found target will be installed.
-
+ will find all targets that hello depends on, and install all
+ of those which are either executables or libraries. More specifically, for
+ each target, other targets that were specified as sources or as dependency
+ properties, will be recursively found. One exception is that targets
+ referred with the
+ use feature are not considered, as that feature is
+ typically used to refer to header-only libraries. If the set of target
+ types is specified, only targets of that type will be installed,
+ otherwise, all found target will be installed.
+
- Preserving Directory Hierarchy
+ Preserving Directory Hierarchy
- install-source-root
- By default, the install rules will stip paths from
- it's sources. So, if sources include a/b/c.hpp,
- the a/b part will be ignored. To make the
- install rule preserve the directory hierarchy you need
- to use the install-source-root feature to specify the
- root of the hierarchy you are installing. Relative paths from that
+ install-source-root
+
+
+ By default, the install rule will strip paths from its
+ sources. So, if sources include a/b/c.hpp, the
+ a/b part will be ignored. To make the
+ install rule preserve the directory hierarchy you need to
+ use the <install-source-root> feature to specify
+ the root of the hierarchy you are installing. Relative paths from that
root will be preserved. For example, if you write:
-
install headers
: a/b/c.h
: <location>/tmp <install-source-root>a
;
-
the a file named /tmp/b/c.h will be created.
-
+
- The glob-tree rule
- can be used to find all files below a given directory, making
- it easy to install entire directory tree.
+
+ The glob-tree rule can be
+ used to find all files below a given directory, making it easy to install
+ an entire directory tree.
+
- Installing into Several Directories
+ Installing into Several Directories
- The alias
- rule can be used when targets must be installed into several
- directories:
+
+ The alias rule can be
+ used when targets need to be installed into several directories:
alias install : install-bin install-lib ;
install install-bin : applications : /usr/bin ;
@@ -340,178 +351,180 @@ install install-lib : helper : /usr/lib ;
Because the install rule just copies targets, most free
- features see the definition of "free" in
- .
- have no effect when used in requirements of the install rule.
- The only two which matter are dependency
- and, on Unix,
- dll-path.
+ features see the definition of "free" in . have no
+ effect when used in requirements of the install rule. The
+ only two that matter are
+ dependency and, on Unix, dll-path
+ .
- (Unix specific). On Unix, executables built with Boost.Build typically
- contain the list of paths to all used dynamic libraries. For installing,
+ (Unix specific) On Unix, executables built using Boost.Build typically
+ contain the list of paths to all used shared libraries. For installing,
this is not desired, so Boost.Build relinks the executable with an empty
list of paths. You can also specify additional paths for installed
- executables with the dll-path feature.
+ executables using the dll-path feature.
+
-
+
+ Testing
-
-
- Testing
-
-
- Boost.Build has convenient support for running unit tests. The simplest
- way is the unit-test rule, which follows the common syntax. For
- example:
+
+ Boost.Build has convenient support for running unit tests. The simplest
+ way is the unit-test rule, which follows the common syntax. For example:
unit-test helpers_test : helpers_test.cpp helpers ;
-
+
- The unit-test rule behaves like the
- exe rule, but after the executable is created it is
- run. If the executable returns an error code, the build system will also
- return an error and will try running the executable on the next
- invocation until it runs successfully. This behaviour ensures that you
- can't miss a unit test failure.
-
+
+ The unit-test rule behaves like the
+ exe rule, but after the executable is created
+ it is also run. If the executable returns an error code, the build system
+ will also return an error and will try running the executable on the next
+ invocation until it runs successfully. This behaviour ensures that you can
+ not miss a unit test failure.
+
- By default, the executable is run directly. Sometimes, it's
- desirable to run the executable using some helper command. You should use the
- testing.launcher property to specify the name of the
- helper command. For example, if you write:
-
+
+ By default, the executable is run directly. Sometimes, it is desirable to
+ run the executable using some helper command. You should use the
+ testing.launcher property to specify the name of the helper
+ command. For example, if you write:
unit-test helpers_test
: helpers_test.cpp helpers
: <testing.launcher>valgrind
;
- The command used to run the executable will be:
+ The command used to run the executable will be:
valgrind bin/$toolset/debug/helpers_test
+
- There are few specialized testing rules, listed below:
-
+
+ There are few specialized testing rules, listed below:
+
rule compile ( sources : requirements * : target-name ? )
rule compile-fail ( sources : requirements * : target-name ? )
rule link ( sources + : requirements * : target-name ? )
rule link-fail ( sources + : requirements * : target-name ? )
-
- They are are given a list of sources and requirements.
- If the target name is not provided, the name of the first
- source file is used instead. The compile*
- tests try to compile the passed source. The link*
- rules try to compile and link an application from all the passed sources.
- The compile and link rules expect
- that compilation/linking succeeds. The compile-fail
- and link-fail rules, on the opposite, expect that
+
+ They are given a list of sources and requirements. If the target name is
+ not provided, the name of the first source file is used instead. The
+ compile* tests try to compile the passed source. The
+ link* rules try to compile and link an application from
+ all the passed sources. The compile and link
+ rules expect that compilation/linking succeeds. The
+ compile-fail and link-fail rules expect that
the compilation/linking fails.
-
+
- There are two specialized rules for running applications, which
- are more powerful than the unit-test rule. The
- run rule has the following signature:
-
+
+ There are two specialized rules for running applications, which are more
+ powerful than the unit-test rule. The run rule
+ has the following signature:
+
rule run ( sources + : args * : input-files * : requirements * : target-name ?
: default-build * )
-
- The rule builds application from the provided sources and runs it,
- passing args and input-files
- as command-line arguments. The args parameter
- is passed verbatim and the values of the input-files
- parameter are treated as paths relative to containing Jamfile, and are
- adjusted if bjam is invoked from a different
- directory. The run-fail rule is identical to the
- run rule, except that it expects that the run fails.
-
+
+ The rule builds application from the provided sources and runs it, passing
+ args and input-files as command-line
+ arguments. The args parameter is passed verbatim and
+ the values of the input-files parameter are treated as
+ paths relative to containing Jamfile, and are adjusted if bjam
+ is invoked from a different directory. The
+ run-fail rule is identical to the run rule,
+ except that it expects that the run fails.
+
- All rules described in this section, if executed successfully,
- create a special manifest file to indicate that the test passed.
- For the unit-test rule the files is named
- target-name.passed and
- for the other rules it is called
- target-name.test.
- The run* rules also capture all output from the program,
- and store it in a file named
- target-name.output.
+
+ All rules described in this section, if executed successfully, create a
+ special manifest file to indicate that the test passed. For the
+ unit-test rule the files is named
+ target-name.passed and for the other rules it is
+ called target-name.test.
+ The run* rules also capture all output from the program, and
+ store it in a file named
+ target-name.output.
+
- The run and the run-fail rules, if
- the test passes, automatically delete the linked executable, to
- save space. This behaviour can be suppressed by passing the
- --preserve-test-targets command line option.
+
+ The run and the run-fail rules, if the test
+ passes, automatically delete the linked executable, to save space. This
+ behaviour can be suppressed by passing the
+ --preserve-test-targets command line option.
+
- It is possible to print the list of all test targets (except for
- unit-test) declared in your project, by passing
- the --dump-tests command-line option. The output
- will consist of lines of the form:
-
+
+ It is possible to print the list of all test targets (except for
+ unit-test) declared in your project, by passing the
+ --dump-tests command-line option. The output will consist of
+ lines of the form:
+
boost-test(test-type) path : sources
-
-
+
+
- It is possible to process the list of tests, the output of
- bjam during command run, and the presense/absense of the
- *.test files created when test passes into
- human-readable status table of tests. Such processing utilities
- are not included in Boost.Build.
+
+ It is possible to process the list of tests, the output of bjam during
+ command run, and the presense/absense of the *.test
+ files created when test passes into human-readable status table of tests.
+ Such processing utilities are not included in Boost.Build.
+
+
-
+
+ Custom commands
-
+
+ When you use most of main target rules, Boost.Build automatically figures
+ what commands to run and it what order. As soon as you want to use new
+ file types or support new tools, one approach is to extend Boost.Build to
+ smoothly support them, as documented in .
+ However, if there is only a single place where the new tool is used, it
+ might be easier to just explicitly specify the commands to run.
+
- Custom commands
+
+
+ Three main target rules can be used for that. The make
+ rule allows you to construct a single file from any number
+ of source file, by running a command you specify. The
+ notfile rule allows you to run an arbitrary command,
+ without creating any files. And finaly, the generate
+ rule allows you to describe transformation using
+ Boost.Build's virtual targets. This is higher-level than file names that
+ the make rule operates with and allows you to
+ create more than one target, create differently named targets depending on
+ properties or use more than one tool.
+
-
- When you use most of main target rules, Boost.Build automatically
- figures what commands to run and it what order. As soon as you want to
- use new file types, or support new tools, one approach is to extend
- Boost.Build to smoothly support them, as documented in
- . However, if there's a single place
- where the new tool is used, it might be easier to just explicitly
- specify the commands to run.
-
+
+ The make rule is used when you want to create
+ one file from a number of sources using some specific command. The
+ notfile is used to unconditionally run a
+ command.
+
-
-
- Three main target rules can be used for that. The make
- rule allows you to construct a single file from any
- number of source file, by running a command you specify. The
- notfile rule allows you to run an arbitrary
- command, without creating any files. And finaly, the
- generate rule allows you to describe transformation using
- Boost.Build's virtual targets. This is higher-level than file names that
- the make rule operates with and allows you
- to create more than one target, create differently named targets
- depending on properties or use more than one tool.
-
+
-
- The make rule is used when you want to
- create one file from a number of sources using some specific command.
- The notfile is used to unconditionally run
- a command.
-
-
-
-
-
- Suppose you want to create file file.out from file
- file.in by running command
- in2out. Here is how you would do this in Boost.Build:
+
+ Suppose you want to create file file.out from file
+ file.in by running command
+ in2out. Here is how you would do this in Boost.Build:
make file.out : file.in : @in2out ;
actions in2out
@@ -519,16 +532,16 @@ actions in2out
in2out $(<) $(>)
}
- If you run bjam and file.out
- does not exist, Boost.Build will run the in2out
- command to create that file. For more details on specifying actions, see
- .
-
+ If you run bjam and file.out does
+ not exist, Boost.Build will run the in2out command to
+ create that file. For more details on specifying actions, see .
+
-
- It could be that you just want to run some command unconditionally, and
- that command does not create any specific files. For that you can use
- the notfile rule. For example:
+
+ It could be that you just want to run some command unconditionally, and
+ that command does not create any specific files. For that you can use the
+ notfile rule. For example:
notfile echo_something : @echo ;
actions echo
@@ -536,56 +549,56 @@ actions echo
echo "something"
}
- The only difference from the make rule is
- that the name of the target is not considered a name of a file, so
- Boost.Build will unconditionally run the action.
-
+ The only difference from the make rule is
+ that the name of the target is not considered a name of a file, so
+ Boost.Build will unconditionally run the action.
+
-
-
- The generate rule is used when you want to
- express transformations using Boost.Build's virtual targets, as opposed
- to just filenames. The generate rule has
- the standard main target rule signature, but you are required to specify
- the generating-rule property. The value of the
- property should be in the form
- @rule-name, the named rule
- should have the following signature:
+
+
+ The generate rule is used when you want to
+ express transformations using Boost.Build's virtual targets, as opposed to
+ just filenames. The generate rule has the
+ standard main target rule signature, but you are required to specify the
+ generating-rule property. The value of the property
+ should be in the form
+ @rule-name, the named rule should
+ have the following signature:
rule generating-rule ( project name : property-set : sources * )
- and will be called with an instance of the project-target
- class, the name of the main target, an instance of the
- property-set class containing build properties, and the
- list of instances of the virtual-target class corresponding
- to sources. The rule must return a list of virtual-target
- instances. The interface of the virtual-target class can be
- learned by looking at the build/virtual-target.jam
- file. The generate example contained in the
- Boost.Build distribution illustrates how the generate
- rule can be used.
-
+ and will be called with an instance of the project-target
+ class, the name of the main target, an instance of the
+ property-set class containing build properties, and the list
+ of instances of the virtual-target class corresponding to
+ sources. The rule must return a list of virtual-target
+ instances. The interface of the virtual-target class can be
+ learned by looking at the build/virtual-target.jam
+ file. The generate example contained in the
+ Boost.Build distribution illustrates how the generate
+ rule can be used.
+
+
-
+
+ Precompiled Headers
-
- Precompiled Headers
+
+ Precompiled headers is a mechanism to speed up compilation by creating a
+ partially processed version of some header files, and then using that
+ version during compilations rather then repeatedly parsing the original
+ headers. Boost.Build supports precompiled headers with gcc and msvc
+ toolsets.
+
-
- Precompiled headers is a mechanism to speed up compilation by creating a
- partially processed version of some header files, and then using that
- version during compilations rather then repeatedly parsing the original
- headers. Boost.Build supports precompiled headers with gcc and msvc
- toolsets.
-
+
+ To use precompiled headers, follow the following steps:
+
-
- To use precompiled headers, follow the following steps:
-
-
-
-
+
+
+
Create a header that includes headers used by your project that you
want precompiled. It is better to include only headers that are
sufficiently stable — like headers from the compiler and
@@ -593,9 +606,11 @@ rule generating-rule ( project name : property-set : sources * )
BOOST_BUILD_PCH_ENABLED, so that the potentially expensive
inclusion of headers is not done when PCH is not enabled. Include the
new header at the top of your source files.
-
+
+
-
+
+
Declare a new Boost.Build target for the precompiled header and add
that precompiled header to the sources of the target whose compilation
you want to speed up:
@@ -606,91 +621,99 @@ exe main : main.cpp pch ;
You can use the c-pch rule if you want to
use the precompiled header in C programs.
-
+
-
- The pch example in Boost.Build distribution can be
- used as reference.
-
+
+ The pch example in Boost.Build distribution can be
+ used as reference.
+
-
- Please note the following:
-
+
+ Please note the following:
+
-
-
+
+
+
The inclusion of the precompiled header must be the first thing in a
source file, before any code or preprocessor directives.
-
+
+
-
+
+
The build properties used to compile the source files and the
precompiled header must be the same. Consider using project
requirements to assure this.
-
+
+
-
+
+
Precompiled headers must be used purely as a way to improve
compilation time, not to save the number of #include
statements. If a source file needs to include some header, explicitly
include it in the source file, even if the same header is included
from the precompiled header. This makes sure that your project will
build even if precompiled headers are not supported.
-
+
+
-
+
+
On the gcc compiler, the name of the header being precompiled must be
equal to the name of the cpp-pch target. This is a gcc
requirement.
-
+
+
-
+
+
Prior to version 4.2, the gcc compiler did not allow anonymous
namespaces in precompiled headers, which limits their utility. See the
- bug
+ bug
report for details.
-
-
-
+
+
+
+
-
- Generated headers
+
+ Generated headers
- Usually, Boost.Build handles implicit dependendies completely
- automatically. For example, for C++ files, all #include
- statements are found and handled. The only aspect where user help
- might be needed is implicit dependency on generated files.
+
+ Usually, Boost.Build handles implicit dependendies completely
+ automatically. For example, for C++ files, all #include
+ statements are found and handled. The only aspect where user help might be
+ needed is implicit dependency on generated files.
+
- By default, Boost.Build handles such dependencies within one
- main target. For example, assume that main target "app" has two
- sources, "app.cpp" and "parser.y". The latter source is converted
- into "parser.c" and "parser.h". Then, if "app.cpp" includes
- "parser.h", Boost.Build will detect this dependency. Moreover,
- since "parser.h" will be generated into a build directory, the
- path to that directory will automatically added to include
- path.
-
- Making this mechanism work across main target boundaries is
- possible, but imposes certain overhead. For that reason, if
- there's implicit dependency on files from other main targets, the
- <implicit-dependency> [ link ] feature must
- be used, for example:
+
+ By default, Boost.Build handles such dependencies within one main target.
+ For example, assume that main target "app" has two sources, "app.cpp" and
+ "parser.y". The latter source is converted into "parser.c" and "parser.h".
+ Then, if "app.cpp" includes "parser.h", Boost.Build will detect this
+ dependency. Moreover, since "parser.h" will be generated into a build
+ directory, the path to that directory will automatically added to include
+ path.
+
+
+ Making this mechanism work across main target boundaries is possible, but
+ imposes certain overhead. For that reason, if there is implicit dependency
+ on files from other main targets, the <implicit-dependency>
+ [ link ] feature must be used, for example:
lib parser : parser.y ;
exe app : app.cpp : <implicit-dependency>parser ;
-
-
- The above example tells the build system that when scanning
- all sources of "app" for implicit-dependencies, it should consider
- targets from "parser" as potential dependencies.
-
-
-
+ The above example tells the build system that when scanning all sources of
+ "app" for implicit-dependencies, it should consider targets from "parser"
+ as potential dependencies.
+
+
-
OBJ generator that could potentially cover the
+# Boost Build bug by clearing its internal viable source target type state.
+obj other-obj : source.unga_cpp ;
+""")
+
+ t.run_build_system()
+ t.expect_addition("bin/$toolset/debug/dummy.obj")
+ t.expect_addition("Other/bin/$toolset/debug/other-obj.obj")
+ t.expect_nothing_more()
+
+ t.cleanup()
+
+
+################################################################################
+#
+# main()
+# ------
+#
+################################################################################
+
+test_generator_added_after_already_building_a_target_of_its_target_type()
+test_using_a_derived_source_type_created_after_generator_already_used()
diff --git a/test/generators-test/Jamfile b/test/generators-test/jamfile.jam
similarity index 100%
rename from test/generators-test/Jamfile
rename to test/generators-test/jamfile.jam
diff --git a/test/generators-test/project-root.jam b/test/generators-test/jamroot.jam
similarity index 100%
rename from test/generators-test/project-root.jam
rename to test/generators-test/jamroot.jam
diff --git a/test/generators-test/lib/Jamfile b/test/generators-test/lib/jamfile.jam
similarity index 100%
rename from test/generators-test/lib/Jamfile
rename to test/generators-test/lib/jamfile.jam
diff --git a/test/generators_test.py b/test/generators_test.py
index 209960845..549a8e0ac 100644
--- a/test/generators_test.py
+++ b/test/generators_test.py
@@ -1,41 +1,30 @@
#!/usr/bin/python
-# Copyright 2003 Dave Abrahams
-# Copyright 2002, 2003, 2005 Vladimir Prus
-# Distributed under the Boost Software License, Version 1.0.
-# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+# Copyright 2003 Dave Abrahams
+# Copyright 2002, 2003, 2005 Vladimir Prus
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
-from BoostBuild import Tester, List
-import os
+import BoostBuild
-t = Tester()
+t = BoostBuild.Tester()
t.set_tree("generators-test")
+
t.run_build_system()
-t.expect_addition(
- "bin/$toolset/debug/"
- * (
- List(
- "a.obj b.obj c.h c.cpp c.obj d_parser.whl d_lexer.dlp d_parser.cpp d_lexer.cpp "
- + "d_parser.lr0 d_parser.h d_parser_symbols.h x.c x.obj y.x1 y.x2 "
- + "y.cpp y.obj e.marked_cpp e.positions e.target_cpp e.obj "))
- )
-ok = 0
-
+t.expect_addition( "bin/$toolset/debug/" * BoostBuild.List( "a.obj b.obj c.h "
+ + "c.cpp c.obj d_parser.whl d_lexer.dlp d_parser.cpp d_lexer.cpp "
+ + "d_parser.lr0 d_parser.h d_parser_symbols.h x.c x.obj y.x1 y.x2 y.cpp "
+ + "y.obj e.marked_cpp e.positions e.target_cpp e.obj"))
t.expect_addition("bin/$toolset/debug/a.exe")
-
t.expect_addition(["lib/bin/$toolset/debug/c.obj",
- "lib/bin/$toolset/debug/auxilliary.lib",
- ])
-
+ "lib/bin/$toolset/debug/auxilliary.lib"])
t.run_build_system(subdir='lib')
-
t.expect_addition(["lib/bin/$toolset/debug/auxilliary2.dll"])
t.run_build_system(subdir='lib', extra_args="link=static")
-
t.expect_addition(["lib/bin/$toolset/debug/link-static/auxilliary2.lib"])
t.cleanup()
diff --git a/test/implicit_dependency.py b/test/implicit_dependency.py
index 5fecdd23a..4fc103ac6 100644
--- a/test/implicit_dependency.py
+++ b/test/implicit_dependency.py
@@ -1,20 +1,18 @@
#!/usr/bin/python
-# Copyright (C) Vladimir Prus 2006.
-# Distributed under the Boost Software License, Version 1.0. (See
-# accompanying file LICENSE_1_0.txt or copy at
-# http://www.boost.org/LICENSE_1_0.txt)
+# Copyright (C) Vladimir Prus 2006.
+# Distributed under the Boost Software License, Version 1.0. (See
+# accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
-# Test the is respected even if the
-# target referred-to is not build itself, but only referred
-# to by .
+# Test the is respected even if the target referred to is
+# not built itself, but only referred to by .
-from BoostBuild import Tester, List
-import string
+import BoostBuild
-t = Tester()
+t = BoostBuild.Tester()
-t.write("Jamroot", """
+t.write("jamroot.jam", """
make a.h : : gen-header ;
explicit a.h ;
@@ -37,20 +35,14 @@ else
}
""")
-t.write("hello.cpp", """
+t.write("hello.cpp", """
#include "a.h"
-
-int main()
-{
- return i;
-}
+int main() { return i; }
""")
-
t.run_build_system()
t.expect_addition("bin/$toolset/debug/hello.exe")
t.cleanup()
-
diff --git a/test/indirect_conditional.py b/test/indirect_conditional.py
index b877e37cc..6e9c18141 100644
--- a/test/indirect_conditional.py
+++ b/test/indirect_conditional.py
@@ -1,16 +1,15 @@
#!/usr/bin/python
-# Copyright (C) Vladimir Prus 2006.
-# Distributed under the Boost Software License, Version 1.0. (See
-# accompanying file LICENSE_1_0.txt or copy at
-# http://www.boost.org/LICENSE_1_0.txt)
+# Copyright (C) Vladimir Prus 2006.
+# Distributed under the Boost Software License, Version 1.0. (See
+# accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
-from BoostBuild import Tester, List
-import string
+import BoostBuild
-t = Tester()
+t = BoostBuild.Tester()
-t.write("Jamroot", """
+t.write("jamroot.jam", """
exe a1 : a1.cpp : @a1-rule ;
rule a1-rule ( properties * )
@@ -21,7 +20,8 @@ rule a1-rule ( properties * )
}
}
-exe a2 : a2.cpp : @$(__name__).a2-rule debug:speed ;
+exe a2 : a2.cpp : @$(__name__).a2-rule
+ debug:speed ;
rule a2-rule ( properties * )
{
@@ -31,7 +31,8 @@ rule a2-rule ( properties * )
}
}
-exe a3 : a3.cpp : @$(__name__).a3-rule-1 @$(__name__).a3-rule-2 ;
+exe a3 : a3.cpp : @$(__name__).a3-rule-1
+ @$(__name__).a3-rule-2 ;
rule a3-rule-1 ( properties * )
{
@@ -48,32 +49,26 @@ rule a3-rule-2 ( properties * )
return speed ;
}
}
-
""")
-t.write("a1.cpp", """
+t.write("a1.cpp", """
#ifdef OK
int main() {}
#endif
-
""")
-t.write("a2.cpp", """
+t.write("a2.cpp", """
#ifdef OK
int main() {}
#endif
-
""")
-t.write("a3.cpp", """
+t.write("a3.cpp", """
#ifdef OK
int main() {}
#endif
-
""")
-
-
t.run_build_system()
t.expect_addition("bin/$toolset/debug/a1.exe")
@@ -81,4 +76,3 @@ t.expect_addition("bin/$toolset/debug/optimization-speed/a2.exe")
t.expect_addition("bin/$toolset/debug/optimization-speed/a3.exe")
t.cleanup()
-
diff --git a/test/inherit_toolset.py b/test/inherit_toolset.py
index dfb4e1a26..ca050d2c4 100644
--- a/test/inherit_toolset.py
+++ b/test/inherit_toolset.py
@@ -1,76 +1,59 @@
#!/usr/bin/python
-# Copyright 2003 Vladimir Prus
-# Distributed under the Boost Software License, Version 1.0.
-# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+# Copyright 2003 Vladimir Prus
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
-from BoostBuild import Tester, List
-from string import find
+import BoostBuild
+import string
-t = Tester(pass_toolset=0)
+t = BoostBuild.Tester(pass_toolset=0)
-t.write("a.cpp", """
+t.write("a.cpp", """
""")
-t.write("yfc1.jam", """
-import feature : extend ;
-import generators : register-standard ;
+t.write("yfc1.jam", """
+import feature ;
+import generators ;
feature.extend toolset : yfc1 ;
-
-rule init ( )
-{
-}
+rule init ( ) { }
generators.register-standard yfc1.compile : CPP : OBJ : yfc1 ;
generators.register-standard yfc1.link : OBJ : EXE : yfc1 ;
-actions compile
-{
- yfc1-compile
-}
-
-actions link
-{
- yfc1-link
-}
+actions compile { yfc1-compile }
+actions link { yfc1-link }
""")
-t.write("yfc2.jam", """
-import feature : extend ;
-import toolset : inherit ;
+t.write("yfc2.jam", """
+import feature ;
+import toolset ;
feature.extend toolset : yfc2 ;
toolset.inherit yfc2 : yfc1 ;
+rule init ( ) { }
-rule init ( )
-{
-}
-
-actions link
-{
- yfc2-link
-}
+actions link { yfc2-link }
""")
-t.write("Jamfile", """
-exe a : a.cpp ;
+t.write("jamfile.jam", """
+exe a : a.cpp ;
""")
-t.write("project-root.jam", """
+t.write("jamroot.jam", """
using yfc1 ;
""")
t.run_build_system("-n -d2 yfc1")
-t.fail_test(find(t.stdout(), "yfc1-link") == -1)
+t.fail_test(string.find(t.stdout(), "yfc1-link") == -1)
-# Make sure we don't have to explicit 'use' yfc1.
-t.write("project-root.jam", """
+# Make sure we do not have to explicitly 'use' yfc1.
+t.write("jamroot.jam", """
using yfc2 ;
""")
t.run_build_system("-n -d2 yfc2")
-t.fail_test(find(t.stdout(), "yfc2-link") == -1)
+t.fail_test(string.find(t.stdout(), "yfc2-link") == -1)
t.cleanup()
-
diff --git a/test/inherited_dependency.py b/test/inherited_dependency.py
new file mode 100755
index 000000000..7d4895e07
--- /dev/null
+++ b/test/inherited_dependency.py
@@ -0,0 +1,237 @@
+#!/usr/bin/python
+#
+# Copyright (c) 2008 Steven Watanabe
+#
+# Distributed under the Boost Software License, Version 1.0. (See
+# accompanying file LICENSE_1_0.txt) or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+import BoostBuild
+
+tester = BoostBuild.Tester()
+
+
+################################################################################
+#
+# Test without giving the project an explicit id.
+#
+################################################################################
+
+tester.write("jamroot.jam", """
+lib test : test.cpp ;
+project : requirements test ;
+build-project a ;
+""")
+
+tester.write("test.cpp", """
+#ifdef _WIN32
+ __declspec(dllexport)
+#endif
+void foo() {}
+""")
+
+tester.write("a/test1.cpp", """
+int main() {}
+""")
+
+tester.write("a/jamfile.jam", """
+exe test1 : test1.cpp ;
+""")
+
+tester.run_build_system()
+
+tester.expect_addition("bin/$toolset/debug/test.obj")
+tester.expect_addition("a/bin/$toolset/debug/test1.exe")
+
+tester.rm("bin")
+tester.rm("a/bin")
+
+
+################################################################################
+#
+# Run the same test from the "a" directory.
+#
+################################################################################
+
+tester.run_build_system(subdir="a")
+
+tester.expect_addition("bin/$toolset/debug/test.obj")
+tester.expect_addition("a/bin/$toolset/debug/test1.exe")
+
+tester.rm("bin")
+tester.rm("a/bin")
+
+
+################################################################################
+#
+# This time, do give the project an id.
+#
+################################################################################
+
+tester.write("jamroot.jam", """
+lib test : test.cpp ;
+project test_project : requirements test ;
+build-project a ;
+""")
+
+tester.run_build_system()
+
+tester.expect_addition("bin/$toolset/debug/test.obj")
+tester.expect_addition("a/bin/$toolset/debug/test1.exe")
+
+tester.rm("bin")
+tester.rm("a/bin")
+
+
+################################################################################
+#
+# Now, give the project an id in its attributes.
+#
+################################################################################
+
+tester.write("jamroot.jam", """
+lib test : test.cpp ;
+project : id test_project : requirements test ;
+build-project a ;
+""")
+
+tester.run_build_system()
+
+tester.expect_addition("bin/$toolset/debug/test.obj")
+tester.expect_addition("a/bin/$toolset/debug/test1.exe")
+
+tester.rm("bin")
+tester.rm("a/bin")
+
+
+################################################################################
+#
+# Give the project an id in both ways at once.
+#
+################################################################################
+
+tester.write("jamroot.jam", """
+lib test : test.cpp ;
+project test_project1 : id test_project : requirements test ;
+build-project a ;
+""")
+
+tester.run_build_system()
+
+tester.expect_addition("bin/$toolset/debug/test.obj")
+tester.expect_addition("a/bin/$toolset/debug/test1.exe")
+
+tester.rm("bin")
+tester.rm("a/bin")
+
+
+################################################################################
+#
+# Test an absolute path in native format.
+#
+################################################################################
+
+tester.write("jamroot.jam", """
+import path ;
+path-constant here : . ;
+current-location = [ path.native [ path.root [ path.make $(here) ] [ path.pwd ]
+ ] ] ;
+project test : requirements $(current-location)/a/test1.cpp ;
+exe test : test.cpp ;
+""")
+
+tester.run_build_system()
+tester.expect_addition("bin/$toolset/debug/test.exe")
+
+tester.rm("bin")
+tester.rm("a/bin")
+
+
+################################################################################
+#
+# Test an absolute path in canonical format.
+#
+################################################################################
+
+tester.write("jamroot.jam", """
+import path ;
+path-constant here : . ;
+current-location = [ path.root [ path.make $(here) ] [ path.pwd ] ] ;
+project test : requirements $(current-location)/a/test1.cpp ;
+exe test : test.cpp ;
+""")
+
+tester.run_build_system()
+tester.expect_addition("bin/$toolset/debug/test.exe")
+
+tester.rm("bin")
+tester.rm("a/bin")
+
+
+################################################################################
+#
+# Test dependency properties (e.g. ) whose targets are specified using a
+# relative path.
+#
+################################################################################
+
+# Use jamroot.jam rather than jamfile.jam to avoid inheriting the from
+# the parent as that would would make test3 a source of itself.
+tester.write("b/jamroot.jam", """
+obj test3 : test3.cpp ;
+""")
+
+tester.write("b/test3.cpp", """
+void bar() {}
+""")
+
+tester.write("jamroot.jam", """
+project test : requirements b//test3 ;
+build-project a ;
+""")
+
+tester.write("a/jamfile.jam", """
+exe test : test1.cpp ;
+""")
+
+tester.write("a/test1.cpp", """
+void bar();
+int main() { bar(); }
+""")
+
+tester.run_build_system()
+tester.expect_addition("b/bin/$toolset/debug/test3.obj")
+tester.expect_addition("a/bin/$toolset/debug/test.exe")
+
+tester.rm("bin")
+tester.rm("a")
+tester.rm("jamroot.jam")
+tester.rm("test.cpp")
+
+
+################################################################################
+#
+# Test that source-location is respected.
+#
+################################################################################
+
+tester.write("build/jamroot.jam", """
+project : requirements test.cpp : source-location ../src ;
+""")
+
+tester.write("src/test.cpp", """
+int main() {}
+""")
+
+tester.write("build/a/jamfile.jam", """
+project : source-location ../../a_src ;
+exe test : test1.cpp ;
+""")
+
+tester.write("a_src/test1.cpp", """
+""")
+
+tester.run_build_system(subdir="build/a")
+tester.expect_addition("build/a/bin/$toolset/debug/test.exe")
+
+tester.cleanup()
diff --git a/test/inline.py b/test/inline.py
index 39bfecd75..df6c09892 100644
--- a/test/inline.py
+++ b/test/inline.py
@@ -1,31 +1,25 @@
#!/usr/bin/python
-# Copyright 2003, 2006 Vladimir Prus
-# Distributed under the Boost Software License, Version 1.0.
-# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+# Copyright 2003, 2006 Vladimir Prus
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
-from BoostBuild import Tester, List
+import BoostBuild
-t = Tester()
+t = BoostBuild.Tester()
-t.write("Jamroot", """
+t.write("jamroot.jam", """
project : requirements static ;
-exe a : a.cpp [ lib helper : helper.cpp ] ;
+exe a : a.cpp [ lib helper : helper.cpp ] ;
""")
t.write("a.cpp", """
extern void helper();
-int main()
-{
- return 0;
-}
-
+int main() {}
""")
t.write("helper.cpp", """
-void helper()
-{
-}
+void helper() {}
""")
t.run_build_system()
@@ -37,13 +31,13 @@ t.expect_addition("bin/$toolset/debug/link-static/a__helper.lib")
t.rm("bin")
-# Now check that inline targets with the same name but
-# present in different places are not confused between
-# each other, and with top-level targets.
-t.write("Jamroot", """
+
+# Now check that inline targets with the same name but present in different
+# places are not confused between each other, and with top-level targets.
+t.write("jamroot.jam", """
project : requirements static ;
exe a : a.cpp [ lib helper : helper.cpp ] ;
-exe a2 : a.cpp [ lib helper : helper.cpp ] ;
+exe a2 : a.cpp [ lib helper : helper.cpp ] ;
""")
t.run_build_system()
@@ -51,9 +45,10 @@ t.expect_addition("bin/$toolset/debug/link-static/a.exe")
t.expect_addition("bin/$toolset/debug/link-static/a__helper.lib")
t.expect_addition("bin/$toolset/debug/link-static/a2__helper.lib")
-# Check that the 'alias' target does not change name of
-# inline targets, and that inline targets are explicit.
-t.write("Jamroot", """
+
+# Check that the 'alias' target does not change the name of inline targets, and
+# that inline targets are explicit.
+t.write("jamroot.jam", """
project : requirements static ;
alias a : [ lib helper : helper.cpp ] ;
explicit a ;
@@ -67,4 +62,3 @@ t.run_build_system("a")
t.expect_addition("bin/$toolset/debug/link-static/helper.lib")
t.cleanup()
-
diff --git a/test/Jamfile b/test/jamfile.jam
similarity index 100%
rename from test/Jamfile
rename to test/jamfile.jam
diff --git a/test/lib_source_property.py b/test/lib_source_property.py
index 34568a4b1..2290c1fbf 100644
--- a/test/lib_source_property.py
+++ b/test/lib_source_property.py
@@ -1,28 +1,27 @@
#!/usr/bin/python
-# Copyright (C) Vladimir Prus 2006.
-# Distributed under the Boost Software License, Version 1.0. (See
-# accompanying file LICENSE_1_0.txt or copy at
-# http://www.boost.org/LICENSE_1_0.txt)
+# Copyright (C) Vladimir Prus 2006.
+# Distributed under the Boost Software License, Version 1.0. (See
+# accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
-# Regression test: if a library had no explicit sources, but
-# only properties, it was built as it it were searched
-# library, and the specified sources were not compiled.
-from BoostBuild import Tester, List
+# Regression test: if a library had no explicit sources, but only
+# properties, it was built as if it were a searched library, and the specified
+# sources were not compiled.
-# Create a temporary working directory
-t = Tester()
+import BoostBuild
-# Create the needed files
-t.write("Jamroot", """
+t = BoostBuild.Tester()
+
+t.write("jamroot.jam", """
lib a : : a.cpp ;
""")
+
t.write("a.cpp", """
#ifdef _WIN32
__declspec(dllexport)
#endif
void foo() {}
-
""")
t.run_build_system()
@@ -30,8 +29,9 @@ t.expect_addition("bin/$toolset/debug/a.obj")
t.rm("bin")
-# Now try with
-t.write("Jamroot", """
+
+# Now try with .
+t.write("jamroot.jam", """
rule test ( properties * )
{
return a.cpp ;
diff --git a/test/library_chain.py b/test/library_chain.py
index f8ecb84be..6df744727 100644
--- a/test/library_chain.py
+++ b/test/library_chain.py
@@ -1,34 +1,31 @@
#!/usr/bin/python
-# Copyright 2003, 2004, 2005, 2006 Vladimir Prus
-# Distributed under the Boost Software License, Version 1.0.
-# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+# Copyright 2003, 2004, 2005, 2006 Vladimir Prus
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
-# Test that a chain of libraries work ok, not matter if we use static or
-# shared linking.
-from BoostBuild import Tester, List, get_toolset
+# Test that a chain of libraries works ok, no matter if we use static or shared
+# linking.
+
+import BoostBuild
import string
import os
-t = Tester()
+t = BoostBuild.Tester()
-t.write("Jamfile", """
-# Stage the binary, so that it will be relinked
-# without hardcode-dll-paths. That will chech that
-# we pass correct -rpath-link, even if not passing
-# -rpath.
+t.write("jamfile.jam", """
+# Stage the binary, so that it will be relinked without hardcode-dll-paths. That
+# will chech that we pass correct -rpath-link, even if not passing -rpath.
stage dist : main ;
-exe main : main.cpp b ;
+exe main : main.cpp b ;
""")
-t.write("main.cpp", """
+t.write("main.cpp", """
void foo();
-
-int main() { foo(); return 0; }
-
+int main() { foo(); }
""")
-t.write("project-root.jam", """
+t.write("jamroot.jam", """
""")
t.write("a/a.cpp", """
@@ -41,26 +38,24 @@ void
#if defined(_WIN32)
__declspec(dllexport)
#endif
-geek() {}
+geek() {}
""")
-t.write("a/Jamfile", """
-lib a : a.cpp ;
+t.write("a/jamfile.jam", """
+lib a : a.cpp ;
""")
-t.write("b/b.cpp", """
+t.write("b/b.cpp", """
void geek();
-
-void
+void
#if defined(_WIN32)
__declspec(dllexport)
#endif
foo() { geek(); }
-
""")
-t.write("b/Jamfile", """
-lib b : b.cpp ../a//a ;
+t.write("b/jamfile.jam", """
+lib b : b.cpp ../a//a ;
""")
t.run_build_system(stderr=None)
@@ -71,84 +66,92 @@ t.run_build_system("link=static")
t.expect_addition("bin/$toolset/debug/link-static/main.exe")
t.rm(["bin", "a/bin", "b/bin"])
-# Check that works for static linking.
-t.write("b/Jamfile", """
-lib b : b.cpp : ../a//a ;
+# Check that works for static linking.
+t.write("b/jamfile.jam", """
+lib b : b.cpp : ../a//a ;
""")
+
t.run_build_system("link=static")
t.expect_addition("bin/$toolset/debug/link-static/main.exe")
t.rm(["bin", "a/bin", "b/bin"])
-t.write("b/Jamfile", """
-lib b : b.cpp ../a//a/shared : static ;
+
+t.write("b/jamfile.jam", """
+lib b : b.cpp ../a//a/shared : static ;
""")
t.run_build_system()
t.expect_addition("bin/$toolset/debug/main.exe")
+
t.rm(["bin", "a/bin", "b/bin"])
-# Test that putting library in sources of a searched library
-# works.
-t.write("Jamfile", """
+
+# Test that putting a library in sources of a searched library works.
+t.write("jamfile.jam", """
exe main : main.cpp png ;
lib png : z : png ;
lib z : : zzz ;
""")
+
t.run_build_system("-a -d+2", status=None, stderr=None)
-# Try to find the "zzz" string either in response file
-# (for Windows compilers), or in standard output.
+# Try to find the "zzz" string either in response file (for Windows compilers),
+# or in the standard output.
rsp = t.adjust_names("bin/$toolset/debug/main.exe.rsp")[0]
-if os.path.exists(rsp) and string.find(open(rsp).read(), "zzz") != -1:
+if os.path.exists(rsp) and ( string.find(open(rsp).read(), "zzz") != -1 ):
pass
elif string.find(t.stdout(), "zzz") != -1:
pass
else:
t.fail_test(1)
-#
-# Test main -> libb -> liba chain
-# in the case where liba is a file, not a Boost.Build target.
-#
+# Test main -> libb -> liba chain in the case where liba is a file and not a
+# Boost.Build target.
t.rm(".")
-t.write("Jamroot", "")
-t.write("a/Jamfile", """
+
+t.write("jamroot.jam", "")
+
+t.write("a/jamfile.jam", """
lib a : a.cpp ;
install dist : a ;
""")
+
t.write("a/a.cpp", """
#if defined(_WIN32)
__declspec(dllexport)
#endif
void a() {}
""")
+
t.run_build_system(subdir="a")
t.expect_addition("a/dist/a.dll")
-if (os.name == 'nt' or os.uname()[0].lower().startswith('cygwin')) and get_toolset() != 'gcc':
+if ( ( os.name == 'nt' ) or os.uname()[0].lower().startswith('cygwin') ) and \
+ ( BoostBuild.get_toolset() != 'gcc' ):
# This is windows import library -- we know the exact name.
file = "a/dist/a.lib"
else:
file = t.adjust_names(["a/dist/a.dll"])[0]
-t.write("b/Jamfile", """
+t.write("b/jamfile.jam", """
lib b : b.cpp ../%s ;
""" % file)
+
t.write("b/b.cpp", """
#if defined(_WIN32)
__declspec(dllimport)
#endif
void a();
-
#if defined(_WIN32)
__declspec(dllexport)
#endif
void b() { a(); }
""")
-t.write("Jamroot", """
+t.write("jamroot.jam", """
exe main : main.cpp b//b ;
""")
+
t.write("main.cpp", """
#if defined(_WIN32)
__declspec(dllimport)
@@ -160,6 +163,4 @@ int main() { b(); }
t.run_build_system()
t.expect_addition("bin/$toolset/debug/main.exe")
-
-
t.cleanup()
diff --git a/test/library_order.py b/test/library_order.py
index f5638a7ba..3a92d2473 100644
--- a/test/library_order.py
+++ b/test/library_order.py
@@ -1,81 +1,61 @@
#!/usr/bin/python
-# Copyright 2004 Vladimir Prus
-# Distributed under the Boost Software License, Version 1.0.
-# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+# Copyright 2004 Vladimir Prus
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
-from BoostBuild import Tester, List
+# Test that on compilers sensitive to library order on linker's command line, we
+# generate the correct order.
+
+import BoostBuild
import string
-# Test that on compilers which are sensitive to library order on
-# linker's command line, we generate the right order.
-t = Tester()
+t = BoostBuild.Tester()
-t.write("a.cpp", """
+t.write("a.cpp", """
void b();
-
-void a()
-{
- b();
-}
-
+void a() { b(); }
""")
-t.write("b.cpp", """
+t.write("b.cpp", """
void c();
-
-void b()
-{
- c();
-}
+void b() { c(); }
""")
-t.write("c.cpp", """
+t.write("c.cpp", """
void d();
-
-void c()
-{
- d();
-}
-
+void c() { d(); }
""")
-t.write("d.cpp", """
+t.write("d.cpp", """
void d() {}
-
""")
-# The order of libraries in 'main' is crafted so that
-# we get error unless we do something about the order ourselfs.
-t.write("Jamfile", """
+# The order of libraries in 'main' is crafted so that we get error unless we do
+# something about the order ourselves.
+t.write("jamfile.jam", """
exe main : main.cpp libd libc libb liba ;
lib libd : d.cpp ;
lib libc : c.cpp : static