From 7240a08587a00eb930cba92efcdda20eafd0c75d Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Sat, 14 Oct 2006 21:41:23 +0000 Subject: [PATCH] Wholespace merge from HEAD [SVN r35613] --- v2/build/alias.jam | 2 +- v2/build/generators.jam | 31 +- v2/build/property.jam | 2 +- v2/build/targets.jam | 21 +- v2/build/virtual-target.jam | 8 + v2/doc/src/advanced.xml | 857 +------------------------------- v2/doc/src/reference.xml | 117 +++-- v2/doc/src/standalone.xml | 15 +- v2/doc/src/userman.xml | 6 +- v2/nightly.sh | 15 +- v2/test/BoostBuild.py | 7 + v2/test/inline.py | 53 +- v2/test/load_order.py | 26 + v2/test/railsys/program/Jamfile | 1 - v2/test/test_all.py | 1 + v2/tools/builtin.jam | 73 ++- v2/tools/common.jam | 143 ++++++ v2/tools/gcc.jam | 110 +++- v2/tools/msvc.jam | 112 ++++- v2/tools/pch.jam | 116 +++-- v2/tools/stage.jam | 2 +- v2/tools/stlport.jam | 2 +- v2/tools/testing.jam | 22 +- 23 files changed, 714 insertions(+), 1028 deletions(-) diff --git a/v2/build/alias.jam b/v2/build/alias.jam index 35bcfea61..d7d68a376 100644 --- a/v2/build/alias.jam +++ b/v2/build/alias.jam @@ -63,7 +63,7 @@ rule alias ( name : sources * : requirements * : default-build * : usage-require targets.main-target-alternative [ new alias-target-class $(name) : $(project) - : [ targets.main-target-sources $(sources) : $(name) ] + : [ targets.main-target-sources $(sources) : $(name) : no-renaming ] : [ targets.main-target-requirements $(requirements) : $(project) ] : [ targets.main-target-default-build $(default-build) : $(project) ] : [ targets.main-target-usage-requirements $(usage-requirements) : $(project) ] diff --git a/v2/build/generators.jam b/v2/build/generators.jam index b538d210b..3c7cfe365 100644 --- a/v2/build/generators.jam +++ b/v2/build/generators.jam @@ -825,22 +825,28 @@ local rule try-one-generator-really ( project name ? : generator : ] ; local usage-requirements ; - if $(targets) && [ class.is-a $(targets[1]) : property-set ] + local success ; + if $(targets) { - usage-requirements = $(targets[1]) ; - targets = $(targets[2-]) ; - } - else - { - usage-requirements = [ property-set.empty ] ; + success = true ; + + if [ class.is-a $(targets[1]) : property-set ] + { + usage-requirements = $(targets[1]) ; + targets = $(targets[2-]) ; + } + else + { + usage-requirements = [ property-set.empty ] ; + } } generators.dout [ indent ] " generator" [ $(generator).id ] " spawned " ; generators.dout [ indent ] " " $(targets) ; - if $(targets) + if $(success) { return $(usage-requirements) $(targets) ; - } + } } # Checks if generator invocation can be pruned, because it's guaranteed @@ -1128,12 +1134,7 @@ local rule construct-really ( # 'construct' in stack, returns only targets of requested 'target-type', # otherwise, returns also unused sources and additionally generated # targets. -# -# Does not return target which are not of 'allowed-type' or of type derived from -# it. If 'allowed-type' is not specified, it's defaulted to 'target-type'. -# See lib-target-class for use case of this. -rule construct ( project name ? : target-type : property-set * : sources * - : allowed-type * ) +rule construct ( project name ? : target-type : property-set * : sources * ) { if (.construct-stack) { diff --git a/v2/build/property.jam b/v2/build/property.jam index 3ad0cd340..a638d9002 100644 --- a/v2/build/property.jam +++ b/v2/build/property.jam @@ -555,7 +555,7 @@ local rule __test__ ( ) assert.true path-order $(test-space) on on ; assert.false path-order $(test-space) on on ; - assert.result gcc off FOO + assert.result FOO off gcc : refine gcc off : FOO : $(test-space) diff --git a/v2/build/targets.jam b/v2/build/targets.jam index 94bfc6b28..8f9134f32 100644 --- a/v2/build/targets.jam +++ b/v2/build/targets.jam @@ -1369,18 +1369,27 @@ class typed-target : basic-target # Return the list of sources to use, if main target rule is invoked # with 'sources'. If there are any objects in 'sources', they are treated -# as main target instances, and WRITEME. -rule main-target-sources ( sources * : main-target-name ) +# as main target instances, and the name of such targets are adjusted to +# be '__'. Such renaming +# is disabled is non-empty value is passed for 'no-renaming' parameter. +# +rule main-target-sources ( sources * : main-target-name : no-renaming ? ) { local result ; for local t in $(sources) { if [ class.is-instance $(t) ] { - local name = [ $(t).name ] ; - local new-name = $(main-target-name)__$(name) ; - $(t).rename $(new-name) ; - result += $(new-name) ; + local name = [ $(t).name ] ; + if ! $(no-renaming) + { + name = $(main-target-name)__$(name) ; + $(t).rename $(name) ; + } + # Inline targets are not built by default. + local p = [ $(t).project ] ; + $(p).mark-target-as-explicit $(name) ; + result += $(name) ; } else { diff --git a/v2/build/virtual-target.jam b/v2/build/virtual-target.jam index 3c52b32d5..fb30279d5 100644 --- a/v2/build/virtual-target.jam +++ b/v2/build/virtual-target.jam @@ -402,6 +402,14 @@ class abstract-file-target : virtual-target ps = [ property-set.empty ] ; } + #~ We add ourselves to the properties so that any tag rule can get + #~ more direct information about the target than just that available + #~ through the properties. This is useful in implementing + #~ name changes based on the sources of the target. For example to + #~ make unique names of object files based on the source file. + #~ --grafik + ps = [ property-set.create [ $(ps).raw ] $(__name__) ] ; + local tag = [ $(ps).get ] ; if $(tag) diff --git a/v2/doc/src/advanced.xml b/v2/doc/src/advanced.xml index 8187a1f9e..ac7fb615c 100644 --- a/v2/doc/src/advanced.xml +++ b/v2/doc/src/advanced.xml @@ -3,7 +3,7 @@ "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd"> - User documentation + Overview This section will provide the information necessary to create your own projects using Boost.Build. The information provided here is relatively @@ -73,7 +73,7 @@
- Boost.Jam language + Boost.Jam Language This section will describe the basics of the Boost.Jam language—just enough for writing Jamfiles. For more information, @@ -536,7 +536,7 @@ bjam optimization=space
- Declaring targets + Declaring Targets A Main target is a user-defined named @@ -769,7 +769,7 @@ rule my-rule ( properties * )
- Default build + Default Build The default-build parameter is a set of properties to be used if the build request does @@ -785,7 +785,7 @@ exe hello : hello.cpp : : <threading>multi ;
- Additional information + Additional Information The ways a target is built can be so different that @@ -826,7 +826,7 @@ exe hello : hello.cpp explicit request, this can be expressed by the explicit rule: - explicit install_programs ; +explicit install_programs ;
@@ -1028,90 +1028,6 @@ project tennis perfectly appropriate to start a user guide with that kind of material. --> - - -
- Jamfile Utility Rules - - The following table describes utility rules that can be - used in Jamfiles. Detailed information for any of these rules can - be obtained by running: - -bjam --help project.rulename - - - - - - <tgroup cols="2"> - <thead> - <row> - <entry>Rule</entry> - - <entry>Semantics</entry> - </row> - </thead> - - <tbody> - <row> - <entry><link linkend= - "bbv2.advanced.projects.attributes.projectrule">project</link> - </entry> - - <entry>Define this project's symbolic ID or attributes.</entry> - </row> - - <row> - <entry><xref linkend= - "bbv2.advanced.projects.relationships.useprojectrule">use-project</xref></entry> - - <entry>Make another project known so that it can be referred to by symbolic ID.</entry> - </row> - - <row> - <entry><xref linkend= - "bbv2.advanced.projects.relationships.buildprojectrule">build-project</xref></entry> - - <entry>Cause another project to be built when this one is built.</entry> - </row> - - <row> - <entry><xref linkend= - "bbv2.reference.buildprocess.explict">explicit</xref></entry> - - <entry>State that a target should be built only by explicit - request.</entry> - </row> - - <row> - <entry>glob</entry> - - <entry>Translate a list of shell-style wildcards into a - corresponding list of files.</entry> - </row> - - <row> - <entry>constant</entry> - - <entry>Injects a variable setting into this project's - Jamfile module and those of all its subprojects.</entry> - </row> - - <row> - <entry>path-constant</entry> - - <entry>Injects a variable set to a path value into - this project's Jamfile module and those of all its subprojects. - If the value is a relative path it will be adjusted for - each subproject so that it refers to the same - directory.</entry> - </row> - - - </tbody> - </tgroup> - </table> - </section> <section id="bbv2.advanced.build_process"> <title>The Build Process @@ -1147,7 +1063,7 @@ bjam --help project.rulename
- Build request + Build Request The command line specifies which targets to build and with which @@ -1253,7 +1169,7 @@ bjam app1 lib1//lib1 gcc debug optimization=full
-
Building a project +
Building a Project Often, a user builds a complete project, not just one main target. In fact, invoking bjam without @@ -1287,763 +1203,6 @@ explicit hello_test ;
- -
- Builtin target types - - This section describes main targets types that Boost.Build supports - of-of-the-box. Unless otherwise noted, all mentioned main target rules - have the common signature, described in . - - -
- Programs - - Builtin - rulesexe - Programs are created using the exe rule, which - follows the common - syntax. For example: - -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. - - - - - 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, for example using the - stage rule. - - - -
- -
- Libraries - - Libraries are created using the lib rule, which - follows the common - syntax. For example: - -lib helpers : helpers.cpp : <include>boost : : <include>. ; - - - - 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. - - - - - 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 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: - -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. - - - - - For convenience, the following syntax is allowed: - -lib z ; -lib gui db aux ; - - and is does exactly the same 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 won't 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. - - - - - 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: - -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 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. - - - - - - 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 threads : /boost/thread//boost_thread : <link>static ; - - and use only the threads alias in your Jamfiles. - - - - - 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 there are some sources, their usage - requirements are propagated, too. For example: - -lib lib : lib.cpp : : : <include>. ; -alias lib_alias ; -exe main : main.cpp lib_alias ; - - will compile main.cpp with the additional include. - - -
- -
- Installing - - 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: - -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. - - - The location property is especially handy when the location - is not fixed, but depends on build variant or environment variables: - -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 - - - - 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. - - - The alias - rule can be used when targets must be installed into several - directories: - -alias install : install-bin install-lib ; -install install-bin : applications : /usr/bin ; -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. - - - - - (Unix specific). On Unix, executables built with Boost.Build typically - contain the list of paths to all used dynamic 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. - - - - -
- -
- - 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: - -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. - - - 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: - - -unit-test helpers_test - : helpers_test.cpp helpers - : <testing.launcher>valgrind - ; - - The command used to run the executable will be: - -valgrind bin/$toolset/debug/helpers_test - - - - - There are rules for more elaborate testing: compile, - compile-fail, run and - run-fail. They are more suitable for automated testing, and - are not covered here. - -
- -
- - Raw commands: 'make' and 'notfile' - - Sometimes, the builtin target types are not enough, and you - want Boost.Build to just run specific commands. There are two main - target rules that make it possible: make - and notfile. - - - 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's how you'd do this in Boost.Build: - -actions in2out -{ - in2out $(<) $(>) -} -make file.out : file.in : @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 . - - - - - The make rule is useful to express custom - transformation that are used just once or twice in your project. For - transformations that are used often, you are advised to declare - new generator, as described in . - - - - - It could be that you just want to run some command unconditionally, - and that command does not create any specific files. The, you can use - the notfile rule. For example: - -notfile echo_something : @echo ; -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. - - -
- -
- -
- Builtin features - - - variant - - - - A feature that combines several low-level features, making - it easy to request common build configurations. - - - Allowed values: debug, release, - profile. - - The value debug expands to - - -<optimization>off <debug-symbols>on <inlining>off <runtime-debugging>on - - - 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: - - -<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. - - - - - - link - - - - A feature that controls how libraries are built. - - - Allowed values: shared, - static - - - source - - - - The <source>X feature has the same effect on - building a target as putting X in the list of sources. - It's useful when you want to add - the same source to all targets in the project - (you can put <source> in requirements) or to conditionally - include a source (using conditional requirements, see ) - See also the <library> feature. - - - - - library - - - - This feature is almost equivalent to the <source> feature, - except that it takes effect only for linking. When you want to - link all targets in a Jamfile to certain library, the - <library> feature is preferred over - <source>X -- the latter will add the library to - all targets, even those that have nothing to do with libraries. - - - - - - dependency - - - - Introduces a dependency on the target named by the - value of this feature (so it will be brought - up-to-date whenever the target being declared is). - The dependency is not used in any other way. For example, in - application with plugins, the plugins are not used when linking - the application, - application might have dependency on its plugins, even though - - - , and - adds its usage requirements to the build properties - of the target being declared. - - The primary use case is when you want - the usage requirements (such as #include paths) of some - library to be applied, but don't want to link to it. - - - - - - - - use - - - - Introduces a dependency on the target named by the - value of this feature (so it will be brought - up-to-date whenever the target being declared is), and - adds its usage requirements to the build properties - - of the target being declared. The dependency is not used - in any other way. The primary use case is when you want - the usage requirements (such as #include paths) of some - library to be applied, but don't want to link to it. - - - - - - - dll-path - - - - Specify an additional directory where the system should - look for shared libraries when the executable or shared - library is run. This feature only affects Unix - compilers. Plase see - in for details. - - - - hardcode-dll-paths - - - - Controls automatic generation of dll-path properties. - - - Allowed values: - true, false. This property - is specific to Unix systems. If an executable is built with - <hardcode-dll-paths>true, the generated binary - will contain the list of all the paths to the used shared - libraries. As the result, the executable can be run without - changing system paths to shared libraries or installing the - libraries to system paths. This - - is very convenient during - development. Plase see the FAQ entry for details. - Note that on Mac OSX, the paths are unconditionally hardcoded by - the linker, and it's not possible to disable that behaviour. - - - - - cflags - cxxflags - linkflags - - - - The value of those features is passed without modification to the - corresponding tools. For cflags that's both the C and C++ - compilers, for cxxflags that's the C++ compiler and for - linkflags that's the linker. The features are handy when - you're trying to do something special that cannot be achieved by - higher-level feature in Boost.Build. - - - - - warnings - - - - The <warnings> feature controls the warning level of compilers. It has the following values: - - off - disables all warnings. - on - enables default warning level for the tool. - all - enables all warnings. - - Default value is all. - - - - - warnings-as-errors - - - - The <warnings-as-errors> makes it possible to treat warnings as errors and abort - compilation on a warning. The value on enables this behaviour. The default value is - off. - - - - - build - - - Allowed values: no - - - The build feature is used to conditionally disable build of a target. If <build>no - is in properties when building a target, build of that target is skipped. Combined with conditional requirements this - allows to skip building some target in configurations where the build is known to fail. - - - - - - - - - -
- -
- Differences to Boost.Build V1 - - - While Boost.Build V2 is based on the same ideas as Boost.Build V1, - some of the syntax was changed, and some new important features were - added. This chapter describes most of the changes. - -
- Configuration - - In V1, toolsets were configured by environment variables. If you - wanted to use two versions of the same toolset, you had to create a new - toolset module that would set the variables and then invoke the base - toolset. In V2, toolsets are configured by the - using, and you can easily configure several - versions of a toolset. See for details. - - -
- -
- Writing Jamfiles - - Probably one of the most important differences in V2 Jamfiles is - the use of project requirements. In V1, if several targets had the same - requirements (for example, a common #include path), it was necessary to - manually write the requirements or use a helper rule or template target. In V2, the - common properties can be specified with the requirements project - attribute, as documented in . - - - Usage requirements - also help to simplify Jamfiles. - - If a library requires - all clients to use specific #include paths or macros when compiling - code that depends on the library, that information can be cleanly - represented. - - The difference between lib and dll targets in V1 is completely - eliminated in V2. There's only one library target type, lib, which can create - either static or shared libraries depending on the value of the - <link> - feature. If your target should be only built in one way, you - can add <link>shared or <link>static to its requirements. - - - The syntax for referring to other targets was changed a bit. While - in V1 one would use: - -exe a : a.cpp <lib>../foo/bar ; - - the V2 syntax is: - -exe a : a.cpp ../foo//bar ; - - Note that you don't need to specify the type of other target, but the - last element should be separated from the others by a double slash to indicate that - you're referring to target bar in project ../foo, and not to - project ../foo/bar. - - - -
- -
- Build process - - The command line syntax in V2 is completely different. For example - -bjam -sTOOLS=msvc -sBUILD=release some_target - - now becomes: - -bjam toolset=msvc variant=release some_target - - or, using implicit features, just: - -bjam msvc release some_target - - See the reference for a - complete description of the syntax. - - - -
- -
diff --git a/v2/doc/src/reference.xml b/v2/doc/src/reference.xml index ceaa9c98c..d3c6796f6 100644 --- a/v2/doc/src/reference.xml +++ b/v2/doc/src/reference.xml @@ -228,49 +228,90 @@ target1 debug gcc/runtime-link=dynamic,static -
- Writing Jamfiles +
+ Jamfile Utility Rules - This section describes specific information about writing Jamfiles. - -
- 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. - - 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: - - -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 following table describes utility rules that can be + used in Jamfiles. Detailed information for any of these rules can + be obtained by running: + +bjam --help project.rulename + + +
+ + <tgroup cols="2"> + <thead> + <row> + <entry>Rule</entry> + + <entry>Semantics</entry> + </row> + </thead> + + <tbody> + <row> + <entry><link linkend= + "bbv2.advanced.projects.attributes.projectrule">project</link> + </entry> + + <entry>Define this project's symbolic ID or attributes.</entry> + </row> + + <row> + <entry><xref linkend= + "bbv2.advanced.projects.relationships.useprojectrule">use-project</xref></entry> + + <entry>Make another project known so that it can be referred to by symbolic ID.</entry> + </row> + + <row> + <entry><xref linkend= + "bbv2.advanced.projects.relationships.buildprojectrule">build-project</xref></entry> + + <entry>Cause another project to be built when this one is built.</entry> + </row> + + <row> + <entry><xref linkend= + "bbv2.reference.buildprocess.explict">explicit</xref></entry> + + <entry>State that a target should be built only by explicit + request.</entry> + </row> + + <row> + <entry>glob</entry> + + <entry>Translate a list of shell-style wildcards into a + corresponding list of files.</entry> + </row> + + <row> + <entry>constant</entry> + + <entry>Injects a variable setting into this project's + Jamfile module and those of all its subprojects.</entry> + </row> + + <row> + <entry>path-constant</entry> + + <entry>Injects a variable set to a path value into + this project's Jamfile module and those of all its subprojects. + If the value is a relative path it will be adjusted for + each subproject so that it refers to the same + directory.</entry> + </row> + + + </tbody> + </tgroup> + </table> </section> - </section> - <section id="bbv2.reference.buildprocess"> <title>Build process diff --git a/v2/doc/src/standalone.xml b/v2/doc/src/standalone.xml index c16af5dfe..527237274 100644 --- a/v2/doc/src/standalone.xml +++ b/v2/doc/src/standalone.xml @@ -1,27 +1,30 @@ - - - Boost.Build v2 User Manual + Boost.Build V2 User Manual + - + - Boost.Jam documentation + Boost.Jam Documentation - + + + diff --git a/v2/doc/src/userman.xml b/v2/doc/src/userman.xml index f4a9202f1..d57e05653 100644 --- a/v2/doc/src/userman.xml +++ b/v2/doc/src/userman.xml @@ -5,18 +5,20 @@ - Boost.Build v2 User Manual + Boost.Build V2 User Manual + - + + diff --git a/v2/nightly.sh b/v2/nightly.sh index 07f33de5a..8ccb1cda4 100644 --- a/v2/nightly.sh +++ b/v2/nightly.sh @@ -5,12 +5,21 @@ # Create the packages set -e +trap "echo 'Nightly build failed'" ERR + +export QTDIR=/usr/share/qt3 +export LC_ALL=C +export LC_MESSAGES=C +export LANG=C cd /tmp rm -rf boost-build +echo "Checking out sources" cvs -d :ext:vladimir_prus@boost.cvs.sourceforge.net:/cvsroot/boost co -P -d boost-build boost/tools > /tmp/boost_build_checkout_log mv /tmp/boost_build_checkout_log boost-build/checkout-log cd boost-build/build/v2 -./roll.sh > ../roll-log +echo "Building packages and uploading docs" +./roll.sh > ../roll-log 2>&1 cd .. -scp boost-build.zip boost-build.tar.bz2 vladimir_prus@shell.sf.net:/home/groups/b/bo/boost/htdocs/boost-build2 > scp-log -echo "Upload successfull" +echo "Uploading packages" +scp boost-build.zip boost-build.tar.bz2 vladimir_prus@shell.sourceforge.net:/home/groups/b/bo/boost/htdocs/boost-build2 > scp-log +echo "Nightly build successful" diff --git a/v2/test/BoostBuild.py b/v2/test/BoostBuild.py index 239f76975..2aa2822f2 100644 --- a/v2/test/BoostBuild.py +++ b/v2/test/BoostBuild.py @@ -234,6 +234,13 @@ class Tester(TestCmd.TestCmd): self.wait_for_time_change() self.write(dst, self.read(src)) + def copy_preserving_timestamp(self, src, dst): + src_name = self.native_file_name(src) + dst_name = self.native_file_name(dst) + stats = os.stat(src_name) + self.write(dst, self.read(src)) + os.utime(dst_name, (stats.st_atime, stats.st_mtime)) + def touch(self, names): self.wait_for_time_change() for name in self.adjust_names(names): diff --git a/v2/test/inline.py b/v2/test/inline.py index c35865cfe..45f0a5b8c 100644 --- a/v2/test/inline.py +++ b/v2/test/inline.py @@ -9,12 +9,13 @@ from BoostBuild import Tester, List t = Tester() -t.write("project-root.jam", "") -t.write("Jamfile", """ -alias everything : [ exe a : a.cpp ] ; +t.write("Jamroot", """ +project : requirements static ; +exe a : a.cpp [ lib helper : helper.cpp ] ; """) -t.write("a.cpp", """ +t.write("a.cpp", """ +extern void helper(); int main() { return 0; @@ -22,29 +23,49 @@ int main() """) -t.run_build_system() -t.expect_addition("bin/$toolset/debug/everything__a.exe") -t.rm("bin/$toolset/debug/everything__a.exe") +t.write("helper.cpp", """ +void helper() +{ +} +""") -t.run_build_system("everything__a") -t.expect_addition("bin/$toolset/debug/everything__a.exe") +t.run_build_system() +t.expect_addition("bin/$toolset/debug/link-static/a__helper.lib") +t.rm("bin/$toolset/debug/link-static/a__helper.lib") + +t.run_build_system("a__helper") +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("Jamfile", """ -exe a : a.cpp ; -alias everything : [ exe a : a.cpp ] ; -alias everything2 : [ exe a : a.cpp ] ; +t.write("Jamroot", """ +project : requirements static ; +exe a : a.cpp [ lib helper : helper.cpp ] ; +exe a2 : a.cpp [ lib helper : helper.cpp ] ; """) t.run_build_system() -t.expect_addition("bin/$toolset/debug/a.exe") -t.expect_addition("bin/$toolset/debug/everything__a.exe") -t.expect_addition("bin/$toolset/debug/everything2__a.exe") +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", """ +project : requirements static ; +alias a : [ lib helper : helper.cpp ] ; +explicit a ; +""") +t.rm("bin") + +t.run_build_system() +t.expect_nothing_more() + +t.run_build_system("a") +t.expect_addition("bin/$toolset/debug/link-static/helper.lib") t.cleanup() diff --git a/v2/test/load_order.py b/v2/test/load_order.py index 535fbafa8..25b4ba803 100644 --- a/v2/test/load_order.py +++ b/v2/test/load_order.py @@ -41,9 +41,35 @@ int main() { return 0; } t.run_build_system() + t.expect_addition("child/bin/$toolset/debug/main.exe") t.fail_test(find(t.stdout(), "Setting child requirements") < find(t.stdout(), "Setting parent requirements")) +# Regression test: parent requirements were ignored in some cases +t.rm(".") +t.write("Jamroot", """ +build-project src ; +""") + +t.write("src/Jamfile", """ +project : requirements EVERYTHING_OK ; +""") + +t.write("src/app/Jamfile", """ +exe test : test.cpp ; +""") + +t.write("src/app/test.cpp", """ +#ifdef EVERYTHING_OK +int main() {} +#endif + +""") + +t.run_build_system(subdir="src/app") +t.expect_addition("src/app/bin/$toolset/debug/test.exe") + + t.cleanup() diff --git a/v2/test/railsys/program/Jamfile b/v2/test/railsys/program/Jamfile index 9e36f408f..b712dea2e 100644 --- a/v2/test/railsys/program/Jamfile +++ b/v2/test/railsys/program/Jamfile @@ -14,7 +14,6 @@ # # 02/21/02! Jrgen Hunold # -# $Id$ # # ================================================================ diff --git a/v2/test/test_all.py b/v2/test/test_all.py index 81b6a14e7..e89e10594 100644 --- a/v2/test/test_all.py +++ b/v2/test/test_all.py @@ -157,6 +157,7 @@ if os.name == 'posix': if string.find(get_toolset(), 'gcc') == 0: tests.append("gcc_runtime") + tests.append("pch") if "--extras" in sys.argv: tests.append("boostbook") diff --git a/v2/tools/builtin.jam b/v2/tools/builtin.jam index 4e1bba72e..859f232bf 100644 --- a/v2/tools/builtin.jam +++ b/v2/tools/builtin.jam @@ -25,9 +25,61 @@ import project ; # This feature is used to determine which OS we're on. # In future, this may become and +# The future is now... local os = [ modules.peek : OS ] ; feature os : $(os) : propagated link-incompatible ; +# Translates from bjam current OS to the os tags used +# in host-os and target-os. I.e. it returns the +# running host-os. +local rule default-host-os ( ) +{ + local host-os ; + local os-list = [ feature.values host-os ] ; + if [ os.name ] in $(os-list:U) + { + host-os = [ os.name ] ; + } + else + { + switch [ os.name ] + { + case NT : host-os = windows ; + case AS400 : host-os = unix ; + case MINGW : host-os = windows ; + case BSDI : host-os = bsd ; + case COHERENT : host-os = unix ; + case DRAGONFLYBSD : host-os = bsd ; + case IRIX : host-os = sgi ; + case MACOSX : host-os = darwin ; + case KFREEBSD : host-os = freebsd ; + case LINUX : host-os = linux ; + case * : host-os = unix ; + } + } + return $(host-os:L) ; +} + +# The two OS features define a known set of abstract OS +# names. The host-os is the OS under which bjam is running. +# Even though this should really be a fixed property we need +# to list all the values to prevent unkown value errors. +# Both set the default value to the current OS to account for +# the default use case of building on the target OS. +feature host-os + : amiga aix bsd cygwin darwin dos emx freebsd hpux + linux netbsd openbsd osf qnx qnxnto sgi solaris sun sunos + svr4 sysv ultrix unix unixware vms windows + : optional ; + feature.set-default host-os : [ default-host-os ] ; +feature target-os + : amiga aix bsd cygwin darwin dos emx freebsd hpux + linux netbsd openbsd osf qnx qnxnto sgi solaris sun sunos + svr4 sysv ultrix unix unixware vms windows + : propagated link-incompatible ; + feature.set-default target-os : [ default-host-os ] ; + + feature toolset : : implicit propagated symmetric ; feature stdlib : native : propagated composite ; @@ -405,8 +457,8 @@ class lib-generator : generator local properties = [ $(property-set).raw ] ; # Determine the needed target type local actual-type ; - # files can be generated by @rule feature - # in which case we don't consider it a SEARCHED_LIB type. + # files can be generated by @rule feature + # in which case we don't consider it a SEARCHED_LIB type. if ! in $(properties:G) && ( in $(properties:G) || in $(properties:G) ) { @@ -428,7 +480,7 @@ class lib-generator : generator property-set = [ $(property-set).add-raw LIB ] ; # Construct the target. return [ generators.construct $(project) $(name) : $(actual-type) - : $(property-set) : $(sources) : LIB ] ; + : $(property-set) : $(sources) ] ; } } @@ -447,6 +499,7 @@ generators.register [ new lib-generator builtin.lib-generator : : LIB ] ; rule lib ( names + : sources * : requirements * : default-build * : usage-requirements * ) { + local result ; local project = [ project.current ] ; # This is a circular module dependency, so it must be imported here @@ -842,6 +895,20 @@ rule register-archiver ( id composing ? : source-types + : target-types + : generators.register $(g) ; } +# Generators that accepts everything, and produces nothing. +# Usefull as general fallback for toolset-specific actions, like +# PCH generation. +class dummy-generator : generator +{ + import property-set ; + + rule run ( project name ? : property-set : sources + ) + { + return [ property-set.empty ] ; + } +} + + IMPORT $(__name__) : register-linker register-archiver : : generators.register-linker generators.register-archiver ; diff --git a/v2/tools/common.jam b/v2/tools/common.jam index 0c42a15d3..5ad6ce235 100644 --- a/v2/tools/common.jam +++ b/v2/tools/common.jam @@ -16,6 +16,7 @@ import errors ; import path ; import sequence ; import toolset ; +import virtual-target ; if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ] { @@ -565,6 +566,148 @@ actions quietly updated piecemeal together RmTemps $(RM) "$(>)" $(IGNORE) } +rule format-name ( format * : name : type ? : property-set ) +{ + if [ type.is-derived $(type) LIB ] + { + local result = "" ; + for local f in $(format) + { + switch $(f:G) + { + case : + result += $(name:B) ; + + case : + result += [ join-tag $(f:G=) : + [ toolset-tag $(name) : $(type) : $(property-set) ] ] ; + + case : + result += [ join-tag $(f:G=) : + [ threading-tag $(name) : $(type) : $(property-set) ] ] ; + + case : + result += [ join-tag $(f:G=) : + [ runtime-tag $(name) : $(type) : $(property-set) ] ] ; + + case : + local key = [ MATCH : $(f:G) ] ; + local version = [ $(property-set).get <$(key)> ] ; + version ?= $(key) ; + version = [ MATCH "^([^.]+)[.]([^.]+)[.]([^.]+)" + : $(version) ] ; + result += [ join-tag $(f:G=) : $(version[1])_$(version[2]) ] ; + + case : + local key = [ MATCH : $(f:G) ] ; + local p = [ $(property-set).get [ MATCH : $(f:G) ] ] ; + if $(p) + { + result += [ join-tag $(f:G=) : $(p) ] ; + } + + case * : + result += $(f:G=) ; + } + } + result = [ virtual-target.add-prefix-and-suffix + $(result:J=) : $(type) : $(property-set) ] ; + return $(result) ; + } +} + +local rule join-tag ( joiner ? : tag ? ) +{ + if ! $(joinder) { joiner = - ; } + return $(joiner)$(tag) ; +} + +local rule toolset-tag ( name : type ? : property-set ) +{ + local tag = ; + + local properties = [ $(property-set).raw ] ; + switch [ $(property-set).get ] + { + case borland* : tag += bcb ; + case como* : tag += como ; + case cw : tag += cw ; + case darwin* : tag += ; + case edg* : tag += edg ; + case gcc* : tag += gcc ; + case intel : + if [ $(property-set).get ] = win + { + tag += iw ; + } + else + { + tag += il ; + } + case kcc* : tag += kcc ; + case kylix* : tag += bck ; + #case metrowerks* : tag += cw ; + #case mingw* : tag += mgw ; + case mipspro* : tag += mp ; + case msvc* : tag += vc ; + case sun* : tag += sw ; + case tru64cxx* : tag += tru ; + case vacpp* : tag += xlc ; + } + local version = [ MATCH "([0123456789]+)[.]([0123456789]*)" + : $(properties) ] ; + # For historical reasons, vc6.0 and vc7.0 use different + # naming. + if $(tag) = vc + { + if $(version[1]) = 6 + { + # Cancel minor version. + version = 6 ; + } + else if $(version[1]) = 7 && $(version[2]) = 0 + { + version = 7 ; + } + } + # On intel, version is not added, because it does not + # matter and it's the version of vc used as backend + # that matters. Ideally, we'd encode the backend + # version but that will break compatibility with + # V1. + if $(tag) = iw + { + version = ; + } + tag += $(version) ; + + return $(tag:J=) ; +} + +local rule threading-tag ( name : type ? : property-set ) +{ + local tag = ; + if multi in $(properties) { tag = mt ; } + + return $(tag:J=) ; +} + +local rule runtime-tag ( name : type ? : property-set ) +{ + local tag = ; + + local properties = [ $(property-set).raw ] ; + if static in $(properties) { tag += s ; } + if on in $(properties) { tag += g ; } + + if debug-python in $(properties) { tag += y ; } + if debug in $(properties) { tag += d ; } + if stlport in $(properties) { tag += p ; } + if hostios in $(properties) { tag += n ; } + + return $(tag:J=) ; +} + rule __test__ ( ) { import assert ; diff --git a/v2/tools/gcc.jam b/v2/tools/gcc.jam index 0c5d4edda..06dd7bcbd 100644 --- a/v2/tools/gcc.jam +++ b/v2/tools/gcc.jam @@ -1,6 +1,8 @@ # Copyright 2001 David Abrahams. # Copyright 2002-2006 Rene Rivera. # Copyright 2002-2003 Vladimir Prus. +# Copyright (c) 2005 Reece H. Dunn. +# Copyright 2006 Ilya Sokolov. # # Distributed under the Boost Software License, Version 1.0. # (See accompanying file LICENSE_1_0.txt or copy at @@ -16,6 +18,8 @@ import "class" : new ; import set ; import common ; import errors ; +import property-set ; +import pch ; if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ] { @@ -144,6 +148,84 @@ generators.register-c-compiler gcc.compile.c++ : CPP : OBJ : gcc ; generators.register-c-compiler gcc.compile.c : C : OBJ : gcc ; generators.register-c-compiler gcc.compile.asm : ASM : OBJ : gcc ; +# pch support + +# The compiler looks for a precompiled header in each directory just +# before it looks for the include file in that directory. +# The name searched for is the name specified in the #include directive +# with ".gch" suffix appended. +# The logic in gcc-pch-generator will make sure that BASE_PCH suffix is +# appended to full name of the header. + +type.set-generated-target-suffix PCH : gcc : gch ; + +# GCC-specific pch generator. +class gcc-pch-generator : pch-generator +{ + import project ; + import property-set ; + import type ; + + rule run-pch ( project name ? : property-set : sources + ) + { + # Find the header in sources. Ignore any CPP sources. + local header ; + for local s in $(sources) + { + if [ type.is-derived [ $(s).type ] H ] + { + header = $(s) ; + } + } + + # error handling + # base name of header file should be the same as the base name + # of precompiled header. + local header-name = [ $(header).name ] ; + local header-basename = $(header-name:B) ; + if $(header-basename) != $(name) + { + local location = [ $(project).project-module ] ; + errors.user-error "in" $(location)": pch target name `"$(name)"' should be the same as the base name of header file `"$(header-name)"'" ; + } + + local pch-file = + [ + generator.run $(project) $(name) + : $(property-set) + : $(header) + ] + ; + + # return result of base class and pch-file property as usage-requirements + return + [ property-set.create $(pch-file) ] + $(pch-file) + ; + } + + # Calls the base version specifying source's name as the + # name of the created target. As result, the PCH will be named + # whatever.hpp.gch, and not whatever.gch. + rule generated-targets ( sources + : property-set : project name ? ) + { + name = [ $(sources[1]).name ] ; + return [ generator.generated-targets $(sources) + : $(property-set) : $(project) $(name) ] ; + } +} + +# Note: the 'H' source type will catch both '.h' header and '.hpp' header. The latter +# have HPP type, but HPP type is derived from H. The type of compilation is determined +# entirely by the destination type. +generators.register [ new gcc-pch-generator gcc.compile.c.pch : H : C_PCH : on gcc ] ; +generators.register [ new gcc-pch-generator gcc.compile.c++.pch : H : CPP_PCH : on gcc ] ; + +# Override default do-nothing generators. +generators.override gcc.compile.c.pch : pch.default-c-pch-generator ; +generators.override gcc.compile.c++.pch : pch.default-cpp-pch-generator ; + +flags gcc.compile PCH_FILE on : ; # Declare flags and action for compilation flags gcc.compile OPTIONS off : -O0 ; @@ -205,6 +287,16 @@ flags gcc.compile.c++ USER_OPTIONS ; flags gcc.compile DEFINES ; flags gcc.compile INCLUDES ; +actions compile.c++.pch +{ + "$(CONFIG_COMMAND)" -x c++-header $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)" +} + +actions compile.c.pch +{ + "$(CONFIG_COMMAND)" -x c-header $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)" +} + rule compile.c++ { # Some extensions are compiled as C++ by default. For others, we need @@ -214,12 +306,7 @@ rule compile.c++ { LANG on $(<) = "-x c++" ; } -} - - -actions compile.c++ -{ - "$(CONFIG_COMMAND)" $(LANG) -ftemplate-depth-128 $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)" + DEPENDS $(<) : [ on $(<) return $(PCH_FILE) ] ; } rule compile.c @@ -231,12 +318,17 @@ rule compile.c #{ LANG on $(<) = "-x c" ; #} + DEPENDS $(<) : [ on $(<) return $(PCH_FILE) ] ; } - -actions compile.c +actions compile.c++ bind PCH_FILE { - "$(CONFIG_COMMAND)" $(LANG) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)" + "$(CONFIG_COMMAND)" $(LANG) -ftemplate-depth-128 $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(PCH_FILE:D)" -I"$(INCLUDES)" -c -o "$(<:W)" "$(>:W)" +} + +actions compile.c bind PCH_FILE +{ + "$(CONFIG_COMMAND)" $(LANG) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(PCH_FILE:D)" -I"$(INCLUDES)" -c -o "$(<)" "$(>)" } rule compile.asm diff --git a/v2/tools/msvc.jam b/v2/tools/msvc.jam index 98fbac877..10fa58732 100644 --- a/v2/tools/msvc.jam +++ b/v2/tools/msvc.jam @@ -2,6 +2,7 @@ # Copyright (c) 2005 Vladimir Prus. # Copyright (c) 2005 Alexey Pakhunov. # Copyright (c) 2006 Bojan Resnik. +# Copyright (c) 2006 Ilya Sokolov. # # Use, modification and distribution is subject to the Boost Software # License Version 1.0. (See accompanying file LICENSE_1_0.txt or @@ -534,7 +535,92 @@ generators.override msvc.compile.idl : midl.compile.idl ; generators.register-standard msvc.compile.mc : MC : H RC : msvc ; generators.override msvc.compile.mc : mc.compile ; -generators.register [ new pch-generator msvc.compile.pch : PCHEADER : OBJ PCH : msvc ] ; +# pch support + +feature pch-source : : free dependency ; + +class msvc-pch-generator : pch-generator +{ + import property-set ; + + rule run-pch ( project name ? : property-set : source-1 source-2 ) + { + # searching header and source file in the sources + local sources = $(source-1) $(source-2) ; + local pch-header ; + local pch-source ; + for local s in $(sources) + { + if [ type.is-derived [ $(s).type ] H ] + { + pch-header = $(s) ; + } + else if + [ type.is-derived [ $(s).type ] CPP ] + || [ type.is-derived [ $(s).type ] C ] + { + pch-source = $(s) ; + } + } + + if ! $(pch-header) + { + errors.user-error "can't build pch without pch-header" ; + } + + if ! $(pch-source) + { + errors.user-error "can't build pch without pch-source" ; + } + + local generated = + [ + # Passing of is a dirty trick, + # needed because non-composing generators + # with multiple inputs are subtly broken: + # https://zigzag.cs.msu.su:7813/boost.build/ticket/111 + generator.run $(project) $(name) + : [ + property-set.create + $(pch-source) + [ $(property-set).raw ] + ] + : $(pch-header) + ] + ; + + local pch-file ; + for local g in $(generated) + { + if [ type.is-derived [ $(g).type ] PCH ] + { + pch-file = $(g) ; + } + } + + return + [ + property-set.create + $(pch-header) + $(pch-file) + ] + $(generated) + ; + } +} + +# Note: the 'H' source type will catch both '.h' header and '.hpp' header. The latter +# have HPP type, but HPP type is derived from H. The type of compilation is determined +# entirely by the destination type. +generators.register [ new msvc-pch-generator msvc.compile.c.pch : H : C_PCH OBJ : on msvc ] ; +generators.register [ new msvc-pch-generator msvc.compile.c++.pch : H : CPP_PCH OBJ : on msvc ] ; + +generators.override msvc.compile.c.pch : pch.default-c-pch-generator ; +generators.override msvc.compile.c++.pch : pch.default-cpp-pch-generator ; + +flags msvc.compile PCH_FILE on : ; +flags msvc.compile PCH_SOURCE on : ; +flags msvc.compile PCH_HEADER on : ; # # Declare flags and action for compilation @@ -580,10 +666,6 @@ flags msvc.compile DEFINES ; flags msvc.compile UNDEFS ; flags msvc.compile INCLUDES ; -flags msvc.compile PCH_SOURCE ; -flags msvc.compile PCH_HEADER on : ; -flags msvc.compile PCH_FILE on : ; - rule get-rspline ( target : lang-opt ) { CC_RSPLINE on $(target) = [ on $(target) return $(lang-opt) -U$(UNDEFS) $(CFLAGS) $(C++FLAGS) $(OPTIONS) -c $(nl)-D$(DEFINES) $(nl)\"-I$(INCLUDES)\" ] ; @@ -609,20 +691,30 @@ rule compile.c ( targets + : sources * : properties * ) rule compile.c++ ( targets + : sources * : properties * ) { - get-rspline $(targets[1]) : -TP ; + get-rspline $(targets) : -TP ; compile-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ; } -actions compile-pch +actions compile-c-c++-pch { - $(.CC) @"@($(<[1]:W).rsp:E="$(>[2]:W)" -Fo"$(<[1]:W)" -Yc"$(>[1]:D=)" -Yl"__bjam_pch_symbol_$(>[1]:D=)" -Fp"$(<[2]:W)" $(CC_RSPLINE))" + $(.CC) @"@($(<[1]:W).rsp:E="$(>[2]:W)" -Fo"$(<[2]:W)" -Yc"$(>[1]:D=)" -Yl"__bjam_pch_symbol_$(>[1]:D=)" -Fp"$(<[1]:W)" $(CC_RSPLINE))" } -rule compile.pch ( targets + : sources * : properties * ) +rule compile.c.pch ( targets + : sources * : properties * ) +{ + C++FLAGS on $(targets[1]) = ; + DEPENDS $(<) : [ on $(<) return $(PCH_SOURCE) ] ; + get-rspline $(targets[1]) : -TC ; + get-rspline $(targets[2]) : -TC ; + compile-c-c++-pch $(targets) : $(sources) [ on $(<) return $(PCH_SOURCE) ] ; +} + +rule compile.c++.pch ( targets + : sources * : properties * ) { DEPENDS $(<) : [ on $(<) return $(PCH_SOURCE) ] ; get-rspline $(targets[1]) : -TP ; - compile-pch $(targets) : $(sources) [ on $(<) return $(PCH_SOURCE) ] ; + get-rspline $(targets[2]) : -TP ; + compile-c-c++-pch $(targets) : $(sources) [ on $(<) return $(PCH_SOURCE) ] ; } actions compile.rc diff --git a/v2/tools/pch.jam b/v2/tools/pch.jam index 370ba67a4..575cbf568 100644 --- a/v2/tools/pch.jam +++ b/v2/tools/pch.jam @@ -1,79 +1,93 @@ # Copyright (c) 2005 Reece H. Dunn. +# Copyright 2006 Ilya Sokolov # # Use, modification and distribution is subject to the Boost Software # License Version 1.0. (See accompanying file LICENSE_1_0.txt or # http://www.boost.org/LICENSE_1_0.txt) +##### Using Precompiled Headers (Quick Guide) ##### +# +# Make precompiled mypch.hpp: +# +# import pch ; +# +# cpp-pch mypch +# : # sources +# mypch.hpp +# : # requiremnts +# msvc:mypch.cpp +# ; +# +# Add cpp-pch to sources: +# +# exe hello +# : main.cpp hello.cpp mypch +# ; + +import "class" : new ; import type ; -import feature : feature ; +import feature ; import generators ; -##### Using Pre-compiled Headers (Quick Guide) ##### -# -# Make mypch.hpp a pre-compiled header (PCH) using mypch.cpp as the source file: -# import cast ; -# pch mypch : [ cast _ pcheader : pch.hpp ] pch.cpp ; -# -# Enable PCHs in a target: -# exe hello : mypch main.cpp hello.cpp ; -# ^^^^^ -- mypch.hpp is a PCH -# -# Don't use PCHs for a specific source: -# obj nopch : nopch.cpp : off ; -# +type.register PCH : pch ; -type.register PCH : pch ; -type.register PCHEADER : pcheader ; +type.register C_PCH : : PCH ; +type.register CPP_PCH : : PCH ; -feature pch : # control precompiled header (PCH) generation - on # this file has support for using PCHs (if available) - off # this file doesn't use PCHs +# control precompiled header (PCH) generation +feature.feature pch : + on + off ; -feature pch-source : : free dependency ; # mypch.cpp -feature pch-header : : free dependency ; # mypch.h[pp] -feature pch-file : : free dependency ; # mypch.pch +feature.feature pch-header : : free dependency ; +feature.feature pch-file : : free dependency ; +# Base PCH generator. The 'run' method has the logic to +# prevent this generator from being run unless it's used +# in top-level PCH target. class pch-generator : generator { import property-set ; - rule __init__ ( * : * ) - { - generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ; - } - rule action-class ( ) { return compile-action ; } - rule run ( project name ? : property-set : sources * ) + rule run ( project name ? : property-set : sources + ) { - # The two sources are cpp file and PCHEADER, but they - # can be passed in any order. Figure out which source - # is what. - local cpp = $(sources[2]) ; - local h = $(sources[1]) ; - if [ $(sources[2]).type ] = PCHEADER + if ! $(name) { - cpp = $(sources[1]) ; - h = $(sources[2]) ; + # Unless this generator is invoked as the top-most + # generator for a main target, fail. This allows using + # 'H' type as input type for this generator, while + # preventing Boost.Build to try this generator when not + # explicitly asked for. + # + # One bad example is msvc, where pch generator produces + # both PCH target and OBJ target, so if there's any + # header generated (like by bison, or by msidl), we'd + # try to use pch generator to get OBJ from that H, which + # is completely wrong. By restricting this generator + # only to pch main target, such problem is solved. } - - local r = - [ generator.run $(project) $(name) : - [ - property-set.create - $(cpp) # mypch.cpp - [ $(property-set).raw ] - ] : $(sources) - ] ; - - return - [ property-set.create - $(h) # mypch.h[pp] - $(r[2]) # mypch.pch - ] $(r) ; + else + { + return [ run-pch $(project) $(name) : $(property-set) + : $(sources) ] ; + } } + + # This rule must be overridden by the derived classes. + rule run-pch ( project name ? : property-set : sources + ) + { + } } + +# NOTE: requiremetns are empty, +# default pch generator can be applied when pch=off +generators.register [ + new dummy-generator pch.default-c-pch-generator : : C_PCH ] ; +generators.register [ + new dummy-generator pch.default-cpp-pch-generator : : CPP_PCH ] ; diff --git a/v2/tools/stage.jam b/v2/tools/stage.jam index cb3806eab..ab9ea585d 100644 --- a/v2/tools/stage.jam +++ b/v2/tools/stage.jam @@ -150,7 +150,7 @@ class install-target-class : basic-target else { local targets = [ generators.construct $(self.project) $(name) : - INSTALLED_$(t) : $(new-properties) : $(i) : * ] ; + INSTALLED_$(t) : $(new-properties) : $(i) ] ; staged-targets += $(targets[2-]) ; } } diff --git a/v2/tools/stlport.jam b/v2/tools/stlport.jam index cda3be262..ad1c1eb15 100644 --- a/v2/tools/stlport.jam +++ b/v2/tools/stlport.jam @@ -172,7 +172,7 @@ class stlport-target-class : basic-target = [ targets.main-target-requirements [ $(lib-file.props).raw ] $(lib-file[-1]) : $(self.project) ] ; - return [ generators.construct $(self.project) $(name) : LIB : $(lib-file.requirements) : : LIB ] ; + return [ generators.construct $(self.project) $(name) : LIB : $(lib-file.requirements) ] ; } else { diff --git a/v2/tools/testing.jam b/v2/tools/testing.jam index 8bb2612f1..542c9f525 100644 --- a/v2/tools/testing.jam +++ b/v2/tools/testing.jam @@ -155,19 +155,11 @@ rule run-fail ( sources + : args * : input-files * : requirements * : target-nam return [ make-test run-fail : $(sources) : $(requirements) : $(target-name) ] ; } -# Rule for grouping tests in suites. -rule test-suite ( suite-name : tests + ) -{ - # In V2, if 'tests' are instances of 'abstract-target', they will be considered - # 'inline-targets' and will suffer some adjustments. This will not be compatible - # with V1 behaviour, so we get names of 'tests' and use them. - local names ; - for local t in $(tests) - { - names += [ $(t).name ] ; - } - modules.call-in [ CALLER_MODULE ] : alias $(suite-name) : $(names) ; -} + +# Use 'test-suite' as synonym for 'alias', for backward compatibility. +IMPORT : alias : : test-suite ; + + # For all main target in 'project-module', # which are typed target with type derived from 'TEST', @@ -442,8 +434,8 @@ actions unit-test $(LAUNCHER) $(>) && $(MAKE_FILE) $(<) } -IMPORT $(__name__) : compile compile-fail test-suite run run-fail link link-fail - : : compile compile-fail test-suite run run-fail link link-fail ; +IMPORT $(__name__) : compile compile-fail run run-fail link link-fail + : : compile compile-fail run run-fail link link-fail ; type.register TIME : time ;