⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 targets.jam

📁 C++的一个好库。。。现在很流行
💻 JAM
📖 第 1 页 / 共 4 页
字号:
                # to use here.
                [ feature.compress-subproperties $(raw) ] 
                  $(defaults-to-apply)
            ] ;
              
            if $(properties)
            {                
                for local p in $(properties)
                {
                    result += [ property-set.create 
                        [ feature.expand [ feature.split $(p) ] ] ] ;
                }
            }
            else
            {
                result = [ property-set.empty ] ;
            }            
            
        }
        else
        {
            result = $(property-set) ;
        }
        return $(result) ;
    }
        
    # Select an alternative for this main target, by finding all alternatives
    # which requirements are satisfied by 'properties' and picking the one with
    # longest requirements set.
    # Returns the result of calling 'generate' on that alternative.
    rule generate ( property-set )
    {
        start-building $(__name__) ;

        # We want composite properties in build request act as if
        # all the properties it expands too are explicitly specified.
        property-set = [ $(property-set).expand ] ;
        
        local all-property-sets = [ apply-default-build $(property-set) ] ;
        local usage-requirements = [ property-set.empty ] ;
        local result ;
        for local p in $(all-property-sets)
        {
            local r = [ generate-really $(p) ] ;
            usage-requirements = [ $(usage-requirements).add $(r[1]) ] ;
            result += $(r[2-]) ;
        }
        end-building $(__name__) ;
        return $(usage-requirements) [ sequence.unique $(result) ] ;                
    }
        
    # Generates the main target with the given property set
    # and returns a list which first element is property-set object
    # containing usage-requirements of generated target and with
    # generated virtual target in other elements. It's possible
    # that no targets are generated.
    local rule generate-really ( property-set )
    {            
        local best-alternatives = [ select-alternatives $(property-set) ] ;
        if ! $(best-alternatives)
        {
            errors.error
                "failed to build" [ full-name ]
                "with properties" [ $(property-set).raw ]
                  "because no best-matching alternative could be found"
                  ; 
            return [ property-set.empty ] ;
        }
        else
        {
            local result = [ $(best-alternatives).generate $(property-set) ] ;
                        
            # Now return virtual targets for the only alternative
            return $(result) ;
        }        
    }
    
    rule rename ( new-name )
    {
        abstract-target.rename $(new-name) ;
        for local a in $(self.alternatives)
        {
            $(a).rename $(new-name) ;
        }
        
    }
    
}

# Abstract target which refers to a source file.
# This is artificial creature; it's usefull so that sources to 
# a target can be represented as list of abstract target instances.
class file-reference : abstract-target 
{
    import virtual-target ;
    import property-set ;
    import path ;
    
    rule __init__ ( file : project )
    {
        abstract-target.__init__ $(file) : $(project) ;
    }
    
    rule generate ( properties )
    {
         return [ property-set.empty ] 
                [ virtual-target.from-file $(self.name)
                                         : [ location ]
                                         : $(self.project) ] ;        
    }    

    # Returns true if the referred file really exists;
    rule exists ( )
    {
        location ;
        return $(self.file-path) ;
    }

    # Returns the location of target. Needed by 'testing.jam'
    rule location ( )
    {
        if ! $(self.file-location)
        {
            local source-location = [ $(self.project).get source-location ] ;

            for local src-dir in $(source-location)
            {
                if ! $(self.file-location)
                {
                    local location = [ path.root $(self.name) $(src-dir) ] ;
                    if [ CHECK_IF_FILE [ path.native $(location) ] ]
                    {
                         self.file-location = $(src-dir) ;
                         self.file-path = $(location) ;
                    }
                }
            }
        }
        return $(self.file-location) ;
    }
}


if "--quiet" in [ modules.peek : ARGV ]
{
    .quiet = true ;
}


# Given a target-reference, made in context of 'project',
# returns the abstract-target instance that is referred to, as well
# as properties explicitly specified for this reference.
rule resolve-reference ( target-reference : project )
{
    # Separate target name from properties override
    local split = [ MATCH "^([^<]*)(/(<.*))?$" : $(target-reference) ] ;
    local id = $(split[1]) ;
    local sproperties = ;
    if $(split[3])
    {
        sproperties = [ property.make [ feature.split $(split[3]) ] ] ;
        sproperties = [ feature.expand-composites $(sproperties) ] ;
    }

    # Find the target
    local target = [ $(project).find $(id) ] ;
    
    return $(target) [ property-set.create $(sproperties) ] ;
}



