summaryrefslogtreecommitdiff
path: root/tools/build/v2/tools/unix.py
blob: 34758f57b555ddf2c0d888fd434baa6960200e5d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#  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):
        result = SearchedLibGenerator.run (project, name, prop_set, sources)
        
        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):
        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.extend(d.value() for d 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)