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

📄 targets.jam

📁 C++的一个好库。。。现在很流行
💻 JAM
📖 第 1 页 / 共 4 页
字号:
#  Copyright (C) Vladimir Prus 2002. Permission to copy, use, modify, sell and
#  distribute this software is granted provided this copyright notice appears in
#  all copies. This software is provided "as is" without express or implied
#  warranty, and with no claim as to its suitability for any purpose.


#   Supports 'abstract' targets, which are targets explicitly defined in Jamfile.
#
#   Abstract targets are represented by classes derived from 'abstract-target' class. 
#   The first abstract target is 'project-target', which is created for each
#   Jamfile, and can be obtained by the 'target' rule in the Jamfile's module.
#   (see project.jam). 
#
#   Project targets keep a list of 'main-target' instances.
#   A main target is what the user explicitly defines in a Jamfile. It is
#   possible to have several definitions for a main target, for example to have
#   different lists of sources for different platforms. So, main targets
#   keep a list of alternatives.
#
#   Each alternative is an instance of 'abstract-target'. When a main target
#   subvariant is defined by some rule, that rule will decide what class to
#   use, create an instance of that class and add it to the list of alternatives
#   for the main target.
#
#   Rules supplied by the build system will use only targets derived
#   from 'basic-target' class, which will provide some default behaviour.
#   There will be two classes derived from it, 'make-target', created by the
#   'make' rule, and 'typed-target', created by rules such as 'exe' and 'dll'.

#
#                         +------------------------+
#                         |abstract-target         |
#                         +========================+
#                         |name                    |
#                         |project                 |                                   
#                         |                        |                                   
#                         |generate(properties) = 0|                                   
#                         +-----------+------------+                                   
#                                     |                                                
#                                     ^                                                
#                                    / \                                               
#                                   +-+-+                                              
#                                     |                                                
#                                     |                                                
#            +------------------------+------+------------------------------+          
#            |                               |                              |          
#            |                               |                              |          
# +----------+-----------+            +------+------+                +------+-------+  
# | project-target       |            | main-target |                | basic-target |  
# +======================+ 1        * +=============+  alternatives  +==============+  
# | generate(properties) |o-----------+ generate    |<>------------->| generate     |  
# | main-target          |            +-------------+                | construct = 0|
# +----------------------+                                           +--------------+  
#                                                                           |          
#                                                                           ^          
#                                                                          / \         
#                                                                         +-+-+        
#                                                                           |          
#                                                                           |          
#                 ...--+----------------+------------------+----------------+---+      
#                      |                |                  |                    |      
#                      |                |                  |                    |      
#               ... ---+-----+   +------+-------+   +------+------+    +--------+-----+
#                            |   | typed-target |   | make-target |    | stage-target |
#                            .   +==============+   +=============+    +==============+
#                            .   | construct    |   | construct   |    | construct    |
#                                +--------------+   +-------------+    +--------------+

import "class" : new ;
import sequence ;
import regex ;
import property ;
import errors ;
import common ;
import property-set ;
import project ;
import feature ;
import virtual-target ;
import path ;
import set ;
import assert ;

# Base class for all abstract targets.
class abstract-target 
{
    import project assert "class" errors ;    
        
    rule __init__ ( name      # name of the target in Jamfile
        : project-target      # the project target to which this one belongs
    )
    {        
        assert.true class.is-a $(project-target) : project-target ;
        # Note: it might seem that we don't need either name or project at all.
        # However, there are places where we really need it. One example is error
        # messages which should name problematic targets. Another is setting correct
        # paths for sources and generated files.
        
        self.name = $(name) ;
        self.project = $(project-target) ;
        self.location = [ errors.nearest-user-location ] ;
    }    
    
    # Returns the name of this target.
    rule name ( )
    {
        return $(self.name) ;
    }
    
    # Returns the project for this target.
    rule project ( )
    {
        return $(self.project) ;
    }
    
    # Return the location where the target was declared
    rule location ( )
    {
        return $(self.location) ;
    }
            
    # Returns a user-readable name for this target.
    rule full-name ( )
    {
        local location = [ $(self.project).get location ] ;
        return $(location)/$(self.name) ;
    }
        
    # Takes a property set.  Generates virtual targets for this abstract
    # target, using the specified properties, unless a different value of some
    # feature is required by the target. 
    # On
    # success, returns: 
    # - a property-set with the usage requirements to be
    #   applied to dependents 
    # - a list of produced virtual targets, which may be
    #    empty.  
    # If 'property-set' are empty, performs default build of this
    # target, in a way specific to derived class.
    rule generate ( property-set )
    {
        errors.error "method should be defined in derived classes" ;
    }
    
    rule rename ( new-name )
    {
        self.name = $(new-name) ;
    }        
}

