From 4d7fc5f3ae450dd8cf3cdddffe302e11ec14deef Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 23 Oct 2001 23:10:28 +0000 Subject: [PATCH] ---------------------------------------------------------------------- Modified Files: allyourbase.jam build_system.htm new-split.jam Tag: jam_src jam_src/Jambase jam_src/compile.c jam_src/compile.h jam_src/headers.c jam_src/jam.c jam_src/jam.h jam_src/jambase.c jam_src/jamgram.c jam_src/jamgram.h jam_src/jamgram.y jam_src/jamgram.yy jam_src/jamgramtab.h jam_src/lists.c jam_src/lists.h jam_src/makedebugjam.bat jam_src/modules.c jam_src/modules.h jam_src/newstr.c jam_src/newstr.h jam_src/parse.c jam_src/parse.h jam_src/rules.c jam_src/rules.h jam_src/search.c jam_src/subst.c No tag test/check-jam-patches.jam Added Files: boost-build.jam ---------------------------------------------------------------------- allyourbase.jam Fix the way new-split.jam is included, by using $(JAM_VERSION) to detect the presence of new language features. build_system.htm Updated documentation to include core Jam extensions. jam_src/Jambase Updated so that the built-in Jambase can be completely overridden based on JAMBASE, BOOST_ROOT, and BOOST_BUILD_PATH environment variables. jam_src/compile.{c,h} Added IMPORT and CALLER_MODULE rules, header legend for profile dump. Moved regex_compile so it could be used by more functions. jam_src/headers.c, jambase.c, jamgram.{c,y,yy}, search.c, subst.c Adjusted for the addition of FRAMEs, which was needed for CALLER_MODULE. jam_src/jam.c added JAM_VERSION and started using FRAMEs. jam_src/jam.h swapped the -d argument numbers that were used by profiling and parse debugging. jam_src/lists.{c,h} Pulled stack frames out of LOL and put them where they belong, in the interpreter. jam_src/modules.{c,h} Use strncat instead of strncpy to get predictable behavior. jam_src/parse.{c,h}, rules.{c,h} Adjust for FRAMEs, and added a rulename field in the PARSE node to support profiling with modules. test/check-jam-patches.jam Added tests for IMPORT and CALLER_MODULE [SVN r11427] --- allyourbase.jam | 3 +- boost-build.jam | 7 + build_system.htm | 1485 +++++++++++++++++++++++---------- test/check-jam-patches.jam | 58 +- v1/allyourbase.jam | 3 +- v1/build_system.htm | 1485 +++++++++++++++++++++++---------- v2/boost-build.jam | 7 + v2/test/check-jam-patches.jam | 58 +- 8 files changed, 2238 insertions(+), 868 deletions(-) create mode 100644 boost-build.jam create mode 100644 v2/boost-build.jam diff --git a/allyourbase.jam b/allyourbase.jam index 105704795..4437dae61 100644 --- a/allyourbase.jam +++ b/allyourbase.jam @@ -1382,8 +1382,9 @@ rule split-path # The new jam executable has slightly different SUBST behavior which we need to # account for. -if $(NEW_BOOST_JAM) { +if $(JAM_VERSION[1]) >= 03 { +SEARCH on new-split.jam = $(BOOST_BUILD_PATH) ; include new-split.jam ; # this is temporary. } else { diff --git a/boost-build.jam b/boost-build.jam new file mode 100644 index 000000000..51a5d4813 --- /dev/null +++ b/boost-build.jam @@ -0,0 +1,7 @@ +# (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and +# distribute this software is granted provided this copyright notice appears in +# all copies. This software is provided "as is" without express or implied +# warranty, and with no claim as to its suitability for any purpose. + +SEARCH on allyourbase.jam = $(BOOST_BUILD_PATH) ; +include allyourbase.jam ; diff --git a/build_system.htm b/build_system.htm index ef0301afe..ecdb21d04 100644 --- a/build_system.htm +++ b/build_system.htm @@ -1,35 +1,40 @@ - + Boost Build System - - - - c++boost.gif (8819 bytes) + c++boost.gif (8819 bytes)

Boost Build System

Synopsis

Boost.Build is a system for large project software construction built on - FTJam, - an open-source make replacement[1]. Key features are: + FTJam, an + open-source make replacement[1]. Key features are:

  • A simple target description language +
  • Build with your choice (or multiple) toolsets from a single command invocation -
  • Build your choice of basic variants (e.g. debug, release, profile...) and - subvariant modifications (e.g. inlining off) from a single command invocation -
  • ``Feature Normalization'' allows target configurations to be described - independently from the toolset used -
  • Modular toolset description files allow build instructions for different - toolsets to be described independently + +
  • Build your choice of basic variants (e.g. debug, release, profile...) + and subvariant modifications (e.g. inlining off) from a single command + invocation + +
  • ``Feature Normalization'' allows target configurations to be + described independently from the toolset used + +
  • Modular toolset description files allow build instructions for + different toolsets to be described independently +
  • Multiple subproject support +
  • Automatic building of subproject dependencies
