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

📄 builtin.jam

📁 C++的一个好库。。。现在很流行
💻 JAM
📖 第 1 页 / 共 2 页
字号:
        {
            errors.user-error "When several names are given to the 'lib' rule" :
              "it's not allowed to specify sources. " ;
        }        
    }
    
    for local name in $(names)
    {    
        local r = $(requirements) ;
        if $(names[2])
        {
            r += <name>$(name) ;
        }        
        result += [ targets.main-target-alternative
          [ new typed-target $(name) : $(project) : LIB
            : [ targets.main-target-sources $(sources) : $(name) ] 
            : [ targets.main-target-requirements $(r) : $(project) ] 
            : [ targets.main-target-default-build $(default-build) : $(project) ]
            : [ targets.main-target-usage-requirements $(usage-requirements) : $(project) ]
         ] ] ;
    }    
    return $(result) ;
}
IMPORT $(__name__) : lib : : lib ;

class searched-lib-generator : generator
{
    import property-set ;
    
    rule __init__ ( )
    {
        # The requirements cause the generators to be tried *only* when we're building
        # lib target and there's 'search' feature. This seems ugly --- all we want
        # is make sure searched-lib-generator is not invoced deep in transformation
        # search.
        generator.__init__ searched-lib-generator : : SEARCHED_LIB ;
    }
    
    rule run ( project name ? : property-set : sources * )
    {
        if $(name)
        {
            # If name is empty, it means we're called not from top-level.
            # In this case, we just fail immediately, because searched-lib-generator
            # cannot be used to produce intermediate targets.
            
            local properties = [ $(property-set).raw ] ;        
            local shared ;
            if <link>shared in $(properties)
            {
                shared = true ;
            }        

            a = [ new null-action $(property-set) ] ;
            local t = [ new searched-lib-target $(name) : $(project) : $(shared)
                            : [ feature.get-values <name> : $(properties) ]
                            : [ feature.get-values <search> : $(properties) ]
                            : $(a)
                      ] ;
            # We return sources for a simple reason. If there's
            #    lib png : z : <name>png ; 
            # the 'z' target should be returned, so that apps linking to
            # 'png' will link to 'z', too.
            return [ virtual-target.register $(t) ] $(sources) ;
        }
    }        
}

generators.register [ new searched-lib-generator ] ;

class prebuilt-lib-generator : generator
{
    rule __init__ ( * : * )
    {
        generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
    }

    rule run ( project name ? : property-set : sources * )
    {
        local f = [ $(property-set).get <file> ] ;
        return $(f) $(sources) ;
    }    
}

generators.register 
  [ new prebuilt-lib-generator builtin.prebuilt : : LIB : <file> ] ;

generators.override builtin.lib-generator : builtin.prebuilt ;

    
class compile-action : action 
{
    import sequence ;
    
    rule __init__ ( targets * : sources * : action-name : properties * )
    {
        action.__init__ $(targets) : $(sources) : $(action-name) : $(properties) ;
    }
   
    
    # For all virtual targets for the same dependency graph as self, 
    # i.e. which belong to the same main target, add their directories
    # to include path.
    rule adjust-properties ( property-set )
    {        
        local s = [ $(self.targets[1]).creating-subvariant ] ;
        return [ $(property-set).add-raw 
          [ $(s).implicit-includes "include" : H ] ] ;
    }    
}

# Declare a special compiler generator.
# The only thing it does is changing the type used to represent
# 'action' in the constructed dependency graph to 'compile-action'.
# That class in turn adds additional include paths to handle a case
# when a source file includes headers which are generated themselfs.
class C-compiling-generator : generator
{
    rule __init__ ( id : source-types + : target-types + :
        requirements * : optional-properties * )
    {
        generator.__init__ $(id) : $(source-types) : $(target-types) :
          $(requirements) : $(optional-properties) ;
    }
            
    rule action-class ( )
    {
        return compile-action ;
    }
}

rule register-c-compiler ( id : source-types + : target-types + :
                            requirements * : optional-properties * )
{
    local g = [ new C-compiling-generator $(id) : $(source-types) 
                : $(target-types) : $(requirements) : $(optional-properties) ] ;
    generators.register $(g) ;
}

# FIXME: this is ugly, should find a better way (we'd want client code to
# register all generators as "generator.some-rule", not with "some-module.some-rule".)
IMPORT $(__name__) : register-c-compiler : : generators.register-c-compiler ;

# The generator class for handling EXE and SHARED_LIB creation.
class linking-generator : generator
{
    import property-set ;
    import type ;
    import path ;
    import project ;
    
    rule __init__ ( id 
        composing ? : # Specify if generator is composing. The generator will be
        # composing if non-empty string is passed, or parameter is
        # not given. To make generator non-composing, pass empty
        # string ("")
        source-types + : target-types + : 
        requirements * )
    {
        composing ?= true ;
        generator.__init__ $(id) $(composing) : $(source-types) : $(target-types) :
          $(requirements) ;
    }
        
