$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r49714 - in trunk/tools/build/v2: build test util
From: ghost_at_[hidden]
Date: 2008-11-13 03:26:39
Author: vladimir_prus
Date: 2008-11-13 03:26:39 EST (Thu, 13 Nov 2008)
New Revision: 49714
URL: http://svn.boost.org/trac/boost/changeset/49714
Log:
When source resides in a subdirectory of source dir, preserve that
subdirectory in the target path.
Text files modified: 
   trunk/tools/build/v2/build/generators.jam     |    35 ++++++++++++++++++++++++++++++-----     
   trunk/tools/build/v2/build/project.jam        |    12 +++++++++++-                            
   trunk/tools/build/v2/test/relative_sources.py |    22 ++++++++++++++++++++--                  
   trunk/tools/build/v2/util/path.jam            |    22 +++++++++++++++++++---                  
   4 files changed, 80 insertions(+), 11 deletions(-)
Modified: trunk/tools/build/v2/build/generators.jam
==============================================================================
--- trunk/tools/build/v2/build/generators.jam	(original)
+++ trunk/tools/build/v2/build/generators.jam	2008-11-13 03:26:39 EST (Thu, 13 Nov 2008)
@@ -172,6 +172,7 @@
     import virtual-target ;
     import "class" : new ;
     import property ;
+    import path ;
 
     EXPORT class_at_generator : indent increase-indent decrease-indent
         generators.dout ;
@@ -458,6 +459,32 @@
         return $(result) ;
     }
 
+    # Determine target name from fullname (maybe including path components)
+    # Place optional prefix and postfix around basename
+    #
+    rule determine-target-name ( fullname  : prefix ? : postfix ? )
+    {
+        # See if we need to add directory to the target name.
+        local dir  = $(fullname:D) ;            
+        local name = $(fullname:B) ; 
+        
+        name = $(prefix:E=)$(name) ;
+        name = $(name)$(postfix:E=) ;
+
+        if $(dir) && 
+          # Never append '..' to target path.
+          ! [ MATCH .*(\\.\\.).* : $(dir) ] 
+            && 
+          ! [ path.is-rooted $(dir) ]
+        {
+            # Relative path is always relative to the source
+            # directory. Retain it, so that users can have files
+            # with the same in two different subdirectories.
+            name = $(dir)/$(name) ;                
+        }            
+        return $(name) ;
+    }
+
     # Determine the name of the produced target from the names of the sources.
     #
     rule determine-output-name ( sources + )
@@ -480,10 +507,7 @@
                 errors.error "$(self.id): source targets have different names: cannot determine target name" ;
             }
         }
-
-        # Names of sources might include directory. We should strip it.
-        name = $(name:D=) ;
-
+        name = [ determine-target-name [ $(sources[1]).name ] ] ;
         return $(name) ;
     }
 
@@ -526,7 +550,8 @@
         local post = $(self.name-postfix) ;
         for local t in $(self.target-types)
         {
-            local generated-name = $(pre[1])$(name)$(post[1]) ;
+            local generated-name = $(pre[1])$(name:B)$(post[1]) ;
+            generated-name = $(generated-name:R=$(name:D)) ;
             pre = $(pre[2-]) ;
             post = $(post[2-]) ;
 
Modified: trunk/tools/build/v2/build/project.jam
==============================================================================
--- trunk/tools/build/v2/build/project.jam	(original)
+++ trunk/tools/build/v2/build/project.jam	2008-11-13 03:26:39 EST (Thu, 13 Nov 2008)
@@ -811,7 +811,17 @@
         # absolute.
         for local p in $(paths)
         {
-            result += [ path.root $(p) [ path.pwd ] ] ;
+            # If the path is below source location, use relative path.
+            # Otherwise, use full path just to avoid any ambiguities.
+            local rel = [ path.relative $(p) $(location) : no-error ] ;
+            if $(rel) = not-a-child
+            {                   
+                result += [ path.root $(p) [ path.pwd ] ] ;
+            }
+            else
+            {
+                result += $(rel) ;
+            }                
         }
     }
     else
Modified: trunk/tools/build/v2/test/relative_sources.py
==============================================================================
--- trunk/tools/build/v2/test/relative_sources.py	(original)
+++ trunk/tools/build/v2/test/relative_sources.py	2008-11-13 03:26:39 EST (Thu, 13 Nov 2008)
@@ -11,10 +11,28 @@
 
 t = BoostBuild.Tester()
 
-t.write("jamroot.jam", "import gcc ;")
-t.write("jamfile.jam", "exe a : src/a.cpp ;")
+# Test that relative path to source, 'src', is preserved.
+t.write("jamroot.jam", "exe a : src/a.cpp ;")
 t.write("src/a.cpp", "int main() {}\n")
 
 t.run_build_system()
+t.expect_addition("bin/$toolset/debug/src/a.obj")
+ 
+# Test that the relative path to source is preserved
+# when using 'glob'.
+t.rm("bin")
+t.write("jamroot.jam", "exe a : [ glob src/*.cpp ] ;")
+t.run_build_system()
+t.expect_addition("bin/$toolset/debug/src/a.obj")
+
+
+# Test that relative path with ".." is *not* added to
+# target path.
+t.rm(".")
+t.write("jamroot.jam", "")
+t.write("a.cpp", "int main() { return 0; }\n")
+t.write("build/Jamfile", "exe a : ../a.cpp ; ")
+t.run_build_system(subdir="build")
+t.expect_addition("build/bin/$toolset/debug/a.obj")
 
 t.cleanup()
Modified: trunk/tools/build/v2/util/path.jam
==============================================================================
--- trunk/tools/build/v2/util/path.jam	(original)
+++ trunk/tools/build/v2/util/path.jam	2008-11-13 03:26:39 EST (Thu, 13 Nov 2008)
@@ -372,8 +372,9 @@
 # Assuming 'child' is a subdirectory of 'parent', return the relative path from
 # 'parent' to 'child'.
 #
-rule relative ( child parent )
+rule relative ( child parent : no-error ? )
 {
+    local not-a-child ;
     if $(parent) = "."
     {
         return $(child) ;
@@ -392,12 +393,27 @@
             }
             else
             {
-                errors.error $(child) is not a subdir of $(parent) ;
+                not-a-child = true ;
+                split1 = ;
             }
         }
         if $(split2)
         {
-            return [ join $(split2) ] ;
+            if $(not-a-child)
+            {
+                if $(no-error)
+                {
+                    return not-a-child ;
+                }
+                else
+                {
+                    errors.error $(child) is not a subdir of $(parent) ;
+                }                        
+            }
+            else
+            {
+                return [ join $(split2) ] ;    
+            }        
         }
         else
         {