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 semantic 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 property. 10 11import feature ; 12import "class" : new ; 13import generators ; 14import type ; 15import set ; 16import order ; 17import builtin ; 18 19class unix-linking-generator : linking-generator 20{ 21 import property-set ; 22 import type ; 23 import unix ; 24 25 rule __init__ ( id 26 composing ? : # Specify if generator is composing. The generator will be 27 # composing if non-empty string is passed, or parameter is 28 # not given. To make generator non-composing, pass empty 29 # string ("") 30 source-types + : target-types + : 31 requirements * ) 32 { 33 composing ?= true ; 34 generator.__init__ $(id) $(composing) : $(source-types) : $(target-types) : 35 $(requirements) ; 36 } 37 38 rule run ( project name ? : property-set : sources + ) 39 { 40 local result = [ linking-generator.run $(project) $(name) : $(property-set) 41 : $(sources) ] ; 42 43 unix.set-library-order $(sources) : $(property-set) : $(result[2-]) ; 44 45 return $(result) ; 46 } 47 48 rule generated-targets ( sources + : property-set : project name ? ) 49 { 50 local sources2 ; 51 local libraries ; 52 for local l in $(sources) 53 { 54 if [ type.is-derived [ $(l).type ] LIB ] 55 { 56 libraries += $(l) ; 57 } 58 else 59 { 60 sources2 += $(l) ; 61 } 62 } 63 64 sources = $(sources2) [ unix.order-libraries $(libraries) ] ; 65 66 return [ linking-generator.generated-targets $(sources) : $(property-set) 67 : $(project) $(name) ] ; 68 } 69 70} 71 72class unix-archive-generator : archive-generator 73{ 74 import unix ; 75 76 rule __init__ ( id composing ? : source-types + : target-types + : 77 requirements * ) 78 { 79 composing ?= true ; 80 archive-generator.__init__ $(id) $(composing) : $(source-types) : $(target-types) : 81 $(requirements) ; 82 } 83 84 rule run ( project name ? : property-set : sources + ) 85 { 86 local result = [ archive-generator.run $(project) $(name) : $(property-set) 87 : $(sources) ] ; 88 89 unix.set-library-order $(sources) : $(property-set) : $(result[2-]) ; 90 91 return $(result) ; 92 93 } 94} 95 96class unix-searched-lib-generator : searched-lib-generator 97{ 98 import unix ; 99 rule __init__ ( * : * ) 100 { 101 generator.__init__ 102 $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ; 103 } 104 105 rule optional-properties ( ) 106 { 107 return $(self.requirements) ; 108 } 109 110 rule run ( project name ? : property-set : sources * ) 111 { 112 local result = [ searched-lib-generator.run $(project) $(name) 113 : $(property-set) : $(sources) ] ; 114 115 unix.set-library-order $(sources) : $(property-set) : $(result[2-]) ; 116 117 return $(result) ; 118 } 119} 120 121class unix-prebuilt-lib-generator : generator 122{ 123 import unix ; 124 rule __init__ ( * : * ) 125 { 126 generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ; 127 } 128 129 rule run ( project name ? : property-set : sources * ) 130 { 131 local f = [ $(property-set).get <file> ] ; 132 unix.set-library-order-aux $(f) : $(sources) ; 133 return $(f) $(sources) ; 134 } 135} 136 137generators.register 138 [ new unix-prebuilt-lib-generator unix.prebuilt : : LIB 139 : <file> <toolset>unix ] ; 140 141generators.override unix.prebuilt : builtin.lib-generator ; 142 143 144# Declare generators 145generators.register [ new unix-linking-generator unix.link : LIB OBJ : EXE 146 : <toolset>unix ] ; 147 148generators.register [ new unix-archive-generator unix.archive : OBJ : STATIC_LIB 149 : <toolset>unix ] ; 150 151generators.register [ new unix-linking-generator unix.link.dll : LIB OBJ : SHARED_LIB 152 : <toolset>unix ] ; 153 154generators.register [ new unix-searched-lib-generator 155 unix.searched-lib-generator : : SEARCHED_LIB : <toolset>unix ] ; 156 157 158# The derived toolset must specify their own actions. 159actions link { 160} 161 162actions link.dll { 163} 164 165actions archive { 166} 167 168actions searched-lib-generator { 169} 170 171actions prebuilt { 172} 173 174 175 176 177 178.order = [ new order ] ; 179 180rule set-library-order-aux ( from * : to * ) 181{ 182 for local f in $(from) 183 { 184 for local t in $(to) 185 { 186 if $(f) != $(t) 187 { 188 $(.order).add-pair $(f) $(t) ; 189 } 190 } 191 } 192} 193 194rule set-library-order ( sources * : property-set : result * ) 195{ 196 local used-libraries ; 197 local deps = [ $(property-set).dependency ] ; 198 for local l in $(sources) $(deps:G=) 199 { 200 if [ $(l).type ] && [ type.is-derived [ $(l).type ] LIB ] 201 { 202 used-libraries += $(l) ; 203 } 204 } 205 206 local created-libraries ; 207 for local l in $(result) 208 { 209 if [ $(l).type ] && [ type.is-derived [ $(l).type ] LIB ] 210 { 211 created-libraries += $(l) ; 212 } 213 } 214 215 created-libraries = [ set.difference $(created-libraries) : $(used-libraries) ] ; 216 set-library-order-aux $(created-libraries) : $(used-libraries) ; 217} 218 219rule order-libraries ( libraries * ) 220{ 221 local r = [ $(.order).order $(libraries) ] ; 222 return $(r) ; 223} 224