Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/tools/build/v2/util/order.jam @ 12

Last change on this file since 12 was 12, checked in by landauf, 17 years ago

added boost

File size: 5.4 KB
Line 
1#  Copyright (C) 2003 Vladimir Prus
2#  Use, modification, and distribution is subject to the Boost Software
3#  License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy
4#  at http://www.boost.org/LICENSE_1_0.txt)
5
6#  This module defines a class which allows to order arbitrary object
7#  with regard to arbitrary binary relation.
8#
9#  The primary use case is the gcc toolset, which is sensitive to
10#  library order: if library 'a' uses symbols from library 'b',
11#  then 'a' must be present before 'b' on the linker's command line.
12#
13#  This requirement can be lifted for gcc with GNU ld, but for gcc with
14#  Solaris LD (and for Solaris toolset as well), the order always matters.
15#
16#  So, we need to store order requirements and then order libraries
17#  according to them. It it not possible to use dependency graph as
18#  order requirements. What we need is "use symbols" relationship
19#  while dependency graph provides "needs to be updated" relationship.
20#
21#  For example::
22#    lib a : a.cpp b;
23#    lib b ;
24#
25#  For static linking, the 'a' library need not depend on 'b'. However, it
26#  still should come before 'b' on the command line.
27
28class order
29{
30    rule __init__ ( ) {
31    }
32   
33    # Adds the constraint that 'first' should precede 'second'
34    rule add-pair ( first second )
35    {
36        .constraits += $(first)--$(second) ;
37    }
38    NATIVE_RULE class@order : add-pair ;
39   
40    # Given a list of objects, reorder them so that the constains specified
41    # by 'add-pair' are satisfied.
42    #
43    # The algorithm was adopted from an awk script by Nikita Youshchenko
44    # (yoush at cs dot msu dot su)
45    rule order ( objects * )
46    {
47        # The algorithm used is the same is standard transitive closure,
48        # except that we're not keeping in-degree for all vertices, but
49        # rather removing edges.
50        local result ;
51        if $(objects)
52        {       
53            local constraints = [ eliminate-unused-constraits $(objects) ] ;           
54           
55            # Find some library that nobody depends upon and add it to
56            # the 'result' array.
57            local obj ;
58            while $(objects)
59            {             
60                local new_objects ;
61                while $(objects)
62                {
63                    obj = $(objects[1]) ;           
64                    if [ has-no-dependents $(obj) : $(constraints) ]
65                    {
66                        # Emulate break ;
67                        new_objects += $(objects[2-]) ;
68                        objects = ;
69                    }               
70                    else
71                    {
72                        new_objects += $(obj) ;
73                        obj = ;
74                        objects = $(objects[2-]) ;
75                    }
76                }
77               
78                if ! $(obj)
79                {
80                    errors.error "Circular order dependencies" ;
81                }
82                # No problem with placing first.
83                result += $(obj) ;
84                # Remove all containts where 'obj' comes first,
85                # since they are already satisfied.
86                constraints = [ remove-satisfied $(constraints) : $(obj) ] ;
87                # Add the remaining objects for further processing
88                # on the next iteration
89                               
90                objects = $(new_objects) ;               
91            }                                               
92           
93        }       
94        return $(result) ;
95    }                     
96    NATIVE_RULE class@order : order ;
97   
98    # Eliminate constains which mentions objects not in 'objects'.
99    # In graph-theory terms, this is finding subgraph induced by
100    # ordered vertices.
101    rule eliminate-unused-constraits ( objects * )
102    {
103        local result ;
104        for local c in $(.constraints)
105        {
106            local m = [ MATCH (.*)--(.*) : $(c) ] ;
107            if $(m[1]) in $(objects) && $(m[2]) in $(objects)
108            {
109                result += $(c) ;
110            }           
111        }   
112        return $(result) ;
113    }
114   
115    # Returns true if there's no constrain in 'constaraint' where
116    # 'obj' comes second.
117    rule has-no-dependents ( obj : constraints * )
118    {
119        local failed ;
120        while $(constraints) && ! $(failed)         
121        {
122            local c = $(constraints[1]) ;
123            local m = [ MATCH (.*)--(.*) : $(c) ] ;
124            if $(m[2]) = $(obj)
125            {
126                failed = true ;
127            }           
128            constraints = $(constraints[2-]) ;
129        }
130        if ! $(failed)
131        {
132            return true ;
133        }   
134    }
135   
136    rule remove-satisfied ( constraints * : obj )
137    {
138        local result ;
139        for local c in $(constraints)
140        {
141            local m = [ MATCH (.*)--(.*) : $(c) ] ;
142            if $(m[1]) != $(obj)
143            {
144                result += $(c) ;
145            }           
146        }
147        return $(result) ;       
148    }           
149}
150
151rule __test__ ( )
152{
153    import "class" : new ;
154    import assert ;
155   
156    c1 = [ new order ] ;
157    $(c1).add-pair l1 l2 ;
158   
159    assert.result l1 l2 : $(c1).order l1 l2 ;
160    assert.result l1 l2 : $(c1).order l2 l1 ;
161   
162    $(c1).add-pair l2 l3 ;
163    assert.result l1 l2 : $(c1).order l2 l1 ;
164    $(c1).add-pair x l2 ;
165    assert.result l1 l2 : $(c1).order l2 l1 ;
166    assert.result l1 l2 l3 : $(c1).order l2 l3 l1 ;
167   
168
169   
170   
171}
172
173
Note: See TracBrowser for help on using the repository browser.