# Attempts to generate the target given by target reference, which
# can refer both to a main target or to a file.
# Returns a list consisting of
# - usage requirements
# - generated virtual targets, if any
rule generate-from-reference 
   ( target-reference            # Target reference
    : project                    # Project where the reference is made
    : property-set               # Properties of the main target that 
                                 # makes the reference
   )
{
    local r = [ resolve-reference $(target-reference) : $(project) ] ;
    local target = $(r[1]) ;
    local sproperties = $(r[2]) ;
    
    # Take properties which should be propagated and refine them
    # with source-specific requirements.
    local propagated = [ $(property-set).propagated ] ;
    local rproperties = [ $(propagated).refine $(sproperties) ] ;
    if $(rproperties[1]) = "@error"
    {
        errors.error
          "When building" [ full-name ] " with properties " $(properties) :
            "Invalid properties specified for " $(source) ":"
              $(rproperties[2-]) ;
    }
    return [ $(target).generate $(rproperties) ] ;
}

# Given build request and requirements, return properties
# common to dependency build request and target build
# properties
rule common-properties ( build-request requirements )
{
    # For optimization, we add free requirements directly,
    # without using complex algorithsm.
    # This gives the complex algorithm better chance of caching results.
    local free = [ $(requirements).free ] ;        
    local non-free = [ property-set.create 
        [ $(requirements).base ]  [ $(requirements).incidental ] ] ;
    
    local key = .rp.$(build-request)-$(non-free) ;
    if ! $($(key))
    {           
        $(key) = [ common-properties2 $(build-request) $(non-free) ] ;        
    }        
    result = [ $($(key)).add-raw $(free) ] ;
}
    
rule common-properties2 ( build-request requirements )
{           
    # This guarantees that default properties are present
    # in result, unless they are overrided by some requirement.
    # FIXME: There is possibility that we've added <foo>bar, which is composite
    # and expands to <foo2>bar2, but default value of <foo2> is not bar2,
    # in which case it's not clear what to do.
    # 
    build-request = [ $(build-request).add-defaults ] ;
    # Featured added by 'add-default' can be composite and expand
    # to features without default values -- so they are not added yet.
    # It could be clearer/faster to expand only newly added properties
    # but that's not critical.
    build-request = [ $(build-request).expand ] ;
    
    # Apply non-conditional requirements. 
    # There's a slight bug here: it's possible that conditional
    # requirement change a value set by non-conditional requirements. This
    # should be error, but we don't detect it yet.
    local raw = [ $(build-request).raw ] ;
    raw = [ property.refine $(raw) : 
      [ feature.expand [ $(requirements).non-conditional ] ] ] ;
    
    # We've collected properties that surely must be present in common
    # properties. We now try to figure out what other properties
    # should be added in order to satisfy rules (4)-(6) from the docs.        
    
    local conditionals = [ $(requirements).conditional ] ;
    local count = $(conditionals) and-once-more ;
    local prev ;
    
    local current = $(raw) ;
    
    local ok ;
    while $(count) 
    {
        # Evaluate conditionals in context of current properties
        local e = [ property.evaluate-conditionals-in-context $(conditionals) 
          : $(current) ] ;
        if $(e) = $(prev)
        {                
            # If we got the same result, we've found final properties.
            count = ;      
            ok = true ;
        }         
        else
        {
            # Oops, results of evaluation of conditionals has changes
            # Also 'current' contains leftover from previous evaluation.
            # Recompute 'current' using initial properties and conditional
            # requirements.
            prev = $(e) ;
            current = [ property.refine $(raw) : [ feature.expand $(e) ] ] ;
        }            
        count = $(count[2-]) ;
    }
    if ! $(ok)
    {
        errors.error "Can't evaluate conditional properties " $(conditionals) ;
    }
    
    
    return [ property-set.create $(current) ] ;
}

# Implements the most standard way of constructing main target
# alternative from sources. Allows sources to be either file or
# other main target and handles generation of those dependency
# targets.
class basic-target : abstract-target
{
    import build-request ;
    import virtual-target targets ;
    import property-set ;
    import set sequence errors ;
    import "class" : new ;
    import property feature ;
        
    rule __init__ ( name : project
        : sources * : requirements * : 
        default-build * : usage-requirements * )
    {        
        abstract-target.__init__ $(name) : $(project) ;
    
        self.sources = $(sources) ;
        if ! $(requirements) {
            requirements = [ property-set.empty ] ;
        }    
        self.requirements = $(requirements) ;
        if ! $(default-build) 
        {
            default-build = [ property-set.empty ] ;
        }    
        self.default-build = $(default-build) ;
        if ! $(usage-requirements)
        {
            usage-requirements = [ property-set.empty ] ;
        }    
        self.usage-requirements = $(usage-requirements) ;
        
        if $(sources:G)
        {
            errors.error "gristed element in sources for" [ full-name ] ;
        }
    }
    
    rule requirements ( )
    {
        return $(self.requirements) ;
    }
                        
    rule default-build ( )
    {
        return $(self.default-build) ;
    }
    
    # Returns the alternative condition for this alternative, if
    # the condition is satisfied by 'property-set'.
    rule match ( property-set )
    {    
        # The condition is composed of all base non-conditional properties.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -