Boost logo

Boost-Build :

From: Jurko Gospodnetiæ (jurko.gospodnetic_at_[hidden])
Date: 2008-05-03 22:45:52


   Hi all.

   Attached is a patch for the stage.jam module adding support for a new
<install-target-root> property. It allows you to control how staged file
paths and names get split, i.e. which part is treated like the _path_
and which is treated like a _name_.

   While not an unavoidable feature does seem to balance out the current
<install-source-root> target. And provides a way to reduce code
duplication in some cases. See text below for a detailed explanation.

   Here's an example:

   You have 2 files you want to install:
     - xxx/a/b/f1.txt
     - xxx/a/b/f2.txt

   You want them installed under the yyy/u/w/b folder so you'd get:
     - yyy/u/w/b/f1.txt
     - yyy/u/w/b/f2.txt

   Now using the already existing install-source-root you can achieve
this like this:
     install my-install
         :
         xxx/a/b/f1.txt
         xxx/a/b/f2
         :
         <location>yyy/u/w
         <install-source-root>xxx/a ;

   However this way your files get the following 'properties':
     - path: yyy/u/w name: b/f1.txt
     - path: yyy/u/w name: b/f2.txt

   Now suppose you wanted to organize it so that they would be split
like this:
     - path: yyy name: u/w/b/f1.txt
     - path: yyy name: u/w/b/f2.txt

   The new <installer-target-root> property allows you to do this like this:
     install my-install
         :
         xxx/a/b/f1.txt
         xxx/a/b/f2.txt
         :
         <location>yyy
         <install-target-root>u/w
         <install-source-root>xxx/a ;

   Here as you can see:
     <install-source-root> tells Boost Build which folders to trim from
the source names while the <install-target-root> tells it which folders
to add to the target names (relative to the <location> folder).

   This is useful when you want to do something else with the
installed/staged target, such as wrap it up in an installer package.
Then the part of the path that you stash into the installed target's
name follows it into the installer package. This allows you to easily
install files into some local folder where you can see them and then
package them up from there into the installer package without having to
respecify the target path again in the rule for creating the installer
package.

   In the example above you are effectively saying 'ok, these files go
to the yyy folder and they keep this part (up from xxx/a) of their
source folder hierarchy and they should expand that hierarchy by
prepending u/w to it. Now they know that wherever they go they should
take the information about their u/w/b folder with them.

   Please let me know if its OK to commit this change or does anyone
have anything against it. Not a critical issue in any way.

   Best regards,
     Jurko Gospodnetiæ

P.S.
   Note that the <install-source-root> property has a 'defect' in that
it is a path property and always rooted from the Jamfile file's folder.
That means that you need to know the exact build directory path while
writing the Jamfile in order to be able to use this property to stage a
any built target. But that is an issue for a separate post.

Index: tools/build/v2/tools/stage.jam
===================================================================
--- tools/build/v2/tools/stage.jam (revision 45104)
+++ tools/build/v2/tools/stage.jam (working copy)
@@ -22,6 +22,14 @@
 feature.feature <install-dependencies> : off on : incidental ;
 feature.feature <install-type> : : free incidental ;
 feature.feature <install-source-root> : : free path ;
+# <install-target-root> must not be a path feature since it always specifies a
+# path relative to the install action's <location> property and not the Jamfile.
+# TODO: We should find a way to make this feature be converted to the internal
+# path format when specified from the outside as a command line parameter but be
+# interpreted as already being in internal path format when read from the
+# Jamfile. However, unlike 'path' features these values should not be rebased to
+# point to their target relative to the Jamfile location.
+feature.feature <install-target-root> : : free ;
 feature.feature <so-version> : : free incidental ;
 
 # If 'on', version symlinks for shared libraries will not be created. Affects
@@ -76,7 +84,7 @@
             ps-raw = [ $(ps).raw ] ;
 
             # Unless <hardcode-dll-paths>true is in properties, which can happen
- # only if the user has explicitly requested it, nuke all.
+ # only if the user has explicitly requested it, nuke all
             # <dll-path> properties
             if [ $(property-set).get <hardcode-dll-paths> ] != true
             {
@@ -118,6 +126,30 @@
             ps-raw += $(d:G=<install-source-root>) ;
         }
 
+ local d = [ $(build-property-set).get <install-target-root> ] ;
+ if $(d)
+ {
+ # We need to manually convert the <install-target-root> property
+ # value into internal Boost Build path representation since its
+ # feature does not represent a path relative to the project's
+ # Jamfile and so could not be marked with the 'path' attribute.
+ d = [ path.make $(d) ] ;
+ if [ path.is-rooted $(d) ]
+ {
+ local error-message =
+ "The <install-target-root> property must specify a relative"
+ "and not an absolute path. That is the path prepended to"
+ "all target names installed with this property." ;
+ if ! ( "--debug-building" in [ modules.peek : ARGV ] )
+ {
+ error-message += "Use the --debug-building command line"
+ "option to get more detailed information." ;
+ }
+ errors.user-error $(error-message) ;
+ }
+ }
+ ps-raw += $(d:G=<install-target-root>) ;
+
         if $(ps-raw)
         {
             return [ property-set.create $(ps-raw) ] ;
@@ -291,6 +323,7 @@
 
     local new-a = [ new non-scanning-action $(source) : common.copy :
         $(properties) ] ;
+ local target-root = [ $(properties).get <install-target-root> ] ;
     local source-root = [ $(properties).get <install-source-root> ] ;
     if $(source-root)
     {
@@ -310,7 +343,7 @@
     # need to explicitly check that relative is not ".", otherwise we might get
     # paths like '<prefix>/boost/.', try to create it and mkdir would obviously
     # fail.
- name = [ path.join $(relative) $(name:D=) ] ;
+ name = [ path.join $(target-root) $(relative) $(name:D=) ] ;
 
     return [ new file-target $(name) exact : [ $(source).type ] : $(project) :
         $(new-a) ] ;


Boost-Build list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk