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

📄 virtual-target.jam

📁 boost库提供标准的C++ API 配合dev c++使用,功能更加强大
💻 JAM
📖 第 1 页 / 共 3 页
字号:
            # File is either source, which will be searched for, or is not a file at
            # all. Use the location of project for distinguishing.
            local project-location = [ project.attribute $(self.project) location ] ;
            local location-grist =
              [ sequence.join [ regex.split $(project-location) "/" ] : "!" ] ;
            
            if $(self.action)
            {
                local ps = [ $(self.action).properties ] ;     
                local property-grist = [ $(ps).as-path ] ;
                location-grist = $(location-grist)/$(property-grist) ;
            }            
                        
            return l$(location-grist) ;
        }                
    }
        
    # Helper to actual-name, above. Compute the 'basename' of the filename
    # of the actual created file.
    rule actual-basename ( )
    {
        local name = [ path.native $(self.name) ] ;
        if $(self.suffix)
        {
            name = $(name).$(self.suffix) ;
        }
        else if $(self.type)
        {
            local properties ;
            if $(self.action)
            {
                local ps = [ $(self.action).properties ] ;
                properties = [ $(ps).raw ] ;
            }                        
            local suffix = [ type.generated-target-suffix $(self.type) :
              $(properties) ] ;
            if $(suffix)
            {                
                name = $(name).$(suffix) ;
            }            
        }
        return $(name) ;        
    }
    

}

# File target with explicitly known location.
#
# The file path is determined as
#    - value passed to the 'set-path' method, if any
#    - for derived files, project's build dir, joined with components
#      that describe action's properties. If the free properties
#      are not equal to the project's reference properties
#      an element with name of main target is added.
#    - for source files, project's source dir
#
# The file suffix is
#     - the value passed to the 'suffix' method, if any, or
#     - the suffix which correspond to the target's type.
#
class file-target : abstract-file-target 
{
    import common ;    
    import errors ;
    
    rule __init__ (
      name
        : type ?  # Optional type for this target
        : project
    )
    {
        abstract-file-target.__init__ $(name) : $(type) : $(project) ;   
    }
        
    rule actualize-location ( target )
    {
        if $(self.action)
        {
            # This is a derived file.
            local path = [ path ] ;
            LOCATE on $(target) = $(path) ;                        

            # Make sure the path exists.
            DEPENDS $(target) : $(path) ;
            common.MkDir $(path) ;
        }
        else
        {
            # This is a source file.
            SEARCH on $(target) =
              [ path.native [ project.attribute $(self.project) source-location ] ] ;
        }        
    }
    
    # Returns the directory for this target
    rule path ( )
    {
        if ! $(self.path)
        {
            if $(self.action)
            {                
                local build-dir = [ project.attribute $(self.project) build-dir ] ;
                if ! $(build-dir)
                {
                    build-dir = [ path.join 
                        [ project.attribute $(self.project) location ]
                        bin
                    ] ;
                }
                
                local path = [ path.join
                    $(build-dir)
                      [ $(self.action).path ]
                ] ;
                
                # Store the computed path, so that it's not recomputed
                # any more
                self.path = [ path.native $(path) ] ;
            }            
        }
        return $(self.path) ;
     }

}

class notfile-target : abstract-file-target
{
    rule __init__ ( name : project )
    {
        abstract-file-target.__init__ $(name) : : $(project) ;
    }
    
            
    rule actualize-location ( target )
    {
        NOTFILE $(target) ;
        ALWAYS $(target) ;
    }    
}    

# Class which represents an action.
# Both 'targets' and 'sources' should list instances of 'virtual-target'.
# Action name should name a rule with this prototype
#     rule action-name ( targets + : sources * : properties * )
# Targets and sources are passed as actual jam targets. The rule may
# not establish dependency relationship, but should do everything else.
class action 
{
    import type toolset property-set indirect class path ;
    
    rule __init__ ( targets + : sources * : action-name + : property-set ? )
    {        
        self.targets = $(targets) ;
        self.sources = $(sources) ;
    
        self.action-name = [ indirect.make-qualified $(action-name) ] ;
        
        if ! $(property-set) 
        {
            property-set = [ property-set.empty ] ;
        }
        
        if ! [ class.is-instance $(property-set) ]
        {        
            errors.error "Property set instance required" ;
        }
        
        self.properties = $(property-set) ;
    }        
    
    rule targets ( )
    {
        return $(self.targets) ;
    }

    rule sources ( )
    {
        return $(self.sources) ;
    }

    rule action-name ( )
    {
        return $(self.action-name) ;
    }

    rule properties ( )
    {
        return $(self.properties) ;
    }

