build: added public_headers support
[ira/wip.git] / buildtools / mktowscript / mktowscript.pl
1 #!/usr/bin/perl -w
2
3 use strict;
4 use Data::Dumper;
5 use File::Basename;
6
7 my $filename=$ARGV[0];
8 my $dname=dirname($filename);
9
10 sub read_file($)
11 {
12         my $filename = shift;
13         open(CONFIG_MK, "$filename");
14         my @lines = <CONFIG_MK>;
15         close(CONFIG_MK);
16         return @lines;
17 }
18
19 sub trim($)
20 {
21         my $string = shift;
22         $string =~ s/^\s+//;
23         $string =~ s/\s+$//;
24         return $string;
25 }
26
27 sub strlist($)
28 {
29         my $s = shift;
30         $s =~ s/\$\(SHLIBEXT\)/so/g;
31         $s =~ s/\$\(heimdalsrcdir\)/..\/heimdal/g;
32         $s =~ s/\$\(heimdalbuildsrcdir\)/..\/heimdal_build/g;
33         $s =~ s/\$\(nsswitchsrcdir\)/..\/nsswitch/g;
34         $s =~ s/\$\(param_OBJ_FILES\)/..\/pyparam.c/g;
35         $s =~ s/\$\(libclisrcdir\)\///g;
36
37         return trim(join(' ', split(/\s+/, $s)));
38 }
39
40 sub find_file($)
41 {
42         my $f = shift;
43         my $orig = $f;
44
45         my $b = basename($f);
46         return $b if (-e $b);
47
48         return $f if (-e $f);
49         while ($f =~ /\//) {
50                 $f =~ s/^[^\/]+\///g;
51                 #printf(STDERR "Trying $f in $dname\n");
52                 return $f if (-e $f);
53         }
54         my $f2;
55         $f2 = `find . -name $f -type f`;
56         return $f2 unless ($f2 eq "");
57         $f2 = `find .. -name $f -type f`;
58         return $f2 unless ($f2 eq "");
59         $f2 = `find ../.. -name $f -type f`;
60         return $f2 unless ($f2 eq "");
61         $f2 = `find ../../.. -name $f -type f`;
62         return $f2 unless ($f2 eq "");
63         printf(STDERR "Failed to find $orig in $dname\n");
64         exit(1);
65         return '';
66 }
67
68 sub find_files($)
69 {
70         my $list = shift;
71         my $ret = '';
72         foreach my $f (split(/\s+/, $list)) {
73                 if ($f =~ /\.[0-9]$/) {
74                         # a man page
75                         my $m = find_file($f . ".xml");
76                         die("Unable to find man page $f\n") if ($m eq "");
77                         $m =~ s/\.xml$//;
78                         return $m;
79                 }
80                 $f = find_file($f);
81                 $f =~ s/^[.]\///;
82                 $ret .= ' ' . $f;
83         }
84         return strlist($ret);
85 }
86
87 sub read_config_mk($)
88 {
89         my $filename = shift;
90         my @lines = read_file($filename);
91         my $prev = "";
92         my $linenum = 1;
93         my $section = "GLOBAL";
94         my $infragment;
95         my $result;
96         my $line = "";
97         my $secnumber = 1;
98
99         $result->{"GLOBAL"}->{SECNUMBER} = $secnumber++;
100
101         foreach (@lines) {
102                 $linenum++;
103
104                 # lines beginning with '#' are ignored
105                 next if (/^\#.*$/);
106
107                 if (/^(.*)\\$/) {
108                         $prev .= $1;
109                         next;
110                 } else {
111                         $line = "$prev$_";
112                         $prev = "";
113                 }
114
115                 if ($line =~ /^\[(\w+)::([\w-]+)\]/)
116                 {
117                         my $type = $1;
118                         $section = $2;
119                         $infragment = 0;
120
121                         $result->{$section}->{TYPE} = $type;
122                         $result->{$section}->{SECNUMBER} = $secnumber++;
123                         next;
124                 }
125
126                 # include
127                 if ($line =~ /^mkinclude (.*)$/) {
128                         my $subfile = $1;
129                         $result->{$subfile}->{TYPE} = 'SUBCONFIG';
130                         $result->{$subfile}->{SECNUMBER} = $secnumber++;
131                         next;
132                 }
133
134                 # empty line
135                 if ($line =~ /^[ \t]*$/) {
136                         next;
137                 }
138
139                 # global stuff is considered part of the makefile
140                 if ($section eq "GLOBAL") {
141                         $infragment = 1;
142                         next;
143                 }
144
145                 # Assignment
146                 if ($line =~ /^([a-zA-Z0-9_-]+)[\t ]*=(.*)$/) {
147                         $result->{$section}->{$1} = $2;
148                         next;
149                 }
150
151                 # +=
152                 if ($line =~ /^([a-zA-Z0-9_-]+)[\t ]*\+=(.*)$/) {
153                         if (!$result->{$section}->{$1}) {
154                                 $result->{$section}->{$1}="";
155                         }
156                         $result->{$section}->{$1} .= " " . $2;
157                         next;
158                 }
159
160                 if ($line =~ /\$\(eval.\$\(call.proto_header_template.*,(.*),.*/) {
161                         $result->{$section}->{AUTOPROTO} = $1;
162                 }
163                 if ($line =~ /^\$\(eval/) {
164                         # skip eval lines for now
165                         next;
166                 }
167
168                 printf(STDERR "$linenum: Bad line: $line\n");
169         }
170
171         return $result;
172 }
173
174
175 my $result = read_config_mk($filename);
176
177 #print Dumper $result;
178
179 print "# AUTOGENERATED by mktowscript.pl\n# Please remove this notice if hand editing\n\n";
180
181 chdir($dname);
182
183 foreach my $s (sort {$result->{$a}->{SECNUMBER} <=> $result->{$b}->{SECNUMBER}} keys %{$result}) {
184     next if ($s eq "GLOBAL");
185     my $sec = $result->{$s};
186     if ($sec->{TYPE} eq "SUBCONFIG") {
187             my $d = dirname($s);
188             next if ($d eq ".");
189             printf "bld.BUILD_SUBDIR('%s')\n", dirname($s);
190     } else {
191             printf "\nbld.SAMBA_%s('%s'", $sec->{TYPE}, $s;
192             my $trailer="";
193             my $got_src = 0;
194
195             foreach my $k (keys %{$sec}) {
196                     #print "key=$k\n";
197
198                     next if ($k eq "SECNUMBER");
199                     next if ($k eq "TYPE");
200                     if ($k eq "INIT_FUNCTION") {
201                             $trailer .= sprintf(",\n\tinit_function='%s'", trim($sec->{$k}));
202                             next;
203                     }
204                     if ($k eq "INIT_FUNCTION_SENTINEL") {
205                             $trailer .= sprintf(",\n\tinit_function_sentinal='%s'", trim($sec->{$k}));
206                             next;
207                     }
208                     if ($k eq "_PY_FILES" ||
209                         $k eq "EPYDOC_OPTIONS" ||
210                         $k eq "COV_TARGET" ||
211                         $k eq "GCOV" ||
212                         $k eq "PC_FILES" ||
213                         $k eq "CONFIG4FILE" ||
214                         $k eq "LMHOSTSFILE4") {
215                             $trailer .= sprintf(",\n\t# %s='%s'", $k, trim($sec->{$k}));
216                             next;
217                     }
218                     if ($k eq "SUBSYSTEM") {
219                             $trailer .= sprintf(",\n\tsubsystem='%s'", trim($sec->{$k}));
220                             next;
221                     }
222                     if ($k eq "PRIVATE_DEPENDENCIES") {
223                             $trailer .= sprintf(",\n\tdeps='%s'", strlist($sec->{$k}));
224                             next;
225                     }
226                     if ($k eq "PUBLIC_DEPENDENCIES") {
227                             $trailer .= sprintf(",\n\tpublic_deps='%s'", strlist($sec->{$k}));
228                             next;
229                     }
230                     if ($k eq "ALIASES") {
231                             $trailer .= sprintf(",\n\taliases='%s'", strlist($sec->{$k}));
232                             next;
233                     }
234                     if ($k eq "CFLAGS") {
235                             $trailer .= sprintf(",\n\tcflags='%s'", strlist($sec->{$k}));
236                             next;
237                     }
238                     if ($k eq "LDFLAGS") {
239                             $trailer .= sprintf(",\n\tldflags='%s'", strlist($sec->{$k}));
240                             next;
241                     }
242                     if ($k eq "INSTALLDIR") {
243                             $trailer .= sprintf(",\n\tinstalldir='%s'", strlist($sec->{$k}));
244                             next;
245                     }
246                     if ($k eq "ENABLE") {
247                             my $v = strlist($sec->{$k});
248                             if ($v eq "NO") {
249                                     $trailer .= sprintf(",\n\tenabled=False");
250                                     next;
251                             }
252                             next if ($v eq "YES");
253                             die("Unknown ENABLE value $v in $s\n");
254                     }
255                     if ($k eq "$s" . "_VERSION") {
256                             $trailer .= sprintf(",\n\tvnum='%s'", strlist($sec->{$k}));
257                             next;
258                     }
259                     if ($k eq "$s" . "_SOVERSION") {
260                             next;
261                     }
262                     if ($k eq "LIBRARY_REALNAME") {
263                             $trailer .= sprintf(",\n\trealname='%s'", strlist($sec->{$k}));
264                             next;
265                     }
266                     if ($k eq "OUTPUT_TYPE") {
267                             $trailer .= sprintf(",\n\toutput_type='%s'", strlist($sec->{$k}));
268                             next;
269                     }
270                     if ($k eq "AUTOPROTO") {
271                             my $list = trim(find_files(strlist($sec->{$k})));
272                             $trailer .= sprintf(",\n\tautoproto='%s'", $list);
273                             next;
274                     }
275                     if ($k eq "PUBLIC_HEADERS") {
276                             my $list = trim(strlist($sec->{$k}));
277                             if ($list =~ /\$\(addprefix .*,(.*)\)(.*)$/) {
278                                     $list = trim("$1 $2");
279                                     $list = find_files($list);
280                             } else {
281                                     $list = trim(find_files(strlist($sec->{$k})));
282                             }
283                             $trailer .= sprintf(",\n\tpublic_headers='%s'", $list);
284                             next;
285                     }
286                     if ($k eq "MANPAGES") {
287                             my $list = trim(find_files(strlist($sec->{$k})));
288                             $trailer .= sprintf(",\n\tmanpages='%s'", $list);
289                             next;
290                     }
291                     if ($k eq "$s" . "_OBJ_FILES") {
292                             my $list = trim(strlist($sec->{$k}));
293                             $list =~ s/\.o/.c/g;
294                             if ($list =~ /\$\(addprefix .*,(.*)\)(.*)$/) {
295                                     $list = trim("$1 $2");
296                                     $list = find_files($list);
297                                     $list = "'$list'";
298                             } elsif ($list =~ /\$\(addprefix \$\((\w+)\)(.*),(.*)\)(.*)$/) {
299                                     my $src = trim($3);
300                                     my $dir = "$1$2";
301                                     $dir =~ s/\/$//;
302                                     my $res = "bld.SUBDIR('$dir', '$src')";
303                                     if ($4) {
304                                             $res = "$res + '$4'";
305                                     }
306                                     $list = $res;
307                             } else {
308                                     $list = find_files($list);
309                                     $list="'$list'";
310                             }
311                             $list =~ s/\$\(\w+srcdir\)\///g;
312                             printf(",\n\t%s", $list);
313                             $got_src = 1;
314                             next;
315                     }
316                     die("Unknown keyword $k in $s\n");
317             }
318             die("No source list in $s\n") unless $got_src;
319             printf("%s\n\t)\n\n", $trailer);
320     }
321 }
322
323 #print Dumper $result;