From 58a9ed603365e90c8d4ad8f3d8cc9e02667fbbf5 Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Wed, 5 Mar 2003 11:17:20 +0000 Subject: [PATCH] Doc improvements. Explain library dependencies. Clarify project ids. [SVN r17729] --- boost_build_v2.html | 111 +++++++++++++++++++++++++++++++---------- v2/boost_build_v2.html | 111 +++++++++++++++++++++++++++++++---------- 2 files changed, 168 insertions(+), 54 deletions(-) diff --git a/boost_build_v2.html b/boost_build_v2.html index bbf4e9ada..a8d67a523 100644 --- a/boost_build_v2.html +++ b/boost_build_v2.html @@ -24,9 +24,9 @@ + - build request, build request expansion and directly requested targets + - conditional properties + -->

Using libraries +

Library dependencies
+
Static and shared libraries
Prebuilt targets
@@ -211,12 +213,13 @@ boost-build /path/to/boost.build ; always be present. This leads to a question: what if user explictly requested single-threading. The answer is that requirement can affect build properties only to a certain degree: the requested and actual - properties must be link-compatible. See link - compatibility below. If they are not link compatible, the bulding of - the target is skipped. Previously, we've added "hello2" target. Seems - like we have to specify the same requirements for it, which results in - duplication. But there's a better way. Each project (i.e. each Jamfile), - can specify a set of attributes, including requirements: + properties must be link-compatible. See link compatibility below. If they are not link + compatible, the bulding of the target is skipped. Previously, we've added + "hello2" target. Seems like we have to specify the same requirements for + it, which results in duplication. But there's a better way. Each project + (i.e. each Jamfile), can specify a set of attributes, including + requirements:
    project 
        : requirements <include>/home/ghost/Work/boost <threading>multi 
@@ -287,9 +290,11 @@ boost-build /path/to/boost.build ;
 
      exe app : app.cpp ../lib/lib1/lib1 ;
 
- When linking the "app" binary, the needed library will be used. But what - is meant by "needed"? For example, we can request to build "app" with - properties + While "app.cpp" is a regular source file, "../lib/lib1/lib1" is a + reference to another target, here, library "lib1" declared in Jamfile at + "../lib/lib1". When linking the "app" binary, the needed version of the + library will be built and linked in. But what is meant by "needed"? For + example, we can request to build "app" with properties
     <optimization>full <cxxflags>-w-8080
 
@@ -313,15 +318,17 @@ boost-build /path/to/boost.build ;
Usage requirements are requirements which are applied to dependents. In this case, <include> will be applied to all targets which use - "lib1". You'd need to specify usage requirements only once, and programs - which use "lib1" don't have to care about include paths any longer. Or - course, the path will be interpreted relatively to "lib/lib1" and will be - adjusted according to the bjams invocation directory. For - example, if building from project root, the final compiler's command line - will contain -Ilib/lib1. The second problem is that we hardcode - the path to library's Jamfile. Imagine it's hardcoded in 20 different - places and we change the directory layout. The solution is to use project - ids. First, we assign a project id to Jamfile in lib/lib1: + "lib1" — i.e. targets which have "lib1" either in sources or in + dependency properties. You'd need to specify usage requirements only + once, and programs which use "lib1" don't have to care about include + paths any longer. Or course, the path will be interpreted relatively to + "lib/lib1" and will be adjusted according to the bjams + invocation directory. For example, if building from project root, the + final compiler's command line will contain -Ilib/lib1. The + second problem is that we hardcode the path to library's Jamfile. Imagine + it's hardcoded in 20 different places and we change the directory layout. + The solution is to use project ids — symbolic names, not tied to + directory layout. First, we assign a project id to Jamfile in lib/lib1:
     project lib1
         : usage-requirements <include>.
@@ -331,10 +338,12 @@ boost-build /path/to/boost.build ;
 
     exe app : app.cpp @/lib1/lib1 ;
 
- This way, users of "lib1" do not depend on its location, only on id, - which is supposedly stable. The only thing left, it to make sure that - src/Jamfile knows the project id that it uses. We add to [top]/Jamfile - the following line: + The "@/lib1/lib1" syntax is used to refer to target "lib1" in project + with global id "@/lib1" (the slash is used to specify global id). This + way, users of "lib1" do not depend on its location, only on id, which is + supposedly stable. The only thing left, it to make sure that src/Jamfile + knows the project id that it uses. We add to [top]/Jamfile the following + line:
     use-project /lib1 : lib/lib1 ;
 