    # Generates actual build instructions.
    rule actualize ( )
    {
        if ! $(self.actualized)
        {
            self.actualized = true ;

            local ps = [ properties ] ;
            local properties = [ adjust-properties [ $(ps).raw ] ] ;


            local actual-targets ;
            for local i in [ targets ]
            {
                actual-targets += [ $(i).actualize ] ;
            }

            actualize-sources [ sources ] ;

            DEPENDS $(actual-targets) : $(self.actual-sources) $(self.dependency-only-sources) ;

            # Action name can include additional argument to rule, which should not
            # be passed to 'set-target-variables'
            toolset.set-target-variables
              [ indirect.get-rule $(self.action-name[1]) ] $(actual-targets)
                : $(properties) ;
            
            indirect.call $(self.action-name) 
              $(actual-targets) : $(self.actual-sources) : $(properties)
                ;
            
            # Since we set up creating action here, we also set up
            # action for cleaning up
            common.Clean clean : $(actual-targets) ;
        }
    }

    # Helper for 'actualize-sources'.
    # For each passed source, actualizes it with the appropriate scanner.
    # Returns the actualized virtual targets.
    rule actualize-source-type ( sources * )
    {
        local result = ;
        for local i in $(sources)
        {
            local scanner ;
            if [ $(i).type ]
            {
                scanner =
                  [ type.get-scanner [ $(i).type ] : $(properties) ] ;
            }
            result += [ $(i).actualize $(scanner) ] ;
        }
        
        return $(result) ;
    }
    
    # Creates actual jam targets for sources. Initialized two member
    # variables:.
    # 'self.actual-sources' -- sources which are passed to updating action
    # 'self.dependency-only-sources' -- sources which are made dependencies, but
    # are not used otherwise.
    #
    # New values will be *appended* to the variables. They may be non-empty,
    # if caller wants it.
    rule actualize-sources ( sources * )
    {
        local dependencies = [ $(self.properties).get <dependency> ] ;
                
        self.dependency-only-sources += [ actualize-source-type $(dependencies) ] ;
        self.actual-sources += [ actualize-source-type $(sources) ] ;
    }

    rule path ( )
    {
        local p = [ $(self.properties).as-path ] ;
        # Really, an ugly hack. Boost regression test system requires
        # specific target paths, and it seems that changing it to handle
        # other directory layout is really hard. For that reason,
        # we teach V2 to do the things regression system requires.
        # The value o '<location-prefix>' is predended to the path.
        local prefix = [ $(self.properties).get <location-prefix> ] ;
        if $(prefix)
        {
            p = [ path.join $(prefix) $(p) ] ;
        }        
        return $(p) ;
    }

    # Determined real properties when trying building with 'properties'.
    # This is last chance to fix properties, for example to adjust includes
    # to get generated headers correctly. Default implementation returns
    # its argument.
    rule adjust-properties ( properties * )
    {
        return $(properties) ;
    }


    rule set-targets ( targets * )
    {
        self.targets = $(targets) ;
    }
}

# Action class which does nothing --- it produces the targets with
# specific properties out of nowhere. It's needed to distinguish virtual
# targets with different properties that are known to exist, and have no 
# actions which create them.
class null-action : action 
{
    rule __init__ ( targets + : property-set ? )
    {
        action.__init__ $(targets) : : .no-action : $(property-set) ;
    }
        
    rule actualize ( )
    {
        if ! $(self.actualized)
        {
            self.actualized = true ;

            for local i in [ targets ]
            {
                $(i).actualize ;
            }
        }        
    }
}


# Creates a virtual target with approariate name and type from 'file'.
# If a target with that name in that project was already created, returns that already
# created target.
# FIXME: more correct way would be to compute path to the file, based on name and source location
# for the project, and use that path to determine if the target was already created.
# TODO: passing project with all virtual targets starts to be annoying.
rule from-file ( file : project )
{
    import type ; # had to do this here to break a circular dependency
    
    if $(.files.$(file).$(project))
    {
        return $(.files.$(file).$(project)) ;
    }
    else
    {
        local name = [ path.make $(file:S=) ] ;
        local type = [ type.type $(file) ] ;
        local result ;
        if ! $(type)
        {
            # warning "cannot determine type for file $(file)" ;
            result = [ new file-target $(file) :  : $(project) ] ;
        }
        else
        {
            local v = [ new file-target $(name) : $(type) : $(project) ] ;
            $(v).suffix [ MATCH ^.(.*)$ : $(file:S) ] ;
            result = $(v) ;
        }
        .files.$(file).$(project) = $(result) ;
        return $(result) ;
    }
}

# Registers a new virtual target. Checks if there's already registered target, with the same
# name, type, project and subvariant properties, and also with the same sources
# and equal action. If such target is found it is retured and 'target' is not registers.
# Otherwise, 'target' is registered and returned.
rule register ( target )
{
    local signature = [ sequence.join
        [ $(target).project ] [ $(target).name ] [ $(target).type ] : - ] ;
    local result ;
    for local t in $(.cache.$(signature))
    {
        local a1 = [ $(t).action ] ;
        local a2 = [ $(target).action ] ;
        
        if ! $(result)
        {
            if ! $(a1) && ! $(a2)
            {

⌨️ 快捷键说明

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