]>
Commit | Line | Data |
---|---|---|
ddf1847d RL |
1 | {- # -*- Mode: perl -*- |
2 | ||
b23238f9 RL |
3 | # A cache of objects for which a recipe has already been generated |
4 | my %cache; | |
ddf1847d RL |
5 | |
6 | # resolvedepends and reducedepends work in tandem to make sure | |
7 | # there are no duplicate dependencies and that they are in the | |
8 | # right order. This is especially used to sort the list of | |
9 | # libraries that a build depends on. | |
10 | sub resolvedepends { | |
11 | my $thing = shift; | |
12 | my @listsofar = @_; # to check if we're looping | |
13 | my @list = @{$unified_info{depends}->{$thing}}; | |
14 | my @newlist = (); | |
15 | if (scalar @list) { | |
16 | foreach my $item (@list) { | |
17 | # It's time to break off when the dependency list starts looping | |
18 | next if grep { $_ eq $item } @listsofar; | |
19 | push @newlist, $item, resolvedepends($item, @listsofar, $item); | |
20 | } | |
21 | } | |
22 | @newlist; | |
23 | } | |
24 | sub reducedepends { | |
25 | my @list = @_; | |
26 | my @newlist = (); | |
27 | while (@list) { | |
28 | my $item = shift @list; | |
29 | push @newlist, $item | |
30 | unless grep { $item eq $_ } @list; | |
31 | } | |
32 | @newlist; | |
33 | } | |
34 | ||
d4605727 RL |
35 | # dogenerate is responsible for producing all the recipes that build |
36 | # generated source files. It recurses in case a dependency is also a | |
37 | # generated source file. | |
ae4c7450 RL |
38 | sub dogenerate { |
39 | my $src = shift; | |
40 | return "" if $cache{$src}; | |
d4605727 RL |
41 | my $obj = shift; |
42 | my $bin = shift; | |
ae4c7450 RL |
43 | my %opts = @_; |
44 | if ($unified_info{generate}->{$src}) { | |
45 | $OUT .= generatesrc(src => $src, | |
46 | generator => $unified_info{generate}->{$src}, | |
47 | deps => $unified_info{depends}->{$src}, | |
d4605727 RL |
48 | incs => [ @{$unified_info{includes}->{$bin}}, |
49 | @{$unified_info{includes}->{$obj}} ], | |
ae4c7450 RL |
50 | %opts); |
51 | foreach (@{$unified_info{depends}->{$src}}) { | |
d4605727 | 52 | dogenerate($_, $obj, $bin, %opts); |
ae4c7450 RL |
53 | } |
54 | } | |
55 | $cache{$src} = 1; | |
56 | } | |
57 | ||
ddf1847d RL |
58 | # doobj is responsible for producing all the recipes that build |
59 | # object files as well as dependency files. | |
60 | sub doobj { | |
61 | my $obj = shift; | |
b23238f9 | 62 | return "" if $cache{$obj}; |
ddf1847d RL |
63 | (my $obj_no_o = $obj) =~ s|\.o$||; |
64 | my $bin = shift; | |
45502bfe | 65 | my %opts = @_; |
ddf1847d RL |
66 | if (@{$unified_info{sources}->{$obj}}) { |
67 | $OUT .= src2obj(obj => $obj_no_o, | |
68 | srcs => $unified_info{sources}->{$obj}, | |
ae4c7450 | 69 | deps => $unified_info{depends}->{$obj}, |
ddf1847d | 70 | incs => [ @{$unified_info{includes}->{$bin}}, |
45502bfe RL |
71 | @{$unified_info{includes}->{$obj}} ], |
72 | %opts); | |
ae4c7450 RL |
73 | foreach ((@{$unified_info{sources}->{$obj}}, |
74 | @{$unified_info{depends}->{$obj}})) { | |
d4605727 | 75 | dogenerate($_, $obj, $bin, %opts); |
ae4c7450 | 76 | } |
ddf1847d | 77 | } |
b23238f9 | 78 | $cache{$obj} = 1; |
ddf1847d RL |
79 | } |
80 | ||
81 | # dolib is responsible for building libraries. It will call | |
82 | # libobj2shlib is shared libraries are produced, and obj2lib in all | |
83 | # cases. It also makes sure all object files for the library are | |
84 | # built. | |
85 | sub dolib { | |
86 | my $lib = shift; | |
b23238f9 | 87 | return "" if $cache{$lib}; |
84af1bae | 88 | unless ($disabled{shared}) { |
ddf1847d RL |
89 | my %ordinals = |
90 | $unified_info{ordinals}->{$lib} | |
91 | ? (ordinals => $unified_info{ordinals}->{$lib}) : (); | |
92 | $OUT .= libobj2shlib(shlib => $unified_info{sharednames}->{$lib}, | |
93 | lib => $lib, | |
94 | objs => [ map { (my $x = $_) =~ s|\.o$||; $x } | |
2a08d1a0 RL |
95 | (@{$unified_info{sources}->{$lib}}, |
96 | @{$unified_info{shared_sources}->{$lib}}) ], | |
ddf1847d RL |
97 | deps => [ reducedepends(resolvedepends($lib)) ], |
98 | %ordinals); | |
2a08d1a0 | 99 | map { doobj($_, $lib, intent => "lib") } @{$unified_info{shared_sources}->{$lib}}; |
ddf1847d RL |
100 | } |
101 | $OUT .= obj2lib(lib => $lib, | |
102 | objs => [ map { (my $x = $_) =~ s|\.o$||; $x } | |
103 | @{$unified_info{sources}->{$lib}} ]); | |
104 | map { doobj($_, $lib, intent => "lib") } @{$unified_info{sources}->{$lib}}; | |
b23238f9 | 105 | $cache{$lib} = 1; |
ddf1847d RL |
106 | } |
107 | ||
108 | # doengine is responsible for building engines. It will call | |
5386287c | 109 | # obj2dso, and also makes sure all object files for the library |
ddf1847d RL |
110 | # are built. |
111 | sub doengine { | |
112 | my $lib = shift; | |
b23238f9 | 113 | return "" if $cache{$lib}; |
5386287c RL |
114 | $OUT .= obj2dso(lib => $lib, |
115 | objs => [ map { (my $x = $_) =~ s|\.o$||; $x } | |
2a08d1a0 RL |
116 | (@{$unified_info{sources}->{$lib}}, |
117 | @{$unified_info{shared_sources}->{$lib}}) ], | |
5386287c | 118 | deps => [ resolvedepends($lib) ]); |
2a08d1a0 RL |
119 | map { doobj($_, $lib, intent => "dso") } (@{$unified_info{sources}->{$lib}}, |
120 | @{$unified_info{shared_sources}->{$lib}}); | |
b23238f9 | 121 | $cache{$lib} = 1; |
ddf1847d RL |
122 | } |
123 | ||
124 | # dobin is responsible for building programs. It will call obj2bin, | |
125 | # and also makes sure all object files for the library are built. | |
126 | sub dobin { | |
127 | my $bin = shift; | |
b23238f9 | 128 | return "" if $cache{$bin}; |
ddf1847d RL |
129 | my $deps = [ reducedepends(resolvedepends($bin)) ]; |
130 | $OUT .= obj2bin(bin => $bin, | |
131 | objs => [ map { (my $x = $_) =~ s|\.o$||; $x } | |
132 | @{$unified_info{sources}->{$bin}} ], | |
133 | deps => $deps); | |
134 | map { doobj($_, $bin, intent => "bin") } @{$unified_info{sources}->{$bin}}; | |
b23238f9 | 135 | $cache{$bin} = 1; |
ddf1847d RL |
136 | } |
137 | ||
138 | # dobin is responsible for building scripts from templates. It will | |
139 | # call in2script. | |
140 | sub doscript { | |
141 | my $script = shift; | |
b23238f9 | 142 | return "" if $cache{$script}; |
ddf1847d RL |
143 | $OUT .= in2script(script => $script, |
144 | sources => $unified_info{sources}->{$script}); | |
b23238f9 | 145 | $cache{$script} = 1; |
ddf1847d RL |
146 | } |
147 | ||
8a67946e RL |
148 | # Start with populating the cache with all the overrides |
149 | %cache = map { $_ => 1 } @{$unified_info{overrides}}; | |
150 | ||
ddf1847d RL |
151 | # Build all known libraries, engines, programs and scripts. |
152 | # Everything else will be handled as a consequence. | |
153 | map { dolib($_) } @{$unified_info{libraries}}; | |
154 | map { doengine($_) } @{$unified_info{engines}}; | |
155 | map { dobin($_) } @{$unified_info{programs}}; | |
156 | map { doscript($_) } @{$unified_info{scripts}}; | |
157 | ||
158 | # Finally, should there be any applicable BEGINRAW/ENDRAW sections, | |
159 | # they are added here. | |
160 | $OUT .= $_."\n" foreach(@{$unified_info{rawlines}}); | |
161 | -} |