# Status: minor updates by Steven Watanabe to make gcc work
#
#  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.

""" Defines standard features and rules.
"""

import sys
from b2.build import feature, property, virtual_target, generators, type, property_set, scanner
from b2.util.utility import *
from b2.util import path, regex
import b2.tools.types
from b2.manager import get_manager

# Records explicit properties for a variant.
# The key is the variant name.
__variant_explicit_properties = {}

def reset ():
    """ Clear the module state. This is mainly for testing purposes.
    """
    global __variant_explicit_properties

    __variant_explicit_properties = {}

def variant (name, parents_or_properties, explicit_properties = []):
    """ Declares a new variant.
        First determines explicit properties for this variant, by
        refining parents' explicit properties with the passed explicit
        properties. The result is remembered and will be used if
        this variant is used as parent.
        
        Second, determines the full property set for this variant by
        adding to the explicit properties default values for all properties 
        which neither present nor are symmetric.
        
        Lastly, makes appropriate value of 'variant' property expand
        to the full property set.
        name:                   Name of the variant
        parents_or_properties:  Specifies parent variants, if 
                                'explicit_properties' are given,
                                and explicit_properties otherwise.
        explicit_properties:    Explicit properties.
    """
    parents = []
    if not explicit_properties:
        if get_grist (parents_or_properties [0]):
            explicit_properties = parents_or_properties

        else:
            parents = parents_or_properties

    else:
        parents = parents_or_properties

    # The problem is that we have to check for conflicts
    # between base variants.
    if len (parents) > 1:
        raise BaseException ("Multiple base variants are not yet supported")
    
    inherited = []
    # Add explicitly specified properties for parents
    for p in parents:
        # TODO: the check may be stricter
        if not feature.is_implicit_value (p):
            raise BaseException ("Invalid base varaint '%s'" % p)
        
        inherited += __variant_explicit_properties [p]

    property.validate (explicit_properties)
    explicit_properties = property.refine (inherited, explicit_properties)
    
    # Record explicitly specified properties for this variant
    # We do this after inheriting parents' properties, so that
    # they affect other variants, derived from this one.
    __variant_explicit_properties [name] = explicit_properties
           
    feature.extend('variant', [name])
    feature.compose (replace_grist (name, '<variant>'), explicit_properties)

__os_names = """
    amiga aix bsd cygwin darwin dos emx freebsd hpux iphone linux netbsd
    openbsd osf qnx qnxnto sgi solaris sun sunos svr4 sysv ultrix unix unixware
    vms windows
""".split()

# Translates from bjam current OS to the os tags used in host-os and target-os,
# i.e. returns the running host-os.
#
def default_host_os():
    host_os = os_name()
    if host_os not in (x.upper() for x in __os_names):
        if host_os == 'NT': host_os = 'windows'
        elif host_os == 'AS400': host_os = 'unix'
        elif host_os == 'MINGW': host_os = 'windows'
        elif host_os == 'BSDI': host_os = 'bsd'
        elif host_os == 'COHERENT': host_os = 'unix'
        elif host_os == 'DRAGONFLYBSD': host_os = 'bsd'
        elif host_os == 'IRIX': host_os = 'sgi'
        elif host_os == 'MACOSX': host_os = 'darwin'
        elif host_os == 'KFREEBSD': host_os = 'freebsd'
        elif host_os == 'LINUX': host_os = 'linux'
        else: host_os = 'unix'
    return host_os.lower()

def register_globals ():
    """ Registers all features and variants declared by this module.
    """

    # This feature is used to determine which OS we're on.
    # In future, this may become <target-os> and <host-os>
    # TODO: check this. Compatibility with bjam names? Subfeature for version?
    os = sys.platform
    feature.feature ('os', [os], ['propagated', 'link-incompatible'])


    # The two OS features define a known set of abstract OS names. The host-os is
    # the OS under which bjam is running. Even though this should really be a fixed
    # property we need to list all the values to prevent unknown value errors. Both
    # set the default value to the current OS to account for the default use case of
    # building on the target OS.
    feature.feature('host-os', __os_names)
    feature.set_default('host-os', default_host_os())

    feature.feature('target-os', __os_names, ['propagated', 'link-incompatible'])
    feature.set_default('target-os', default_host_os())
    
    feature.feature ('toolset', [], ['implicit', 'propagated' ,'symmetric'])
    
    feature.feature ('stdlib', ['native'], ['propagated', 'composite'])
    
    feature.feature ('link', ['shared', 'static'], ['propagated'])
    feature.feature ('runtime-link', ['shared', 'static'], ['propagated'])
    feature.feature ('runtime-debugging', ['on', 'off'], ['propagated'])
    
    
    feature.feature ('optimization',  ['off', 'speed', 'space'], ['propagated'])
    feature.feature ('profiling', ['off', 'on'], ['propagated'])
    feature.feature ('inlining', ['off', 'on', 'full'], ['propagated'])
    
    feature.feature ('threading', ['single', 'multi'], ['propagated'])
    feature.feature ('rtti', ['on', 'off'], ['propagated'])
    feature.feature ('exception-handling', ['on', 'off'], ['propagated'])
    feature.feature ('debug-symbols', ['on', 'off'], ['propagated'])
    feature.feature ('define', [], ['free'])
    feature.feature ('include', [], ['free', 'path']) #order-sensitive
    feature.feature ('cflags', [], ['free'])
    feature.feature ('cxxflags', [], ['free'])
    feature.feature ('linkflags', [], ['free'])
    feature.feature ('archiveflags', [], ['free'])
    feature.feature ('version', [], ['free'])
    
    feature.feature ('location-prefix', [], ['free'])

    feature.feature ('action', [], ['free'])

    
    # The following features are incidental, since
    # in themself they have no effect on build products.
    # Not making them incidental will result in problems in corner
    # cases, for example:
    # 
    #    unit-test a : a.cpp : <use>b ;
    #    lib b : a.cpp b ;
    # 
    # Here, if <use> is not incidental, we'll decide we have two 
    # targets for a.obj with different properties, and will complain.
    #
    # Note that making feature incidental does not mean it's ignored. It may
    # be ignored when creating the virtual target, but the rest of build process
    # will use them.
    feature.feature ('use', [], ['free', 'dependency', 'incidental'])
    feature.feature ('dependency', [], ['free', 'dependency', 'incidental'])
    feature.feature ('implicit-dependency', [], ['free', 'dependency', 'incidental'])

    feature.feature('warnings', [
        'on',         # Enable default/"reasonable" warning level for the tool.
        'all',        # Enable all possible warnings issued by the tool.
        'off'],       # Disable all warnings issued by the tool.
        ['incidental', 'propagated'])

    feature.feature('warnings-as-errors', [
        'off',        # Do not fail the compilation if there are warnings.
        'on'],        # Fail the compilation if there are warnings.
        ['incidental', 'propagated'])
    
    feature.feature ('source', [], ['free', 'dependency', 'incidental'])
    feature.feature ('library', [], ['free', 'dependency', 'incidental'])
    feature.feature ('file', [], ['free', 'dependency', 'incidental'])
    feature.feature ('find-shared-library', [], ['free']) #order-sensitive ;
    feature.feature ('find-static-library', [], ['free']) #order-sensitive ;
    feature.feature ('library-path', [], ['free', 'path']) #order-sensitive ;
    # Internal feature.
    feature.feature ('library-file', [], ['free', 'dependency'])
    
    feature.feature ('name', [], ['free'])
    feature.feature ('tag', [], ['free'])
    feature.feature ('search', [], ['free', 'path']) #order-sensitive ;
    feature.feature ('location', [], ['free', 'path'])
    
    feature.feature ('dll-path', [], ['free', 'path'])
    feature.feature ('hardcode-dll-paths', ['true', 'false'], ['incidental'])
    
    
    # This is internal feature which holds the paths of all dependency
    # dynamic libraries. On Windows, it's needed so that we can all
    # those paths to PATH, when running applications.
    # On Linux, it's needed to add proper -rpath-link command line options.
    feature.feature ('xdll-path', [], ['free', 'path'])
    
    #provides means to specify def-file for windows dlls.
    feature.feature ('def-file', [], ['free', 'dependency'])
    
    # This feature is used to allow specific generators to run.
    # For example, QT tools can only be invoked when QT library
    # is used. In that case, <allow>qt will be in usage requirement
    # of the library.
    feature.feature ('allow', [], ['free'])
    
    # The addressing model to generate code for. Currently a limited set only
    # specifying the bit size of pointers.
    feature.feature('address-model', ['16', '32', '64'], ['propagated', 'optional'])

    # Type of CPU architecture to compile for.
    feature.feature('architecture', [
        # x86 and x86-64
        'x86',

        # ia64
        'ia64',

        # Sparc
        'sparc',

        # RS/6000 & PowerPC
        'power',

        # MIPS/SGI
        'mips1', 'mips2', 'mips3', 'mips4', 'mips32', 'mips32r2', 'mips64',

        # HP/PA-RISC
        'parisc',
        
        # Advanced RISC Machines
        'arm',

        # Combined architectures for platforms/toolsets that support building for
        # multiple architectures at once. "combined" would be the default multi-arch
        # for the toolset.
        'combined',
        'combined-x86-power'],

        ['propagated', 'optional'])

    # The specific instruction set in an architecture to compile.
    feature.feature('instruction-set', [
        # x86 and x86-64
        'i386', 'i486', 'i586', 'i686', 'pentium', 'pentium-mmx', 'pentiumpro', 'pentium2', 'pentium3',
        'pentium3m', 'pentium-m', 'pentium4', 'pentium4m', 'prescott', 'nocona', 'conroe', 'conroe-xe',
        'conroe-l', 'allendale', 'mermon', 'mermon-xe', 'kentsfield', 'kentsfield-xe', 'penryn', 'wolfdale',
        'yorksfield', 'nehalem', 'k6', 'k6-2', 'k6-3', 'athlon', 'athlon-tbird', 'athlon-4', 'athlon-xp',
        'athlon-mp', 'k8', 'opteron', 'athlon64', 'athlon-fx', 'winchip-c6', 'winchip2', 'c3', 'c3-2',

        # ia64
        'itanium', 'itanium1', 'merced', 'itanium2', 'mckinley',

        # Sparc
        'v7', 'cypress', 'v8', 'supersparc', 'sparclite', 'hypersparc', 'sparclite86x', 'f930', 'f934',
        'sparclet', 'tsc701', 'v9', 'ultrasparc', 'ultrasparc3',

        # RS/6000 & PowerPC
        '401', '403', '405', '405fp', '440', '440fp', '505', '601', '602',
        '603', '603e', '604', '604e', '620', '630', '740', '7400',
        '7450', '750', '801', '821', '823', '860', '970', '8540',
        'power-common', 'ec603e', 'g3', 'g4', 'g5', 'power', 'power2',
        'power3', 'power4', 'power5', 'powerpc', 'powerpc64', 'rios',
        'rios1', 'rsc', 'rios2', 'rs64a',

        # MIPS
        '4kc', '4kp', '5kc', '20kc', 'm4k', 'r2000', 'r3000', 'r3900', 'r4000',
        'r4100', 'r4300', 'r4400', 'r4600', 'r4650',
        'r6000', 'r8000', 'rm7000', 'rm9000', 'orion', 'sb1', 'vr4100',
        'vr4111', 'vr4120', 'vr4130', 'vr4300',
        'vr5000', 'vr5400', 'vr5500',

        # HP/PA-RISC
        '700', '7100', '7100lc', '7200', '7300', '8000',
        
        # Advanced RISC Machines
        'armv2', 'armv2a', 'armv3', 'armv3m', 'armv4', 'armv4t', 'armv5',
        'armv5t', 'armv5te', 'armv6', 'armv6j', 'iwmmxt', 'ep9312'],

        ['propagated', 'optional'])
    
    # Windows-specific features
    feature.feature ('user-interface', ['console', 'gui', 'wince', 'native', 'auto'], [])
    feature.feature ('variant', [], ['implicit', 'composite', 'propagated', 'symmetric'])


    variant ('debug', ['<optimization>off', '<debug-symbols>on', '<inlining>off', '<runtime-debugging>on'])
    variant ('release', ['<optimization>speed', '<debug-symbols>off', '<inlining>full', 
                         '<runtime-debugging>off', '<define>NDEBUG'])
    variant ('profile', ['release'], ['<profiling>on', '<debug-symbols>on'])

    type.register ('H', ['h'])
    type.register ('HPP', ['hpp'], 'H')
    type.register ('C', ['c'])
    

