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

📄 generators.jam

📁 boost库提供标准的C++ API 配合dev c++使用,功能更加强大
💻 JAM
📖 第 1 页 / 共 3 页
字号:
            generators.dout [ indent ] "  FAILURE" ;
        }
        generators.dout ;
        return $(result) ;        
    }

    # Constructs the dependency graph that will be returned by this 
    # generator
    rule construct-result ( 
        consumed + # Already prepared list of consumable targets
                   # If generator requires several source files will contain 
                   # exactly len $(self.source-types) targets with matching types
                   # Otherwise, might contain several targets with the type of 
                   # $(self.source-types[1])                               
        : project name ? 
        : property-set  # Properties to be used for all actions create here
    )
    {
        local result ;
        # If this is 1->1 transformation, apply it to all consumed targets in order.
        if ! $(self.source-types[2]) && ! $(self.composing)
        {
            generators.dout [ indent ] "alt1" ;
            for local r in $(consumed)
            {                
                result += [ generated-targets $(r) : $(property-set) : $(project) $(name) ] ; #(targets) ;
            }
        }
        else
        {
            generators.dout [ indent ] "alt2 : consumed is" $(consumed) ;
            if $(consumed) 
            {
                result += [ generated-targets $(consumed) : $(property-set) 
                            : $(project) $(name) ] ;
            }                        
        }
        return $(result) ;
    }   
    
    # Constructs targets that are created after consuming 'sources'.
    # The result will be the list of virtual-target, which the same length
    # as 'target-types' attribute and with corresponding types.
    # 
    # When 'name' is empty, all source targets must have the same value of 
    # the 'name' attribute, which will be used instead of the 'name' argument.
    #
    # The value of 'name' attribute for each generated target will be equal to
    # the 'name' parameter if there's no name pattern for this type. Otherwise,
    # the '%' symbol in the name pattern will be replaced with the 'name' parameter 
    # to obtain the 'name' attribute.
    #
    # For example, if targets types are T1 and T2(with name pattern "%_x"), suffixes
    # for T1 and T2 are .t1 and t2, and source if foo.z, then created files would
    # be "foo.t1" and "foo_x.t2". The 'name' attribute actually determined the
    # basename of a file.
    #
    # Note that this pattern mechanism has nothing to do with implicit patterns
    # in make. It's a way to produce target which name is different for name of 
    # source.
    rule generated-targets ( sources + : property-set : project name ? )
    {
        if ! $(name)
        {
            name = [ $(sources[1]).name ] ;            

            for local s in $(sources[2])
            {
                if [ $(s).name ] != $(name)
                {
                    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=) ;
        }
        
        # Create generated target for each target type.
        local targets ;
        local pre = $(self.name-prefix) ;
        local post = $(self.name-postfix) ;
        for local t in $(self.target-types)                 
        {      
            local generated-name = $(pre[1])$(name)$(post[1]) ;
            pre = $(pre[2-]) ;
            post = $(post[2-]) ;
            
            targets += [ class.new file-target $(generated-name) : $(t) : $(project) ] ;
        }                 
        # Assign an action for each target
        local action = [ action-class ] ;
        local a = [ class.new $(action) $(targets) : $(sources) : $(self.id) : 
                    $(property-set) ] ;
        for local t in $(targets)
        {
            $(t).action $(a) ;
        }       
        
        return [ sequence.transform virtual-target.register : $(targets) ] ;
    }    
    
    # Attempts to convert 'source' to the types that this generator can
    # handle. The intention is to produce the set of targets can should be
    # used when generator is run.
    rule convert-to-consumable-types ( project name ? : 
        property-set : sources + : multiple ? 
        : only-one ? # convert 'source' to only one of source types
                     # if there's more that one possibility, report an
                     # error 
        : consumed-var # name of variable which recieves all targets which 
                       # can be consumed. 
          bypassed-var # name variable which recieves all targets which 
                       # cannot be consumed  
    )
    {        
        # We're likely to be passed 'consumed' and 'bypassed'
        # var names. Use "_" to avoid name conflicts.
        local _consumed ;
        local _bypassed ;
        local missing-types ; 

        if $(sources[2])
        {
            # Don't know how to handle several sources yet. Just try 
            # to pass the request to other generator
            missing-types = $(self.source-types) ;
        }
        else
        {            
            consume-directly $(sources) : _consumed : missing-types ;
        }
        
        # No need to search for transformation if
        # some source type has consumed source and
        # no more source types are needed.
        if $(only-one) && $(_consumed) 
        {
            missing-types = ;
        }
            
        #TODO: we should check that only one source type
        #if create of 'only-one' is true.
        # TODO: consider if consuned/bypassed separation should
        # be done by 'construct-types'.
                    
        if $(missing-types)
        {            
            local transformed = [ generators.construct-types $(project) $(name)
              : $(missing-types) : $(multiple) : $(property-set) : $(sources) ] ;
                                
            # Add targets of right type to 'consumed'. Add others to
            # 'bypassed'. The 'generators.construct' rule has done
            # its best to convert everything to the required type.
            # There's no need to rerun it on targets of different types.
                
            for local t in $(transformed)
            {
                if [ $(t).type ] in $(missing-types)
                {
                    _consumed += $(t) ;
                }
                else
                {
                    _bypassed += $(t) ;
                }
            }               
        }   
        
        _consumed = [ sequence.unique $(_consumed) ] ;        
        _bypassed = [ sequence.unique $(_bypassed) ] ;
        
        # remove elements of '_bypassed' that are in '_consumed'
        
        # Suppose the target type of current generator, X is produced from 
        # X_1 and X_2, which are produced from Y by one generator.
        # When creating X_1 from Y, X_2 will be added to 'bypassed'
        # Likewise, when creating X_2 from Y, X_1 will be added to 'bypassed'
        # But they are also in 'consumed'. We have to remove them from
        # bypassed, so that generators up the call stack don't try to convert
        # them. 
            
        # In this particular case, X_1 instance in 'consumed' and X_1 instance
        # in 'bypassed' will be the same: because they have the same source and
        # action name, and 'virtual-target.register' won't allow two different
        # instances. Therefore, it's OK to use 'set.difference'.
        
        _bypassed = [ set.difference $(_bypassed) : $(_consumed) ] ;
        
                
        $(consumed-var) += $(_consumed) ;
        $(bypassed-var) += $(_bypassed) ;
    }
    
    # Converts several files to consumable types.
    rule convert-multiple-sources-to-consumable-types
      ( project : property-set : sources * : consumed-var bypassed-var : multiple ? )
    {
        multiple ?= * ;
        # We process each source one-by-one, trying to convert it to
        # a usable type.
        local failed ;
        while $(sources) && ! $(failed)
        {
            local _c ;
            local _b ;
            # TODO: need to check for failure on each source.
            convert-to-consumable-types $(project) : $(property-set)
              : $(sources[1]) : $(multiple) : true : _c _b ;
            if ! $(_c)
            {
                generators.dout [ indent ] " failed to convert " [ $(sources[1]).str ] ;
                # failed = true ;
            }
            $(consumed-var) += $(_c) ;            
            $(bypassed-var) += $(_b) ;
            sources = $(sources[2-]) ;
        }           
        if $(failed)
        {
            $(consumed-var) = ;
            $(bypassed-var) = ;
        }        
    }
        
    rule consume-directly ( source : consumed-var : missing-types-var )
    {
        local real-source-type = [ $(source).type ] ;

        for local st in $(self.source-types)
        {
            # The 'source' if of right type already)
            if $(real-source-type) = $(st) || 
              [ type.is-derived $(real-source-type) $(st) ]
            {
                $(consumed-var) += $(source) ;
            }
            else
            {
               $(missing-types-var) += $(st) ;
            }
        }        
    }
    
    
    # Returns the class to be used to actions. Default implementation 
    # returns "action".
    rule action-class ( )
    {
        return "action" ;
    }    
}

