evr: Fix typo in video_mixer_init_dxva_videodesc() (Coverity).
[wine.git] / tools / make_makefiles
blobc18fa90e2d3e9483ca560f2d110d5cdc064a436b
1 #!/usr/bin/perl -w
3 # Build the auto-generated parts of the Wine makefiles.
5 # Copyright 2006 Alexandre Julliard
7 # This library is free software; you can redistribute it and/or
8 # modify it under the terms of the GNU Lesser General Public
9 # License as published by the Free Software Foundation; either
10 # version 2.1 of the License, or (at your option) any later version.
12 # This library is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 # Lesser General Public License for more details.
17 # You should have received a copy of the GNU Lesser General Public
18 # License along with this library; if not, write to the Free Software
19 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 use strict;
24 # Dlls and programs that are 16-bit specific
25 my %modules16 =
27 "ifsmgr.vxd" => 1,
28 "mmdevldr.vxd" => 1,
29 "monodebg.vxd" => 1,
30 "vdhcp.vxd" => 1,
31 "vmm.vxd" => 1,
32 "vnbt.vxd" => 1,
33 "vnetbios.vxd" => 1,
34 "vtdapi.vxd" => 1,
35 "vwin32.vxd" => 1,
36 "w32skrnl.dll" => 1,
37 "winevdm.exe" => 1,
38 "wow32.dll" => 1,
41 my %exported_wine_headers = (
42 "wine/debug.h" => 1,
43 "wine/exception.h" => 1,
44 "wine/library.h" => 1,
45 "wine/itss.idl" => 1,
46 "wine/svcctl.idl" => 1,
49 my %ignored_source_files = (
50 "dlls/wineps.drv/afm2c.c" => 1,
51 "dlls/wineps.drv/mkagl.c" => 1,
52 "include/config.h.in" => 1,
53 "include/stamp-h.in" => 1,
54 "programs/winetest/dist.rc" => 1,
55 "tools/makedep.c" => 1,
58 my @source_vars = (
59 "BISON_SRCS",
60 "C_SRCS",
61 "FONT_SRCS",
62 "HEADER_SRCS",
63 "IDL_SRCS",
64 "IN_SRCS",
65 "LEX_SRCS",
66 "MANPAGES",
67 "MC_SRCS",
68 "OBJC_SRCS",
69 "PO_SRCS",
70 "RC_SRCS",
71 "SOURCES",
72 "SVG_SRCS",
73 "XTEMPLATE_SRCS"
76 my (@makefiles, %makefiles);
77 my @inf_files;
78 my @nls_files;
80 sub dirname($)
82 my $ret = shift;
83 return "" unless $ret =~ /\//;
84 $ret =~ s!/[^/]*$!!;
85 return $ret;
88 # update a file if changed
89 sub update_file($$)
91 my $file = shift;
92 my $new = shift;
94 open FILE, ">$file.new" or die "cannot create $file.new";
95 print FILE $new;
96 close FILE;
97 rename "$file.new", "$file";
98 print "$file updated\n";
99 if ($file eq "configure.ac")
101 system "autoconf";
102 print "configure updated\n";
106 # replace some lines in a file between two markers
107 sub replace_in_file($$$@)
109 my $file = shift;
110 my $start = shift;
111 my $end = shift;
112 my ($old, $new);
114 open OLD_FILE, "$file" or die "cannot open $file";
115 while (<OLD_FILE>)
117 $old .= $_;
118 last if /$start/;
119 $new .= $_;
122 $new .= join "", @_;
124 my $skip = 1;
125 while (<OLD_FILE>)
127 $old .= $_;
128 $new .= $_ unless $skip;
129 $skip = 0 if /$end/;
132 close OLD_FILE;
133 update_file($file, $new) if $old ne $new;
136 # replace all source variables in a makefile
137 sub replace_makefile_variables($)
139 my $file = shift;
140 my $make = $makefiles{$file};
141 my $source_vars_regexp = join "|", @source_vars;
142 my %replaced;
143 my $old;
144 my $new;
146 open OLD_FILE, "$file.in" or die "cannot open $file.in";
147 while (<OLD_FILE>)
149 $old .= $_;
150 if (/^\s*($source_vars_regexp)(\s*)=/)
152 # try to preserve formatting
153 my $var = $1;
154 my $spaces = $2;
155 my $replaced = 0;
156 my @values;
158 if (defined ${$make}{"=$var"})
160 @values = @{${$make}{"=$var"}};
161 ${$make}{$var} = \@values;
163 else
165 undef ${$make}{$var};
167 my $multiline = /\\$/ || (@values > 1);
168 my $old_str = $_;
169 while (/\\$/)
171 $_ = <OLD_FILE>;
172 last unless $_;
173 $old .= $_;
174 $old_str .= $_;
176 my $new_str = "";
177 if (!@values)
179 # nothing
181 elsif ($multiline)
183 $new_str = "$var = \\\n\t" . join(" \\\n\t", sort @values) . "\n";
184 $new .= $new_str;
186 else
188 $new_str = "$var$spaces= @values\n";
189 $new .= $new_str;
191 $replaced{$var} = 1;
192 next;
194 $new .= $_;
196 # if we are using SOURCES, ignore the other variables
197 unless ($replaced{"SOURCES"})
199 foreach my $var (@source_vars)
201 next if defined $replaced{$var};
202 next if $var eq "SOURCES";
203 next unless defined ${$make}{"=$var"};
204 my @values = @{${$make}{"=$var"}};
205 next unless @values;
206 $new .= "\n$var = \\\n\t" . join(" \\\n\t", sort @values) . "\n";
209 close OLD_FILE;
210 update_file("$file.in", $new) if $old ne $new;
213 # parse the specified makefile and load the variables
214 sub parse_makefile($)
216 my $file = shift;
217 my %make;
219 ($make{"=dir"} = $file) =~ s/[^\/]+$//;
221 open MAKE, "$file.in" or die "cannot open $file.in\n";
223 while (<MAKE>)
225 chomp;
226 next if (/^\s*#/);
227 while (/\\$/) { chop; $_ .= <MAKE>; chomp; } # merge continued lines
228 next if (/^\s*$/);
230 if (/\@[A-Z_]+\@/) # config.status substitution variable
232 die "Configure substitution is not allowed in $file" unless $file eq "Makefile";
234 if (/^\s*(MODULE|IMPORTLIB|TESTDLL|PARENTSRC|APPMODE|EXTRADLLFLAGS)\s*=\s*(.*)/)
236 my $var = $1;
237 $make{$var} = $2;
238 next;
240 my $source_vars_regexp = join "|", @source_vars;
241 if (/^\s*($source_vars_regexp|PROGRAMS|EXTRA_TARGETS|EXTRA_OBJS|INSTALL_LIB|INSTALL_DEV)\s*=\s*(.*)/)
243 my $var = $1;
244 my @list = split(/\s+/, $2);
245 $make{$var} = \@list;
246 next;
248 if (/^\s*(TOPSRCDIR|TOPOBJDIR|SRCDIR|VPATH)\s*=\s*(.*)/)
250 die "Variable $1 in $file.in is obsolete";
254 return %make;
257 # read pragma makedep flags from a source file
258 sub get_makedep_flags($)
260 my $file = shift;
261 my %flags;
263 open FILE, $file or die "cannot open $file";
264 if ($file =~ /\.sfd$/)
266 while (<FILE>)
268 next unless /^UComments:\s*\"(.*)\"$/;
269 foreach my $pragma (split /\+AAoA/, $1)
271 next unless $pragma =~ /^#\s*pragma\s+makedep\s+(.*)/;
272 foreach my $flag (split /\s+/, $1)
274 $flags{$flag} = 1;
275 last if $flag eq "font";
280 else
282 while (<FILE>)
284 next unless /^#\s*pragma\s+makedep\s+(.*)/;
285 foreach my $flag (split /\s+/, $1)
287 last if $flag eq "depend";
288 $flags{$flag} = 1;
292 close FILE;
293 return %flags;
296 sub get_parent_makefile($)
298 my $file = shift;
299 my %make = %{$makefiles{$file}};
300 my $reldir = $make{"PARENTSRC"} || "";
301 return "" unless $reldir;
302 (my $path = $file) =~ s/\/Makefile$/\//;
303 while ($reldir =~ /^\.\.\//)
305 $reldir =~ s/^\.\.\///;
306 $path =~ s/[^\/]+\/$//;
308 return "$path$reldir/Makefile";
311 # preserve shared source files that are listed in the existing makefile
312 sub preserve_shared_source_files($$$)
314 my ($make, $parent, $var) = @_;
315 my %srcs;
317 return unless defined ${$parent}{"=$var"};
318 foreach my $file (@{${$parent}{"=$var"}}) { $srcs{$file} = 1; }
319 foreach my $file (@{${$make}{"=$var"}}) { $srcs{$file} = 0; }
321 foreach my $file (@{${$make}{$var}})
323 next unless defined $srcs{$file} && $srcs{$file} == 1;
324 push @{${$make}{"=$var"}}, $file;
328 # assign source files to their respective makefile
329 sub assign_sources_to_makefiles(@)
331 foreach my $file (@_)
333 next if defined $ignored_source_files{$file};
334 next if $file =~ /Makefile\.in$/;
335 my $dir = dirname( $file );
336 my $subdir = $dir;
338 while ($dir && !defined $makefiles{"$dir/Makefile"}) { $dir = dirname( $dir ); }
339 $subdir =~ s/^$dir\/?//;
340 next unless $dir;
342 die "no makefile found for $file\n" unless defined $makefiles{"$dir/Makefile"};
344 my $make = $makefiles{"$dir/Makefile"};
345 my $name = substr( $file, length($dir) + 1 );
347 next if $file =~ /^include\/wine\// && !get_makedep_flags($file) && !$exported_wine_headers{$name};
349 if ($name =~ /\.m$/) { push @{${$make}{"=OBJC_SRCS"}}, $name; }
350 elsif ($name =~ /\.l$/) { push @{${$make}{"=LEX_SRCS"}}, $name; }
351 elsif ($name =~ /\.y$/) { push @{${$make}{"=BISON_SRCS"}}, $name; }
352 elsif ($name =~ /\.svg$/) { push @{${$make}{"=SVG_SRCS"}}, $name; }
353 elsif ($name =~ /\.sfd$/)
355 push @{${$make}{"=FONT_SRCS"}}, $name;
357 elsif ($name =~ /\.c$/)
359 push @{${$make}{"=C_SRCS"}}, $name;
361 elsif ($name =~ /\.h$/ || $name =~ /\.rh$/ || $name =~ /\.inl$/ || $name =~ /\.x$/)
363 next if $dir ne "include";
365 elsif ($name =~ /\.rc$/)
367 push @{${$make}{"=RC_SRCS"}}, $name;
369 elsif ($name =~ /\.mc$/)
371 push @{${$make}{"=MC_SRCS"}}, $name;
373 elsif ($name =~ /\.po$/)
375 push @{${$make}{"=PO_SRCS"}}, $name;
377 elsif ($name =~ /\.idl$/)
379 die "no makedep flags specified in $file" unless $dir eq "include" || get_makedep_flags($file);
380 push @{${$make}{"=IDL_SRCS"}}, $name;
382 elsif ($name =~ /\.man\.in$/)
384 push @{${$make}{"=MANPAGES"}}, $name;
386 elsif ($name =~ /\.inf\.in$/)
388 push @inf_files, $name unless $name eq "wine.inf.in";
390 elsif ($name =~ /\.in$/)
392 push @{${$make}{"=IN_SRCS"}}, $name;
394 elsif ($name =~ /\.spec$/)
396 next unless defined ${$make}{"TESTDLL"};
398 elsif ($name =~ /\.nls$/)
400 push @nls_files, $name if $dir eq "nls";
402 elsif ($dir ne "loader") # loader dir contains misc files
404 next;
406 push @{${$make}{"=SOURCES"}}, $name;
409 # preserve shared source files from the parent makefile
410 foreach my $file (@makefiles)
412 my $make = $makefiles{$file};
413 my $parent = get_parent_makefile( $file );
414 next unless $parent;
415 preserve_shared_source_files( $makefiles{$file}, $makefiles{$parent}, "C_SRCS" );
416 preserve_shared_source_files( $makefiles{$file}, $makefiles{$parent}, "RC_SRCS" );
417 preserve_shared_source_files( $makefiles{$file}, $makefiles{$parent}, "IDL_SRCS" );
418 preserve_shared_source_files( $makefiles{$file}, $makefiles{$parent}, "LEX_SRCS" );
419 preserve_shared_source_files( $makefiles{$file}, $makefiles{$parent}, "BISON_SRCS" );
423 ################################################################
424 # update the makefile list in configure.ac
426 sub update_makefiles(@)
428 my (@lines);
430 foreach my $file (sort @_)
432 next if $file eq "Makefile";
433 my %make = %{$makefiles{$file}};
434 (my $dir = $file) =~ s/^(.*)\/Makefile/$1/;
435 my $args = "";
436 if (defined($make{"TESTDLL"})) # test
438 die "TESTDLL should not be defined in $file" unless $file =~ /\/tests\/Makefile$/;
439 die "MODULE should not be defined in $file" if defined $make{"MODULE"};
440 die "STATICLIB should not be defined in $file" if defined $make{"STATICLIB"};
442 elsif (defined($make{"MODULE"}) && $make{"MODULE"} =~ /\.a$/) # import lib
444 die "MODULE should not be defined as static lib in $file" unless $file =~ /^dlls\//;
445 die "APPMODE should not be defined in $file" if defined $make{"APPMODE"};
446 die "STATICLIB should not be defined in $file" if defined $make{"STATICLIB"};
448 elsif (defined($make{"MODULE"})) # dll or program
450 (my $name = $file) =~ s/^(dlls|programs)\/(.*)\/Makefile/$2/;
451 my $dllflags = $make{"EXTRADLLFLAGS"} || "";
452 if (defined $make{"APPMODE"}) { $dllflags .= " " . $make{"APPMODE"}; }
453 die "MODULE should not be defined in $file" unless $file =~ /^(dlls|programs)\//;
454 die "STATICLIB should not be defined in $file" if defined $make{"STATICLIB"};
455 die "Invalid MODULE in $file" if $name =~ /\./ && $make{"MODULE"} ne $name;
456 if ($file =~ /^programs\//)
458 die "EXTRADLLFLAGS should be defined in $file" unless $dllflags;
459 die "EXTRADLLFLAGS should contain -mconsole or -mwindows in $file" unless $dllflags =~ /-m(console|windows)/;
460 die "Invalid MODULE in $file" unless $name =~ /\./ || $make{"MODULE"} eq "$name.exe";
462 else
464 die "APPMODE should not be defined in $file" if defined $make{"APPMODE"} ;
465 die "EXTRADLLFLAGS should not contain -mconsole or -mwindows in $file" if $dllflags =~ /-m(console|windows)/;
466 die "Invalid MODULE in $file" unless $name =~ /\./ || $make{"MODULE"} eq "$name.dll";
468 if (defined $make{"IMPORTLIB"})
470 die "IMPORTLIB not allowed in programs\n" if $file =~ /^programs\//;
471 die "Invalid IMPORTLIB name in $file" if $make{"IMPORTLIB"} =~ /\./;
473 $args = ",enable_win16" if $make{"MODULE"} =~ /16$/ || $modules16{$make{"MODULE"}};
475 elsif ($file =~ /^tools.*\/Makefile$/)
477 die "APPMODE should not be defined in $file" if defined $make{"APPMODE"};
478 die "EXTRADLLFLAGS should not be defined in $file" if defined $make{"EXTRADLLFLAGS"};
479 die "STATICLIB should not be defined in $file" if defined $make{"STATICLIB"};
480 $args = ",,[test \"x\$enable_tools\" = xno]";
482 push @lines, "WINE_CONFIG_MAKEFILE($dir$args)\n";
485 # update the source variables in all the makefiles
487 foreach my $file (sort @_) { replace_makefile_variables( $file ); }
489 push @lines, "dnl End of auto-generated output commands\n";
490 replace_in_file( "configure.ac", '^WINE_CONFIG_MAKEFILE', '^dnl End of auto-generated output commands\n$', @lines);
493 sub update_wine_inf()
495 my @lines;
496 push @lines, "[InfFiles]", sort grep { s/\.in$//; } @inf_files;
497 push @lines, "\n[NlsFiles]", sort grep(!/^sort/, @nls_files);
498 push @lines, "\n[SortFiles]", sort grep(/^sort/, @nls_files);
499 push @lines, "\n[WineSourceDirs]\n";
500 replace_in_file "loader/wine.inf.in", '^\[InfFiles\]', '^\[WineSourceDirs\]', join( "\n", @lines );
503 my $git_dir = $ENV{GIT_DIR} || ".git";
504 die "needs to be run from a git checkout" unless -e $git_dir;
506 my @all_files = split /\0/, `git ls-files -c -z`;
507 map { $ignored_source_files{$_} = 1; } split /\0/, `git ls-files -d -z`;
508 @makefiles = map { (my $ret = $_) =~ s/\.in$//; $ret; } grep /Makefile.in$/, @all_files;
510 foreach my $file (sort @makefiles)
512 my %make = parse_makefile( $file );
513 $makefiles{$file} = \%make;
516 assign_sources_to_makefiles( @all_files );
517 update_makefiles( @makefiles );
518 update_wine_inf();