1# Copyright (c) 2004 Vladimir Prus. 2# 3# Use, modification and distribution is subject to the Boost Software 4# License Version 1.0. (See accompanying file LICENSE_1_0.txt or 5# http://www.boost.org/LICENSE_1_0.txt) 6 7""" This file implements linking semantics common to all unixes. On unix, static 8 libraries must be specified in a fixed order on the linker command line. Generators 9 declared there store information about the order and use it properly. 10""" 11 12import builtin 13from b2.build import generators, type 14from b2.util.utility import * 15from b2.util import set, sequence 16 17class UnixLinkingGenerator (builtin.LinkingGenerator): 18 19 def __init__ (self, id, composing, source_types, target_types, requirements): 20 builtin.LinkingGenerator.__init__ (self, id, composing, source_types, target_types, requirements) 21 22 def run (self, project, name, prop_set, sources): 23 result = builtin.LinkingGenerator.run (self, project, name, prop_set, sources) 24 if result: 25 set_library_order (project.manager (), sources, prop_set, result [1]) 26 27 return result 28 29 def generated_targets (self, sources, prop_set, project, name): 30 sources2 = [] 31 libraries = [] 32 for l in sources: 33 if type.is_derived (l.type (), 'LIB'): 34 libraries.append (l) 35 36 else: 37 sources2.append (l) 38 39 sources = sources2 + order_libraries (libraries) 40 41 return builtin.LinkingGenerator.generated_targets (self, sources, prop_set, project, name) 42 43 44class UnixArchiveGenerator (builtin.ArchiveGenerator): 45 def __init__ (self, id, composing, source_types, target_types_and_names, requirements): 46 builtin.ArchiveGenerator.__init__ (self, id, composing, source_types, target_types_and_names, requirements) 47 48 def run (self, project, name, prop_set, sources): 49 result = builtin.ArchiveGenerator.run(self, project, name, prop_set, sources) 50 set_library_order(project.manager(), sources, prop_set, result) 51 return result 52 53class UnixSearchedLibGenerator (builtin.SearchedLibGenerator): 54 55 def __init__ (self): 56 builtin.SearchedLibGenerator.__init__ (self) 57 58 def optional_properties (self): 59 return self.requirements () 60 61 def run (self, project, name, prop_set, sources): 62 result = SearchedLibGenerator.run (project, name, prop_set, sources) 63 64 set_library_order (sources, prop_set, result) 65 66 return result 67 68class UnixPrebuiltLibGenerator (generators.Generator): 69 def __init__ (self, id, composing, source_types, target_types_and_names, requirements): 70 generators.Generator.__init__ (self, id, composing, source_types, target_types_and_names, requirements) 71 72 def run (self, project, name, prop_set, sources): 73 f = prop_set.get ('<file>') 74 set_library_order_aux (f, sources) 75 return f + sources 76 77### # The derived toolset must specify their own rules and actions. 78# FIXME: restore? 79# action.register ('unix.prebuilt', None, None) 80 81 82generators.register (UnixPrebuiltLibGenerator ('unix.prebuilt', False, [], ['LIB'], ['<file>', '<toolset>unix'])) 83 84 85 86 87 88### # Declare generators 89### generators.register [ new UnixLinkingGenerator unix.link : LIB OBJ : EXE 90### : <toolset>unix ] ; 91generators.register (UnixArchiveGenerator ('unix.archive', True, ['OBJ'], ['STATIC_LIB'], ['<toolset>unix'])) 92 93### generators.register [ new UnixLinkingGenerator unix.link.dll : LIB OBJ : SHARED_LIB 94### : <toolset>unix ] ; 95### 96### generators.register [ new UnixSearchedLibGenerator 97### unix.SearchedLibGenerator : : SEARCHED_LIB : <toolset>unix ] ; 98### 99### 100### # The derived toolset must specify their own actions. 101### actions link { 102### } 103### 104### actions link.dll { 105### } 106 107def unix_archive (manager, targets, sources, properties): 108 pass 109 110# FIXME: restore? 111#action.register ('unix.archive', unix_archive, ['']) 112 113### actions searched-lib-generator { 114### } 115### 116### actions prebuilt { 117### } 118 119 120from b2.util.order import Order 121__order = Order () 122 123def set_library_order_aux (from_libs, to_libs): 124 for f in from_libs: 125 for t in to_libs: 126 if f != t: 127 __order.add_pair (f, t) 128 129def set_library_order (manager, sources, prop_set, result): 130 used_libraries = [] 131 deps = prop_set.dependency () 132 133 sources.extend(d.value() for d in deps) 134 sources = sequence.unique(sources) 135 136 for l in sources: 137 if l.type () and type.is_derived (l.type (), 'LIB'): 138 used_libraries.append (l) 139 140 created_libraries = [] 141 for l in result: 142 if l.type () and type.is_derived (l.type (), 'LIB'): 143 created_libraries.append (l) 144 145 created_libraries = set.difference (created_libraries, used_libraries) 146 set_library_order_aux (created_libraries, used_libraries) 147 148def order_libraries (libraries): 149 return __order.order (libraries) 150 151