@@ -342,6 +351,54 @@ boost-build /path/to/boost.build ; library is moved somewhere, only a single line in the top-level Jamfile should be changed. +

Library dependencies

+ +

The previous example was simple. Often, there are long chains of + dependencies between libraries. The main application is a thin wrapper on + top of library with core logic, which uses library of utility functions, + which uses boost filesystem library. Looks like successfull linking of + main application requires something like:

+
+    lib utils : utils.cpp ; # Uses Boost.Filesystem
+    lib core : core.cpp ;   # Uses 'utils'
+    exe app : app.cpp core utils @/boost/filesystem/fs ;
+   
+
+ This works, but each application should, in effect, explicitly specify + all libraries that it uses, either directly or indirectly. This is + troublesome: when the 'utils' library starts using another libraries, you + have to adjust list of sources for all applications. Jamfiles become + unstable. + +

Usage requirements can help again. There's a builtin dependency + feature <library>. When found in properties for executable, it + causes a library, identified by the feature's value, to be linked into + executable. Seems like the effect is the same as when library is + specified in sources. But the feature allows us to write:

+
+    lib utils : utils.cpp : : : <library>@/boost/filesystem/fs ;
+    lib core : core.cpp : : : <library>utils ;
+    exe app : app.cpp core ;
+   
+
+ +

The application uses "core", which has <library>utils in usage + requirements, so that property will added to build properties for "app". + As the result, "utils" will be linked to "app" — automatically. + Likewise, "@/boost/filesystem/fs" will be linked in without any + effort.

+ +

The <library> property can be used in more ways. For example, if + "@/boost/filesystem/fs" should be linked to all applications in your + project, you can add <library>@/boost/filesystem/fs to requirements + of the project, like this:

+
+    project 
+       : requirements <library>@/boost/filesystem/fs
+       ;
+   
+
+

Static and shared libaries

