blob: 025391d2d8dd32a800af8d6dd432083329d7f455 [file] [log] [blame]
# Copyright (c) 2004 Vladimir Prus.
#
# Use, modification and distribution is subject to the Boost Software
# License Version 1.0. (See accompanying file LICENSE_1_0.txt or
# http://www.boost.org/LICENSE_1_0.txt)
""" This file implements linking semantics common to all unixes. On unix, static
libraries must be specified in a fixed order on the linker command line. Generators
declared there store information about the order and use it properly.
"""
import builtin
from b2.build import generators, type
from b2.util.utility import *
from b2.util import set, sequence
class UnixLinkingGenerator (builtin.LinkingGenerator):
def __init__ (self, id, composing, source_types, target_types, requirements):
builtin.LinkingGenerator.__init__ (self, id, composing, source_types, target_types, requirements)
def run (self, project, name, prop_set, sources):
result = builtin.LinkingGenerator.run (self, project, name, prop_set, sources)
if result:
set_library_order (project.manager (), sources, prop_set, result [1])
return result
def generated_targets (self, sources, prop_set, project, name):
sources2 = []
libraries = []
for l in sources:
if type.is_derived (l.type (), 'LIB'):
libraries.append (l)
else:
sources2.append (l)
sources = sources2 + order_libraries (libraries)
return builtin.LinkingGenerator.generated_targets (self, sources, prop_set, project, name)
class UnixArchiveGenerator (builtin.ArchiveGenerator):
def __init__ (self, id, composing, source_types, target_types_and_names, requirements):
builtin.ArchiveGenerator.__init__ (self, id, composing, source_types, target_types_and_names, requirements)
def run (self, project, name, prop_set, sources):
result = builtin.ArchiveGenerator.run(self, project, name, prop_set, sources)
set_library_order(project.manager(), sources, prop_set, result)
return result
class UnixSearchedLibGenerator (builtin.SearchedLibGenerator):
def __init__ (self):
builtin.SearchedLibGenerator.__init__ (self)
def optional_properties (self):
return self.requirements ()
def run (self, project, name, prop_set, sources, multiple):
result = SearchedLibGenerator.run (project, name, prop_set, sources, multiple)
set_library_order (sources, prop_set, result)
return result
class UnixPrebuiltLibGenerator (generators.Generator):
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, multiple):
f = prop_set.get ('<file>')
set_library_order_aux (f, sources)
return (f, sources)
### # The derived toolset must specify their own rules and actions.
# FIXME: restore?
# action.register ('unix.prebuilt', None, None)
generators.register (UnixPrebuiltLibGenerator ('unix.prebuilt', False, [], ['LIB'], ['<file>', '<toolset>unix']))
### # Declare generators
### generators.register [ new UnixLinkingGenerator unix.link : LIB OBJ : EXE
### : <toolset>unix ] ;
generators.register (UnixArchiveGenerator ('unix.archive', True, ['OBJ'], ['STATIC_LIB'], ['<toolset>unix']))
### generators.register [ new UnixLinkingGenerator unix.link.dll : LIB OBJ : SHARED_LIB
### : <toolset>unix ] ;
###
### generators.register [ new UnixSearchedLibGenerator
### unix.SearchedLibGenerator : : SEARCHED_LIB : <toolset>unix ] ;
###
###
### # The derived toolset must specify their own actions.
### actions link {
### }
###
### actions link.dll {
### }
def unix_archive (manager, targets, sources, properties):
pass
# FIXME: restore?
#action.register ('unix.archive', unix_archive, [''])
### actions searched-lib-generator {
### }
###
### actions prebuilt {
### }
from b2.util.order import Order
__order = Order ()
def set_library_order_aux (from_libs, to_libs):
for f in from_libs:
for t in to_libs:
if f != t:
__order.add_pair (f, t)
def set_library_order (manager, sources, prop_set, result):
used_libraries = []
deps = prop_set.dependency ()
[ sources.append (manager.get_object (get_value (x))) for x in deps ]
sources = sequence.unique (sources)
for l in sources:
if l.type () and type.is_derived (l.type (), 'LIB'):
used_libraries.append (l)
created_libraries = []
for l in result:
if l.type () and type.is_derived (l.type (), 'LIB'):
created_libraries.append (l)
created_libraries = set.difference (created_libraries, used_libraries)
set_library_order_aux (created_libraries, used_libraries)
def order_libraries (libraries):
return __order.order (libraries)