Remove extra empty lines in data.mk.
[kai/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         if (not defined($mod->{OUTPUT_TYPE})) {
94                 if ($INPUT->{$mod->{SUBSYSTEM}}->{TYPE} eq "EXT_LIB") {
95                         $mod->{OUTPUT_TYPE} = undef;
96                 } else {
97                         $mod->{OUTPUT_TYPE} = $default_ot;
98                 }
99         }
100
101         if (grep(/SHARED_LIBRARY/, @{$mod->{OUTPUT_TYPE}})) {
102                 my $sane_subsystem = lc($mod->{SUBSYSTEM});
103                 $sane_subsystem =~ s/^lib//;
104                 $mod->{INSTALLDIR} = "MODULESDIR/$sane_subsystem";
105                 push (@{$mod->{PUBLIC_DEPENDENCIES}}, $mod->{SUBSYSTEM});
106                 add_libreplace($mod);
107         } 
108         if (grep(/MERGED_OBJ/, @{$mod->{OUTPUT_TYPE}})) {
109                 push (@{$INPUT->{$mod->{SUBSYSTEM}}{INIT_FUNCTIONS}}, $mod->{INIT_FUNCTION}) if defined($mod->{INIT_FUNCTION});
110                 push (@{$INPUT->{$mod->{SUBSYSTEM}}{PRIVATE_DEPENDENCIES}}, $mod->{NAME});
111         }
112 }
113
114 sub check_library($$$)
115 {
116         my ($INPUT, $lib, $default_ot) = @_;
117
118         return if ($lib->{ENABLE} ne "YES");
119
120         unless (defined($lib->{OUTPUT_TYPE})) { $lib->{OUTPUT_TYPE} = $default_ot; }
121
122         if (defined($lib->{VERSION}) and not defined($lib->{SO_VERSION})) {
123                 print "$lib->{NAME}: Please specify SO_VERSION when specifying VERSION\n";
124                 return;
125         }
126
127         if (defined($lib->{SO_VERSION}) and not defined($lib->{VERSION})) {
128                 print "$lib->{NAME}: Please specify VERSION when specifying SO_VERSION\n";
129                 return;
130         }
131
132         unless (defined($lib->{INIT_FUNCTION_TYPE})) { $lib->{INIT_FUNCTION_TYPE} = "NTSTATUS (*) (void)"; }
133         unless (defined($lib->{INIT_FUNCTION_SENTINEL})) { $lib->{INIT_FUNCTION_SENTINEL} = "NULL"; }
134         unless (defined($lib->{INSTALLDIR})) { $lib->{INSTALLDIR} = "LIBDIR"; }
135
136         add_libreplace($lib);
137 }
138
139 sub check_python($$$)
140 {
141         my ($INPUT, $python, $default_ot) = @_;
142
143         return if ($INPUT->{LIBPYTHON}{ENABLE} ne "YES");
144
145         $python->{INSTALLDIR} = "PYTHONDIR";
146         unless (defined($python->{CFLAGS})) { $python->{CFLAGS} = []; }
147         if (defined($python->{SWIG_FILE})) {
148                 my $dirname = dirname($python->{SWIG_FILE});
149                 my $basename = basename($python->{SWIG_FILE}, ".i");
150
151                 $dirname .= "/" unless $dirname =~ /\/$/;
152                 $dirname = "" if $dirname eq "./";
153
154                 $python->{LIBRARY_REALNAME} = "_$basename.\$(SHLIBEXT)";
155                 $python->{PYTHON_FILES} = ["$dirname$basename.py"];
156                 push (@{$python->{CFLAGS}}, "\$(CFLAG_NO_UNUSED_MACROS)");
157                 push (@{$python->{CFLAGS}}, "\$(CFLAG_NO_CAST_QUAL)");
158                 $python->{INIT_FUNCTION} = "{ (char *)\"_$basename\", init_$basename }";
159         } else {
160                 my $basename = $python->{NAME};
161                 $basename =~ s/^python_//g;
162                 $python->{LIBRARY_REALNAME} = "$basename.\$(SHLIBEXT)";
163                 $python->{INIT_FUNCTION} = "{ (char *)\"$basename\", init$basename }";
164         }
165         push (@{$python->{CFLAGS}}, "\$(EXT_LIB_PYTHON_CFLAGS)");
166
167         $python->{SUBSYSTEM} = "LIBPYTHON";
168
169         check_module($INPUT, $python, $default_ot);
170 }
171
172 sub check_binary($$)
173 {
174         my ($INPUT, $bin) = @_;
175
176         return if ($bin->{ENABLE} ne "YES");
177
178         ($bin->{BINARY} = (lc $bin->{NAME})) if not defined($bin->{BINARY});
179
180         $bin->{OUTPUT_TYPE} = ["BINARY"];
181         add_libreplace($bin);
182 }
183
184 sub add_implicit($$)
185 {
186         my ($INPUT, $n) = @_;
187
188         $INPUT->{$n} = {
189                 TYPE => "MAKE_RULE",
190                 NAME => $n,
191                 OUTPUT_TYPE => undef,
192                 LIBS => ["\$(".uc($n)."_LIBS)"],
193                 LDFLAGS => ["\$(".uc($n)."_LDFLAGS)"],
194                 CFLAGS => ["\$(".uc($n)."_CFLAGS)"],
195                 CPPFLAGS => ["\$(".uc($n)."_CPPFLAGS)"]
196         };
197 }
198
199 sub calc_unique_deps($$$$$$$$)
200 {
201         sub calc_unique_deps($$$$$$$$);
202         my ($name, $INPUT, $deps, $udeps, $withlibs, $forward, $pubonly, $busy) = @_;
203
204         foreach my $n (@$deps) {
205                 add_implicit($INPUT, $n) unless (defined($INPUT->{$n}));
206                 my $dep = $INPUT->{$n};
207                 if (grep (/^$n$/, @$busy)) {
208                         next if (@{$dep->{OUTPUT_TYPE}}[0] eq "MERGED_OBJ");
209                         die("Recursive dependency: $n, list: " . join(',', @$busy));
210                 }
211                 next if (grep /^$n$/, @$udeps);
212
213                 push (@{$udeps}, $dep->{NAME}) if $forward;
214
215                 if (defined ($dep->{OUTPUT_TYPE}) && 
216                         ($withlibs or 
217                         (@{$dep->{OUTPUT_TYPE}}[0] eq "MERGED_OBJ") or 
218                         (@{$dep->{OUTPUT_TYPE}}[0] eq "STATIC_LIBRARY"))) {
219                                 push (@$busy, $dep->{NAME});
220                                 calc_unique_deps($dep->{NAME}, $INPUT, $dep->{PUBLIC_DEPENDENCIES}, $udeps, $withlibs, $forward, $pubonly, $busy);
221                                 calc_unique_deps($dep->{NAME}, $INPUT, $dep->{PRIVATE_DEPENDENCIES}, $udeps, $withlibs, $forward, $pubonly, $busy) unless $pubonly;
222                                 pop (@$busy);
223                 }
224
225                 unshift (@{$udeps}, $dep->{NAME}) unless $forward;
226         }
227 }
228
229 sub check($$$$$)
230 {
231         my ($INPUT, $enabled, $subsys_ot, $lib_ot, $module_ot) = @_;
232
233         foreach my $part (values %$INPUT) {
234                 if (defined($enabled->{$part->{NAME}})) { 
235                         $part->{ENABLE} = $enabled->{$part->{NAME}};
236                         next;
237                 }
238                 
239                 unless(defined($part->{ENABLE})) {
240                         if ($part->{TYPE} eq "EXT_LIB") {
241                                 $part->{ENABLE} = "NO";
242                         } else {
243                                 $part->{ENABLE} = "YES";
244                         }
245                 }
246         }
247
248         foreach my $part (values %$INPUT) {
249                 $part->{LINK_FLAGS} = [];
250                 $part->{FULL_OBJ_LIST} = ["\$($part->{NAME}_OBJ_FILES)"];
251
252                 if ($part->{TYPE} eq "SUBSYSTEM") { 
253                         check_subsystem($INPUT, $part, $subsys_ot);
254                 } elsif ($part->{TYPE} eq "MODULE") {
255                         check_module($INPUT, $part, $module_ot);
256                 } elsif ($part->{TYPE} eq "LIBRARY") {
257                         check_library($INPUT, $part, $lib_ot);
258                 } elsif ($part->{TYPE} eq "BINARY") {
259                         check_binary($INPUT, $part);
260                 } elsif ($part->{TYPE} eq "PYTHON") {
261                         check_python($INPUT, $part, $module_ot);
262                 } elsif ($part->{TYPE} eq "EXT_LIB") {
263                 } else {
264                         die("Unknown type $part->{TYPE}");
265                 }
266         }
267
268         foreach my $part (values %$INPUT) {
269                 if (defined($part->{INIT_FUNCTIONS})) {
270                         push (@{$part->{LINK_FLAGS}}, "\$(DYNEXP)");
271                 }
272         }
273
274         foreach my $part (values %$INPUT) {
275                 $part->{UNIQUE_DEPENDENCIES_LINK} = [];
276                 calc_unique_deps($part->{NAME}, $INPUT, $part->{PUBLIC_DEPENDENCIES}, $part->{UNIQUE_DEPENDENCIES_LINK}, 0, 0, 0, []);
277                 calc_unique_deps($part->{NAME}, $INPUT, $part->{PRIVATE_DEPENDENCIES}, $part->{UNIQUE_DEPENDENCIES_LINK}, 0, 0, 0, []);
278         }
279
280         foreach my $part (values %$INPUT) {
281                 $part->{UNIQUE_DEPENDENCIES_COMPILE} = [];
282                 calc_unique_deps($part->{NAME}, $INPUT, $part->{PUBLIC_DEPENDENCIES}, $part->{UNIQUE_DEPENDENCIES_COMPILE}, 1, 1, 1, []);
283                 calc_unique_deps($part->{NAME}, $INPUT, $part->{PRIVATE_DEPENDENCIES}, $part->{UNIQUE_DEPENDENCIES_COMPILE}, 1, 1, 1, []);
284         }
285
286         foreach my $part (values %$INPUT) {
287                 $part->{UNIQUE_DEPENDENCIES_ALL} = [];
288                 calc_unique_deps($part->{NAME}, $INPUT, $part->{PUBLIC_DEPENDENCIES}, $part->{UNIQUE_DEPENDENCIES_ALL}, 1, 0, 0, []);
289                 calc_unique_deps($part->{NAME}, $INPUT, $part->{PRIVATE_DEPENDENCIES}, $part->{UNIQUE_DEPENDENCIES_ALL}, 1, 0, 0, []);
290         }
291
292         return $INPUT;
293 }
294
295 1;