]>
Commit | Line | Data |
---|---|---|
ddf1847d RL |
1 | {- # -*- Mode: perl -*- |
2 | ||
0ad1d94d RL |
3 | use File::Basename; |
4 | ||
bdea50ca RL |
5 | my $debug_resolvedepends = $ENV{BUILDFILE_DEBUG_DEPENDS}; |
6 | my $debug_rules = $ENV{BUILDFILE_DEBUG_RULES}; | |
7 | ||
0ad1d94d RL |
8 | # A cache of objects for which a recipe has already been generated |
9 | my %cache; | |
ddf1847d | 10 | |
bdea50ca RL |
11 | # collectdepends, expanddepends and reducedepends work together to make |
12 | # sure there are no duplicate or weak dependencies and that they are in | |
13 | # the right order. This is used to sort the list of libraries that a | |
14 | # build depends on. | |
186a31e5 RL |
15 | sub extensionlesslib { |
16 | my @result = map { $_ =~ /(\.a)?$/; $` } @_; | |
17 | return @result if wantarray; | |
18 | return $result[0]; | |
19 | } | |
bdea50ca RL |
20 | |
21 | # collectdepends dives into the tree of dependencies and returns | |
22 | # a list of all the non-weak ones. | |
23 | sub collectdepends { | |
24 | return () unless @_; | |
25 | ||
ddf1847d | 26 | my $thing = shift; |
186a31e5 | 27 | my $extensionlessthing = extensionlesslib($thing); |
ddf1847d | 28 | my @listsofar = @_; # to check if we're looping |
33105818 RL |
29 | my @list = @{$unified_info{depends}->{$thing} // |
30 | $unified_info{depends}->{$extensionlessthing}}; | |
ddf1847d | 31 | my @newlist = (); |
bdea50ca RL |
32 | |
33 | print STDERR "DEBUG[collectdepends] $thing > ", join(' ', @listsofar), "\n" | |
34 | if $debug_resolvedepends; | |
35 | foreach my $item (@list) { | |
36 | my $extensionlessitem = extensionlesslib($item); | |
37 | # It's time to break off when the dependency list starts looping | |
38 | next if grep { extensionlesslib($_) eq $extensionlessitem } @listsofar; | |
39 | # Don't add anything here if the dependency is weak | |
40 | next if defined $unified_info{attributes}->{depends}->{$thing}->{$item}->{'weak'}; | |
41 | my @resolved = collectdepends($item, @listsofar, $item); | |
42 | push @newlist, $item, @resolved; | |
ddf1847d | 43 | } |
bdea50ca RL |
44 | print STDERR "DEBUG[collectdepends] $thing < ", join(' ', @newlist), "\n" |
45 | if $debug_resolvedepends; | |
ddf1847d RL |
46 | @newlist; |
47 | } | |
bdea50ca RL |
48 | |
49 | # expanddepends goes through a list of stuff, checks if they have any | |
50 | # dependencies, and adds them at the end of the current position if | |
51 | # they aren't already present later on. | |
52 | sub expanddepends { | |
53 | my @after = ( @_ ); | |
54 | print STDERR "DEBUG[expanddepends]> ", join(' ', @after), "\n" | |
55 | if $debug_resolvedepends; | |
56 | my @before = (); | |
57 | while (@after) { | |
58 | my $item = shift @after; | |
59 | print STDERR "DEBUG[expanddepends]\\ ", join(' ', @before), "\n" | |
60 | if $debug_resolvedepends; | |
61 | print STDERR "DEBUG[expanddepends] - ", $item, "\n" | |
62 | if $debug_resolvedepends; | |
63 | my @middle = ( | |
64 | $item, | |
65 | map { | |
66 | my $x = $_; | |
67 | my $extlessx = extensionlesslib($x); | |
68 | if (grep { $extlessx eq extensionlesslib($_) } @before | |
69 | and | |
70 | !grep { $extlessx eq extensionlesslib($_) } @after) { | |
71 | print STDERR "DEBUG[expanddepends] + ", $x, "\n" | |
72 | if $debug_resolvedepends; | |
73 | ( $x ) | |
74 | } else { | |
75 | print STDERR "DEBUG[expanddepends] ! ", $x, "\n" | |
76 | if $debug_resolvedepends; | |
77 | () | |
78 | } | |
79 | } @{$unified_info{depends}->{$item} // []} | |
80 | ); | |
81 | print STDERR "DEBUG[expanddepends] = ", join(' ', @middle), "\n" | |
82 | if $debug_resolvedepends; | |
83 | print STDERR "DEBUG[expanddepends]/ ", join(' ', @after), "\n" | |
84 | if $debug_resolvedepends; | |
85 | push @before, @middle; | |
86 | } | |
87 | print STDERR "DEBUG[expanddepends]< ", join(' ', @before), "\n" | |
88 | if $debug_resolvedepends; | |
89 | @before; | |
90 | } | |
91 | ||
92 | # reducedepends looks through a list, and checks if each item is | |
93 | # repeated later on. If it is, the earlier copy is dropped. | |
ddf1847d RL |
94 | sub reducedepends { |
95 | my @list = @_; | |
bdea50ca RL |
96 | print STDERR "DEBUG[reducedepends]> ", join(' ', @list), "\n" |
97 | if $debug_resolvedepends; | |
ddf1847d | 98 | my @newlist = (); |
33105818 | 99 | my %replace = (); |
ddf1847d RL |
100 | while (@list) { |
101 | my $item = shift @list; | |
186a31e5 | 102 | my $extensionlessitem = extensionlesslib($item); |
33105818 RL |
103 | if (grep { $extensionlessitem eq extensionlesslib($_) } @list) { |
104 | if ($item ne $extensionlessitem) { | |
46f4e1be | 105 | # If this instance of the library is explicitly static, we |
33105818 RL |
106 | # prefer that to any shared library name, since it must have |
107 | # been done on purpose. | |
108 | $replace{$extensionlessitem} = $item; | |
109 | } | |
110 | } else { | |
111 | push @newlist, $item; | |
112 | } | |
ddf1847d | 113 | } |
bdea50ca RL |
114 | @newlist = map { $replace{$_} // $_; } @newlist; |
115 | print STDERR "DEBUG[reducedepends]< ", join(' ', @newlist), "\n" | |
116 | if $debug_resolvedepends; | |
117 | @newlist; | |
118 | } | |
119 | ||
120 | # Do it all | |
121 | # This takes multiple inputs and combine them into a single list of | |
122 | # interdependent things. The returned value will include all the input. | |
123 | # Callers are responsible for taking away the things they are building. | |
124 | sub resolvedepends { | |
125 | print STDERR "DEBUG[resolvedepends] START (", join(', ', @_), ")\n" | |
126 | if $debug_resolvedepends; | |
127 | my @all = | |
128 | reducedepends(expanddepends(map { ( $_, collectdepends($_) ) } @_)); | |
129 | print STDERR "DEBUG[resolvedepends] END (", join(', ', @_), ") : ", | |
130 | join(',', map { "\n $_" } @all), "\n" | |
131 | if $debug_resolvedepends; | |
132 | @all; | |
ddf1847d RL |
133 | } |
134 | ||
d4605727 RL |
135 | # dogenerate is responsible for producing all the recipes that build |
136 | # generated source files. It recurses in case a dependency is also a | |
137 | # generated source file. | |
ae4c7450 RL |
138 | sub dogenerate { |
139 | my $src = shift; | |
140 | return "" if $cache{$src}; | |
d4605727 RL |
141 | my $obj = shift; |
142 | my $bin = shift; | |
ae4c7450 RL |
143 | my %opts = @_; |
144 | if ($unified_info{generate}->{$src}) { | |
05a7aee0 RL |
145 | die "$src is generated by Configure, should not appear in build file\n" |
146 | if ref $unified_info{generate}->{$src} eq ""; | |
8d34daf0 | 147 | my $script = $unified_info{generate}->{$src}->[0]; |
ae4c7450 | 148 | $OUT .= generatesrc(src => $src, |
66a24ab8 | 149 | product => $bin, |
ae4c7450 | 150 | generator => $unified_info{generate}->{$src}, |
8d34daf0 RL |
151 | generator_incs => $unified_info{includes}->{$script}, |
152 | generator_deps => $unified_info{depends}->{$script}, | |
ae4c7450 | 153 | deps => $unified_info{depends}->{$src}, |
829f86bb RL |
154 | incs => [ defined $obj |
155 | ? @{$unified_info{includes}->{$obj}} | |
156 | : (), | |
157 | defined $bin | |
158 | ? @{$unified_info{includes}->{$bin}} | |
159 | : () ], | |
160 | defs => [ defined $obj | |
161 | ? @{$unified_info{defines}->{$obj}} | |
162 | : (), | |
163 | defined $bin | |
164 | ? @{$unified_info{defines}->{$bin}} | |
165 | : () ], | |
ae4c7450 RL |
166 | %opts); |
167 | foreach (@{$unified_info{depends}->{$src}}) { | |
d4605727 | 168 | dogenerate($_, $obj, $bin, %opts); |
ae4c7450 RL |
169 | } |
170 | } | |
171 | $cache{$src} = 1; | |
172 | } | |
173 | ||
ddf1847d RL |
174 | # doobj is responsible for producing all the recipes that build |
175 | # object files as well as dependency files. | |
176 | sub doobj { | |
177 | my $obj = shift; | |
b23238f9 | 178 | return "" if $cache{$obj}; |
ddf1847d | 179 | my $bin = shift; |
45502bfe | 180 | my %opts = @_; |
ddf1847d | 181 | if (@{$unified_info{sources}->{$obj}}) { |
e805c2d6 RL |
182 | my @srcs = @{$unified_info{sources}->{$obj}}; |
183 | my @deps = @{$unified_info{depends}->{$obj}}; | |
184 | my @incs = ( @{$unified_info{includes}->{$obj}}, | |
185 | @{$unified_info{includes}->{$bin}} ); | |
186 | my @defs = ( @{$unified_info{defines}->{$obj}}, | |
187 | @{$unified_info{defines}->{$bin}} ); | |
188 | print STDERR "DEBUG[doobj] \@srcs for $obj ($bin) : ", | |
189 | join(",", map { "\n $_" } @srcs), "\n" | |
190 | if $debug_rules; | |
191 | print STDERR "DEBUG[doobj] \@deps for $obj ($bin) : ", | |
192 | join(",", map { "\n $_" } @deps), "\n" | |
193 | if $debug_rules; | |
194 | print STDERR "DEBUG[doobj] \@incs for $obj ($bin) : ", | |
195 | join(",", map { "\n $_" } @incs), "\n" | |
196 | if $debug_rules; | |
197 | print STDERR "DEBUG[doobj] \@defs for $obj ($bin) : ", | |
198 | join(",", map { "\n $_" } @defs), "\n" | |
199 | if $debug_rules; | |
200 | print STDERR "DEBUG[doobj] \%opts for $obj ($bin) : ", , | |
201 | join(",", map { "\n $_ = $opts{$_}" } sort keys %opts), "\n" | |
202 | if $debug_rules; | |
203 | $OUT .= src2obj(obj => $obj, product => $bin, | |
204 | srcs => [ @srcs ], deps => [ @deps ], | |
205 | incs => [ @incs ], defs => [ @defs ], | |
45502bfe | 206 | %opts); |
ae4c7450 RL |
207 | foreach ((@{$unified_info{sources}->{$obj}}, |
208 | @{$unified_info{depends}->{$obj}})) { | |
d4605727 | 209 | dogenerate($_, $obj, $bin, %opts); |
ae4c7450 | 210 | } |
ddf1847d | 211 | } |
b23238f9 | 212 | $cache{$obj} = 1; |
ddf1847d RL |
213 | } |
214 | ||
e805c2d6 RL |
215 | # Helper functions to grab all applicable intermediary files. |
216 | # This is particularly useful when a library is given as source | |
217 | # rather than a dependency. In that case, we consider it to be a | |
218 | # container with object file references, or possibly references | |
219 | # to further libraries to pilfer in the same way. | |
220 | sub getsrclibs { | |
221 | my $section = shift; | |
222 | ||
223 | # For all input, see if it sources static libraries. If it does, | |
224 | # return them together with the result of a recursive call. | |
225 | map { ( $_, getsrclibs($section, $_) ) } | |
226 | grep { $_ =~ m|\.a$| } | |
227 | map { @{$unified_info{$section}->{$_} // []} } | |
228 | @_; | |
229 | } | |
230 | ||
231 | sub getlibobjs { | |
232 | my $section = shift; | |
233 | ||
234 | # For all input, see if it's an intermediary file (library or object). | |
235 | # If it is, collect the result of a recursive call, or if that returns | |
236 | # an empty list, the element itself. Return the result. | |
237 | map { | |
238 | my @x = getlibobjs($section, @{$unified_info{$section}->{$_}}); | |
239 | @x ? @x : ( $_ ); | |
240 | } | |
241 | grep { defined $unified_info{$section}->{$_} } | |
242 | @_; | |
243 | } | |
244 | ||
ddf1847d | 245 | # dolib is responsible for building libraries. It will call |
e805c2d6 | 246 | # obj2shlib if shared libraries are produced, and obj2lib in all |
ddf1847d RL |
247 | # cases. It also makes sure all object files for the library are |
248 | # built. | |
249 | sub dolib { | |
250 | my $lib = shift; | |
b23238f9 | 251 | return "" if $cache{$lib}; |
e805c2d6 RL |
252 | |
253 | my %attrs = %{$unified_info{attributes}->{libraries}->{$lib}}; | |
254 | ||
255 | my @deps = ( resolvedepends(getsrclibs('sources', $lib)) ); | |
256 | ||
257 | # We support two types of objs, those who are specific to this library | |
258 | # (they end up in @objs) and those that we get indirectly, via other | |
259 | # libraries (they end up in @foreign_objs). We get the latter any time | |
260 | # someone has done something like this in build.info: | |
261 | # SOURCE[libfoo.a]=libbar.a | |
262 | # The indirect object files must be kept in a separate array so they | |
263 | # don't get rebuilt unnecessarily (and with incorrect auxiliary | |
264 | # information). | |
265 | # | |
266 | # Object files can't be collected commonly for shared and static | |
267 | # libraries, because we contain their respective object files in | |
268 | # {shared_sources} and {sources}, and because the implications are | |
269 | # slightly different for each library form. | |
270 | # | |
271 | # We grab all these "foreign" object files recursively with getlibobjs(). | |
272 | ||
33105818 | 273 | unless ($disabled{shared} || $lib =~ /\.a$/) { |
f6196227 | 274 | my $obj2shlib = defined &obj2shlib ? \&obj2shlib : \&libobj2shlib; |
e805c2d6 RL |
275 | # If this library sources other static libraries and those |
276 | # libraries are marked {noinst}, there's no need to include | |
277 | # all of their object files. Instead, we treat those static | |
278 | # libraries as dependents alongside any other library this | |
279 | # one depends on, and let symbol resolution do its job. | |
280 | my @sourced_libs = (); | |
281 | my @objs = (); | |
282 | my @foreign_objs = (); | |
283 | my @deps = (); | |
284 | foreach (@{$unified_info{shared_sources}->{$lib}}) { | |
285 | if ($_ !~ m|\.a$|) { | |
286 | push @objs, $_; | |
287 | } elsif ($unified_info{attributes}->{libraries}->{$_}->{noinst}) { | |
288 | push @deps, $_; | |
289 | } else { | |
290 | push @deps, getsrclibs('sources', $_); | |
291 | push @foreign_objs, getlibobjs('sources', $_); | |
292 | } | |
293 | } | |
294 | @deps = ( grep { $_ ne $lib } resolvedepends($lib, @deps) ); | |
295 | print STDERR "DEBUG[dolib:shlib] \%attrs for $lib : ", , | |
296 | join(",", map { "\n $_ = $attrs{$_}" } sort keys %attrs), "\n" | |
297 | if %attrs && $debug_rules; | |
298 | print STDERR "DEBUG[dolib:shlib] \@deps for $lib : ", | |
299 | join(",", map { "\n $_" } @deps), "\n" | |
300 | if @deps && $debug_rules; | |
301 | print STDERR "DEBUG[dolib:shlib] \@objs for $lib : ", | |
302 | join(",", map { "\n $_" } @objs), "\n" | |
303 | if @objs && $debug_rules; | |
304 | print STDERR "DEBUG[dolib:shlib] \@foreign_objs for $lib : ", | |
305 | join(",", map { "\n $_" } @foreign_objs), "\n" | |
306 | if @foreign_objs && $debug_rules; | |
f5fb6f05 | 307 | $OUT .= $obj2shlib->(lib => $lib, |
e805c2d6 RL |
308 | attrs => { %attrs }, |
309 | objs => [ @objs, @foreign_objs ], | |
310 | deps => [ @deps ]); | |
311 | foreach (@objs) { | |
81183680 RL |
312 | # If this is somehow a compiled object, take care of it that way |
313 | # Otherwise, it might simply be generated | |
314 | if (defined $unified_info{sources}->{$_}) { | |
e805c2d6 RL |
315 | if($_ =~ /\.a$/) { |
316 | dolib($_); | |
317 | } else { | |
318 | doobj($_, $lib, intent => "shlib", attrs => { %attrs }); | |
319 | } | |
81183680 RL |
320 | } else { |
321 | dogenerate($_, undef, undef, intent => "lib"); | |
322 | } | |
2110febb | 323 | } |
ddf1847d | 324 | } |
e805c2d6 RL |
325 | { |
326 | # When putting static libraries together, we cannot rely on any | |
327 | # symbol resolution, so for all static libraries used as source for | |
328 | # this one, as well as other libraries they depend on, we simply | |
329 | # grab all their object files unconditionally, | |
330 | # Symbol resolution will happen when any program, module or shared | |
331 | # library is linked with this one. | |
332 | my @objs = (); | |
333 | my @sourcedeps = (); | |
334 | my @foreign_objs = (); | |
335 | foreach (@{$unified_info{sources}->{$lib}}) { | |
336 | if ($_ !~ m|\.a$|) { | |
337 | push @objs, $_; | |
338 | } else { | |
339 | push @sourcedeps, $_; | |
340 | } | |
341 | } | |
342 | @sourcedeps = ( grep { $_ ne $lib } resolvedepends(@sourcedeps) ); | |
343 | print STDERR "DEBUG[dolib:lib] : \@sourcedeps for $_ : ", | |
344 | join(",", map { "\n $_" } @sourcedeps), "\n" | |
345 | if @sourcedeps && $debug_rules; | |
346 | @foreign_objs = getlibobjs('sources', @sourcedeps); | |
347 | print STDERR "DEBUG[dolib:lib] \%attrs for $lib : ", , | |
348 | join(",", map { "\n $_ = $attrs{$_}" } sort keys %attrs), "\n" | |
349 | if %attrs && $debug_rules; | |
350 | print STDERR "DEBUG[dolib:lib] \@objs for $lib : ", | |
351 | join(",", map { "\n $_" } @objs), "\n" | |
352 | if @objs && $debug_rules; | |
353 | print STDERR "DEBUG[dolib:lib] \@foreign_objs for $lib : ", | |
354 | join(",", map { "\n $_" } @foreign_objs), "\n" | |
355 | if @foreign_objs && $debug_rules; | |
356 | $OUT .= obj2lib(lib => $lib, attrs => { %attrs }, | |
357 | objs => [ @objs, @foreign_objs ]); | |
358 | foreach (@objs) { | |
359 | doobj($_, $lib, intent => "lib", attrs => { %attrs }); | |
360 | } | |
2110febb | 361 | } |
b23238f9 | 362 | $cache{$lib} = 1; |
ddf1847d RL |
363 | } |
364 | ||
1842f369 | 365 | # domodule is responsible for building modules. It will call |
5386287c | 366 | # obj2dso, and also makes sure all object files for the library |
ddf1847d | 367 | # are built. |
1842f369 | 368 | sub domodule { |
285daccd RL |
369 | my $module = shift; |
370 | return "" if $cache{$module}; | |
e805c2d6 RL |
371 | my %attrs = %{$unified_info{attributes}->{modules}->{$module}}; |
372 | my @objs = @{$unified_info{sources}->{$module}}; | |
373 | my @deps = ( grep { $_ ne $module } | |
374 | resolvedepends($module) ); | |
375 | print STDERR "DEBUG[domodule] \%attrs for $module :", | |
376 | join(",", map { "\n $_ = $attrs{$_}" } sort keys %attrs), "\n" | |
377 | if $debug_rules; | |
378 | print STDERR "DEBUG[domodule] \@objs for $module : ", | |
379 | join(",", map { "\n $_" } @objs), "\n" | |
380 | if $debug_rules; | |
381 | print STDERR "DEBUG[domodule] \@deps for $module : ", | |
382 | join(",", map { "\n $_" } @deps), "\n" | |
383 | if $debug_rules; | |
285daccd | 384 | $OUT .= obj2dso(module => $module, |
e805c2d6 RL |
385 | attrs => { %attrs }, |
386 | objs => [ @objs ], | |
387 | deps => [ @deps ]); | |
285daccd | 388 | foreach (@{$unified_info{sources}->{$module}}) { |
66a24ab8 RL |
389 | # If this is somehow a compiled object, take care of it that way |
390 | # Otherwise, it might simply be generated | |
391 | if (defined $unified_info{sources}->{$_}) { | |
e805c2d6 | 392 | doobj($_, $module, intent => "dso", attrs => { %attrs }); |
66a24ab8 | 393 | } else { |
285daccd | 394 | dogenerate($_, undef, $module, intent => "dso"); |
66a24ab8 | 395 | } |
2110febb | 396 | } |
285daccd | 397 | $cache{$module} = 1; |
ddf1847d RL |
398 | } |
399 | ||
400 | # dobin is responsible for building programs. It will call obj2bin, | |
401 | # and also makes sure all object files for the library are built. | |
402 | sub dobin { | |
403 | my $bin = shift; | |
b23238f9 | 404 | return "" if $cache{$bin}; |
e805c2d6 RL |
405 | my %attrs = %{$unified_info{attributes}->{programs}->{$bin}}; |
406 | my @objs = @{$unified_info{sources}->{$bin}}; | |
407 | my @deps = ( grep { $_ ne $bin } resolvedepends($bin) ); | |
408 | print STDERR "DEBUG[dobin] \%attrs for $bin : ", | |
409 | join(",", map { "\n $_ = $attrs{$_}" } sort keys %attrs), "\n" | |
410 | if %attrs && $debug_rules; | |
411 | print STDERR "DEBUG[dobin] \@objs for $bin : ", | |
412 | join(",", map { "\n $_" } @objs), "\n" | |
413 | if @objs && $debug_rules; | |
414 | print STDERR "DEBUG[dobin] \@deps for $bin : ", | |
415 | join(",", map { "\n $_" } @deps), "\n" | |
416 | if @deps && $debug_rules; | |
ddf1847d | 417 | $OUT .= obj2bin(bin => $bin, |
e805c2d6 RL |
418 | attrs => { %attrs }, |
419 | objs => [ @objs ], | |
420 | deps => [ @deps ]); | |
421 | foreach (@objs) { | |
422 | doobj($_, $bin, intent => "bin", attrs => { %attrs }); | |
2110febb | 423 | } |
b23238f9 | 424 | $cache{$bin} = 1; |
ddf1847d RL |
425 | } |
426 | ||
427 | # dobin is responsible for building scripts from templates. It will | |
428 | # call in2script. | |
429 | sub doscript { | |
430 | my $script = shift; | |
b23238f9 | 431 | return "" if $cache{$script}; |
ddf1847d | 432 | $OUT .= in2script(script => $script, |
5f825749 | 433 | attrs => $unified_info{attributes}->{$script}, |
5cae2d34 | 434 | sources => $unified_info{sources}->{$script}); |
b23238f9 | 435 | $cache{$script} = 1; |
ddf1847d RL |
436 | } |
437 | ||
0ad1d94d RL |
438 | sub dodir { |
439 | my $dir = shift; | |
440 | return "" if !exists(&generatedir) or $cache{$dir}; | |
441 | $OUT .= generatedir(dir => $dir, | |
442 | deps => $unified_info{dirinfo}->{$dir}->{deps}, | |
443 | %{$unified_info{dirinfo}->{$_}->{products}}); | |
444 | $cache{$dir} = 1; | |
445 | } | |
446 | ||
829f86bb RL |
447 | # dodocs is responsible for building documentation from .pods. |
448 | # It will call generatesrc. | |
449 | sub dodocs { | |
450 | my $type = shift; | |
451 | my $section = shift; | |
452 | foreach my $doc (@{$unified_info{"${type}docs"}->{$section}}) { | |
453 | next if $cache{$doc}; | |
454 | $OUT .= generatesrc(src => $doc, | |
455 | generator => $unified_info{generate}->{$doc}); | |
456 | foreach ((@{$unified_info{depends}->{$doc}})) { | |
457 | dogenerate($_, undef, undef, %opts); | |
458 | } | |
459 | $cache{$doc} = 1; | |
460 | } | |
461 | } | |
462 | ||
8a67946e RL |
463 | # Start with populating the cache with all the overrides |
464 | %cache = map { $_ => 1 } @{$unified_info{overrides}}; | |
465 | ||
4f858293 RL |
466 | # Build mandatory generated headers |
467 | foreach (@{$unified_info{depends}->{""}}) { dogenerate($_); } | |
468 | ||
1842f369 | 469 | # Build all known libraries, modules, programs and scripts. |
ddf1847d | 470 | # Everything else will be handled as a consequence. |
f246f90e | 471 | foreach (@{$unified_info{libraries}}) { dolib($_); } |
1842f369 | 472 | foreach (@{$unified_info{modules}}) { domodule($_); } |
f246f90e RL |
473 | foreach (@{$unified_info{programs}}) { dobin($_); } |
474 | foreach (@{$unified_info{scripts}}) { doscript($_); } | |
829f86bb RL |
475 | foreach (sort keys %{$unified_info{htmldocs}}) { dodocs('html', $_); } |
476 | foreach (sort keys %{$unified_info{mandocs}}) { dodocs('man', $_); } | |
0ad1d94d | 477 | foreach (sort keys %{$unified_info{dirinfo}}) { dodir($_); } |
ddf1847d | 478 | -} |