$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r63914 - in trunk/tools/build/v2: build tools
From: ghost_at_[hidden]
Date: 2010-07-12 03:43:01
Author: vladimir_prus
Date: 2010-07-12 03:43:00 EDT (Mon, 12 Jul 2010)
New Revision: 63914
URL: http://svn.boost.org/trac/boost/changeset/63914
Log:
Wip on zlib auto-configuration
Added:
   trunk/tools/build/v2/build/ac.jam   (contents, props changed)
   trunk/tools/build/v2/tools/zlib.jam   (contents, props changed)
Text files modified: 
   trunk/tools/build/v2/build/configure.jam |     6 ++++++                                  
   1 files changed, 6 insertions(+), 0 deletions(-)
Added: trunk/tools/build/v2/build/ac.jam
==============================================================================
--- (empty file)
+++ trunk/tools/build/v2/build/ac.jam	2010-07-12 03:43:00 EDT (Mon, 12 Jul 2010)
@@ -0,0 +1,198 @@
+# Copyright (c) 2010 Vladimir Prus.
+#
+# Use, modification and distribution is subject to the Boost Software
+# License Version 1.0. (See accompanying file LICENSE_1_0.txt or
+# http://www.boost.org/LICENSE_1_0.txt)
+
+import property-set ;
+import path ;
+import modules ;
+import "class" ; 
+import errors ;
+import configure ;
+
+rule find-include-path ( variable : properties : header 
+    : provided-path ? )
+{
+    # FIXME: document which properties affect this function by
+    # default.
+    local target-os = [ $(properties).get <target-os> ] ;
+    properties = [ property-set.create <target-os>$(toolset) ] ;    
+    if $($(variable)-$(properties))
+    {
+        return $($(variable)-$(properties)) ;
+    }
+    else
+    {
+        provided-path ?= [ modules.peek : $(variable) ] ;
+        includes = $(provided-path) ;
+        includes += [ $(properties).get <include> ] ;
+        if [ $(properties).get <target-os> ] != windows
+        {
+            # FIXME: use sysroot
+            includes += /usr/include ;
+        }
+        
+        local result ;
+        while ! $(result) && $(includes)
+        {            
+            local f = [ path.root $(header) $(includes[1]) ] ;
+            ECHO "Checking " $(f) ;
+            if [ path.exists $(f) ]
+            {
+                result = $(includes[1]) ;
+            }
+            else if $(provided-path)
+            {
+                errors.user-error "Could not find header" $(header)
+                  : "in the user-specified directory" $(provided-path) ;
+            }            
+            includes = $(includes[2-]) ;                
+        }        
+        $(variable)-$(properties) = $(result) ;
+        return $(result) ;
+    }        
+}
+
+rule find-library ( variable : properties : names + : provided-path ? )
+{
+    local target-os = [ $(properties).get <target-os> ] ;
+    properties = [ property-set.create <target-os>$(toolset) ] ;
+    if $($(variable)-$(properties))
+    {
+        return $($(variable)-$(properties)) ;
+    }
+    else
+    {
+        provided-path ?= [ modules.peek : $(variable) ] ;
+        paths = $(provided-path) ;
+        paths += [ $(properties).get <library-path> ] ;
+        if [ $(properties).get <target-os> ] != windows
+        {
+            paths += /usr/lib /usr/lib32 /usr/lib64 ;
+        }
+        
+        local result ;               
+        while ! $(result) && $(paths)
+        {   
+            while ! $(result) && $(names)
+            {
+                local f ;
+                if $(target-os) = windows
+                {         
+                    f = $(paths[1])/$(names[1]).lib ;                
+                    if [ path.exists $(f) ] 
+                    {
+                        result = $(f) ;
+                    }
+                }
+                else
+                {
+                    # FIXME: check for .a as well, depending on
+                    # the 'link' feature.
+                    f = $(paths[1])/lib$(names[1]).so ;                
+                    ECHO "CHECKING $(f) " ;
+                    if [ path.exists $(f) ] 
+                    {
+                        result = $(f) ;
+                    }
+                }
+                if ! $(result) && $(provided-path)
+                {
+                    errors.user-error "Could not find either of: " $(names)
+                      : "in the user-specified directory" $(provided-path) ;
+                    
+                }                
+                names = $(names[2-]) ;
+            }
+            paths = $(paths[2-]) ;
+        }        
+        $(variable)-$(properties) = $(result) ;
+        return $(result) ;
+    }
+}
+
+class ac-library : basic-target
+{
+    import errors ;
+    import indirect ;
+    import virtual-target ;
+    import ac ;
+    import configure ;
+
+    rule __init__ ( name : project : * : * )
+    {
+        basic-target.__init__ $(name) : $(project) : $(sources)
+          : $(requirements) ;
+        
+        reconfigure $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ; 
+    }
+    
+    rule set-header ( header )
+    {
+        self.header = $(header) ; 
+    }
+        
+    rule set-default-names ( names + )
+    {
+        self.default-names = $(names) ;
+    }
+        
+    rule reconfigure ( * : * )
+    {
+        ECHO "XXX" $(1) ;
+        if ! $(1)
+        {
+            # This is 'using xxx ;'. Nothing to configure, really.
+        }
+        else
+        {
+            for i in 1 2 3 4 5 6 7 8 9             
+            {
+                # FIXME: this naming is inconsistent with XXX_INCLUDE/XXX_LIBRARY
+                if ! ( $($(i)[1]) in root include-path library-path library-name condition )
+                {
+                    errors.user-error "Invalid named parameter" $($(i)[1]) ;
+                }   
+                local name = $($(i)[1]) ;
+                local value = $($(i)[2-]) ;
+                if $($(name)) && $($(name)) != $(value)
+                {
+                    errors.user-error "Attempt to change value of '$(name)'" ;
+                }
+                $(name) = $(value) ;
+            }
+            
+            include-path ?= $(root)/include ;
+            library-path ?= $(root)/lib ;            
+        }        
+    }
+    
+    rule construct ( name : sources * : property-set )
+    {
+        # FIXME: log results.
+        local libnames = $(library-name) ;
+        if ! $(libnames) && ! $(include-path) && ! $(library-path)
+        {
+            libnames = [ modules.peek : $(name:U)_NAME ] ;
+            # Backward compatibility only.
+            libnames ?= [ modules.peek : $(name:U)_BINARY ] ;
+        }
+        libnames ?= $(self.default-names) ;
+                        
+        local includes = [ 
+          ac.find-include-path $(name:U)_INCLUDE : $(property-set) : $(self.header) : $(include-path) ] ;
+        local library = [ ac.find-library $(name:U)_LIBRARY : $(property-set) : $(libnames) : $(library-path) ] ;
+        if $(includes) && $(library)
+        {
+            library = [ virtual-target.from-file $(library) : . : $(self.project) ] ;
+            configure.log-library-search-result $(name) : "found" ;
+            return [ property-set.create <include>$(includes) <source>$(library) ] ;
+        }
+        else
+        {
+            configure.log-library-search-result $(name) : "no found" ;
+        }        
+    }
+}
+
Modified: trunk/tools/build/v2/build/configure.jam
==============================================================================
--- trunk/tools/build/v2/build/configure.jam	(original)
+++ trunk/tools/build/v2/build/configure.jam	2010-07-12 03:43:00 EDT (Mon, 12 Jul 2010)
@@ -63,6 +63,12 @@
     #.check-results += $(result) ;
 }
 
+rule log-library-search-result ( library : result )
+{
+    local x = [ PAD "    - $(library) : $(result)" : $(.width) ] ;
+    log-check-result "$(x)" ;
+}
+
 rule print-component-configuration ( )
 {
     local c = [ sequence.unique $(.components) ] ;
Added: trunk/tools/build/v2/tools/zlib.jam
==============================================================================
--- (empty file)
+++ trunk/tools/build/v2/tools/zlib.jam	2010-07-12 03:43:00 EDT (Mon, 12 Jul 2010)
@@ -0,0 +1,92 @@
+# Copyright (c) 2010 Vladimir Prus.
+#
+# Use, modification and distribution is subject to the Boost Software
+# License Version 1.0. (See accompanying file LICENSE_1_0.txt or
+# http://www.boost.org/LICENSE_1_0.txt)
+
+# Supports the zlib library
+#
+# After 'using zlib', the following targets are available:
+#
+# /zlib//zlib -- The zlib library
+
+
+# In addition to direct purpose of supporting zlib, this module also
+# serves as canonical example of how third-party condiguration works
+# in Boost.Build. The operation is as follows
+#
+# - For each 'using zlib : condition ... : ...' we create a target alternative
+#   for zlib, with the specified condition.
+# - There's one target alternative for 'zlib' with no specific condition
+#   properties. 
+#
+# Two invocations of 'using zlib' with the same condition but different
+# properties are not permitted, e.g.:
+#
+#   using zlib : condition <target-os>windows : include foo ;
+#   using zlib : condition <target-os>windows : include bar ;
+#
+# is in error. One exception is for empty condition, 'using' without any
+# parameters is overridable. That is:
+#
+#   using zlib ;
+#   using zlib : include foo ;
+# 
+# Is OK then the first 'using' is ignored. Likewise if the order of the statements
+# is reversed.
+#
+# When 'zlib' target is built, a target alternative is selected as usual for
+# Boost.Build. The selected alternative is a custom target class, which:
+#
+# - calls ac.find-include-path to find header path. If explicit path is provided
+#   in 'using', only that path is checked, and if no header is found there, error
+#   is emitted. Otherwise, we check a directory specified using ZLIB_INCLUDE
+#   environment variable, and failing that, in standard directories.
+#   [TODO: document sysroot handling]
+# - calls ac.find-library to find the library, in an identical fashion.
+#
+
+import project ;
+import ac ;
+import errors ;
+import "class" : new ;
+import targets ; 
+
+project.initialize $(__name__) ;
+project = [ project.current ] ;
+project zlib ;
+
+header = zlib.h ;
+names = z zlib zll zdll ;
+
+.default-alternative = [ new ac-library zlib : $(project) ] ;
+$(.default-alternative).set-header $(header) ;
+$(.default-alternative).set-default-names $(names) ;
+targets.main-target-alternative $(.default-alternative) ;
+
+rule init ( * : * )
+{
+    if ! $(condition)
+    {
+        # Special case the no-condition case so that 'using' without parameters
+        # can mix with more specific 'using'.
+        $(.default-alternative).reconfigure $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
+    }
+    else                    
+    {
+        # FIXME: consider if we should allow overriding definitions for a given
+        # condition -- e.g. project-config.jam might want to override whatever is
+        # in user-config.jam. 
+        local mt = [ new ac-library zlib : $(project)
+          : $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ] ;
+        $(mt).set-header $(header) ;
+        $(mt).set-default-names $(names) ;
+        targets.main-target-alternative $(mt) ;
+    }    
+}
+
+
+
+
+
+