OLD | NEW |
1 # Copyright (c) 2012 The Native Client Authors. All rights reserved. | 1 # Copyright (c) 2012 The Native Client Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """Simple harness for defining library dependencies for scons files.""" | 5 """Simple harness for defining library dependencies for scons files.""" |
6 | 6 |
| 7 |
7 # The following is a map from a library, to the corresponding | 8 # The following is a map from a library, to the corresponding |
8 # list of dependent libraries that must be included after that library, in | 9 # list of dependent libraries that must be included after that library, in |
9 # the list of libraries. | 10 # the list of libraries. |
10 # Note: These are default rules that are used if platform specific rules are | |
11 # not specified below in PLATFORM_LIBRARY_DEPENDENCIES. | |
12 LIBRARY_DEPENDENCIES_DEFAULT = { | 11 LIBRARY_DEPENDENCIES_DEFAULT = { |
13 'platform': [ | 12 'platform': [ |
14 'gio', | 13 'gio', |
15 ], | 14 ], |
| 15 'sel': [ |
| 16 'manifest_proxy', |
| 17 'simple_service', |
| 18 'thread_interface', |
| 19 'gio_wrapped_desc', |
| 20 'nonnacl_srpc', |
| 21 'nrd_xfer', |
| 22 'nacl_perf_counter', |
| 23 'nacl_base', |
| 24 'imc', |
| 25 'container', |
| 26 'nacl_fault_inject', |
| 27 'nacl_interval', |
| 28 'platform', |
| 29 'platform_qual_lib', |
| 30 'gio', |
| 31 ], |
16 } | 32 } |
17 | 33 |
18 def _AddDefaultLibraryDependencies(dependencies): | |
19 """ Adds default library dependencies to library dependencies. | |
20 | |
21 Takes the contents of the platform-specific library dependencies, and | |
22 adds default dependencies if needed. | |
23 """ | |
24 for key in LIBRARY_DEPENDENCIES_DEFAULT: | |
25 if key not in dependencies: | |
26 dependencies[key] = LIBRARY_DEPENDENCIES_DEFAULT[key] | |
27 return dependencies | |
28 | 34 |
29 # Platform specific library dependencies. Mapping from a platform, | 35 # Platform specific library dependencies. Mapping from a platform, |
30 # to a map from a library, to the corresponding list of dependendent | 36 # to a map from a library, to the corresponding list of dependendent |
31 # libraries that must be included after that library, in the list | 37 # libraries that must be included after that library, in the list |
32 # of libraries. | 38 # of libraries. |
33 PLATFORM_LIBRARY_DEPENDENCIES = { | 39 PLATFORM_LIBRARY_DEPENDENCIES = { |
34 'x86-32': _AddDefaultLibraryDependencies({ | 40 'x86-32': { |
35 'nc_decoder_x86_32': [ | 41 'nc_decoder_x86_32': [ |
36 'ncval_base_x86_32', | 42 'ncval_base_x86_32', |
37 'nc_opcode_modeling_x86_32', | 43 'nc_opcode_modeling_x86_32', |
38 ], | 44 ], |
39 'ncdis_util_x86_32': [ | 45 'ncdis_util_x86_32': [ |
40 'ncval_reg_sfi_verbose_x86_32', | 46 'ncval_reg_sfi_verbose_x86_32', |
41 'ncdis_seg_sfi_verbose_x86_32', | 47 'ncdis_seg_sfi_verbose_x86_32', |
42 ], | 48 ], |
43 'ncdis_seg_sfi_verbose_x86_32': [ | 49 'ncdis_seg_sfi_verbose_x86_32': [ |
44 'ncdis_seg_sfi_x86_32', | 50 'ncdis_seg_sfi_x86_32', |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 'nccopy_x86_32', | 83 'nccopy_x86_32', |
78 'ncdis_seg_sfi_x86_32', | 84 'ncdis_seg_sfi_x86_32', |
79 'ncval_base_x86_32', | 85 'ncval_base_x86_32', |
80 # When turning on the DEBUGGING flag in the x86-32 validator | 86 # When turning on the DEBUGGING flag in the x86-32 validator |
81 # or decoder, add the following: | 87 # or decoder, add the following: |
82 #'nc_opcode_modeling_verbose_x86_32', | 88 #'nc_opcode_modeling_verbose_x86_32', |
83 ], | 89 ], |
84 'sel': [ | 90 'sel': [ |
85 'ncvalidate_x86_32', | 91 'ncvalidate_x86_32', |
86 ], | 92 ], |
87 }), | 93 }, |
88 'x86-64': _AddDefaultLibraryDependencies({ | 94 'x86-64': { |
89 'nc_decoder_x86_64': [ | 95 'nc_decoder_x86_64': [ |
90 'ncval_base_x86_64', | 96 'ncval_base_x86_64', |
91 'nc_opcode_modeling_x86_64', | 97 'nc_opcode_modeling_x86_64', |
92 # When turning on the DEBUGGING flag in the x86-64 validator | 98 # When turning on the DEBUGGING flag in the x86-64 validator |
93 # or decoder, add the following: | 99 # or decoder, add the following: |
94 #'nc_opcode_modeling_verbose_x86_64', | 100 #'nc_opcode_modeling_verbose_x86_64', |
95 ], | 101 ], |
96 'ncdis_util_x86_64': [ | 102 'ncdis_util_x86_64': [ |
97 'ncval_reg_sfi_verbose_x86_64', | 103 'ncval_reg_sfi_verbose_x86_64', |
98 'ncdis_seg_sfi_verbose_x86_64', | 104 'ncdis_seg_sfi_verbose_x86_64', |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 'nc_decoder_x86_64', | 137 'nc_decoder_x86_64', |
132 ], | 138 ], |
133 'ncval_seg_sfi_x86_64': [ | 139 'ncval_seg_sfi_x86_64': [ |
134 'nccopy_x86_64', | 140 'nccopy_x86_64', |
135 'ncdis_seg_sfi_x86_64', | 141 'ncdis_seg_sfi_x86_64', |
136 'ncval_base_x86_64', | 142 'ncval_base_x86_64', |
137 ], | 143 ], |
138 'sel': [ | 144 'sel': [ |
139 'ncvalidate_x86_64', | 145 'ncvalidate_x86_64', |
140 ], | 146 ], |
141 }), | 147 }, |
142 'arm': _AddDefaultLibraryDependencies({ | 148 'arm': { |
143 'ncvalidate_arm_v2': [ | 149 'ncvalidate_arm_v2': [ |
144 'arm_validator_core', | 150 'arm_validator_core', |
145 ], | 151 ], |
146 'sel': [ | 152 'sel': [ |
147 'ncvalidate_arm_v2', | 153 'ncvalidate_arm_v2', |
148 ], | 154 ], |
149 }), | 155 }, |
150 'arm-thumb2': _AddDefaultLibraryDependencies({ | 156 'arm-thumb2': { |
151 'ncvalidate_arm_v2': [ | 157 'ncvalidate_arm_v2': [ |
152 'arm_validator_core', | 158 'arm_validator_core', |
153 ], | 159 ], |
154 }), | 160 }, |
155 } | 161 } |
156 | 162 |
| 163 |
157 def AddLibDeps(platform, libraries): | 164 def AddLibDeps(platform, libraries): |
158 """ Adds dependent libraries to list of libraries. | 165 """ Adds dependent libraries to list of libraries. |
159 | 166 |
160 Computes the transitive closure of library dependencies for each library | 167 Computes the transitive closure of library dependencies for each library |
161 in the given list. Dependent libraries are added after libraries | 168 in the given list. Dependent libraries are added after libraries |
162 as defined in LIBRARY_DEPENDENCIES, unless there is a cycle. If | 169 as defined in LIBRARY_DEPENDENCIES, unless there is a cycle. If |
163 a cycle occurs, it is broken and the remaining (acyclic) graph | 170 a cycle occurs, it is broken and the remaining (acyclic) graph |
164 is used. Also removes duplicate library entries. | 171 is used. Also removes duplicate library entries. |
165 | 172 |
166 Note: Keeps libraries (in same order) as given | 173 Note: Keeps libraries (in same order) as given |
167 in the argument list. This includes duplicates if specified. | 174 in the argument list. This includes duplicates if specified. |
168 """ | 175 """ |
169 if not libraries: return [] | |
170 | |
171 visited = set() # Nodes already visited | 176 visited = set() # Nodes already visited |
172 closure = [] # Collected closure | 177 closure = [] # Collected closure |
173 if platform in PLATFORM_LIBRARY_DEPENDENCIES: | |
174 # Use platform specific library dependencies. | |
175 dependencies = PLATFORM_LIBRARY_DEPENDENCIES[platform] | |
176 else: | |
177 # No specific library dependencies defined, use default. | |
178 dependencies = LIBRARY_DEPENDENCIES_DEFAULT | |
179 | 178 |
180 # Add dependencies of each library to the closure, then add the library to | 179 # If library A depends on library B, B must appear in the link line |
181 # the closure. | 180 # after A. This is why we reverse the list and reverse it back |
182 for lib in reversed(libraries): | 181 # again later. |
183 # Be sure to remove the library if it is already there, so that it will be | 182 def VisitList(libraries): |
184 # added again. | 183 for library in reversed(libraries): |
185 if lib in visited: visited.remove(lib) | 184 if library not in visited: |
186 to_visit = [lib] # Nodes needing dependencies added. | 185 VisitLibrary(library) |
187 expanding = [] # libraries with expanded dependencies, | 186 |
188 # but not yet added to the closure. | 187 def VisitLibrary(library): |
189 while to_visit: | 188 visited.add(library) |
190 lib = to_visit.pop() | 189 VisitList(LIBRARY_DEPENDENCIES_DEFAULT.get(library, [])) |
191 if lib in visited: | 190 VisitList(PLATFORM_LIBRARY_DEPENDENCIES.get(platform, {}).get(library, [])) |
192 if expanding and lib is expanding[-1]: | 191 closure.append(library) |
193 # Second visit, so we know that dependencies have been added. | 192 |
194 # It is now safe to add lib. | 193 # Ideally we would just do "VisitList(libraries)" here, but some |
195 closure.append(lib) | 194 # PPAPI tests (specifically, tests/ppapi_gles_book) list "ppapi_cpp" |
196 expanding.pop() | 195 # twice in the link line, and we need to maintain these duplicates. |
197 else: | 196 for library in reversed(libraries): |
198 visited.add(lib) | 197 VisitLibrary(library) |
199 if lib in dependencies: | 198 |
200 # Must process library dependencies first. | |
201 # Be sure to add library to list of nodes to visit, | |
202 # so that we can add it to the closure once all | |
203 # dependencies have been added. | |
204 to_visit.append(lib) | |
205 for dep in dependencies[lib]: | |
206 to_visit.append(dep) | |
207 expanding.append(lib) | |
208 else: | |
209 # No dependent library, just add. | |
210 closure.append(lib) | |
211 closure.reverse() | 199 closure.reverse() |
212 return closure | 200 return closure |
OLD | NEW |