While the previous section explained how to create and use libraries, it omitted one important detail. Libraries can be either static, @@ -387,7 +444,7 @@ boost-build /path/to/boost.build ;
  • What if library can be both static and shared, but when using it in specific executable, you want it static? Target references are here to help: + "#target_reference">Target references are here to help:
         exe important : main.cpp helpers/<link>static ;
        
    @@ -887,7 +944,7 @@ exe hello : hello.cpp : <toolset>yfc:<cxxflags>-disable-pointless-wa
     
         

    Command line

    -

    The comamnd line may contain:

    +

    The command line may contain:

    • Jam options,
    • diff --git a/v2/boost_build_v2.html b/v2/boost_build_v2.html index bbf4e9ada..a8d67a523 100644 --- a/v2/boost_build_v2.html +++ b/v2/boost_build_v2.html @@ -24,9 +24,9 @@ + - build request, build request expansion and directly requested targets + - conditional properties + -->

      Using libraries +

      Library dependencies
      +
      Static and shared libraries
      Prebuilt targets
      @@ -211,12 +213,13 @@ boost-build /path/to/boost.build ; always be present. This leads to a question: what if user explictly requested single-threading. The answer is that requirement can affect build properties only to a certain degree: the requested and actual - properties must be link-compatible. See link - compatibility below. If they are not link compatible, the bulding of - the target is skipped. Previously, we've added "hello2" target. Seems - like we have to specify the same requirements for it, which results in - duplication. But there's a better way. Each project (i.e. each Jamfile), - can specify a set of attributes, including requirements: + properties must be link-compatible. See link compatibility below. If they are not link + compatible, the bulding of the target is skipped. Previously, we've added + "hello2" target. Seems like we have to specify the same requirements for + it, which results in duplication. But there's a better way. Each project + (i.e. each Jamfile), can specify a set of attributes, including + requirements:
          project 
              : requirements <include>/home/ghost/Work/boost <threading>multi 
      @@ -287,9 +290,11 @@ boost-build /path/to/boost.build ;
       
            exe app : app.cpp ../lib/lib1/lib1 ;
       
      - When linking the "app" binary, the needed library will be used. But what - is meant by "needed"? For example, we can request to build "app" with - properties + While "app.cpp" is a regular source file, "../lib/lib1/lib1" is a + reference to another target, here, library "lib1" declared in Jamfile at + "../lib/lib1". When linking the "app" binary, the needed version of the + library will be built and linked in. But what is meant by "needed"? For + example, we can request to build "app" with properties
           <optimization>full <cxxflags>-w-8080
       
      @@ -313,15 +318,17 @@ boost-build /path/to/boost.build ;
      Usage requirements are requirements which are applied to dependents. In this case, <include> will be applied to all targets which use - "lib1". You'd need to specify usage requirements only once, and programs - which use "lib1" don't have to care about include paths any longer. Or - course, the path will be interpreted relatively to "lib/lib1" and will be - adjusted according to the bjams invocation directory. For - example, if building from project root, the final compiler's command line - will contain -Ilib/lib1. The second problem is that we hardcode - the path to library's Jamfile. Imagine it's hardcoded in 20 different - places and we change the directory layout. The solution is to use project - ids. First, we assign a project id to Jamfile in lib/lib1: + "lib1" — i.e. targets which have "lib1" either in sources or in + dependency properties. You'd need to specify usage requirements only + once, and programs which use "lib1" don't have to care about include + paths any longer. Or course, the path will be interpreted relatively to + "lib/lib1" and will be adjusted according to the bjams + invocation directory. For example, if building from project root, the + final compiler's command line will contain -Ilib/lib1. The + second problem is that we hardcode the path to library's Jamfile. Imagine + it's hardcoded in 20 different places and we change the directory layout. + The solution is to use project ids — symbolic names, not tied to + directory layout. First, we assign a project id to Jamfile in lib/lib1:
           project lib1
               : usage-requirements <include>.
      @@ -331,10 +338,12 @@ boost-build /path/to/boost.build ;
       
           exe app : app.cpp @/lib1/lib1 ;
       
      - This way, users of "lib1" do not depend on its location, only on id, - which is supposedly stable. The only thing left, it to make sure that - src/Jamfile knows the project id that it uses. We add to [top]/Jamfile - the following line: + The "@/lib1/lib1" syntax is used to refer to target "lib1" in project + with global id "@/lib1" (the slash is used to specify global id). This + way, users of "lib1" do not depend on its location, only on id, which is + supposedly stable. The only thing left, it to make sure that src/Jamfile + knows the project id that it uses. We add to [top]/Jamfile the following + line:
           use-project /lib1 : lib/lib1 ;
       
      @@ -342,6 +351,54 @@ boost-build /path/to/boost.build ; library is moved somewhere, only a single line in the top-level Jamfile should be changed. +

      Library dependencies

      + +

      The previous example was simple. Often, there are long chains of + dependencies between libraries. The main application is a thin wrapper on + top of library with core logic, which uses library of utility functions, + which uses boost filesystem library. Looks like successfull linking of + main application requires something like:

      +
      +    lib utils : utils.cpp ; # Uses Boost.Filesystem
      +    lib core : core.cpp ;   # Uses 'utils'
      +    exe app : app.cpp core utils @/boost/filesystem/fs ;
      +   
      +
      + This works, but each application should, in effect, explicitly specify + all libraries that it uses, either directly or indirectly. This is + troublesome: when the 'utils' library starts using another libraries, you + have to adjust list of sources for all applications. Jamfiles become + unstable. + +

      Usage requirements can help again. There's a builtin dependency + feature <library>. When found in properties for executable, it + causes a library, identified by the feature's value, to be linked into + executable. Seems like the effect is the same as when library is + specified in sources. But the feature allows us to write:

      +
      +    lib utils : utils.cpp : : : <library>@/boost/filesystem/fs ;
      +    lib core : core.cpp : : : <library>utils ;
      +    exe app : app.cpp core ;
      +   
      +
      + +

      The application uses "core", which has <library>utils in usage + requirements, so that property will added to build properties for "app". + As the result, "utils" will be linked to "app" — automatically. + Likewise, "@/boost/filesystem/fs" will be linked in without any + effort.

      + +

      The <library> property can be used in more ways. For example, if + "@/boost/filesystem/fs" should be linked to all applications in your + project, you can add <library>@/boost/filesystem/fs to requirements + of the project, like this:

      +
      +    project 
      +       : requirements <library>@/boost/filesystem/fs
      +       ;
      +   
      +
      +

      Static and shared libaries

      While the previous section explained how to create and use libraries, it omitted one important detail. Libraries can be either static, @@ -387,7 +444,7 @@ boost-build /path/to/boost.build ;
    • What if library can be both static and shared, but when using it in specific executable, you want it static? Target references are here to help: + "#target_reference">Target references are here to help:
           exe important : main.cpp helpers/<link>static ;
          
      @@ -887,7 +944,7 @@ exe hello : hello.cpp : <toolset>yfc:<cxxflags>-disable-pointless-wa
       
           

      Command line

      -

      The comamnd line may contain:

      +

      The command line may contain:

      • Jam options,