Merge Samba3 and Samba4 together
[amitay/samba.git] / source4 / build / smb_build / input.pm
1 # Samba Build System
2 # - the input checking functions
3 #
4 #  Copyright (C) Stefan (metze) Metzmacher 2004
5 #  Copyright (C) Jelmer Vernooij 2004
6 #  Released under the GNU GPL
7
8 use strict;
9 package smb_build::input;
10 use File::Basename;
11
12 sub strtrim($)
13 {
14         $_ = shift;
15         s/^[\t\n ]*//g;
16         s/[\t\n ]*$//g;
17         return $_;
18 }
19
20 sub str2array($)
21 {
22         $_ = shift;
23         s/^[\t\n ]*//g;
24         s/[\t\n ]*$//g;
25         s/([\t\n ]+)/ /g;
26
27         return () if (length($_)==0);
28         return split /[ \t\n]/;
29 }
30
31 sub add_libreplace($)
32 {
33         my ($part) = @_;
34
35         return if ($part->{NAME} eq "LIBREPLACE");
36         return if ($part->{NAME} eq "LIBREPLACE_HOSTCC");
37         return if ($part->{NAME} eq "REPLACE_READDIR");
38
39         foreach my $n (@{$part->{PRIVATE_DEPENDENCIES}}) {
40                 return if ($n eq "LIBREPLACE");
41                 return if ($n eq "LIBREPLACE_HOSTCC");
42         }
43         foreach my $n (@{$part->{PUBLIC_DEPENDENCIES}}) {
44                 return if ($n eq "LIBREPLACE");
45                 return if ($n eq "LIBREPLACE_HOSTCC");
46         }
47
48         if (defined($part->{USE_HOSTCC}) && $part->{USE_HOSTCC} eq "YES") {
49                 unshift (@{$part->{PRIVATE_DEPENDENCIES}}, "LIBREPLACE_HOSTCC");
50         } else {
51                 unshift (@{$part->{PRIVATE_DEPENDENCIES}}, "LIBREPLACE");
52         }
53 }
54
55 sub check_subsystem($$$)
56 {
57         my ($INPUT, $subsys, $default_ot) = @_;
58         return if ($subsys->{ENABLE} ne "YES");
59         
60         unless (defined($subsys->{OUTPUT_TYPE})) { $subsys->{OUTPUT_TYPE} = $default_ot; }
61         unless (defined($subsys->{INIT_FUNCTION_TYPE})) { $subsys->{INIT_FUNCTION_TYPE} = "NTSTATUS (*) (void)"; }
62         unless (defined($subsys->{INIT_FUNCTION_SENTINEL})) { $subsys->{INIT_FUNCTION_SENTINEL} = "NULL"; }
63 }
64
65 sub check_module($$$)
66 {
67         my ($INPUT, $mod, $default_ot) = @_;
68
69         die("Module $mod->{NAME} does not have a SUBSYSTEM set") if not defined($mod->{SUBSYSTEM});
70
71         if (not exists($INPUT->{$mod->{SUBSYSTEM}}{INIT_FUNCTIONS})) {
72                 $INPUT->{$mod->{SUBSYSTEM}}{INIT_FUNCTIONS} = [];
73         }
74
75         if (!(defined($INPUT->{$mod->{SUBSYSTEM}}))) {
76                 die("Unknown subsystem $mod->{SUBSYSTEM} for module $mod->{NAME}");
77         }
78
79         if ($INPUT->{$mod->{SUBSYSTEM}} eq "NO") {
80                 warn("Disabling module $mod->{NAME} because subsystem $mod->{SUBSYSTEM} is disabled");
81                 $mod->{ENABLE} = "NO";
82                 return;
83         }
84
85         return if ($mod->{ENABLE} ne "YES");
86
87         if (exists($INPUT->{$mod->{SUBSYSTEM}}{INIT_FUNCTION_TYPE})) {
88                 $mod->{INIT_FUNCTION_TYPE} = $INPUT->{$mod->{SUBSYSTEM}}{INIT_FUNCTION_TYPE};
89         } else {
90                 $mod->{INIT_FUNCTION_TYPE} = "NTSTATUS (*) (void)";
91         }
92
93         unless (defined($mod->{INIT_FUNCTION_SENTINEL})) { $mod->{INIT_FUNCTION_SENTINEL} = "NULL"; }
94
95         if (not defined($mod->{OUTPUT_TYPE})) {
96                 if ((not defined($INPUT->{$mod->{SUBSYSTEM}}->{TYPE})) or 
97                         $INPUT->{$mod->{SUBSYSTEM}}->{TYPE} eq "EXT_LIB") {
98                         $mod->{OUTPUT_TYPE} = undef;
99                 } else {
100                         $mod->{OUTPUT_TYPE} = $default_ot;
101                 }
102         }
103
104         if (grep(/SHARED_LIBRARY/, @{$mod->{OUTPUT_TYPE}})) {
105                 my $sane_subsystem = lc($mod->{SUBSYSTEM});
106                 $sane_subsystem =~ s/^lib//;
107                 $mod->{INSTALLDIR} = "MODULESDIR/$sane_subsystem";
108                 push (@{$mod->{PUBLIC_DEPENDENCIES}}, $mod->{SUBSYSTEM});
109                 add_libreplace($mod);
110         } 
111         if (grep(/MERGED_OBJ/, @{$mod->{OUTPUT_TYPE}})) {
112                 push (@{$INPUT->{$mod->{SUBSYSTEM}}{INIT_FUNCTIONS}}, $mod->{INIT_FUNCTION}) if defined($mod->{INIT_FUNCTION});
113                 push (@{$INPUT->{$mod->{SUBSYSTEM}}{PRIVATE_DEPENDENCIES}}, $mod->{NAME});
114         }
115 }
116
117 sub check_library($$$)
118 {
119         my ($INPUT, $lib, $default_ot) = @_;
120
121         return if ($lib->{ENABLE} ne "YES");
122
123         unless (defined($lib->{OUTPUT_TYPE})) { $lib->{OUTPUT_TYPE} = $default_ot; }
124
125         unless (defined($lib->{INIT_FUNCTION_TYPE})) { $lib->{INIT_FUNCTION_TYPE} = "NTSTATUS (*) (void)"; }
126         unless (defined($lib->{INIT_FUNCTION_SENTINEL})) { $lib->{INIT_FUNCTION_SENTINEL} = "NULL"; }
127         unless (defined($lib->{INSTALLDIR})) { $lib->{INSTALLDIR} = "LIBDIR"; }
128
129         add_libreplace($lib);
130 }
131
132 sub check_python($$$)
133 {
134         my ($INPUT, $python, $default_ot) = @_;
135
136         return if ($INPUT->{LIBPYTHON}{ENABLE} ne "YES");
137
138         $python->{INSTALLDIR} = "PYTHONDIR";
139         unless (defined($python->{CFLAGS})) { $python->{CFLAGS} = []; }
140         my $basename = $python->{NAME};
141         $basename =~ s/^python_//g;
142         unless (defined($python->{LIBRARY_REALNAME})) {
143                 $python->{LIBRARY_REALNAME} = "$basename.\$(SHLIBEXT)";
144         }
145         $python->{INIT_FUNCTION} = "{ (char *)\"$basename\", init$basename }";
146         push (@{$python->{CFLAGS}}, "\$(EXT_LIB_PYTHON_CFLAGS)");
147
148         $python->{SUBSYSTEM} = "LIBPYTHON";
149
150         check_module($INPUT, $python, $default_ot);
151 }
152
153 sub check_binary($$)
154 {
155         my ($INPUT, $bin) = @_;
156
157         return if ($bin->{ENABLE} ne "YES");
158
159         ($bin->{BINARY} = (lc $bin->{NAME})) if not defined($bin->{BINARY});
160         unless (defined($bin->{INIT_FUNCTION_SENTINEL})) { $bin->{INIT_FUNCTION_SENTINEL} = "NULL"; }
161         unless (defined($bin->{INIT_FUNCTION_TYPE})) { $bin->{INIT_FUNCTION_TYPE} = "NTSTATUS (*) (void)"; }
162
163         $bin->{OUTPUT_TYPE} = ["BINARY"];
164         add_libreplace($bin);
165 }
166
167 sub add_implicit($$)
168 {
169         my ($INPUT, $n) = @_;
170
171         $INPUT->{$n}->{TYPE} = "MAKE_RULE";
172         $INPUT->{$n}->{NAME} = $n;
173         $INPUT->{$n}->{OUTPUT_TYPE} = undef;
174         $INPUT->{$n}->{LIBS} = ["\$(".uc($n)."_LIBS)"];
175         $INPUT->{$n}->{LDFLAGS} = ["\$(".uc($n)."_LDFLAGS)"];
176         $INPUT->{$n}->{CFLAGS} = ["\$(".uc($n)."_CFLAGS)"];
177         $INPUT->{$n}->{CPPFLAGS} = ["\$(".uc($n)."_CPPFLAGS)"];
178         $INPUT->{$n}->{ENABLE} = "YES";
179 }
180
181 sub calc_unique_deps($$$$$$$$)
182 {
183         sub calc_unique_deps($$$$$$$$);
184         my ($name, $INPUT, $deps, $udeps, $withlibs, $forward, $pubonly, $busy) = @_;
185
186         foreach my $n (@$deps) {
187                 add_implicit($INPUT, $n) unless (defined($INPUT->{$n}) and defined($INPUT->{$n}->{TYPE}));
188                 my $dep = $INPUT->{$n};
189                 if (grep (/^$n$/, @$busy)) {
190                         next if (@{$dep->{OUTPUT_TYPE}}[0] eq "MERGED_OBJ");
191                         die("Recursive dependency: $n, list: " . join(',', @$busy));
192                 }
193                 next if (grep /^$n$/, @$udeps);
194
195                 push (@{$udeps}, $n) if $forward;
196
197                 if (defined ($dep->{OUTPUT_TYPE}) && 
198                         ($withlibs or 
199                         (@{$dep->{OUTPUT_TYPE}}[0] eq "MERGED_OBJ") or 
200                         (@{$dep->{OUTPUT_TYPE}}[0] eq "STATIC_LIBRARY"))) {
201                                 push (@$busy, $n);
202                                 calc_unique_deps($n, $INPUT, $dep->{PUBLIC_DEPENDENCIES}, $udeps, $withlibs, $forward, $pubonly, $busy);
203                                 calc_unique_deps($n, $INPUT, $dep->{PRIVATE_DEPENDENCIES}, $udeps, $withlibs, $forward, $pubonly, $busy) unless $pubonly;
204                                 pop (@$busy);
205                 }
206
207                 unshift (@{$udeps}, $n) unless $forward;
208         }
209 }
210
211 sub check($$$$$)
212 {
213         my ($INPUT, $enabled, $subsys_ot, $lib_ot, $module_ot) = @_;
214
215         foreach my $part (values %$INPUT) {
216                 if (defined($enabled->{$part->{NAME}})) { 
217                         $part->{ENABLE} = $enabled->{$part->{NAME}};
218                         next;
219                 }
220                 
221                 unless(defined($part->{ENABLE})) {
222                         if ($part->{TYPE} eq "EXT_LIB") {
223                                 $part->{ENABLE} = "NO";
224                         } else {
225                                 $part->{ENABLE} = "YES";
226                         }
227                 }
228         }
229
230         foreach my $part (values %$INPUT) {
231                 $part->{LINK_FLAGS} = [];
232                 $part->{FULL_OBJ_LIST} = ["\$($part->{NAME}_OBJ_FILES)"];
233
234                 if ($part->{TYPE} eq "SUBSYSTEM") { 
235                         check_subsystem($INPUT, $part, $subsys_ot);
236                 } elsif ($part->{TYPE} eq "MODULE") {
237                         check_module($INPUT, $part, $module_ot);
238                 } elsif ($part->{TYPE} eq "LIBRARY") {
239                         check_library($INPUT, $part, $lib_ot);
240                 } elsif ($part->{TYPE} eq "BINARY") {
241                         check_binary($INPUT, $part);
242                 } elsif ($part->{TYPE} eq "PYTHON") {
243                         check_python($INPUT, $part, $module_ot);
244                 } elsif ($part->{TYPE} eq "EXT_LIB") {
245                 } else {
246                         die("Unknown type $part->{TYPE}");
247                 }
248         }
249
250         foreach my $part (values %$INPUT) {
251                 if (defined($part->{INIT_FUNCTIONS})) {
252                         push (@{$part->{LINK_FLAGS}}, "\$(DYNEXP)");
253                 }
254         }
255
256         foreach my $part (values %$INPUT) {
257                 $part->{UNIQUE_DEPENDENCIES_LINK} = [];
258                 calc_unique_deps($part->{NAME}, $INPUT, $part->{PUBLIC_DEPENDENCIES}, $part->{UNIQUE_DEPENDENCIES_LINK}, 0, 0, 0, []);
259                 calc_unique_deps($part->{NAME}, $INPUT, $part->{PRIVATE_DEPENDENCIES}, $part->{UNIQUE_DEPENDENCIES_LINK}, 0, 0, 0, []);
260         }
261
262         foreach my $part (values %$INPUT) {
263                 $part->{UNIQUE_DEPENDENCIES_COMPILE} = [];
264                 calc_unique_deps($part->{NAME}, $INPUT, $part->{PUBLIC_DEPENDENCIES}, $part->{UNIQUE_DEPENDENCIES_COMPILE}, 1, 1, 1, []);
265                 calc_unique_deps($part->{NAME}, $INPUT, $part->{PRIVATE_DEPENDENCIES}, $part->{UNIQUE_DEPENDENCIES_COMPILE}, 1, 1, 1, []);
266         }
267
268         foreach my $part (values %$INPUT) {
269                 $part->{UNIQUE_DEPENDENCIES_ALL} = [];
270                 calc_unique_deps($part->{NAME}, $INPUT, $part->{PUBLIC_DEPENDENCIES}, $part->{UNIQUE_DEPENDENCIES_ALL}, 1, 0, 0, []);
271                 calc_unique_deps($part->{NAME}, $INPUT, $part->{PRIVATE_DEPENDENCIES}, $part->{UNIQUE_DEPENDENCIES_ALL}, 1, 0, 0, []);
272         }
273
274         return $INPUT;
275 }
276
277 1;