    rule run ( project name ? : property-set : sources + )
    {   
        sources += [ $(property-set).get <library>  ] ;        
        
        # Add <library-path> properties for all searched libraries
        local extra ;
        for local s in $(sources)
        {
            if [ $(s).type ] = SEARCHED_LIB
            {
                local search = [ $(s).search ] ;
                extra += <library-path>$(search) ;
            }
        }

        # Hardcode dll paths only when linking executables.
        # Pros: don't need to relinking libraries when installing.
        # Cons: "standalone" libraries (plugins, python extensions)
        # can't hardcode paths to dependent libraries.
        if [ $(property-set).get <hardcode-dll-paths> ] = true
         && [ type.is-derived $(self.target-types[1]) EXE ] 
        {
            local xdll-path = [ $(property-set).get <xdll-path> ] ;
            # It's possible that we have libraries in sources which did not came
            # from 'lib' target. For example, libraries which are specified
            # just as filenames as sources. We don't have xdll-path properties
            # for such target, but still need to add proper dll-path properties.
            for local s in $(sources)
            {
                if [ type.is-derived [ $(s).type ] SHARED_LIB ] && ! [ $(s).action ] 
                {
                    # Unfortunately, we don't have a good way to find the path
                    # to a file, so use this nasty approach.
                    local p = [ $(s).project ] ;
                    local location = [ path.root [ $(s).name ]
                      [ $(p).get source-location ] ] ;
                    xdll-path += [ path.parent $(location) ] ;
                }                
            }
                          
            extra += <dll-path>$(xdll-path) ;
        }
        
        if $(extra)
        {
            property-set = [ $(property-set).add-raw $(extra) ] ;
        }            
                        
        local result = [ generator.run $(project) $(name) : $(property-set)
          : $(sources) ] ;
                        
        return [ extra-usage-requirements $(result) : $(property-set) ] 
               $(result) ;
    }
    
    rule extra-usage-requirements ( created-targets * : property-set )
    {           
        local result = [ property-set.empty ] ;        
        local extra ;
                        
        # Add appropricate <xdll-path> usage requirements.
        local raw = [ $(property-set).raw ] ;
        if <link>shared in $(raw)
        {
            local paths ;
            local pwd = [ path.pwd ] ;
            for local t in $(created-targets)
            {
                if [ type.is-derived [ $(t).type ] SHARED_LIB ] 
                {
                    paths += [ path.root [ path.make [ $(t).path ] ] $(pwd) ] ;
                }                                
            }       
            extra += $(paths:G=<xdll-path>) ;
        }
        
        # We need to pass <xdll-path> features that we've got from sources,
        # because if shared library is built, exe which uses it must know paths
        # to other shared libraries this one depends on, to be able to find them
        # all at runtime.
                        
        # Just pass all features in property-set, it's theorically possible
        # that we'll propagate <xdll-path> features explicitly specified by
        # the user, but then the user's to blaim for using internal feature.                
        local values = [ $(property-set).get <xdll-path> ] ;
        extra += $(values:G=<xdll-path>) ;
               
        if $(extra)
        {
            result = [ property-set.create $(extra) ] ;
        }
        return $(result) ;
    }
        
    rule generated-targets ( sources + : property-set : project name ? )
    {
        local sources2 ;     # sources to pass to inherited rule
        local properties2 ;  # properties to pass to inherited rule
        local libraries ;    # sources which are libraries
        
        # Searched libraries are not passed as argument to linker
        # but via some option. So, we pass them to the action
        # via property. 
        properties2 = [ $(property-set).raw ] ;
        local fsa ;
        local fst ;
        for local s in $(sources)
        {
            if [ type.is-derived [ $(s).type ] SEARCHED_LIB ]
            {
                local name = [ $(s).real-name ] ;
                if [ $(s).shared ] 
                {                    
                    fsa +=  $(name) ;
                }
                else
                {
                    fst += $(name) ;
                }                         
            }
            else
            {
                sources2 += $(s) ;
            }
        }
        properties2 += <find-shared-library>$(fsa:J=&&) 
                       <find-static-library>$(fst:J=&&) ;
                
        local spawn = [ generator.generated-targets $(sources2)
          : [ property-set.create $(properties2) ] : $(project) $(name) ] ;
        
        return $(spawn) ;
    }
}                             

rule register-linker ( id composing ? : source-types + : target-types + :
                            requirements * )
{
    local g = [ new linking-generator $(id) $(composing) : $(source-types) 
                : $(target-types) : $(requirements) ] ;
    generators.register $(g) ;
}

# The generator class for handling STATIC_LIB creation.
class archive-generator : generator
{
    import property-set ; 

    rule __init__ ( id composing ? : source-types + : target-types + : 
        requirements * )
    {
        composing ?= true ;
        generator.__init__ $(id) $(composing) : $(source-types) : $(target-types) :
          $(requirements) ;
    }
        
    rule run ( project name ? : property-set : sources + )
    {                                
        sources += [ $(property-set).get <library>  ] ;                
        
        local result = [ generator.run $(project) $(name) : $(property-set)
          : $(sources) ] ;
        
        # For static linking, if we get a library in source, we can't
        # directly link to it. So, we need to cause our dependencies 
        # to link to that library. There are two approaches:
        # - adding the library to the list of returned targets.
        # - using the <library> usage requirements.
        # The problem with the first is:
        # 
        #     lib a1 : : <file>liba1.a ;
        #     lib a2 : a2.cpp a1 : <link>static ;
        #     install dist : a2 ;
        #
        # here we'll try to install 'a1', even though it's not necessary in
        # the general case.
        # With the second approaches, even indirect dependents will link to
        # the library, but it should not cause any harm.
        # So, return all LIB sources together with created targets,
        # so that dependents link to them.
        local usage-requirements ;
        if [ $(property-set).get <link> ] = static
        {
            for local t in $(sources)
            {
                if [ type.is-derived [ $(t).type ] LIB ]
                {
                    usage-requirements += <library>$(t) ;
                }                
            }            
        }
                
        usage-requirements = [ property-set.create $(usage-requirements) ] ;
                                
        return $(usage-requirements) $(result) ;
    }    
}

rule register-archiver ( id composing ? : source-types + : target-types + :
                            requirements * )
{
    local g = [ new archive-generator $(id) $(composing) : $(source-types) 
                : $(target-types) : $(requirements) ] ;
    generators.register $(g) ;
}


IMPORT $(__name__) : register-linker register-archiver 
  : : generators.register-linker generators.register-archiver ;



⌨️ 快捷键说明

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