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 from b2.build.property_set import PropertySet 50 result = builtin.ArchiveGenerator.run(self, project, name, prop_set, sources) 51 if result and isinstance(result[0], PropertySet): 52 _, targets = result 53 else: 54 targets = result 55 set_library_order(project.manager(), sources, prop_set, targets) 56 return result 57 58class UnixSearchedLibGenerator (builtin.SearchedLibGenerator): 59 60 def __init__ (self): 61 builtin.SearchedLibGenerator.__init__ (self) 62 63 def optional_properties (self): 64 return self.requirements () 65 66 def run (self, project, name, prop_set, sources): 67 result = SearchedLibGenerator.run (project, name, prop_set, sources) 68 69 set_library_order (sources, prop_set, result) 70 71 return result 72 73class UnixPrebuiltLibGenerator (generators.Generator): 74 def __init__ (self, id, composing, source_types, target_types_and_names, requirements): 75 generators.Generator.__init__ (self, id, composing, source_types, target_types_and_names, requirements) 76 77 def run (self, project, name, prop_set, sources): 78 f = prop_set.get ('<file>') 79 set_library_order_aux (f, sources) 80 return f + sources 81 82### # The derived toolset must specify their own rules and actions. 83# FIXME: restore? 84# action.register ('unix.prebuilt', None, None) 85 86 87generators.register (UnixPrebuiltLibGenerator ('unix.prebuilt', False, [], ['LIB'], ['<file>', '<toolset>unix'])) 88 89 90 91 92 93### # Declare generators 94### generators.register [ new UnixLinkingGenerator unix.link : LIB OBJ : EXE 95### : <toolset>unix ] ; 96generators.register (UnixArchiveGenerator ('unix.archive', True, ['OBJ'], ['STATIC_LIB'], ['<toolset>unix'])) 97 98### generators.register [ new UnixLinkingGenerator unix.link.dll : LIB OBJ : SHARED_LIB 99### : <toolset>unix ] ; 100### 101### generators.register [ new UnixSearchedLibGenerator 102### unix.SearchedLibGenerator : : SEARCHED_LIB : <toolset>unix ] ; 103### 104### 105### # The derived toolset must specify their own actions. 106### actions link { 107### } 108### 109### actions link.dll { 110### } 111 112def unix_archive (manager, targets, sources, properties): 113 pass 114 115# FIXME: restore? 116#action.register ('unix.archive', unix_archive, ['']) 117 118### actions searched-lib-generator { 119### } 120### 121### actions prebuilt { 122### } 123 124 125from b2.util.order import Order 126__order = Order () 127 128def set_library_order_aux (from_libs, to_libs): 129 for f in from_libs: 130 for t in to_libs: 131 if f != t: 132 __order.add_pair (f, t) 133 134def set_library_order (manager, sources, prop_set, result): 135 used_libraries = [] 136 deps = prop_set.dependency () 137 138 sources.extend(d.value for d in deps) 139 sources = sequence.unique(sources) 140 141 for l in sources: 142 if l.type () and type.is_derived (l.type (), 'LIB'): 143 used_libraries.append (l) 144 145 created_libraries = [] 146 for l in result: 147 if l.type () and type.is_derived (l.type (), 'LIB'): 148 created_libraries.append (l) 149 150 created_libraries = set.difference (created_libraries, used_libraries) 151 set_library_order_aux (created_libraries, used_libraries) 152 153def order_libraries (libraries): 154 return __order.order (libraries) 155 156