reset ()
register_globals ()

class SearchedLibTarget (virtual_target.AbstractFileTarget):
    def __init__ (self, name, project, shared, real_name, search, action):
        virtual_target.AbstractFileTarget.__init__ (self, name, False, 'SEARCHED_LIB', project, action)
        
        self.shared_ = shared
        self.real_name_ = real_name
        if not self.real_name_:
            self.real_name_ = name
        self.search_ = search

    def shared (self):
        return self.shared_
    
    def real_name (self):
        return self.real_name_
    
    def search (self):
        return self.search_
        
    def actualize_location (self, target):
        project.manager ().engine ().add_not_file_target (target)
    
    def path (self):
        #FIXME: several functions rely on this not being None
        return ""


class CScanner (scanner.Scanner):
    def __init__ (self, includes):
        scanner.Scanner.__init__ (self)
    
        self.includes_ = includes

    def pattern (self):
        return r'#[ \t]*include[ ]*(<(.*)>|"(.*)")'

    def process (self, target, matches, binding):
       
        angle = regex.transform (matches, "<(.*)>")
        quoted = regex.transform (matches, '"(.*)"')

        g = str(id(self))
        b = os.path.normpath(os.path.dirname(binding[0]))
        
        # Attach binding of including file to included targets.
        # When target is directly created from virtual target
        # this extra information is unnecessary. But in other
        # cases, it allows to distinguish between two headers of the 
        # same name included from different places.      
        # We don't need this extra information for angle includes,
        # since they should not depend on including file (we can't
        # get literal "." in include path).
        g2 = g + "#" + b

        g = "<" + g + ">"
        g2 = "<" + g2 + ">"
        angle = [g + x for x in angle]
        quoted = [g2 + x for x in quoted]

        all = angle + quoted
        bjam.call("mark-included", target, all)

        engine = get_manager().engine()
        engine.set_target_variable(angle, "SEARCH", self.includes_)
        engine.set_target_variable(quoted, "SEARCH", self.includes_)
        
        # Just propagate current scanner to includes, in a hope
        # that includes do not change scanners. 
        get_manager().scanners().propagate(self, angle + quoted)
        
scanner.register (CScanner, 'include')
type.set_scanner ('CPP', CScanner)

# Ported to trunk@47077
class LibGenerator (generators.Generator):
    """ The generator class for libraries (target type LIB). Depending on properties it will
        request building of the approapriate specific type -- SHARED_LIB, STATIC_LIB or 
        SHARED_LIB.
    """

    def __init__(self, id = 'LibGenerator', composing = True, source_types = [], target_types_and_names = ['LIB'], requirements = []):
        generators.Generator.__init__(self, id, composing, source_types, target_types_and_names, requirements)
    
    def run(self, project, name, prop_set, sources):
        # The lib generator is composing, and can be only invoked with
        # explicit name. This check is present in generator.run (and so in
        # builtin.LinkingGenerator), but duplicate it here to avoid doing
        # extra work.
        if name:
            properties = prop_set.raw()
            # Determine the needed target type
            actual_type = None
            properties_grist = get_grist(properties)
            if '<source>' not in properties_grist  and \
               ('<search>' in properties_grist or '<name>' in properties_grist):
                actual_type = 'SEARCHED_LIB'
            elif '<file>' in properties_grist:
                # The generator for 
                actual_type = 'LIB'
            elif '<link>shared' in properties:
                actual_type = 'SHARED_LIB'
            else:
                actual_type = 'STATIC_LIB'

            prop_set = prop_set.add_raw(['<main-target-type>LIB'])

            # Construct the target.
            return generators.construct(project, name, actual_type, prop_set, sources)

    def viable_source_types(self):
        return ['*']

generators.register(LibGenerator())

### # The implementation of the 'lib' rule. Beyond standard syntax that rule allows
### # simplified:
### #    lib a b c ;
### # so we need to write code to handle that syntax. 
### rule lib ( names + : sources * : requirements * : default-build * 
###     : usage-requirements * )
### {
###     local project = [ project.current ] ;
###     
###     # This is a circular module dependency, so it must be imported here
###     import targets ;
### 
###     local result ;
###     if ! $(sources) && ! $(requirements) 
###       && ! $(default-build) && ! $(usage-requirements)
###     {
###         for local name in $(names)
###         {    
###             result += [ 
###             targets.main-target-alternative
###               [ new typed-target $(name) : $(project) : LIB 
###                 : 
###                 : [ targets.main-target-requirements $(requirements) <name>$(name)  :
###                     $(project) ] 
###                 : [ targets.main-target-default-build $(default-build) : $(project) ]
###                 : [ targets.main-target-usage-requirements $(usage-requirements) : $(project) ]
###              ] ] ;        
###         }        
###     }
###     else
###     {
###         if $(names[2])
###         {
###             errors.user-error "When several names are given to the 'lib' rule" :
###               "it's not allowed to specify sources or requirements. " ;
###         }
###                 
###         local name = $(names[1]) ;
###         result = [ targets.main-target-alternative
###           [ new typed-target $(name) : $(project) : LIB
###             : [ targets.main-target-sources $(sources) : $(name) ] 
###             : [ targets.main-target-requirements $(requirements) : $(project) ] 
###             : [ targets.main-target-default-build $(default-build) : $(project) ]
###             : [ targets.main-target-usage-requirements $(usage-requirements) : $(project) ]
###          ] ] ;
###     }    
###     return $(result) ;
### }
### IMPORT $(__name__) : lib : : lib ;