import errors : error ;

.generators = ;

# Registers new generator instance 'g'.
rule register ( g )
{
    .generators += $(g) ;
                   
    for local t in [ $(g).target-types ] 
    {            
        .generators.$(t) += $(g) ;
    }    
    
    # Update the set of generators for toolset
    local id = [ $(g).id ] ;

    # Some generators have multiple periods in their name, so the
    # normal $(id:S=) won't generate the right toolset name.
    # e.g. if id = gcc.compile.c++, then
    # .generators-for-toolset.$(id:S=) will append to
    # .generators-for-toolset.gcc.compile, which is a separate
    # value from .generators-for-toolset.gcc. Correcting this
    # makes generator inheritance work properly.
    # See also inherit-generators in module toolset
    local base = $(id) ;
    while $(base:S)
    {
        base = $(base:B) ;
    }
    .generators-for-toolset.$(base) += $(g) ;
}
    
# Creates new instance of the 'generator' class and registers it.
# Retursn the creates instance.
# Rationale: the instance is returned so that it's possible to first register
# a generator and then call 'run' method on that generator, bypassing all
# generator selection.
rule register-standard ( id : source-types + : target-types + : requirements * )
{
    local g = [ new generator $(id) : $(source-types) : $(target-types)
      : $(requirements) ] ;
    register $(g) ;   
    return $(g) ;
}

# Creates new instance of the 'composing-generator' class and
# registers it.
rule register-composing ( id : source-types + : target-types + : requirements * )
{
    local g = [ new generator $(id) true : $(source-types) 
                : $(target-types) : $(requirements) ] ;
    register $(g) ;
    return $(g) ;
}

# Returns all generators which belong to 'toolset', i.e. which
# ids are $(toolset).<something>
rule generators-for-toolset ( toolset )
{
    return $(.generators-for-toolset.$(toolset)) ;
}

    
# Set if results of the current generators search are going to be cached
# This means no futher attempts to cache generators search should be
# made.
.caching = ;

# For all t in 'targets':
# if [ $(t).type ] in $(target-types), add 't' to result
# if [ $(t).type ] in base type for any of 'target-types', add 't' to result
# otherwise, add 't' to extra.
rule base-to-derived-type-conversion ( targets * : target-types +
    : result-var extra-var )
{
    for local t in $(targets) 
    {
        if [ $(t).type ] in $(target-types)
        {
            $(result-var) += $(t) ;
        }
        else 
        {
            # We might have asked for a type 'D', but found only generator for
            # a type 'B', where 'D' is derived from 'B'. In this case, the 
            # generation succeeds, but we should change type of the generated target.
            
            local at = [ $(t).type ] ;
            local found ;
            for local tt in $(target-types)
            {
                if ! $(found) && [ type.is-derived $(tt) $(at) ] 
                {
                    $(t).set-type $(tt) ;
                    $(result-var) += $(t) ;
                    found = 1 ;
                }                
            }            
            if ! $(found)
            {
                $(extra-var) += $(t) ;                
            }            

⌨️ 快捷键说明

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