[Home]Boost.Build V2/ExtendingInstallRule

BOOST WIKI | Boost.Build V2 | RecentChanges | Preferences | Page List | Links List

Showing revision 7
output structure created by the Jamfile below
    dist3/a.lib
    root/borland/debug/a.lib
    borland/horay/a.lib
    tool/var/horay/a.dll

The extended-install rule provides all the functionality of install (surprise) with the ability to :

    1.  invoke a new feature <location-root> which invokes the same logic used 
        to create the bin structure but under the <location-root> structure.
    2.  provide a rule that defines a location for the install, this rule overrides the default rule supplied with
        extended-install

Enjoy and Good Luck

Jamfile


import extended-install ;
import property-set ;

# a rule for defining the location of the install files
rule custom-install-location ( property-set )
{
    local toolset = [ $(property-set).get <toolset> ] ;

    local location = $(toolset)/horay ;
    local rawps = [ extended-install.refine [ $(property-set).raw ] : 
                             $(location:G=<location>) ] ;

    return [ property-set.create $(rawps) ] ;
}

# another rule for defining the location of the install files
rule custom-install-location2 ( property-set )
{
    local location = tool/var/horay ;
    local rawps = [ extended-install.refine [ $(property-set).raw ] : 
                             $(location:G=<location>) ] ;

    return [ property-set.create $(rawps) ] ;
} 

lib a : a.cpp ;

extended-install dist3 : a : ;
extended-install dist2 : a : <location>./otherlibs ;
extended-install dist1 : a : <location-root>root ;
extended-install dist4 : a : <location-root>ignoredbymyrule : : custom-install-location ;
extended-install dist5 : a : : : custom-install-location2 ;

extended-install.jam


# This module defines the 'extended-install' rule, used to copy a set of
# targets to a single location.  extended-install provides one feature ontop of
# what the install rule provides.  If the feature is defined the install 
# location is similar to the build structure used.

import "class" : new ;
import errors : error ;
import feature : feature compose ;
import indirect ;
import project ;
import property ;
import property-set ;
import path ;
import sequence ;
import stage ;          # automaticlly imported any way
import targets ;

feature location-root : : free path ;

class extended-install-target : install-target-class
{
    import "class" : new ;
    import indirect ;
    import property-set ;
    
    rule __init__ ( name-and-dir : project : sources * : 
                    requirements * : default-build * : generate-path-rule )
    {
        self.generate-path-rule = $(generate-path-rule) ;

        install-target-class.__init__ $(name-and-dir) : $(project) : 
                            $(sources) : $(requirements) : $(default-build) ;
    }

    rule construct ( name : source-targets * : property-set )
    {        
        if [ $(property-set).get <location-root> ]
        {
            property-set = [ indirect.call $(self.generate-path-rule) 
                                           $(property-set) ] ;
        }

        return [ install-target-class.construct $(name) : 
                        $(source-targets) : $(property-set) ] ;
    }

}    
    
# this function was *HACKED* from property.jam, unfortunately the
# property.refine would not modify free features, it simply added then
# together which is not what I wanted.
rule refine ( properties * : requirements * )
{
    local result ;
    local error ;
    
    # All the elements of requirements should be present in the result
    # Record them so that we can handle 'properties'.
    for local r in $(requirements)
    {
        # Don't consider conditional requirements.
        if ! [ MATCH (:) : $(r:G=) ]
        {            
            # Note: cannot use local here, so take an ugly name
            __require__$(r:G) = $(r:G=) ;
        }        
    }

    for local p in $(properties)
    {       
        local required-value = $(__require__$(p:G)) ;
        if $(required-value)
        {
            local value = $(p:G=) ;
            if $(value) != $(required-value)
            {
                result += $(p:G)$(required-value) ;
            }
            else
            {
                result += $(p) ;
            }
        }
        else
        {
            result += $(p) ;
        }
    }

    # Unset our ugly map.        
    for local r in $(requirements)
    {
         __require__$(r:G) = ;
    }
    
    if $(error)
    {
        return $(error) ;
    }
    else
    {
        return [ sequence.unique $(result) $(requirements) ] ;
    }
}

# generate an install location using <location-root> and the property-set
# algorithm.
rule generate-install-location ( property-set )
{
    local path = [ $(property-set).target-path ] ;

    local location-root = [ $(property-set).get <location-root> ] ;

    local location = $(location-root)/$(path[1]) ;
    local rawps = [ extended-install.refine [ $(property-set).raw ] : 
                             $(location:G=<location>) ] ;

    return [ property-set.create $(rawps) ] ;
} 

# Main target rule for 'install'
rule extended-install ( name : sources * : requirements * 
                        : default-build * : generate-path-rule * )
{
    local project = [ project.current ] ;

    if ! $(generate-path-rule)
    {
        generate-path-rule = [ indirect.make-qualified 
                                extended-install.generate-install-location ] ;
    }
    else
    {
        requirements += <location-root>trigger_user_rule ;
        generate-path-rule = [ indirect.make-qualified $(generate-path-rule) ] ;
    }

    if <location-root> in $(requirements:G) && <location> in $(requirements:G)
    {
        errors.user-error 
          "You must not define <location-root> and <location> together for"
          "the 'extended-install' rule" ;
    }

    targets.main-target-alternative
      [ new extended-install-target $(name) : $(project) 
        : [ targets.main-target-sources $(sources) : $(name) ]
        : [ targets.main-target-requirements $(requirements) : $(project) ] 
        : [ targets.main-target-default-build $(default-build) : $(project) ] 
        : $(generate-path-rule)
      ] ;
}

IMPORT $(__name__) : extended-install : : extended-install ;

[buy lipitor online] [buy lipitor] [[buy lipitor online]]

[buy fioricet online] [buy fioricet] [[buy fioricet online]]


BOOST WIKI | Boost.Build V2 | RecentChanges | Preferences | Page List | Links List
Edit revision 7 of this page | View other revisions | View current revision
Edited August 24, 2008 1:55 pm (diff)
Search:
Disclaimer: This site not officially maintained by Boost Developers