# Updated to trunk@47077
class SearchedLibGenerator (generators.Generator):
    def __init__ (self, id = 'SearchedLibGenerator', composing = False, source_types = [], target_types_and_names = ['SEARCHED_LIB'], requirements = []):
        # TODO: the comment below looks strange. There are no requirements!
        # 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 SearchedLibGenerator is not invoked deep in transformation
        # search.
        generators.Generator.__init__ (self, id, composing, source_types, target_types_and_names, requirements)
    
    def run(self, project, name, prop_set, sources):
        if not name:
            return None

        # If name is empty, it means we're called not from top-level.
        # In this case, we just fail immediately, because SearchedLibGenerator
        # cannot be used to produce intermediate targets.
        
        properties = prop_set.raw ()
        shared = '<link>shared' in properties

        a = virtual_target.NullAction (project.manager(), prop_set)
        
        real_name = feature.get_values ('<name>', properties)
        if real_name:
            real_name = real_name[0]
        else:
            real_nake = name
        search = feature.get_values('<search>', properties)
        usage_requirements = property_set.create(['<xdll-path>' + p for p in search])
        t = SearchedLibTarget(name, project, shared, real_name, search, 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(usage_requirements, [b2.manager.get_manager().virtual_targets().register(t)] + sources)

generators.register (SearchedLibGenerator ())

### class prebuilt-lib-generator : generator
### {
###     rule __init__ ( * : * )
###     {
###         generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
###     }
### 
###     rule run ( project name ? : prop_set : sources * : multiple ? )
###     {
###         local f = [ $(prop_set).get <file> ] ;
###         return $(f) $(sources) ;
###     }    
### }
### 
### generators.register 
###   [ new prebuilt-lib-generator builtin.prebuilt : : LIB : <file> ] ;


class CompileAction (virtual_target.Action):
    def __init__ (self, manager, sources, action_name, prop_set):
        virtual_target.Action.__init__ (self, manager, sources, action_name, prop_set)

    def adjust_properties (self, prop_set):
        """ 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.
        """
        s = self.targets () [0].creating_subvariant ()

        return prop_set.add_raw (s.implicit_includes ('include', 'H'))

class CCompilingGenerator (generators.Generator):
    """ Declare a special compiler generator.
        The only thing it does is changing the type used to represent
        'action' in the constructed dependency graph to 'CompileAction'.
        That class in turn adds additional include paths to handle a case
        when a source file includes headers which are generated themselfs.
    """
    def __init__ (self, id, composing, source_types, target_types_and_names, requirements):
        # TODO: (PF) What to do with optional_properties? It seemed that, in the bjam version, the arguments are wrong.
        generators.Generator.__init__ (self, id, composing, source_types, target_types_and_names, requirements)
            
    def action_class (self):
        return CompileAction

def register_c_compiler (id, source_types, target_types, requirements, optional_properties = []):
    g = CCompilingGenerator (id, False, source_types, target_types, requirements + optional_properties)
    return generators.register (g)


class LinkingGenerator (generators.Generator):
    """ The generator class for handling EXE and SHARED_LIB creation.
    """
    def __init__ (self, id, composing, source_types, target_types_and_names, requirements):
        generators.Generator.__init__ (self, id, composing, source_types, target_types_and_names, requirements)
        
    def run (self, project, name, prop_set, sources):
        lib_sources = prop_set.get('<library>')
        [ sources.append (project.manager().get_object(x)) for x in lib_sources ]
        
        # Add <library-path> properties for all searched libraries
        extra = []
        for s in sources:
            if s.type () == 'SEARCHED_LIB':
                search = s.search()
                extra.append(replace_grist(search, '<library-path>'))

        orig_xdll_path = []
                   
        if prop_set.get('<hardcode-dll-paths>') == ['true'] and type.is_derived(self.target_types_ [0], 'EXE'):
            xdll_path = prop_set.get('<xdll-path>')
            orig_xdll_path = [ replace_grist(x, '<dll-path>') for x in 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 s in sources:
                if type.is_derived (s.type (), 'SHARED_LIB') and not s.action ():
                    # Unfortunately, we don't have a good way to find the path
                    # to a file, so use this nasty approach.
                    p = s.project()
                    location = path.root(s.name(), p.get('source-location'))
                    xdll_path.append(path.parent(location))
                          
            extra += [ replace_grist(x, '<dll-path>') for x in xdll_path ]
        
        if extra:
            prop_set = prop_set.add_raw (extra)
                        
        result = generators.Generator.run(self, project, name, prop_set, sources)

        if result:
            ur = self.extra_usage_requirements(result, prop_set)
            ur = ur.add(property_set.create(orig_xdll_path))
        else:
            return None
        
        return(ur, result)
    
    def extra_usage_requirements (self, created_targets, prop_set):
        
        result = property_set.empty ()
        extra = []
                        
        # Add appropriate <xdll-path> usage requirements.
        raw = prop_set.raw ()
        if '<link>shared' in raw:
            paths = []
            
            # TODO: is it safe to use the current directory? I think we should use 
            # another mechanism to allow this to be run from anywhere.
            pwd = os.getcwd()
            
            for t in created_targets:
                if type.is_derived(t.type(), 'SHARED_LIB'):
                    paths.append(path.root(path.make(t.path()), pwd))

            extra += replace_grist(paths, '<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.                
        values = prop_set.get('<xdll-path>')
        extra += replace_grist(values, '<xdll-path>')
        
        if extra:
            result = property_set.create(extra)

        return result

    def generated_targets (self, sources, prop_set, project, name):

        # sources to pass to inherited rule
        sources2 = []
        # properties to pass to inherited rule
        properties2  = []
        # sources which are libraries
        libraries  = []
        
        # Searched libraries are not passed as argument to linker
        # but via some option. So, we pass them to the action
        # via property. 
        properties2 = prop_set.raw()
        fsa = []
        fst = []
        for s in sources:
            if type.is_derived(s.type(), 'SEARCHED_LIB'):
                name = s.real_name()
                if s.shared():
                    fsa.append(name)

                else:
                    fst.append(name)

            else:
                sources2.append(s)

        if fsa:
            properties2 += [replace_grist('&&'.join(fsa), '<find-shared-library>')]
        if fst:
            properties2 += [replace_grist('&&'.join(fst), '<find-static-library>')]
                
        spawn = generators.Generator.generated_targets(self, sources2, property_set.create(properties2), project, name)
        
        return spawn


def register_linker(id, source_types, target_types, requirements):
    g = LinkingGenerator(id, True, source_types, target_types, requirements)
    generators.register(g)

class ArchiveGenerator (generators.Generator):
    """ The generator class for handling STATIC_LIB creation.
    """
    def __init__ (self, id, composing, source_types, target_types_and_names, requirements):
        generators.Generator.__init__ (self, id, composing, source_types, target_types_and_names, requirements)
        
    def run (self, project, name, prop_set, sources):
        sources += prop_set.get ('<library>')
        
        result = generators.Generator.run (self, project, name, prop_set, sources)
             
        return result

### rule register-archiver ( id composing ? : source_types + : target_types + :
###                             requirements * )
### {
###     local g = [ new ArchiveGenerator $(id) $(composing) : $(source_types) 
###                 : $(target_types) : $(requirements) ] ;
###     generators.register $(g) ;
### }
### 
### 
### IMPORT $(__name__) : register-linker register-archiver 
###   : : generators.register-linker generators.register-archiver ;
### 
### 
### 