if --debug-building in [ modules.peek : ARGV ]            
{
    modules.poke : .debug-building : true ;
}


rule indent ( )
{
    return $(.indent:J="") ;
}

rule increase-indent ( )
{
    .indent += "    " ;
}

rule decrease-indent ( )
{
    .indent = $(.indent[2-]) ;
}

#  Project target class (derived from 'abstract-target')
#
#  This class these responsibilities:
#  - maintaining a list of main target in this project and
#    building it
#
#  Main targets are constructed in two stages:
#  - When Jamfile is read, a number of calls to 'add-alternative' is made.
#    At that time, alternatives can also be renamed to account for inline
#    targets.
#  - The first time 'main-target' or 'has-main-target' rule is called,
#    all alternatives are enumerated an main targets are created.
class project-target : abstract-target 
{
    import project targets ;
    import path ;
    import print ;
    import property-set ;
    import set : difference : set.difference ;
    import sequence ;
    import "class" : new ;
    import errors ;
        
    rule __init__ ( name : project-module parent-project ?
        : requirements * : default-build * )
    {    
        abstract-target.__init__ $(name) : $(__name__) ;
        
        self.project-module = $(project-module) ;
        self.location = [ project.attribute $(project-module) location ] ;
        self.requirements = $(requirements) ;
        self.default-build = $(default-build) ;
                        
        if $(parent-project)
        {            
            inherit $(parent-project) ;
        }        
    }

    # This is needed only by the 'make' rule. Need to find the
    # way to make 'make' work without this method.
    rule project-module ( )
    {
        return $(self.project-module) ;
    }
        
    rule get ( attribute )    
    {
        return [ project.attribute $(self.project-module) $(attribute) ] ;
    }

    rule build-dir ( )
    {
        if ! $(self.build-dir)
        {            
            self.build-dir = [ get build-dir ] ;
            if ! $(self.build-dir)
            {
                self.build-dir = [ path.join 
                    [ $(self.project).get location ]
                      bin
                ] ;
            }
        }
        return $(self.build-dir) ;
    }        
    
    # Generates all possible targets contained in this project.
    rule generate ( property-set * )
    {
        if [ modules.peek : .debug-building ] 
        {
            ECHO [ targets.indent ] "building project" [ name ] " ('$(__name__)') with" [ $(property-set).raw ] ;
            targets.increase-indent ;
        }
                
        local usage-requirements = [ property-set.empty ] ;
        local targets ;
                
        for local t in [ targets-to-build ] 
        {
            local g = [ $(t).generate $(property-set) ] ;
            usage-requirements = [ $(usage-requirements).add $(g[1]) ] ;
            targets += $(g[2-]) ;
        }
        targets.decrease-indent ;
        return $(usage-requirements) [ sequence.unique $(targets) ] ;        
    }
        
    # Computes and returns a list of abstract-target instances which
    # must be built when this project is built.
    rule targets-to-build ( )
    {
        local result ;
        
        if ! $(self.built-main-targets)
        {
            build-main-targets ;
        }
        
        # Collect all main targets here, except for "explicit" ones.
        for local t in $(self.main-targets)
        {
            if ! [ $(t).name ] in $(self.explicit-targets)
            {                    
                result += $(t) ;
            }
        }

        # Collect all projects referenced via "projects-to-build" attribute.
        local self-location = [ get location ] ;
        for local pn in [ get projects-to-build ]
        {
            local p = [ project.module-name [ path.join $(self-location) $(pn) ] ] ;
            result += [ project.target $(p) ] ;
        }
                        
        return $(result) ;
    }
    
    # Add 'target' to the list of targets in this project that should be build
    # only by explicit request
    rule mark-target-as-explicit ( target-name )
    {
        # Record the name of the target, not instance, since this
        # rule is called before main target instaces are created.
        self.explicit-targets += $(target-name) ;
    }
    
    # Add new target alternative
    rule add-alternative ( target-instance )
    {
        if $(self.built-main-targets)
        {
            errors.error "add-alternative called when main targets are already created." 
              : "in project" [ full-name ] ;
        }        
        self.alternatives += $(target-instance) ;
    }
    
            
    # Returns a 'main-target' class instance corresponding to the 'name'.
    rule main-target ( name )
    {
        if ! $(self.built-main-targets)
        {
            build-main-targets ;
        }
                        
        return $(self.main-target.$(name)) ;
    }

    # Tells if a main target with the specified name exists.
    rule has-main-target ( name )
    {
        if ! $(self.built-main-targets)
        {
            build-main-targets ;
        }
        
        if $(self.main-target.$(name)) 
        {
            return true ;
        } 
    }

    # Find and return the target with the specified id, treated
    # relative to self.
    rule find-really ( id )
    {
        local result ;    
        local project = $(self.project) ;
        local current-location = [ get location ] ;

⌨️ 快捷键说明

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