@@ -41,14 +46,20 @@
  • Synopsis -
  • Getting Started - +
  • + Getting Started + +
  • Basic Design and Terminology @@ -71,34 +82,86 @@ Usage - -
  • Internals -
  • - Design Criteria + Internals + + + +
  • + Design Criteria +
    • Assumptions @@ -111,26 +174,28 @@

      Getting Started

      Installing FTJam

      - +
      • This page describes how and where to get FTJam sources.
      • The Jam - README contains basic installation instructions. + README contains basic installation instructions.
      • If you are installing on Windows NT, please read this - note. You may need to use the ``SUBST hack'' described at - the bottom of the message to bootstrap Jam. Also, when defining the - MSVCNT, BCCROOT, etc. environment variables as - described in the Jam - README, please remember that they are case-sensitive. + "http://frankenrouter.perforce.com/lists/jamming/msg00474.html">this + note. You may need to use the ``SUBST hack'' described at + the bottom of the message to bootstrap Jam. Also, when defining the + MSVCNT, BCCROOT, etc. environment variables as + described in the Jam README, please + remember that they are case-sensitive.
      • Note that the supplied Makefile may require editing for your - platform; see the Jam - README for details. The Makefile is used for bootstrapping Jam; it builds Jam - into a subdirectory called bin.platform. + platform; see the Jam README for + details. The Makefile is used for bootstrapping Jam; it builds Jam into a + subdirectory called bin.platform.

      Initiating a Build

      @@ -140,9 +205,9 @@ the path to the allyourbase.jam file supplied in this directory. When the system matures, this file may be compiled directly into Jam as the Jambase or we will find another - way to make sure the -f option is no longer needed. The environment - variables necessary for bootstrapping Jam are not needed once it has been - built. + way to make sure the -f option is no longer needed. The + environment variables necessary for bootstrapping Jam are not needed once + it has been built.

      Here are some sample Boost Jam invocations: @@ -153,63 +218,84 @@ Effects -

      jam -fallyourbase-path -sTOOLS=gcc my_target
      + +
      +jam -fallyourbase-path -sTOOLS=gcc my_target
      +
      - default (debug) BUILD of my_targetwith GCC + default (debug) BUILD of + my_targetwith GCC -
      jam -fallyourbase-path -sTOOLS="msvc gcc"
      + +
      +jam -fallyourbase-path -sTOOLS="msvc gcc"
      +
      default-build all with msvc and gcc -
      set TOOLS=msvc
      -jam -fallyourbase-path
      + +
      +set TOOLS=msvc
      +jam -fallyourbase-path
      +
      Set an NT environment variable to always build with MSVC
      - default-build all. + default-build all. -
      jam -fallyourbase-path -sBUILD=release
      + +
      +jam -fallyourbase-path -sBUILD=release
      +
      - release build all with default TOOLS:
      + release build all with default TOOLS:
      -
      jam -fallyourbase-path -sBUILD="debug release"
      + +
      +jam -fallyourbase-path -sBUILD="debug release"
      +
      debug and release build all.

      Setting Jam Variables

      -

      The "-s" options in the command lines above are - passing variable settings to the build system. There are actually three ways to do - that: +

      The "-s" options in the command lines above are passing + variable settings to the build system. There are actually three ways to do + that: -

        -
      • Jam picks up variable settings from your environment by default, so - you can set them there: -
        -> BUILD="debug release"  # assuming Unix
        +    
          +
        • + Jam picks up variable settings from your environment by default, so you + can set them there: + +
          +
          +> BUILD="debug release"  # assuming Unix
           > export BUILD
           > jam ...
          -
          - This approach can be OK for quick-and-dirty tests, but environment variable - settings tend to be unstable and non-uniform across users and machines, so - it's best not to rely on the environment much. -
        • Explicitly on the command-line, with the "-s" - option. -
        • Directly in Jam code. A project's Jamrules file is a convenient place - to make global settings. -
        +
        +
        + This approach can be OK for quick-and-dirty tests, but environment + variable settings tend to be unstable and non-uniform across users and + machines, so it's best not to rely on the environment much. + +
      • Explicitly on the command-line, with the "-s" option. + +
      • Directly in Jam code. A project's Jamrules + file is a convenient place to make global settings. +

      An Example Jamfile

      - Here is an example of a simple subproject Jamfile. In this example, it is assumed that the user has set BOOST_ROOT, either as an environment - variable, on the command-line or in the project's Jamrules file: + variable, on the command-line or in the project's Jamrules file:
      @@ -246,32 +332,40 @@ subinclude foo/bar/baz foo/bar/... ;
           

      Support Files

      To use the build system, the following must be located in your project's - root directory, or in a directory specified in the BOOST_BUILD_INSTALLATION - variable. It is usually convenient to specify the - BOOST_BUILD_INSTALLATION in your project's Jamrules file. The Boost + root directory, or in a directory specified in the + BOOST_BUILD_INSTALLATION variable. It is usually convenient to + specify the BOOST_BUILD_INSTALLATION in your project's Jamrules file. The Boost Jamrules file shows an example. - + + + + +
      Filename(s) Meaning +
      Filename(s) -
      toolset-tools.jam - Feature-to-command-line mapping for toolset. + Meaning -
      features.jam Abstract toolset - feature descriptions. +
      toolset-tools.jam -
      boost-base.jam Boost build - system-specific rule definitions. + Feature-to-command-line mapping for toolset. -
      unit-tests.jam Unit tests - and assertions for boost Jam code. +
      features.jam + Abstract toolset feature descriptions. + +
      boost-base.jam + + Boost build system-specific rule definitions. + +
      unit-tests.jam + + Unit tests and assertions for boost Jam code.
      - The boost-base.jam file is temporary, and will eventually be - compiled into our Jam executable. - + compiled into our Jam executable.

      Basic Design and Terminology

      This section gives an overview of the way that the system works, outlining @@ -283,10 +377,10 @@ subinclude foo/bar/baz foo/bar/... ;

      A project is a source directory tree containing at least one Jamfile. The root directory of the project is known as the - project root. The root directory of a project may contain a - Jamrules file, which contains project-specific Jam code. If the - Jamrules file is not present when Jam is invoked, a warning will - be issued. + project root. The root directory of a project + may contain a Jamrules file, which contains project-specific Jam + code. If the Jamrules file is not present when Jam is invoked, a + warning will be issued.

      Subdirectories containing Jamfiles are called subproject directories. Each such Jamfile describes a subproject. @@ -317,17 +411,16 @@ subinclude foo/bar/baz foo/bar/... ; directory can be customized by changing the BIN_DIRECTORY variable. -

    • If the variable ALL_LOCATE_TARGET - is set, it specifies an alternate build directory tree whose structure - mirrors that of the project. In this case, built targets of a subproject - are generated into the corresponding directory of the build directory - tree. - +
    • If the variable + ALL_LOCATE_TARGET is set, it specifies an alternate build + directory tree whose structure mirrors that of the project. In this case, + built targets of a subproject are generated into the corresponding + directory of the build directory tree.
    - For each main target, there is a corresponding location in the build directory tree known as the target's build root, where all intermediate and final targets resulting from that main target are located. +

    Features and Properties

    @@ -341,29 +434,29 @@ subinclude foo/bar/baz foo/bar/... ; values. For example, the feature optimization might take one of the values off, speed, or space. Simple features have a default value. The key aspect of simple features is that - they are assumed to affect link compatibility: object files generated with different - values for a simple feature are generated into a separate directories, and - (with a few exceptions) main targets generated with different values won't - be linked together. + they are assumed to affect link compatibility: object files generated + with different values for a simple feature are generated into a separate + directories, and (with a few exceptions) main targets generated with + different values won't be linked together. -
  • Free features can either be single-valued, as above, or may take on - any number of user-specified values simultaneously. For example, the - define feature for a release build might have the values +
  • Free features can either be single-valued, as above, or may + take on any number of user-specified values simultaneously. For example, + the define feature for a release build might have the values NDEBUG and BOOST_RELEASE_BUILD. Free features are assumed not to affect link compatibility. - +
  • Path features are free features whose values describe paths - which may be relative to the subproject (such as linked libraries or #include - search directories). The build system treats the values of these features - specially to ensure that they are interpreted relative to the subproject - directory regardless of the directory where Jam was invoked. + which may be relative to the subproject (such as linked libraries or + #include search directories). The build system treats the values + of these features specially to ensure that they are interpreted relative + to the subproject directory regardless of the directory where Jam was + invoked.
  • Dependency features are path features whose values describe a dependency of built targets. For example, an external library might be - specified with a dependency-feature: if the library is updated, the target - will be updated also. The <library-file> feature works this - way [2]. - + specified with a dependency-feature: if the library is updated, the + target will be updated also. The <library-file> feature + works this way [2].

    A feature-value pair is known as a build property, or simply @@ -377,9 +470,8 @@ subinclude foo/bar/baz foo/bar/... ; least two separate variants: one for debugging, and one for your release code. -

    Built - targets for distinct build variants and toolsets are generated in separate - parts of the build directory tree, known as the variant +

    Built targets for distinct build variants and toolsets are generated in + separate parts of the build directory tree, known as the variant directories. For example, a (sub)project with main targets foo and bar, compiled with both GCC and KAI for debug and release variants might generate the following structure (target @@ -405,7 +497,7 @@ subinclude foo/bar/baz foo/bar/... ; -

    The properties constituting a variant may differ according to toolset, +

    The properties constituting a variant may differ according to toolset, so debug may mean a slightly different set of properties for two different compilers. @@ -495,15 +587,15 @@ subinclude foo/bar/baz foo/bar/... ;

    When a main target depends on the product of a second main target (as when an executable depends on and links to a static library), each build - configuration of the dependent target is depends on the corresponding build - of the dependency. Because only simple features participate in build - identity, the dependent and dependency targets may have completely different - free features. This puts the onus on the user for ensuring - link-compatibility when certain free properties are used. For example, when - assert() is used in header files, the preprocessor symbol - NDEBUG can impact link-compatibility of separate compilation - units. This danger can be minimized by encapsulating such feature - differences inside of build variants. + configuration of the dependent target is depends on the + corresponding build of the dependency. Because only simple features + participate in build identity, the dependent and dependency targets may + have completely different free features. This puts the onus on the user for + ensuring link-compatibility when certain free properties are used. For + example, when assert() is used in header files, the preprocessor + symbol NDEBUG can impact link-compatibility of separate + compilation units. This danger can be minimized by encapsulating such + feature differences inside of build variants.

    Usage

    @@ -512,79 +604,115 @@ subinclude foo/bar/baz foo/bar/... ; files written in the Jam language: build-tool specification files, feature descriptions files. -

    The Command Line

    - -

    This section describes in detail how the build system can be invoked. +

    The Command Line

    -

    User Targets

    +

    This section describes in detail how the build system can be invoked. -

    The Jam command line ends with an optional list of target names; if - no target names are supplied, the built-in pseudotarget all is - built. In a large project, naming targets can be dicey because of - collisions. Jam uses a mechanism called grist to - distinguish targets that would otherwise have the same - name. Fortunately, you won't often have to supply grist at the - command-line. When you declare a main target, a Jam pseudotarget of the - same name is created which depends on - all of the subvariants requested for your invocation of the - build system. For example, if your subproject declares: -

    +    

    User Targets

    + +

    The Jam command line ends with an optional list of target names; if no + target names are supplied, the built-in pseudotarget all is built. + In a large project, naming targets can be dicey because of collisions. Jam + uses a mechanism called grist to distinguish targets + that would otherwise have the same name. Fortunately, you won't often have + to supply grist at the command-line. When you declare a main target, a Jam + pseudotarget of the same name is created which depends on all of the + subvariants requested for your invocation of the build system. For example, + if your subproject declares: + +

    +
     exe my_target : my_source1.cpp my_source2.c ;
    -
    - and you invoke Jam with -sBUILD="debug - release" my_target, you will build both the debug and - release versions of my_target. - -

    These simple, ungristed names are called user targets, and - are only available for the subproject where Jam is invoked. That way, - builds from the top level (which may include many Jamfiles through - the subinclude rule) and builds of library dependencies (which may - live in other subprojects), don't collide. If it - is neccessary to refer more explicitly to a particular target from the - command-line, you will have to add ``grist''. Please see this section for a more complete description of how - to name particular targets in a build. +

    +
    + and you invoke Jam with -sBUILD="debug release" my_target, you + will build both the debug and release versions of my_target. -

    Global Variables

    +

    These simple, ungristed names are called user targets, and are + only available for the subproject where Jam is invoked. That way, builds + from the top level (which may include many Jamfiles through the subinclude + rule) and builds of library dependencies (which may live in other + subprojects), don't collide. If it is neccessary to refer more explicitly + to a particular target from the command-line, you will have to add + ``grist''. Please see this section for a more + complete description of how to name particular targets in a build. -

    This is a partial list of global variables that can be set on the - command-line. Of course you are free to write your own Jam rules which - interpret other variables from the command-line. This list just - details some of the variables used by the build system itself. Note - also that if you don't like the default values you can override them in - your project's Jamrules file. +

    Global Variables

    + +

    This is a partial list of global variables that can be set on the + command-line. Of course you are free to write your own Jam rules which + interpret other variables from the command-line. This list just details + some of the variables used by the build system itself. Note also that if + you don't like the default values you can override them in your project's + Jamrules file. - + + + + + + + +
    Variable Default Example Notes +
    Variable -
    TOOLS Platform-dependent - -sTOOLS="gcc msvc" build with gcc and msvc -
    -sTOOLS=gcc build with gcc + Default -
    BUILD - - debug + Example - -sBUILD=release build the release variant + Notes -
    -sBUILD="debug release" build both - debug and release variants +
    TOOLS + -
    -sBUILD="<optimization>speed" build a - subvariant of the default variant (debug) with optimization for speed. + Platform-dependent -
    -sBUILD="debug release <runtime-link>static/dynamic" build - subvariants of the debug and release variants that link to the runtime - both statically and dynamically. + -sTOOLS="gcc msvc" -
    ALL_LOCATE_TARGET - - - empty - -sALL_LOCATE_TARGET=~/build - Generate all build results in the build subdirectory of the - user's home directory (Unix). + build with gcc and msvc +
    -sTOOLS=gcc + + build with gcc + +
    BUILD + + + + + debug + + -sBUILD=release + + build the release variant + +
    -sBUILD="debug release" + + build both debug and release variants + +
    -sBUILD="<optimization>speed" + + build a subvariant of the default variant (debug) with + optimization for speed. + +
    -sBUILD="debug release <runtime-link>static/dynamic" + + + build subvariants of the debug and release variants that link to + the runtime both statically and dynamically. + +
    ALL_LOCATE_TARGET + + + + + empty + + -sALL_LOCATE_TARGET=~/build + + Generate all build results in the build subdirectory of + the user's home directory (Unix).

    SubProject Jamfiles

    @@ -606,9 +734,12 @@ subproject path-from-top ; targets from the subproject in case ALL_LOCATE_TARGET is used to specify the build directory tree. If there is a Jamfile in the project root directory, you should use the project-root rule instead: -
    +
    +    
    +
     project-root ;
    -
    +
    +

    Describing Main Targets

    @@ -617,24 +748,22 @@ project-root ;
     target-type name : sources
    -    [ : requirements [ : default-BUILD ] ] ;
    +    [ : requirements [ : default-BUILD ] ] ;
     
      -
    • target-type may be one of exe, lib, or dll. These are actually names of Jam rules. Additional main - target rules are possible; see status/Jamfile or libs/python/build/Jamfile - for examples. - -

      - + target rules are possible; see status/Jamfile or libs/python/build/Jamfile for + examples.
      +
      -
    • name specifies the name of the main target
      +
    • name specifies the name of the main target

      @@ -642,14 +771,14 @@ project-root ; targets. A dependency target path is preceded by <lib>, and the final path component specifies the name of a main target in a Jamfile located in the directory given by the inital path components. - Paths may be absolute or relative.
      + Paths may be absolute or relative.

    • requirements specifies the - build properties intrinsic to the target. Requirements are given as sets - of optionally-qualified build properties: + build properties intrinsic to the target. Requirements are given as + sets of optionally-qualified build properties:
      @@ -664,18 +793,19 @@ project-root ;
               

      The system checks that simple feature requirements are not violated by explicit subvariant build requests, and will issue a warning otherwise. Free features specified as requirements are simply added to - each corresponding build configuration. -
      + each corresponding build configuration.

      +

    • - default-BUILD specifies the configurations that should be built - if the BUILD variable is not otherwise specified. Any elements - not beginning with ``<...>'' refer to build - variants. Other elements use the same syntax as the requirements - described above, except that multiple values may be specified for a - simple feature by separating them with a slash, forming (qualified) - multi-valued properties: + default-BUILD specifies the + configurations that should be built if the BUILD variable is not otherwise specified. Any + elements not beginning with ``<...>'' refer to + build variants. Other elements use the same syntax as the requirements described above, except that + multiple values may be specified for a simple feature by separating + them with a slash, forming (qualified) multi-valued properties:
      @@ -686,8 +816,10 @@ project-root ;
               configurations to be built by default.
           
    -

    NOTE: for simple features in both requirements and - default-BUILD, more-specific qualification overrides less-specific. +

    NOTE: for simple features in both requirements and default-BUILD, more-specific qualification + overrides less-specific.

    Example

    @@ -752,29 +884,31 @@ exe foo : foo.cpp src/bar.cpp <lib>../bazlib/baz

    Feature Descriptions

    -

    Features are described by stating the feature type (simple features are - specified with "feature"), followed by the feature - name. An optional second argument can be used to list the permissible values - of the feature. Examples can be found in features.jam. - +

    Features are described by stating the feature type (simple features are + specified with "feature"), followed by the feature name. An + optional second argument can be used to list the permissible values of the + feature. Examples can be found in features.jam. +

    Variant Descriptions

    Variants are described with the following syntax: -

    -variant name : [<toolset-name>]<feature>value... ;
    -
    - The variant rule specifies the list of properties comprising a - variant. Properties may be optionally qualified with a toolset name, - which specifies that the property applies only to that toolset. Examples - can be found in features.jam. +
    +
    +variant name : [<toolset-name>]<feature>value... ;
    +
    +
    + The variant rule specifies the list of properties comprising a + variant. Properties may be optionally qualified with a toolset name, which + specifies that the property applies only to that toolset. Examples can be + found in features.jam.

    Toolset Description Files

    Toolset descriptions are located in the project's root directory, or a directory specified by BOOST_BUILD_INSTALLATION, which may be set - in a Jamfile or the project's Jamrules file. Each file is called + in a Jamfile or the project's Jamrules file. Each file is called toolset-name-tools.jam, where toolset-name is the name of the toolset. The toolset description file has two main jobs: @@ -810,10 +944,9 @@ actions msvc-C++-action - Note that Link-action may require special care: on platforms - where the global variable gEXPORT_SUFFIX(DLL) is defined - (e.g. Windows), the first argument may have two elements when linking a + where the global variable gEXPORT_SUFFIX(DLL) is defined (e.g. + Windows), the first argument may have two elements when linking a shared library. The first is the shared library target, and the second is the import library target, with suffix given by $(gEXPORT_SUFFIX(DLL)). It will always have a third argument @@ -821,7 +954,9 @@ actions msvc-C++-action to dispatch to different actions for linking DLLs and EXEs if neccessary, but usually it will be easier to take advantage of the special <target-type> feature, which will have the same - value using the flags rule described below. + value using the flags rule described below. + +

  • Translate build settings given in the global gBUILD_PROPERTIES @@ -846,10 +981,12 @@ flags toolset variable condition [: value...]
  • condition - one one or more elements in the following forms: +
    1. a property-set of the form: - <feature>value[/<feature>value...] + <feature>value[/<feature> + value...]
    2. <feature>
    @@ -860,14 +997,16 @@ flags toolset variable condition [: value...]

    Semantics only affect targets built with the specified toolset, and depend on the target's build configuration: -

      -
    1. if any specified property-set is a subset of the target's build properties, - the values specified in $(3) will be appended once to variable. +
        +
      1. if any specified property-set is a subset of the target's build + properties, the values specified in $(3) will be + appended once to variable. - -
      2. The value of each specified feature that participates in the target's - build properaties is appended to variable. In either case, the - variable will be set "on" the target so it may be used in the build actions. +
      3. The value of each specified feature that participates in the + target's build properaties is appended to variable. In either + case, the variable will be set "on" the target so it may be used in + the build actions. +

    Example

    @@ -905,155 +1044,647 @@ flags msvc HDRS <include> ;

    The use of these variables should be apparent from the declaration of actions msvc-C++-action in the previous section. +

    Internals

    -

    Internals

    +

    Jam Fundamentals

    -

    Jam Fundamentals

    - -

    This section is derived from the official Jam documentation and from my +

    This section is derived from the official Jam documentation and from my experience using it and reading the Jambase rules. I repeat the information here mostly because it is essential to understanding and using Jam, but is not consolidated in a single place. Some of it is missing from the official documentation altogether. I hope it will be useful to anyone wishing to become familiar with Jam and the Boost build system. -

      - -
    • Jam ``rules'' are actually simple procedural entities. Think of - them as functions. Arguments are separated by colons. - -
    • A Jam target is an abstract entity identified by an arbitrary - string. The build-in DEPENDS rule creates a link in the dependency - graph between the named targets. - -
    • Note that the documentation for the built-in INCLUDES rule is - incorrect: -INCLUDES targets1 : targets2  - causes everything that depends on a member of targets1 to depend on all members of targets2. - -
    • When a rule is invoked, if there are actions declared - with the same name as the rule, the actions are added to the - updating actions for the target identified by the rule's first argument. It - is actually possible to invoke an undeclared rule if corresponding actions - are declared: the rule is treated as empty. - -
    • Targets (other than NOTFILE targets) are associated with - paths in the file system through a process called binding. - -
    • In addition to local and global variables, jam allows you to set a - variable on a target. Target-specific variable values can usually - not be read, and take effect only in the following contexts: +

        -
      • In updating actions, variable values are first looked up on - the target named by the first argument (the target being updated). - Because Jam builds its entire dependency tree before executing - actions, Jam rules make target-specific variable settings as - a way of supplying parameters to the corresponding - actions. +
      • + Jam ``rules'' are actually simple procedural entities. Think of + them as functions. Arguments are separated by colons. -
      • Binding is controlled entirely by the target-specific setting of the - SEARCH and LOCATE variables, as described here. - -
      • In the special rule used for header - file scanning, variable values are first looked up on the target - named by the rule's first argument (the source file being - scanned). +

        + +

      • + A Jam target is an abstract entity identified by an arbitrary + string. The build-in DEPENDS rule creates a link in the + dependency graph between the named targets. + +

        + +

      • + Note that the documentation for the built-in INCLUDES rule is + incorrect: INCLUDES targets1 : targets2  causes everything + that depends on a member of targets1 to depend on all members of + targets2. + +

        + +

      • + When a rule is invoked, if there are actions declared + with the same name as the rule, the actions are added to the + updating actions for the target identified by the rule's first + argument. It is actually possible to invoke an undeclared rule if + corresponding actions are declared: the rule is treated as empty. + +

        + +

      • + Targets (other than NOTFILE targets) are + associated with paths in the file system through a process called binding. + Binding is a process of searching for a file with the same name as the + target (sans grist), based on the settings of the + target-specific SEARCH and + LOCATE variables. + +

        + +

      • + In addition to local and global + variables, jam allows you to set a variable on a + target. Target-specific variable values can usually not be read, and + take effect only in the following contexts: + +

        + +

          +
        • In updating actions, variable values are first looked up + on the target named by the first argument (the target + being updated). Because Jam builds its entire dependency tree before + executing actions, Jam rules make target-specific variable + settings as a way of supplying parameters to the corresponding + actions. + +
        • Binding is controlled entirely by the target-specific + setting of the SEARCH and LOCATE variables, as + described here. + +
        • In the special rule used for header + file scanning, variable values are first looked up + on the target named by the rule's first argument (the + source file being scanned). +
        + +

        + +

      • + The ``bound value'' of a variable is the path associated with + the target named by the variable. In build actions, the first + two arguments are automatically replaced with their bound values. + Target-specific variables can be selectively replaced by their bound + values using the bind + action modifier. + +

        + +

      • + Note that the term ``binding'' as used in the Jam documentation + indicates a phase of processing that includes three sub-phases: + binding (yes!), update determination, and header file scanning. + The repetition of the term ``binding'' can lead to some confusion. In + particular, the Modifying + Binding section in the Jam documentation should probably be titled + ``Modifying Update Determination''. + +

        + +

      • +

        ``Grist'' is just a string prefix of the form + <characters>. It is used in Jam to + create unique target names based on simpler names. For example, the + file name ``test.exe'' may be used by targets in separate + subprojects, or for the debug and release variants of the ``same'' + abstract target. Each distinct target bound to a file called + ``test.exe'' has its own unique grist prefix. The Boost build + system also takes full advantage of Jam's ability to divide strings on + grist boundaries, sometimes concatenating multiple gristed elements at + the beginning of a string. Grist is used instead of identifying targets + with absolute paths for two reasons: + +

          +
        1. The location of targets cannot always be derived solely from what + the user puts in a Jamfile, but sometimes depends also on the binding process. Some mechanism to distinctly + identify targets with the same name is still needed. + +
        2. Grist allows us to use a uniform abstract identifier for each + built target, regardless of target file location (as allowed by + setting ALL_LOCATE_TARGET. +
        + When grist is extracted from a name with + $(var:G), the result includes the leading and + trailing angle brackets. When grist is added to a name with + $(var:G=expr), existing grist + is first stripped. Then, if expr is non-empty, leading + <s and trailing >s are added if neccessary to + form an expression of the form <expr2>; + <expr2> is then prepended.
      -
    • The ``bound value'' of a variable is the path associated with the - target named by the variable. In build actions, the first two - arguments are automatically replaced with their bound - values. Target-specific variables can be selectively replaced by their bound - values using the bind - action modifier. - -
    • - Note that the term ``binding'' as used in the Jam documentation indicates - a phase of processing that includes three sub-phases: binding - (yes!), update determination, and header file scanning. The repetition of - the term ``binding'' can lead to some confusion. In particular, the Modifying - Binding section in the Jam documentation should probably be titled - ``Modifying Update Determination''. - -
    • +

      Please also read The Jam language + reference for the additional details, and the Jam release notes + for a brief description of recent, but fundamental changes to the Jam + language without which you will probably not understand any of the + build system code. In particular, note that the return statement + does not affect control flow. -

      In the Jam language, a name can be divided into two - parts. If the name starts with a '<' symbol and contains a - '>' symbol, the characters between the '<' and the - first '>', inclusive, is known as grist (if the name - doesn't match this format, the grist is empty). The rest of the name is - known as the ungristed part. In Jam, Grist is added to user-specified - target names from different subprojects to distinguish them from one another - in case the same target name is used twice. The Boost build system also - takes full advantage of Jam's ability to divide strings on grist boundaries, - sometimes concatenating multiple gristed elements at the beginning of a - string. +

      Core Jam Extensions

      -``Grist'' is just a string prefix of the form - <characters>. It is used in Jam to create - unique target names based on simpler names. For example, the file - name ``test.exe'' may be used by targets in separate subprojects, - or for the debug and release variants of the ``same'' abstract target. Grist - is used instead of identifying targets with absolute paths for two reasons: +

      A number of enhancements have been made to the core language of Classic + Jam. These changes were aimed primarily at making it easier to manage the + complexity of a large system such as Boost.Build. -

        -
      1. The location of header files can not be derived solely from what the - user puts in a Jamfile, but depend also on the binding process. Some - mechanism to identify headers with the same name is still needed. +
        +

        Jambase Replacement

        -
      2. Grist allows us to use a uniform abstract identifier for each built - target, regardless of target file location (as allowed by setting - ALL_LOCATE_TARGET -
      +

      New logic has been added to allow the built-in Jambase to be replaced + without recompiling Jam or adding command-line arguments. The user can + control the location of the build system by setting any of the JAMBASE, + BOOST_ROOT, or BOOST_BUILD_PATH environment variables (the settings of + these variables can also be overridden on the command-line using the + -sVARIABLE=... option). - When grist is extracted from a name with - $(var:G), the result includes the leading and - trailing angle brackets. When grist is added to a name with - $(var:G=expr), existing grist is - first stripped. Then, if expr is non-empty, as few leading - <s and >s as - neccessary - to form an expression of the form - <expr2> are added; - <expr2> is then prepended. - Grist prefixes are stripped from target names when binding them to - filesystem paths. +

      The process is controlled by variables (in decreasing +precedence): +

        + +
      • If JAMBASE is set, it specifies the path to the Jambase + replacement. Non-rooted paths are computed relative to the directory of + Jam's invocation. + +
      • Otherwise, if BOOST_BUILD_PATH or BOOST_ROOT is set, + the build system filename is boost-build.jam. + +
      • If the build system filename does not contain a path specification, + the build system file is searched for on $(BOOST_BUILD_PATH), + then at $(BOOST_ROOT)/tools/build. + +
      • If BOOST_BUILD_PATH was not set, it will be set to + $(BOOST_ROOT)/tools/build. + +
      • If neither JAMBASE, BOOST_ROOT, nor + BOOST_BUILD_PATH is set, we use the built-in Jambase (nearly + identical to the FTJam Jambase) + and load the user's Jamfile. Perforce Jam has this behavior, and it is + used for building Jam itself. Thus, when you rebuild Jam, these + variables should be unset. + +
      + +

      The rationale for this behavior is as follows: +

        + +
      • The Jam executable should allow the Jambase to be overridden to + implement other build systems without the user having any knowledge + of Boost, thus the JAMBASE variable. + +
      • BOOST_BUILD_PATH is designed to be used to find all modules used by the build system, so that users + and system administrators may non-intrusively add modules to the system. + +
      • Many Boost users already have BOOST_ROOT set. If a user + doesn't want to explicitly set up BOOST_BUILD_PATH, + BOOST_ROOT will supply reasonable behavior. + +
      +

      Rule Indirection

      + +

      Boost Jam allows you to call a rule whose name is held in a variable or + computed as the result of an expression: +

      +x = foo ;
      +rule foobar { ECHO foobar ; }   # a trivial rule
      +$(x)bar ;                       # invokes foobar
      +
      +
      + +

      Argument lists

      + +

      You can now describe the arguments accepted by a rule, and refer to + them by name within the rule. For example, the following prints ``I'm + sorry, Dave'' to the console: + +

      +
      +rule report ( pronoun index ? : state : names + )
      +{
      +    local he.suffix she.suffix it.suffix = s ;
      +    local I.suffix = m ;
      +    local they.suffix you.suffix = re ;
      +
      +    ECHO $(pronoun)'$($(pronoun).suffix) $(state), $(names[$(index)]) ;
      +}
      +report I 2 : sorry : Joe Dave Pete ;
      +
      +
      + Each name in a list of formal arguments (separated by ``:'' in + the rule declaration) is bound to a single element of the corresponding + actual argument unless followed by one of these modifiers: + + + + + + +
      Symbol + + Semantics of preceding symbol + +
      ? + + optional + +
      * + + Bind to zero or more unbound elements of the actual argument. + +
      + + + Bind to one or more unbound elements of the actual argument. +
      + +

      The acutal and formal arguments are checked for inconsistencies, which + cause Jam to exit with an error code: + +

      +
      +### argument error
      +# rule report ( pronoun index ?  : state  : names + )
      +# called with: ( I 2 foo  : sorry  : Joe Dave Pete )
      +# extra argument foo
      +
      +### argument error
      +# rule report ( pronoun index ?  : state  : names + )
      +# called with: ( I 2  : sorry )
      +# missing argument names
      +
      +
      +

      If you omit the list of formal arguments, all checking is + bypassed as in ``classic'' Jam. Argument lists drastically improve the + reliability and readability of your rules, however, and are strongly + recommended for any new Jam code you write. + +

      Module Support

      + +

      Boost Jam introduces support for modules, which provide some + rudimentary namespace protection for rules and variables. A new keyword, + ``module'' was also introduced. + +

      + +

      +
      Declaration
      + module  + expression {  ... }  + +

      Code within the ... } executes within the + module named by evaluating expression. Rule definitions can be + found in the module's own namespace, and in the namespace of the global + module as module-name.rule-name, so within a + module, other rules in that module may always be invoked without + qualification: + +

      +
      +module my_module
      +{
      +    rule salute ( x ) { ECHO $(x), world ; }
      +    rule greet ( ) { salute hello ; }
      +    greet ;
      +}
      +my_module.salute goodbye ;
      +
      +
      + When an invoked rule is not found in the current module's namespace, it + is looked up in the namespace of the global module, so qualified calls + work across modules: + +
      +
      +module your_module
      +{
      +    rule bedtime ( ) { my_module.salute goodnight ; }
      +}
      +
      +
      + +

      Note that, like the IMPORT and CALLER_MODULE rules, module + declaration is really a primitive, and is best used through a + wrapper interface which implements a system of module files using the + built-in INCLUDE rule. + +

      + +

      Local Variables
      + module local  expression ;
      + - or -
      + module local  expression =  + expression2 ; + +

      The variables named by expression are given a distinct value + in the module, and can be manipulated by code executing in the module + without affecting variable bindings seen by other modules. If the + assignment form is used, expression2 is assigned to the + variables when the declaration is executed. For example: + +

      +
      +module M {
      +  module local x = a b c ;
      +
      +  rule f ( )
      +  {
      +    {
      +      local x = 1 2 3 ; # temp override for M's x
      +      N.g ;             # call into module N, below
      +    }
      +    ECHO $(x) ;         # prints "a b c"
      +  }
      +}
      +
      +module N {
      +  rule g ( )
      +  {
      +    x = foo bar baz ; # sets global x
      +    M.h ;             # call back into M, below
      +  }
      +}
      +
      +module M {
      +  rule h ( )
      +  {
      +    ECHO $(x) ;      # prints "1 2 3"
      +  }
      +}
      +
      +M.f ; 
      +ECHO $(x) ;          # prints "foo bar baz"
      +
      +
      + The only way to access another module's local variables is through a + rule defined in that module: + +
      +
      +module M {
      +  rule get ( names * )
      +  {
      +    return $($(names)) ;
      +  }
      +}
      +ECHO [ M.get x ] ;  # prints "a b c"
      +
      +
      + +
      The IMPORT Rule
      + + IMPORT allows rule name aliasing across modules: + +
      +
      +rule IMPORT ( target_module ? : source_module ?
      +                : rule_names * : target_names * )
      +
      +
      + Rules are copied from the source_module into the + target_module. If either module name is missing, the global + module is used in its place. If any rule_names are supplied, + they specify which rules from the source_module to import; + otherwise all rules are imported. The rules are given the names in + target_names; if not enough target_names are supplied, + the excess rules are given the same names as they had in + source_module. For example, + +
      +
      +IMPORT m1 : m2 ;               # imports all rules from m2 into m1
      +IMPORT    : m2 : my-rule ;     # imports m2.my-rule into the global module
      +IMPORT m1 : m2 : r1 x : r2 y ; # imports m2.r1 as r2 and m2.x as y into m1
      +
      +
      + Like the module declaration syntax and + the CALLER_MODULE rule, this + rule is a primitive, and is probably best wrapped in a Jam rule. + +
      The CALLER_MODULE Rule
      + +
      +
      +rule CALLER_MODULE ( )
      +
      +
      + CALLER_MODULE returns the name of the module scope + enclosing the call to its caller. If the scope belongs to the global + module, or if no such module exists, returns the empty list. For + example, the following prints "{Y}": + +
      +
      +module X {
      +    rule get-caller { return [ CALLER_MODULE ] ; }
      +}
      +module Y {
      +    rule call-X { X.get-caller ; }
      +}
      +callers = [ X.get-caller ] [ Y.call-X ] ;
      +ECHO {$(callers)} ;
      +
      + Like the module declaration syntax and + the IMPORT rule, this rule is a + primitive, and is probably best wrapped in a Jam rule. + +
      + +
      + +

      Local For Loop Variables

      + +

      Boost Jam allows you to declare a local for loop control + variable right in the loop: +

      +x = 1 2 3 ;
      +y = 4 5 6 ;
      +for local y in $(x)
      +{
      +    ECHO $(y) ; # prints "1", "2", or "3"
      +}
      +ECHO $(y) ;     # prints "4 5 6"
      +
      + +

      While Loops

      + + In classic Jam, some constructs are only possible using recursion: +
      +# returns the part of $(list) following the first occurrence of $(symbol)
      +rule after-symbol ( symbol : list * )
      +{
      +    if ! $(list) || ( $(symbol) = $(list[1]) )
      +    {
      +        return $(list[2-]) ;
      +    }
      +    else
      +    {
      +        return [ after-symbol $(symbol) : $(list[2-]) ] ;
      +    }
      +}
      +
      +The addition of while loops allows a simpler formulation for this and +many other rules: +
      +rule after-symbol ( symbol : list * )
      +{
      +    while $(list) && $(list[1]) != $(symbol)
      +    {
      +        list = $(list[2-]) ;
      +    }
      +    return $(list) ;
      +}
      +
      + +

      Negative Indexing

      + + Classic Jam supplies 1-based list indexing, and slicing on a closed + (inclusive) range: +
      +x = 1 2 3 4 5 ;
      +ECHO $(x[3]) ;   # prints "3"
      +ECHO $(x[2-4]) ; # prints "2 3 4"
      +ECHO $(x[2-]) ;  # prints "2 3 4 5"
      +
      + + Boost Jam adds Python-style negative indexing to access locations relative + to the end of the list. + +
      +ECHO $(x[-1]) $(x[-3]) ; # prints "5 3"
      +ECHO $(x[-3--1]) ;       # prints "3 4 5"
      +ECHO $(x[-3-4]) ;        # prints "3 4"
      +ECHO $(x[2--2]) ;        # prints "2 3 4"       
      +
      + + Consistency with the 1-based, inclusive + indexing of Classic Jam and the use of ``-'' as the + range separator make this feature a bit clumsier than it would otherwise + need to be, but it does work. + +

      Target Binding Detection

      + +

      Whenever a target is bound to a location in the + filesystem, Boost Jam will look for a variable called BINDRULE (first + ``on'' the target being bound, then in the global module). If + non-empty, $(BINDRULE[1]) names a rule which is called with the + name of the target and the path it is being bound to. The signature of the + rule named by $(BINDRULE[1]) should match the following: + +

      +rule bind-rule ( target : path )
      +
      + + This facility is useful for correct header file scanning, since many + compilers will search for #included files first in the directory + containing the file doing the #include + directive. $(BINDRULE) can be used to make a record of that + directory. + +

      Return Code Inversion

      + +

      For handling targets whose build actions are expected to fail + (e.g. when testing that assertions or compile-time type checkin work + properly), Boost Jam supplies a FAIL_EXPECTED rule in the same + style as NOCARE, et. al. During target updating, the return code + of the build actions for arguments to FAIL_EXPECTED is inverted: + if it fails, building of dependent targets continues as though it + succeeded. If it succeeds, dependent targets are skipped. + +

      The SUBST Rule

      + +

      The behavior of the SUBST rule for regular-expression matching + and replacement (originally added in FTJam) has been + modified: + +

        +
      • + One or more replacement patterns may be supplied. The new signature + for SUBST is: + +
        +
        +SUBST ( source pattern replacements + )
        +
        +
        + The return value is the concatenated results of applying each element + of replacements in turn. For example, the following will + print ``[x] (y) {z}'': + +
        +
        +ECHO [ SUBST xyz (.)(.)(.) [$1] ($2) {$3} ] ;
        +
        +
        + +
      • + If there is no match, SUBST now returns an empty list. In + FTJam, the original source string was returned, making it + awkward to check whether a pattern was matched. + +

        + +

      • Compiled regular expressions are now internally cached, making it + much faster to use SUBST multiple times with the same string. +
      + +

      The JAM_VERSION global variable

      + +

      A predefined global variable with two elements indicates the version + number of Boost Jam. Boost Jam versions start at "03" "00". Earlier + versions of Jam do not automatically define JAM_VERSION. + + +

      Debugging Support

      + +

      The -d command-line option admits new arguments: + +

        +
      • -d+10 - enables profiling of rule + invocations. When Jam exits, it dumps all rules invoked, their gross + and net times in platform-dependent units, and the number of times the + rule was invoked. + +
      • -d+11 - enables parser + debugging, if Jam has been compiled with the "--debug" + option to the parser generator named by $(YACC).
      - - -

      Please also read The - Jam language reference for the additional details, and the Jam release - notes for a brief description of recent, but fundamental changes to the - Jam language without which you will probably not understand any of the - build system code. In particular, note that the return statement does - not affect control flow. - - + + +

      Target Names

      -

      In addition to user targets, which correspond - directly to the names the user writes in her subproject Jamfile, several - additional targets are generated, regardless of the directory from which Jam - was invoked: +

      In addition to user targets, which + correspond directly to the names the user writes in her subproject Jamfile, + several additional targets are generated, regardless of the directory from + which Jam was invoked:

        -
      • A main target has all the same dependencies as a user target - (i.e. building it updates all requested subvariants). Its name is the same - except for the addition of $(SOURCE_GRIST), which identifies the - subproject. The identification looks like the names of the path components - from the project root to the subproject, separated by exclamation - points. Thus, if the project is rooted at foo, in the subproject - at foo/bar/baz the target my_target is + (i.e. building it updates all requested subvariants). Its name is the + same except for the addition of $(SOURCE_GRIST), which + identifies the subproject. The identification looks like the names of the + path components from the project root to the subproject, separated by + exclamation points. Thus, if the project is rooted at foo, in + the subproject at foo/bar/baz the target my_target is identified by <bar!baz>my_target.
      • A subvariant target has additional grist identifying its main @@ -1062,69 +1693,64 @@ flags msvc HDRS <include> ; target of my_target above might be identified as <bar!baz/my_target/optimization-space/runtime-link-static>my_source.o. Note that the part of the grist following the first slash, known as the - subvariant id, also corresponds - to a fragment of the subvariant directory path where the corresponding - target is generated. Most built targets will be identified this way. + subvariant id, also corresponds to a fragment of the subvariant + directory path where the corresponding target is generated. Most built + targets will be identified this way.

      Global Variables

      This section describes some of the global variables used by the build - system. Please note that some parts of the system (particularly those in - allyourbase.jam) are heavily based on the Jambase file supplied - with Jam, and as such do not follow the conventions described below. + system. Please note that some parts of the system (particularly those in + allyourbase.jam) are heavily based on the Jambase file supplied + with Jam, and as such do not follow the conventions described below. -

      Global variables used in the build system fall into three categories: +

      Global variables used in the build system fall into three categories:

        -
      • Global variables intended to - be set by the user on the command-line or in the environment use - ALL_UPPER_CASE names. +
      • Global variables intended to be set by the user on the command-line + or in the environment use ALL_UPPER_CASE names. -
      • Internal global variables begin with a lower-case "g" and - continue in upper-case: gSOME_GLOBAL +
      • Internal global variables begin with a lower-case "g" and continue in + upper-case: gSOME_GLOBAL -
      • Global variables of the form: - gBASE_NAME(arguments), where arguments is a - comma-separated argument list, are used internally to achieve a kind of - indirection by concatenating variable values: - -
        +      
      • + Global variables of the form: + gBASE_NAME(arguments), where arguments + is a comma-separated argument list, are used internally to achieve a + kind of indirection by concatenating variable values: + +
        +
             ECHO $(gFUBAR($(x),$(y))) ;
        -
        +
      • +
      -

      Please note that the build system commonly takes advantage of Jam's - Dynamic Scoping feature (see the local command in the - "Flow of Control" section below the link target) to temporarily - "change" a global variable by declaring a local of the - same name. +

      Please note that the build system commonly takes advantage of Jam's + Dynamic Scoping feature (see the local command in the "Flow of + Control" section below the link target) to temporarily "change" a global + variable by declaring a local of the same name.

      Variables Associated with SubProject Identity

        -
      • SUBDIR_TOKENS - a list of the path elements relative to the - project root of the current subproject. - -
      • SUBDIR - the path from the invocation directory to the - current subproject directory. - -
      • + project root of the current subproject. +
      • SUBDIR - the path from the invocation directory to the + current subproject directory.

      Grist Variables

      - +
        - -
      • TARGET_GRIST takes the form - subproject!id/target/toolset/variant/subvariant-path. - +
      • TARGET_GRIST takes the form + subproject!id/target/toolset/variant/subvariant-path.
      -

      Design Criteria

      +

      Design Criteria

      Assumptions

      @@ -1187,20 +1813,20 @@ flags msvc HDRS <include> ; the source directories (they may be read-only)
    -

    Footnotes

    +

    Footnotes

    + [1] FTJam is a variant of Jam/MR. It is hoped that crucial + features we rely on from FTJam will eventually be incorportated into the + official Jam release. - [1] FTJam is a variant of Jam/MR. It is hoped that - crucial features we rely on from FTJam will eventually be incorportated into - the official Jam release. +

    [2]Note: right now, a dependency feature of a main + target makes all resulting built targets dependent, including + intermediate targets. That means that if an executable is dependent on an + external library, and that library changes, all the sources comprising the + executable will be recompiled as well. This behavior should probably be + fixed. +


    -

    [2]Note: right now, a dependency feature of a main target makes - all resulting built targets dependent, including intermediate - targets. That means that if an executable is dependent on an external - library, and that library changes, all the sources comprising the - executable will be recompiled as well. This behavior should probably be fixed. - -


    © Copyright David Abrahams 2001. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. This document is provided "as is" without express or @@ -1208,5 +1834,8 @@ flags msvc HDRS <include> ;

    Revised 29 July, 2001 \ No newline at end of file + -->29 July, 2001 + + + diff --git a/test/check-jam-patches.jam b/test/check-jam-patches.jam index a1720d70b..cf5275887 100644 --- a/test/check-jam-patches.jam +++ b/test/check-jam-patches.jam @@ -99,11 +99,13 @@ rule identity ( list * ) } # -# test modules +# test module primitives # { - local x = a b c d e ; - local y = c d e ; + local x = a b c d e f g h i j ; + local y = $(x[3-]) ; + + rule shift1 ( dummy ) { } module my_module { @@ -149,7 +151,53 @@ rule identity ( list * ) assert-equal $(x) : identity $(y) ; # Prove that the module's rule is not exposed to the world at large without - # qualification. This is expected to produce an "unknown rule" warning. - shift1 ; + # qualification + shift1 nothing ; assert-equal $(x) : identity $(y) ; + + IMPORT : my_module : shift1 shift2 : shifty ; + + shifty ; + y = $(y[2-]) ; + assert-equal $(x) : identity $(y) ; + + shift2 ; + y = $(y[2-]) ; + assert-equal $(x) : identity $(y) ; + + + IMPORT : my_module ; + + shift1 ; + y = $(y[2-]) ; + assert-equal $(x) : identity $(y) ; + + shift2 ; + y = $(y[2-]) ; + assert-equal $(x) : identity $(y) ; +} + +# +# test CALLER_MODULE +# +{ + module module1 + { + rule f ( ) + { + local m = [ CALLER_MODULE ] ; + assert-equal : identity $(m) ; + module2.f ; + } + + } + module module2 + { + rule f ( ) + { + local m = [ CALLER_MODULE ] ; + assert-equal module1 : identity $(m) ; + } + } + module1.f ; } \ No newline at end of file diff --git a/v1/allyourbase.jam b/v1/allyourbase.jam index 105704795..4437dae61 100644 --- a/v1/allyourbase.jam +++ b/v1/allyourbase.jam @@ -1382,8 +1382,9 @@ rule split-path # The new jam executable has slightly different SUBST behavior which we need to # account for. -if $(NEW_BOOST_JAM) { +if $(JAM_VERSION[1]) >= 03 { +SEARCH on new-split.jam = $(BOOST_BUILD_PATH) ; include new-split.jam ; # this is temporary. } else { diff --git a/v1/build_system.htm b/v1/build_system.htm index ef0301afe..ecdb21d04 100644 --- a/v1/build_system.htm +++ b/v1/build_system.htm @@ -1,35 +1,40 @@ - + Boost Build System - - - - c++boost.gif (8819 bytes) + c++boost.gif (8819 bytes)

    Boost Build System

    Synopsis

    Boost.Build is a system for large project software construction built on - FTJam, - an open-source make replacement[1]. Key features are: + FTJam, an + open-source make replacement[1]. Key features are:

    • A simple target description language +
    • Build with your choice (or multiple) toolsets from a single command invocation -
    • Build your choice of basic variants (e.g. debug, release, profile...) and - subvariant modifications (e.g. inlining off) from a single command invocation -
    • ``Feature Normalization'' allows target configurations to be described - independently from the toolset used -
    • Modular toolset description files allow build instructions for different - toolsets to be described independently + +
    • Build your choice of basic variants (e.g. debug, release, profile...) + and subvariant modifications (e.g. inlining off) from a single command + invocation + +
    • ``Feature Normalization'' allows target configurations to be + described independently from the toolset used + +
    • Modular toolset description files allow build instructions for + different toolsets to be described independently +
    • Multiple subproject support +
    • Automatic building of subproject dependencies
    @@ -41,14 +46,20 @@
    • Synopsis -
    • Getting Started - +
    • + Getting Started + +
    • Basic Design and Terminology @@ -71,34 +82,86 @@ Usage - -
    • Internals -
    • - Design Criteria + Internals + + + +
    • + Design Criteria +
      • Assumptions @@ -111,26 +174,28 @@

        Getting Started

        Installing FTJam

        - +
        • This page describes how and where to get FTJam sources.
        • The Jam - README contains basic installation instructions. + README contains basic installation instructions.
        • If you are installing on Windows NT, please read this - note. You may need to use the ``SUBST hack'' described at - the bottom of the message to bootstrap Jam. Also, when defining the - MSVCNT, BCCROOT, etc. environment variables as - described in the Jam - README, please remember that they are case-sensitive. + "http://frankenrouter.perforce.com/lists/jamming/msg00474.html">this + note. You may need to use the ``SUBST hack'' described at + the bottom of the message to bootstrap Jam. Also, when defining the + MSVCNT, BCCROOT, etc. environment variables as + described in the Jam README, please + remember that they are case-sensitive.
        • Note that the supplied Makefile may require editing for your - platform; see the Jam - README for details. The Makefile is used for bootstrapping Jam; it builds Jam - into a subdirectory called bin.platform. + platform; see the Jam README for + details. The Makefile is used for bootstrapping Jam; it builds Jam into a + subdirectory called bin.platform.

        Initiating a Build

        @@ -140,9 +205,9 @@ the path to the allyourbase.jam file supplied in this directory. When the system matures, this file may be compiled directly into Jam as the Jambase or we will find another - way to make sure the -f option is no longer needed. The environment - variables necessary for bootstrapping Jam are not needed once it has been - built. + way to make sure the -f option is no longer needed. The + environment variables necessary for bootstrapping Jam are not needed once + it has been built.

        Here are some sample Boost Jam invocations: @@ -153,63 +218,84 @@ Effects -

        jam -fallyourbase-path -sTOOLS=gcc my_target
        + +
        +jam -fallyourbase-path -sTOOLS=gcc my_target
        +
        - default (debug) BUILD of my_targetwith GCC + default (debug) BUILD of + my_targetwith GCC -
        jam -fallyourbase-path -sTOOLS="msvc gcc"
        + +
        +jam -fallyourbase-path -sTOOLS="msvc gcc"
        +
        default-build all with msvc and gcc -
        set TOOLS=msvc
        -jam -fallyourbase-path
        + +
        +set TOOLS=msvc
        +jam -fallyourbase-path
        +
        Set an NT environment variable to always build with MSVC
        - default-build all. + default-build all. -
        jam -fallyourbase-path -sBUILD=release
        + +
        +jam -fallyourbase-path -sBUILD=release
        +
        - release build all with default TOOLS:
        + release build all with default TOOLS:
        -
        jam -fallyourbase-path -sBUILD="debug release"
        + +
        +jam -fallyourbase-path -sBUILD="debug release"
        +
        debug and release build all.

        Setting Jam Variables

        -

        The "-s" options in the command lines above are - passing variable settings to the build system. There are actually three ways to do - that: +

        The "-s" options in the command lines above are passing + variable settings to the build system. There are actually three ways to do + that: -

          -
        • Jam picks up variable settings from your environment by default, so - you can set them there: -
          -> BUILD="debug release"  # assuming Unix
          +    
            +
          • + Jam picks up variable settings from your environment by default, so you + can set them there: + +
            +
            +> BUILD="debug release"  # assuming Unix
             > export BUILD
             > jam ...
            -
            - This approach can be OK for quick-and-dirty tests, but environment variable - settings tend to be unstable and non-uniform across users and machines, so - it's best not to rely on the environment much. -
          • Explicitly on the command-line, with the "-s" - option. -
          • Directly in Jam code. A project's Jamrules file is a convenient place - to make global settings. -
          +
          +
          + This approach can be OK for quick-and-dirty tests, but environment + variable settings tend to be unstable and non-uniform across users and + machines, so it's best not to rely on the environment much. + +
        • Explicitly on the command-line, with the "-s" option. + +
        • Directly in Jam code. A project's Jamrules + file is a convenient place to make global settings. +

        An Example Jamfile

        - Here is an example of a simple subproject Jamfile. In this example, it is assumed that the user has set BOOST_ROOT, either as an environment - variable, on the command-line or in the project's Jamrules file: + variable, on the command-line or in the project's Jamrules file:
        @@ -246,32 +332,40 @@ subinclude foo/bar/baz foo/bar/... ;
             

        Support Files

        To use the build system, the following must be located in your project's - root directory, or in a directory specified in the BOOST_BUILD_INSTALLATION - variable. It is usually convenient to specify the - BOOST_BUILD_INSTALLATION in your project's Jamrules file. The Boost + root directory, or in a directory specified in the + BOOST_BUILD_INSTALLATION variable. It is usually convenient to + specify the BOOST_BUILD_INSTALLATION in your project's Jamrules file. The Boost Jamrules file shows an example. - + + + + +
        Filename(s) Meaning +
        Filename(s) -
        toolset-tools.jam - Feature-to-command-line mapping for toolset. + Meaning -
        features.jam Abstract toolset - feature descriptions. +
        toolset-tools.jam -
        boost-base.jam Boost build - system-specific rule definitions. + Feature-to-command-line mapping for toolset. -
        unit-tests.jam Unit tests - and assertions for boost Jam code. +
        features.jam + Abstract toolset feature descriptions. + +
        boost-base.jam + + Boost build system-specific rule definitions. + +
        unit-tests.jam + + Unit tests and assertions for boost Jam code.
        - The boost-base.jam file is temporary, and will eventually be - compiled into our Jam executable. - + compiled into our Jam executable.

        Basic Design and Terminology

        This section gives an overview of the way that the system works, outlining @@ -283,10 +377,10 @@ subinclude foo/bar/baz foo/bar/... ;

        A project is a source directory tree containing at least one Jamfile. The root directory of the project is known as the - project root. The root directory of a project may contain a - Jamrules file, which contains project-specific Jam code. If the - Jamrules file is not present when Jam is invoked, a warning will - be issued. + project root. The root directory of a project + may contain a Jamrules file, which contains project-specific Jam + code. If the Jamrules file is not present when Jam is invoked, a + warning will be issued.

        Subdirectories containing Jamfiles are called subproject directories. Each such Jamfile describes a subproject. @@ -317,17 +411,16 @@ subinclude foo/bar/baz foo/bar/... ; directory can be customized by changing the BIN_DIRECTORY variable. -

      • If the variable ALL_LOCATE_TARGET - is set, it specifies an alternate build directory tree whose structure - mirrors that of the project. In this case, built targets of a subproject - are generated into the corresponding directory of the build directory - tree. - +
      • If the variable + ALL_LOCATE_TARGET is set, it specifies an alternate build + directory tree whose structure mirrors that of the project. In this case, + built targets of a subproject are generated into the corresponding + directory of the build directory tree.
      - For each main target, there is a corresponding location in the build directory tree known as the target's build root, where all intermediate and final targets resulting from that main target are located. +

      Features and Properties

      @@ -341,29 +434,29 @@ subinclude foo/bar/baz foo/bar/... ; values. For example, the feature optimization might take one of the values off, speed, or space. Simple features have a default value. The key aspect of simple features is that - they are assumed to affect link compatibility: object files generated with different - values for a simple feature are generated into a separate directories, and - (with a few exceptions) main targets generated with different values won't - be linked together. + they are assumed to affect link compatibility: object files generated + with different values for a simple feature are generated into a separate + directories, and (with a few exceptions) main targets generated with + different values won't be linked together. -
    • Free features can either be single-valued, as above, or may take on - any number of user-specified values simultaneously. For example, the - define feature for a release build might have the values +
    • Free features can either be single-valued, as above, or may + take on any number of user-specified values simultaneously. For example, + the define feature for a release build might have the values NDEBUG and BOOST_RELEASE_BUILD. Free features are assumed not to affect link compatibility. - +
    • Path features are free features whose values describe paths - which may be relative to the subproject (such as linked libraries or #include - search directories). The build system treats the values of these features - specially to ensure that they are interpreted relative to the subproject - directory regardless of the directory where Jam was invoked. + which may be relative to the subproject (such as linked libraries or + #include search directories). The build system treats the values + of these features specially to ensure that they are interpreted relative + to the subproject directory regardless of the directory where Jam was + invoked.
    • Dependency features are path features whose values describe a dependency of built targets. For example, an external library might be - specified with a dependency-feature: if the library is updated, the target - will be updated also. The <library-file> feature works this - way [2]. - + specified with a dependency-feature: if the library is updated, the + target will be updated also. The <library-file> feature + works this way [2].

      A feature-value pair is known as a build property, or simply @@ -377,9 +470,8 @@ subinclude foo/bar/baz foo/bar/... ; least two separate variants: one for debugging, and one for your release code. -

      Built - targets for distinct build variants and toolsets are generated in separate - parts of the build directory tree, known as the variant +

      Built targets for distinct build variants and toolsets are generated in + separate parts of the build directory tree, known as the variant directories. For example, a (sub)project with main targets foo and bar, compiled with both GCC and KAI for debug and release variants might generate the following structure (target @@ -405,7 +497,7 @@ subinclude foo/bar/baz foo/bar/... ; -

      The properties constituting a variant may differ according to toolset, +

      The properties constituting a variant may differ according to toolset, so debug may mean a slightly different set of properties for two different compilers. @@ -495,15 +587,15 @@ subinclude foo/bar/baz foo/bar/... ;

      When a main target depends on the product of a second main target (as when an executable depends on and links to a static library), each build - configuration of the dependent target is depends on the corresponding build - of the dependency. Because only simple features participate in build - identity, the dependent and dependency targets may have completely different - free features. This puts the onus on the user for ensuring - link-compatibility when certain free properties are used. For example, when - assert() is used in header files, the preprocessor symbol - NDEBUG can impact link-compatibility of separate compilation - units. This danger can be minimized by encapsulating such feature - differences inside of build variants. + configuration of the dependent target is depends on the + corresponding build of the dependency. Because only simple features + participate in build identity, the dependent and dependency targets may + have completely different free features. This puts the onus on the user for + ensuring link-compatibility when certain free properties are used. For + example, when assert() is used in header files, the preprocessor + symbol NDEBUG can impact link-compatibility of separate + compilation units. This danger can be minimized by encapsulating such + feature differences inside of build variants.

      Usage

      @@ -512,79 +604,115 @@ subinclude foo/bar/baz foo/bar/... ; files written in the Jam language: build-tool specification files, feature descriptions files. -

      The Command Line

      - -

      This section describes in detail how the build system can be invoked. +

      The Command Line

      -

      User Targets

      +

      This section describes in detail how the build system can be invoked. -

      The Jam command line ends with an optional list of target names; if - no target names are supplied, the built-in pseudotarget all is - built. In a large project, naming targets can be dicey because of - collisions. Jam uses a mechanism called grist to - distinguish targets that would otherwise have the same - name. Fortunately, you won't often have to supply grist at the - command-line. When you declare a main target, a Jam pseudotarget of the - same name is created which depends on - all of the subvariants requested for your invocation of the - build system. For example, if your subproject declares: -

      +    

      User Targets

      + +

      The Jam command line ends with an optional list of target names; if no + target names are supplied, the built-in pseudotarget all is built. + In a large project, naming targets can be dicey because of collisions. Jam + uses a mechanism called grist to distinguish targets + that would otherwise have the same name. Fortunately, you won't often have + to supply grist at the command-line. When you declare a main target, a Jam + pseudotarget of the same name is created which depends on all of the + subvariants requested for your invocation of the build system. For example, + if your subproject declares: + +

      +
       exe my_target : my_source1.cpp my_source2.c ;
      -
      - and you invoke Jam with -sBUILD="debug - release" my_target, you will build both the debug and - release versions of my_target. - -

      These simple, ungristed names are called user targets, and - are only available for the subproject where Jam is invoked. That way, - builds from the top level (which may include many Jamfiles through - the subinclude rule) and builds of library dependencies (which may - live in other subprojects), don't collide. If it - is neccessary to refer more explicitly to a particular target from the - command-line, you will have to add ``grist''. Please see this section for a more complete description of how - to name particular targets in a build. +

      +
      + and you invoke Jam with -sBUILD="debug release" my_target, you + will build both the debug and release versions of my_target. -

      Global Variables

      +

      These simple, ungristed names are called user targets, and are + only available for the subproject where Jam is invoked. That way, builds + from the top level (which may include many Jamfiles through the subinclude + rule) and builds of library dependencies (which may live in other + subprojects), don't collide. If it is neccessary to refer more explicitly + to a particular target from the command-line, you will have to add + ``grist''. Please see this section for a more + complete description of how to name particular targets in a build. -

      This is a partial list of global variables that can be set on the - command-line. Of course you are free to write your own Jam rules which - interpret other variables from the command-line. This list just - details some of the variables used by the build system itself. Note - also that if you don't like the default values you can override them in - your project's Jamrules file. +

      Global Variables

      + +

      This is a partial list of global variables that can be set on the + command-line. Of course you are free to write your own Jam rules which + interpret other variables from the command-line. This list just details + some of the variables used by the build system itself. Note also that if + you don't like the default values you can override them in your project's + Jamrules file. - + + + + + + + +
      Variable Default Example Notes +
      Variable -
      TOOLS Platform-dependent - -sTOOLS="gcc msvc" build with gcc and msvc -
      -sTOOLS=gcc build with gcc + Default -
      BUILD - - debug + Example - -sBUILD=release build the release variant + Notes -
      -sBUILD="debug release" build both - debug and release variants +
      TOOLS + -
      -sBUILD="<optimization>speed" build a - subvariant of the default variant (debug) with optimization for speed. + Platform-dependent -
      -sBUILD="debug release <runtime-link>static/dynamic" build - subvariants of the debug and release variants that link to the runtime - both statically and dynamically. + -sTOOLS="gcc msvc" -
      ALL_LOCATE_TARGET - - - empty - -sALL_LOCATE_TARGET=~/build - Generate all build results in the build subdirectory of the - user's home directory (Unix). + build with gcc and msvc +
      -sTOOLS=gcc + + build with gcc + +
      BUILD + + + + + debug + + -sBUILD=release + + build the release variant + +
      -sBUILD="debug release" + + build both debug and release variants + +
      -sBUILD="<optimization>speed" + + build a subvariant of the default variant (debug) with + optimization for speed. + +
      -sBUILD="debug release <runtime-link>static/dynamic" + + + build subvariants of the debug and release variants that link to + the runtime both statically and dynamically. + +
      ALL_LOCATE_TARGET + + + + + empty + + -sALL_LOCATE_TARGET=~/build + + Generate all build results in the build subdirectory of + the user's home directory (Unix).

      SubProject Jamfiles

      @@ -606,9 +734,12 @@ subproject path-from-top ; targets from the subproject in case ALL_LOCATE_TARGET is used to specify the build directory tree. If there is a Jamfile in the project root directory, you should use the project-root rule instead: -
      +
      +    
      +
       project-root ;
      -
      +
      +

      Describing Main Targets

      @@ -617,24 +748,22 @@ project-root ;
       target-type name : sources
      -    [ : requirements [ : default-BUILD ] ] ;
      +    [ : requirements [ : default-BUILD ] ] ;
       
        -
      • target-type may be one of exe, lib, or dll. These are actually names of Jam rules. Additional main - target rules are possible; see status/Jamfile or libs/python/build/Jamfile - for examples. - -

        - + target rules are possible; see status/Jamfile or libs/python/build/Jamfile for + examples.
        +
        -
      • name specifies the name of the main target
        +
      • name specifies the name of the main target

        @@ -642,14 +771,14 @@ project-root ; targets. A dependency target path is preceded by <lib>, and the final path component specifies the name of a main target in a Jamfile located in the directory given by the inital path components. - Paths may be absolute or relative.
        + Paths may be absolute or relative.

      • requirements specifies the - build properties intrinsic to the target. Requirements are given as sets - of optionally-qualified build properties: + build properties intrinsic to the target. Requirements are given as + sets of optionally-qualified build properties:
        @@ -664,18 +793,19 @@ project-root ;
                 

        The system checks that simple feature requirements are not violated by explicit subvariant build requests, and will issue a warning otherwise. Free features specified as requirements are simply added to - each corresponding build configuration. -
        + each corresponding build configuration.

        +

      • - default-BUILD specifies the configurations that should be built - if the BUILD variable is not otherwise specified. Any elements - not beginning with ``<...>'' refer to build - variants. Other elements use the same syntax as the requirements - described above, except that multiple values may be specified for a - simple feature by separating them with a slash, forming (qualified) - multi-valued properties: + default-BUILD specifies the + configurations that should be built if the BUILD variable is not otherwise specified. Any + elements not beginning with ``<...>'' refer to + build variants. Other elements use the same syntax as the requirements described above, except that + multiple values may be specified for a simple feature by separating + them with a slash, forming (qualified) multi-valued properties:
        @@ -686,8 +816,10 @@ project-root ;
                 configurations to be built by default.
             
      -

      NOTE: for simple features in both requirements and - default-BUILD, more-specific qualification overrides less-specific. +

      NOTE: for simple features in both requirements and default-BUILD, more-specific qualification + overrides less-specific.

      Example

      @@ -752,29 +884,31 @@ exe foo : foo.cpp src/bar.cpp <lib>../bazlib/baz

      Feature Descriptions

      -

      Features are described by stating the feature type (simple features are - specified with "feature"), followed by the feature - name. An optional second argument can be used to list the permissible values - of the feature. Examples can be found in features.jam. - +

      Features are described by stating the feature type (simple features are + specified with "feature"), followed by the feature name. An + optional second argument can be used to list the permissible values of the + feature. Examples can be found in features.jam. +

      Variant Descriptions

      Variants are described with the following syntax: -

      -variant name : [<toolset-name>]<feature>value... ;
      -
      - The variant rule specifies the list of properties comprising a - variant. Properties may be optionally qualified with a toolset name, - which specifies that the property applies only to that toolset. Examples - can be found in features.jam. +
      +
      +variant name : [<toolset-name>]<feature>value... ;
      +
      +
      + The variant rule specifies the list of properties comprising a + variant. Properties may be optionally qualified with a toolset name, which + specifies that the property applies only to that toolset. Examples can be + found in features.jam.

      Toolset Description Files

      Toolset descriptions are located in the project's root directory, or a directory specified by BOOST_BUILD_INSTALLATION, which may be set - in a Jamfile or the project's Jamrules file. Each file is called + in a Jamfile or the project's Jamrules file. Each file is called toolset-name-tools.jam, where toolset-name is the name of the toolset. The toolset description file has two main jobs: @@ -810,10 +944,9 @@ actions msvc-C++-action - Note that Link-action may require special care: on platforms - where the global variable gEXPORT_SUFFIX(DLL) is defined - (e.g. Windows), the first argument may have two elements when linking a + where the global variable gEXPORT_SUFFIX(DLL) is defined (e.g. + Windows), the first argument may have two elements when linking a shared library. The first is the shared library target, and the second is the import library target, with suffix given by $(gEXPORT_SUFFIX(DLL)). It will always have a third argument @@ -821,7 +954,9 @@ actions msvc-C++-action to dispatch to different actions for linking DLLs and EXEs if neccessary, but usually it will be easier to take advantage of the special <target-type> feature, which will have the same - value using the flags rule described below. + value using the flags rule described below. + +

    • Translate build settings given in the global gBUILD_PROPERTIES @@ -846,10 +981,12 @@ flags toolset variable condition [: value...]
    • condition - one one or more elements in the following forms: +
      1. a property-set of the form: - <feature>value[/<feature>value...] + <feature>value[/<feature> + value...]
      2. <feature>
      @@ -860,14 +997,16 @@ flags toolset variable condition [: value...]

      Semantics only affect targets built with the specified toolset, and depend on the target's build configuration: -

        -
      1. if any specified property-set is a subset of the target's build properties, - the values specified in $(3) will be appended once to variable. +
          +
        1. if any specified property-set is a subset of the target's build + properties, the values specified in $(3) will be + appended once to variable. - -
        2. The value of each specified feature that participates in the target's - build properaties is appended to variable. In either case, the - variable will be set "on" the target so it may be used in the build actions. +
        3. The value of each specified feature that participates in the + target's build properaties is appended to variable. In either + case, the variable will be set "on" the target so it may be used in + the build actions. +

      Example

      @@ -905,155 +1044,647 @@ flags msvc HDRS <include> ;

      The use of these variables should be apparent from the declaration of actions msvc-C++-action in the previous section. +

      Internals

      -

      Internals

      +

      Jam Fundamentals

      -

      Jam Fundamentals

      - -

      This section is derived from the official Jam documentation and from my +

      This section is derived from the official Jam documentation and from my experience using it and reading the Jambase rules. I repeat the information here mostly because it is essential to understanding and using Jam, but is not consolidated in a single place. Some of it is missing from the official documentation altogether. I hope it will be useful to anyone wishing to become familiar with Jam and the Boost build system. -

        - -
      • Jam ``rules'' are actually simple procedural entities. Think of - them as functions. Arguments are separated by colons. - -
      • A Jam target is an abstract entity identified by an arbitrary - string. The build-in DEPENDS rule creates a link in the dependency - graph between the named targets. - -
      • Note that the documentation for the built-in INCLUDES rule is - incorrect: -INCLUDES targets1 : targets2  - causes everything that depends on a member of targets1 to depend on all members of targets2. - -
      • When a rule is invoked, if there are actions declared - with the same name as the rule, the actions are added to the - updating actions for the target identified by the rule's first argument. It - is actually possible to invoke an undeclared rule if corresponding actions - are declared: the rule is treated as empty. - -
      • Targets (other than NOTFILE targets) are associated with - paths in the file system through a process called binding. - -
      • In addition to local and global variables, jam allows you to set a - variable on a target. Target-specific variable values can usually - not be read, and take effect only in the following contexts: +

          -
        • In updating actions, variable values are first looked up on - the target named by the first argument (the target being updated). - Because Jam builds its entire dependency tree before executing - actions, Jam rules make target-specific variable settings as - a way of supplying parameters to the corresponding - actions. +
        • + Jam ``rules'' are actually simple procedural entities. Think of + them as functions. Arguments are separated by colons. -
        • Binding is controlled entirely by the target-specific setting of the - SEARCH and LOCATE variables, as described here. - -
        • In the special rule used for header - file scanning, variable values are first looked up on the target - named by the rule's first argument (the source file being - scanned). +

          + +

        • + A Jam target is an abstract entity identified by an arbitrary + string. The build-in DEPENDS rule creates a link in the + dependency graph between the named targets. + +

          + +

        • + Note that the documentation for the built-in INCLUDES rule is + incorrect: INCLUDES targets1 : targets2  causes everything + that depends on a member of targets1 to depend on all members of + targets2. + +

          + +

        • + When a rule is invoked, if there are actions declared + with the same name as the rule, the actions are added to the + updating actions for the target identified by the rule's first + argument. It is actually possible to invoke an undeclared rule if + corresponding actions are declared: the rule is treated as empty. + +

          + +

        • + Targets (other than NOTFILE targets) are + associated with paths in the file system through a process called binding. + Binding is a process of searching for a file with the same name as the + target (sans grist), based on the settings of the + target-specific SEARCH and + LOCATE variables. + +

          + +

        • + In addition to local and global + variables, jam allows you to set a variable on a + target. Target-specific variable values can usually not be read, and + take effect only in the following contexts: + +

          + +

            +
          • In updating actions, variable values are first looked up + on the target named by the first argument (the target + being updated). Because Jam builds its entire dependency tree before + executing actions, Jam rules make target-specific variable + settings as a way of supplying parameters to the corresponding + actions. + +
          • Binding is controlled entirely by the target-specific + setting of the SEARCH and LOCATE variables, as + described here. + +
          • In the special rule used for header + file scanning, variable values are first looked up + on the target named by the rule's first argument (the + source file being scanned). +
          + +

          + +

        • + The ``bound value'' of a variable is the path associated with + the target named by the variable. In build actions, the first + two arguments are automatically replaced with their bound values. + Target-specific variables can be selectively replaced by their bound + values using the bind + action modifier. + +

          + +

        • + Note that the term ``binding'' as used in the Jam documentation + indicates a phase of processing that includes three sub-phases: + binding (yes!), update determination, and header file scanning. + The repetition of the term ``binding'' can lead to some confusion. In + particular, the Modifying + Binding section in the Jam documentation should probably be titled + ``Modifying Update Determination''. + +

          + +

        • +

          ``Grist'' is just a string prefix of the form + <characters>. It is used in Jam to + create unique target names based on simpler names. For example, the + file name ``test.exe'' may be used by targets in separate + subprojects, or for the debug and release variants of the ``same'' + abstract target. Each distinct target bound to a file called + ``test.exe'' has its own unique grist prefix. The Boost build + system also takes full advantage of Jam's ability to divide strings on + grist boundaries, sometimes concatenating multiple gristed elements at + the beginning of a string. Grist is used instead of identifying targets + with absolute paths for two reasons: + +

            +
          1. The location of targets cannot always be derived solely from what + the user puts in a Jamfile, but sometimes depends also on the binding process. Some mechanism to distinctly + identify targets with the same name is still needed. + +
          2. Grist allows us to use a uniform abstract identifier for each + built target, regardless of target file location (as allowed by + setting ALL_LOCATE_TARGET. +
          + When grist is extracted from a name with + $(var:G), the result includes the leading and + trailing angle brackets. When grist is added to a name with + $(var:G=expr), existing grist + is first stripped. Then, if expr is non-empty, leading + <s and trailing >s are added if neccessary to + form an expression of the form <expr2>; + <expr2> is then prepended.
        -
      • The ``bound value'' of a variable is the path associated with the - target named by the variable. In build actions, the first two - arguments are automatically replaced with their bound - values. Target-specific variables can be selectively replaced by their bound - values using the bind - action modifier. - -
      • - Note that the term ``binding'' as used in the Jam documentation indicates - a phase of processing that includes three sub-phases: binding - (yes!), update determination, and header file scanning. The repetition of - the term ``binding'' can lead to some confusion. In particular, the Modifying - Binding section in the Jam documentation should probably be titled - ``Modifying Update Determination''. - -
      • +

        Please also read The Jam language + reference for the additional details, and the Jam release notes + for a brief description of recent, but fundamental changes to the Jam + language without which you will probably not understand any of the + build system code. In particular, note that the return statement + does not affect control flow. -

        In the Jam language, a name can be divided into two - parts. If the name starts with a '<' symbol and contains a - '>' symbol, the characters between the '<' and the - first '>', inclusive, is known as grist (if the name - doesn't match this format, the grist is empty). The rest of the name is - known as the ungristed part. In Jam, Grist is added to user-specified - target names from different subprojects to distinguish them from one another - in case the same target name is used twice. The Boost build system also - takes full advantage of Jam's ability to divide strings on grist boundaries, - sometimes concatenating multiple gristed elements at the beginning of a - string. +

        Core Jam Extensions

        -``Grist'' is just a string prefix of the form - <characters>. It is used in Jam to create - unique target names based on simpler names. For example, the file - name ``test.exe'' may be used by targets in separate subprojects, - or for the debug and release variants of the ``same'' abstract target. Grist - is used instead of identifying targets with absolute paths for two reasons: +

        A number of enhancements have been made to the core language of Classic + Jam. These changes were aimed primarily at making it easier to manage the + complexity of a large system such as Boost.Build. -

          -
        1. The location of header files can not be derived solely from what the - user puts in a Jamfile, but depend also on the binding process. Some - mechanism to identify headers with the same name is still needed. +
          +

          Jambase Replacement

          -
        2. Grist allows us to use a uniform abstract identifier for each built - target, regardless of target file location (as allowed by setting - ALL_LOCATE_TARGET -
        +

        New logic has been added to allow the built-in Jambase to be replaced + without recompiling Jam or adding command-line arguments. The user can + control the location of the build system by setting any of the JAMBASE, + BOOST_ROOT, or BOOST_BUILD_PATH environment variables (the settings of + these variables can also be overridden on the command-line using the + -sVARIABLE=... option). - When grist is extracted from a name with - $(var:G), the result includes the leading and - trailing angle brackets. When grist is added to a name with - $(var:G=expr), existing grist is - first stripped. Then, if expr is non-empty, as few leading - <s and >s as - neccessary - to form an expression of the form - <expr2> are added; - <expr2> is then prepended. - Grist prefixes are stripped from target names when binding them to - filesystem paths. +

        The process is controlled by variables (in decreasing +precedence): +

          + +
        • If JAMBASE is set, it specifies the path to the Jambase + replacement. Non-rooted paths are computed relative to the directory of + Jam's invocation. + +
        • Otherwise, if BOOST_BUILD_PATH or BOOST_ROOT is set, + the build system filename is boost-build.jam. + +
        • If the build system filename does not contain a path specification, + the build system file is searched for on $(BOOST_BUILD_PATH), + then at $(BOOST_ROOT)/tools/build. + +
        • If BOOST_BUILD_PATH was not set, it will be set to + $(BOOST_ROOT)/tools/build. + +
        • If neither JAMBASE, BOOST_ROOT, nor + BOOST_BUILD_PATH is set, we use the built-in Jambase (nearly + identical to the FTJam Jambase) + and load the user's Jamfile. Perforce Jam has this behavior, and it is + used for building Jam itself. Thus, when you rebuild Jam, these + variables should be unset. + +
        + +

        The rationale for this behavior is as follows: +

          + +
        • The Jam executable should allow the Jambase to be overridden to + implement other build systems without the user having any knowledge + of Boost, thus the JAMBASE variable. + +
        • BOOST_BUILD_PATH is designed to be used to find all modules used by the build system, so that users + and system administrators may non-intrusively add modules to the system. + +
        • Many Boost users already have BOOST_ROOT set. If a user + doesn't want to explicitly set up BOOST_BUILD_PATH, + BOOST_ROOT will supply reasonable behavior. + +
        +

        Rule Indirection

        + +

        Boost Jam allows you to call a rule whose name is held in a variable or + computed as the result of an expression: +

        +x = foo ;
        +rule foobar { ECHO foobar ; }   # a trivial rule
        +$(x)bar ;                       # invokes foobar
        +
        +
        + +

        Argument lists

        + +

        You can now describe the arguments accepted by a rule, and refer to + them by name within the rule. For example, the following prints ``I'm + sorry, Dave'' to the console: + +

        +
        +rule report ( pronoun index ? : state : names + )
        +{
        +    local he.suffix she.suffix it.suffix = s ;
        +    local I.suffix = m ;
        +    local they.suffix you.suffix = re ;
        +
        +    ECHO $(pronoun)'$($(pronoun).suffix) $(state), $(names[$(index)]) ;
        +}
        +report I 2 : sorry : Joe Dave Pete ;
        +
        +
        + Each name in a list of formal arguments (separated by ``:'' in + the rule declaration) is bound to a single element of the corresponding + actual argument unless followed by one of these modifiers: + + + + + + +
        Symbol + + Semantics of preceding symbol + +
        ? + + optional + +
        * + + Bind to zero or more unbound elements of the actual argument. + +
        + + + Bind to one or more unbound elements of the actual argument. +
        + +

        The acutal and formal arguments are checked for inconsistencies, which + cause Jam to exit with an error code: + +

        +
        +### argument error
        +# rule report ( pronoun index ?  : state  : names + )
        +# called with: ( I 2 foo  : sorry  : Joe Dave Pete )
        +# extra argument foo
        +
        +### argument error
        +# rule report ( pronoun index ?  : state  : names + )
        +# called with: ( I 2  : sorry )
        +# missing argument names
        +
        +
        +

        If you omit the list of formal arguments, all checking is + bypassed as in ``classic'' Jam. Argument lists drastically improve the + reliability and readability of your rules, however, and are strongly + recommended for any new Jam code you write. + +

        Module Support

        + +

        Boost Jam introduces support for modules, which provide some + rudimentary namespace protection for rules and variables. A new keyword, + ``module'' was also introduced. + +

        + +

        +
        Declaration
        + module  + expression {  ... }  + +

        Code within the ... } executes within the + module named by evaluating expression. Rule definitions can be + found in the module's own namespace, and in the namespace of the global + module as module-name.rule-name, so within a + module, other rules in that module may always be invoked without + qualification: + +

        +
        +module my_module
        +{
        +    rule salute ( x ) { ECHO $(x), world ; }
        +    rule greet ( ) { salute hello ; }
        +    greet ;
        +}
        +my_module.salute goodbye ;
        +
        +
        + When an invoked rule is not found in the current module's namespace, it + is looked up in the namespace of the global module, so qualified calls + work across modules: + +
        +
        +module your_module
        +{
        +    rule bedtime ( ) { my_module.salute goodnight ; }
        +}
        +
        +
        + +

        Note that, like the IMPORT and CALLER_MODULE rules, module + declaration is really a primitive, and is best used through a + wrapper interface which implements a system of module files using the + built-in INCLUDE rule. + +

        + +

        Local Variables
        + module local  expression ;
        + - or -
        + module local  expression =  + expression2 ; + +

        The variables named by expression are given a distinct value + in the module, and can be manipulated by code executing in the module + without affecting variable bindings seen by other modules. If the + assignment form is used, expression2 is assigned to the + variables when the declaration is executed. For example: + +

        +
        +module M {
        +  module local x = a b c ;
        +
        +  rule f ( )
        +  {
        +    {
        +      local x = 1 2 3 ; # temp override for M's x
        +      N.g ;             # call into module N, below
        +    }
        +    ECHO $(x) ;         # prints "a b c"
        +  }
        +}
        +
        +module N {
        +  rule g ( )
        +  {
        +    x = foo bar baz ; # sets global x
        +    M.h ;             # call back into M, below
        +  }
        +}
        +
        +module M {
        +  rule h ( )
        +  {
        +    ECHO $(x) ;      # prints "1 2 3"
        +  }
        +}
        +
        +M.f ; 
        +ECHO $(x) ;          # prints "foo bar baz"
        +
        +
        + The only way to access another module's local variables is through a + rule defined in that module: + +
        +
        +module M {
        +  rule get ( names * )
        +  {
        +    return $($(names)) ;
        +  }
        +}
        +ECHO [ M.get x ] ;  # prints "a b c"
        +
        +
        + +
        The IMPORT Rule
        + + IMPORT allows rule name aliasing across modules: + +
        +
        +rule IMPORT ( target_module ? : source_module ?
        +                : rule_names * : target_names * )
        +
        +
        + Rules are copied from the source_module into the + target_module. If either module name is missing, the global + module is used in its place. If any rule_names are supplied, + they specify which rules from the source_module to import; + otherwise all rules are imported. The rules are given the names in + target_names; if not enough target_names are supplied, + the excess rules are given the same names as they had in + source_module. For example, + +
        +
        +IMPORT m1 : m2 ;               # imports all rules from m2 into m1
        +IMPORT    : m2 : my-rule ;     # imports m2.my-rule into the global module
        +IMPORT m1 : m2 : r1 x : r2 y ; # imports m2.r1 as r2 and m2.x as y into m1
        +
        +
        + Like the module declaration syntax and + the CALLER_MODULE rule, this + rule is a primitive, and is probably best wrapped in a Jam rule. + +
        The CALLER_MODULE Rule
        + +
        +
        +rule CALLER_MODULE ( )
        +
        +
        + CALLER_MODULE returns the name of the module scope + enclosing the call to its caller. If the scope belongs to the global + module, or if no such module exists, returns the empty list. For + example, the following prints "{Y}": + +
        +
        +module X {
        +    rule get-caller { return [ CALLER_MODULE ] ; }
        +}
        +module Y {
        +    rule call-X { X.get-caller ; }
        +}
        +callers = [ X.get-caller ] [ Y.call-X ] ;
        +ECHO {$(callers)} ;
        +
        + Like the module declaration syntax and + the IMPORT rule, this rule is a + primitive, and is probably best wrapped in a Jam rule. + +
        + +
        + +

        Local For Loop Variables

        + +

        Boost Jam allows you to declare a local for loop control + variable right in the loop: +

        +x = 1 2 3 ;
        +y = 4 5 6 ;
        +for local y in $(x)
        +{
        +    ECHO $(y) ; # prints "1", "2", or "3"
        +}
        +ECHO $(y) ;     # prints "4 5 6"
        +
        + +

        While Loops

        + + In classic Jam, some constructs are only possible using recursion: +
        +# returns the part of $(list) following the first occurrence of $(symbol)
        +rule after-symbol ( symbol : list * )
        +{
        +    if ! $(list) || ( $(symbol) = $(list[1]) )
        +    {
        +        return $(list[2-]) ;
        +    }
        +    else
        +    {
        +        return [ after-symbol $(symbol) : $(list[2-]) ] ;
        +    }
        +}
        +
        +The addition of while loops allows a simpler formulation for this and +many other rules: +
        +rule after-symbol ( symbol : list * )
        +{
        +    while $(list) && $(list[1]) != $(symbol)
        +    {
        +        list = $(list[2-]) ;
        +    }
        +    return $(list) ;
        +}
        +
        + +

        Negative Indexing

        + + Classic Jam supplies 1-based list indexing, and slicing on a closed + (inclusive) range: +
        +x = 1 2 3 4 5 ;
        +ECHO $(x[3]) ;   # prints "3"
        +ECHO $(x[2-4]) ; # prints "2 3 4"
        +ECHO $(x[2-]) ;  # prints "2 3 4 5"
        +
        + + Boost Jam adds Python-style negative indexing to access locations relative + to the end of the list. + +
        +ECHO $(x[-1]) $(x[-3]) ; # prints "5 3"
        +ECHO $(x[-3--1]) ;       # prints "3 4 5"
        +ECHO $(x[-3-4]) ;        # prints "3 4"
        +ECHO $(x[2--2]) ;        # prints "2 3 4"       
        +
        + + Consistency with the 1-based, inclusive + indexing of Classic Jam and the use of ``-'' as the + range separator make this feature a bit clumsier than it would otherwise + need to be, but it does work. + +

        Target Binding Detection

        + +

        Whenever a target is bound to a location in the + filesystem, Boost Jam will look for a variable called BINDRULE (first + ``on'' the target being bound, then in the global module). If + non-empty, $(BINDRULE[1]) names a rule which is called with the + name of the target and the path it is being bound to. The signature of the + rule named by $(BINDRULE[1]) should match the following: + +

        +rule bind-rule ( target : path )
        +
        + + This facility is useful for correct header file scanning, since many + compilers will search for #included files first in the directory + containing the file doing the #include + directive. $(BINDRULE) can be used to make a record of that + directory. + +

        Return Code Inversion

        + +

        For handling targets whose build actions are expected to fail + (e.g. when testing that assertions or compile-time type checkin work + properly), Boost Jam supplies a FAIL_EXPECTED rule in the same + style as NOCARE, et. al. During target updating, the return code + of the build actions for arguments to FAIL_EXPECTED is inverted: + if it fails, building of dependent targets continues as though it + succeeded. If it succeeds, dependent targets are skipped. + +

        The SUBST Rule

        + +

        The behavior of the SUBST rule for regular-expression matching + and replacement (originally added in FTJam) has been + modified: + +

          +
        • + One or more replacement patterns may be supplied. The new signature + for SUBST is: + +
          +
          +SUBST ( source pattern replacements + )
          +
          +
          + The return value is the concatenated results of applying each element + of replacements in turn. For example, the following will + print ``[x] (y) {z}'': + +
          +
          +ECHO [ SUBST xyz (.)(.)(.) [$1] ($2) {$3} ] ;
          +
          +
          + +
        • + If there is no match, SUBST now returns an empty list. In + FTJam, the original source string was returned, making it + awkward to check whether a pattern was matched. + +

          + +

        • Compiled regular expressions are now internally cached, making it + much faster to use SUBST multiple times with the same string. +
        + +

        The JAM_VERSION global variable

        + +

        A predefined global variable with two elements indicates the version + number of Boost Jam. Boost Jam versions start at "03" "00". Earlier + versions of Jam do not automatically define JAM_VERSION. + + +

        Debugging Support

        + +

        The -d command-line option admits new arguments: + +

          +
        • -d+10 - enables profiling of rule + invocations. When Jam exits, it dumps all rules invoked, their gross + and net times in platform-dependent units, and the number of times the + rule was invoked. + +
        • -d+11 - enables parser + debugging, if Jam has been compiled with the "--debug" + option to the parser generator named by $(YACC).
        - - -

        Please also read The - Jam language reference for the additional details, and the Jam release - notes for a brief description of recent, but fundamental changes to the - Jam language without which you will probably not understand any of the - build system code. In particular, note that the return statement does - not affect control flow. - - + + +

        Target Names

        -

        In addition to user targets, which correspond - directly to the names the user writes in her subproject Jamfile, several - additional targets are generated, regardless of the directory from which Jam - was invoked: +

        In addition to user targets, which + correspond directly to the names the user writes in her subproject Jamfile, + several additional targets are generated, regardless of the directory from + which Jam was invoked:

          -
        • A main target has all the same dependencies as a user target - (i.e. building it updates all requested subvariants). Its name is the same - except for the addition of $(SOURCE_GRIST), which identifies the - subproject. The identification looks like the names of the path components - from the project root to the subproject, separated by exclamation - points. Thus, if the project is rooted at foo, in the subproject - at foo/bar/baz the target my_target is + (i.e. building it updates all requested subvariants). Its name is the + same except for the addition of $(SOURCE_GRIST), which + identifies the subproject. The identification looks like the names of the + path components from the project root to the subproject, separated by + exclamation points. Thus, if the project is rooted at foo, in + the subproject at foo/bar/baz the target my_target is identified by <bar!baz>my_target.
        • A subvariant target has additional grist identifying its main @@ -1062,69 +1693,64 @@ flags msvc HDRS <include> ; target of my_target above might be identified as <bar!baz/my_target/optimization-space/runtime-link-static>my_source.o. Note that the part of the grist following the first slash, known as the - subvariant id, also corresponds - to a fragment of the subvariant directory path where the corresponding - target is generated. Most built targets will be identified this way. + subvariant id, also corresponds to a fragment of the subvariant + directory path where the corresponding target is generated. Most built + targets will be identified this way.

        Global Variables

        This section describes some of the global variables used by the build - system. Please note that some parts of the system (particularly those in - allyourbase.jam) are heavily based on the Jambase file supplied - with Jam, and as such do not follow the conventions described below. + system. Please note that some parts of the system (particularly those in + allyourbase.jam) are heavily based on the Jambase file supplied + with Jam, and as such do not follow the conventions described below. -

        Global variables used in the build system fall into three categories: +

        Global variables used in the build system fall into three categories:

          -
        • Global variables intended to - be set by the user on the command-line or in the environment use - ALL_UPPER_CASE names. +
        • Global variables intended to be set by the user on the command-line + or in the environment use ALL_UPPER_CASE names. -
        • Internal global variables begin with a lower-case "g" and - continue in upper-case: gSOME_GLOBAL +
        • Internal global variables begin with a lower-case "g" and continue in + upper-case: gSOME_GLOBAL -
        • Global variables of the form: - gBASE_NAME(arguments), where arguments is a - comma-separated argument list, are used internally to achieve a kind of - indirection by concatenating variable values: - -
          +      
        • + Global variables of the form: + gBASE_NAME(arguments), where arguments + is a comma-separated argument list, are used internally to achieve a + kind of indirection by concatenating variable values: + +
          +
               ECHO $(gFUBAR($(x),$(y))) ;
          -
          +
        • +
        -

        Please note that the build system commonly takes advantage of Jam's - Dynamic Scoping feature (see the local command in the - "Flow of Control" section below the link target) to temporarily - "change" a global variable by declaring a local of the - same name. +

        Please note that the build system commonly takes advantage of Jam's + Dynamic Scoping feature (see the local command in the "Flow of + Control" section below the link target) to temporarily "change" a global + variable by declaring a local of the same name.

        Variables Associated with SubProject Identity

          -
        • SUBDIR_TOKENS - a list of the path elements relative to the - project root of the current subproject. - -
        • SUBDIR - the path from the invocation directory to the - current subproject directory. - -
        • + project root of the current subproject. +
        • SUBDIR - the path from the invocation directory to the + current subproject directory.

        Grist Variables

        - +
          - -
        • TARGET_GRIST takes the form - subproject!id/target/toolset/variant/subvariant-path. - +
        • TARGET_GRIST takes the form + subproject!id/target/toolset/variant/subvariant-path.
        -

        Design Criteria

        +

        Design Criteria

        Assumptions

        @@ -1187,20 +1813,20 @@ flags msvc HDRS <include> ; the source directories (they may be read-only)
      -

      Footnotes

      +

      Footnotes

      + [1] FTJam is a variant of Jam/MR. It is hoped that crucial + features we rely on from FTJam will eventually be incorportated into the + official Jam release. - [1] FTJam is a variant of Jam/MR. It is hoped that - crucial features we rely on from FTJam will eventually be incorportated into - the official Jam release. +

      [2]Note: right now, a dependency feature of a main + target makes all resulting built targets dependent, including + intermediate targets. That means that if an executable is dependent on an + external library, and that library changes, all the sources comprising the + executable will be recompiled as well. This behavior should probably be + fixed. +


      -

      [2]Note: right now, a dependency feature of a main target makes - all resulting built targets dependent, including intermediate - targets. That means that if an executable is dependent on an external - library, and that library changes, all the sources comprising the - executable will be recompiled as well. This behavior should probably be fixed. - -


      © Copyright David Abrahams 2001. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. This document is provided "as is" without express or @@ -1208,5 +1834,8 @@ flags msvc HDRS <include> ;

      Revised 29 July, 2001 \ No newline at end of file + -->29 July, 2001 + + + diff --git a/v2/boost-build.jam b/v2/boost-build.jam new file mode 100644 index 000000000..51a5d4813 --- /dev/null +++ b/v2/boost-build.jam @@ -0,0 +1,7 @@ +# (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and +# distribute this software is granted provided this copyright notice appears in +# all copies. This software is provided "as is" without express or implied +# warranty, and with no claim as to its suitability for any purpose. + +SEARCH on allyourbase.jam = $(BOOST_BUILD_PATH) ; +include allyourbase.jam ; diff --git a/v2/test/check-jam-patches.jam b/v2/test/check-jam-patches.jam index a1720d70b..cf5275887 100644 --- a/v2/test/check-jam-patches.jam +++ b/v2/test/check-jam-patches.jam @@ -99,11 +99,13 @@ rule identity ( list * ) } # -# test modules +# test module primitives # { - local x = a b c d e ; - local y = c d e ; + local x = a b c d e f g h i j ; + local y = $(x[3-]) ; + + rule shift1 ( dummy ) { } module my_module { @@ -149,7 +151,53 @@ rule identity ( list * ) assert-equal $(x) : identity $(y) ; # Prove that the module's rule is not exposed to the world at large without - # qualification. This is expected to produce an "unknown rule" warning. - shift1 ; + # qualification + shift1 nothing ; assert-equal $(x) : identity $(y) ; + + IMPORT : my_module : shift1 shift2 : shifty ; + + shifty ; + y = $(y[2-]) ; + assert-equal $(x) : identity $(y) ; + + shift2 ; + y = $(y[2-]) ; + assert-equal $(x) : identity $(y) ; + + + IMPORT : my_module ; + + shift1 ; + y = $(y[2-]) ; + assert-equal $(x) : identity $(y) ; + + shift2 ; + y = $(y[2-]) ; + assert-equal $(x) : identity $(y) ; +} + +# +# test CALLER_MODULE +# +{ + module module1 + { + rule f ( ) + { + local m = [ CALLER_MODULE ] ; + assert-equal : identity $(m) ; + module2.f ; + } + + } + module module2 + { + rule f ( ) + { + local m = [ CALLER_MODULE ] ; + assert-equal module1 : identity $(m) ; + } + } + module1.f ; } \ No newline at end of file