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
24 # Dlls and programs that are 16-bit specific
41 my %exported_wine_headers = (
43 "wine/exception.h" => 1,
45 "wine/svcctl.idl" => 1,
48 my %ignored_source_files = (
49 "dlls/wineps.drv/afm2c.c" => 1,
50 "dlls/wineps.drv/mkagl.c" => 1,
51 "include/config.h.in" => 1,
52 "include/stamp-h.in" => 1,
53 "programs/winetest/dist.rc" => 1,
54 "tools/makedep.c" => 1,
75 my (@makefiles, %makefiles);
82 return "" unless $ret =~ /\//;
87 # update a file if changed
93 open FILE
, ">$file.new" or die "cannot create $file.new";
96 rename "$file.new", "$file";
97 print "$file updated\n";
98 if ($file eq "configure.ac")
101 print "configure updated\n";
105 # replace some lines in a file between two markers
106 sub replace_in_file
($$$@
)
113 open OLD_FILE
, "$file" or die "cannot open $file";
127 $new .= $_ unless $skip;
132 update_file
($file, $new) if $old ne $new;
135 # replace all source variables in a makefile
136 sub replace_makefile_variables
($)
139 my $make = $makefiles{$file};
140 my $source_vars_regexp = join "|", @source_vars;
145 open OLD_FILE
, "$file.in" or die "cannot open $file.in";
149 if (/^\s*($source_vars_regexp)(\s*)=/)
151 # try to preserve formatting
157 if (defined ${$make}{"=$var"})
159 @values = @
{${$make}{"=$var"}};
160 ${$make}{$var} = \
@values;
164 undef ${$make}{$var};
166 my $multiline = /\\$/ || (@values > 1);
182 $new_str = "$var = \\\n\t" . join(" \\\n\t", sort @values) . "\n";
187 $new_str = "$var$spaces= @values\n";
195 # if we are using SOURCES, ignore the other variables
196 unless ($replaced{"SOURCES"})
198 foreach my $var (@source_vars)
200 next if defined $replaced{$var};
201 next if $var eq "SOURCES";
202 next unless defined ${$make}{"=$var"};
203 my @values = @
{${$make}{"=$var"}};
205 $new .= "\n$var = \\\n\t" . join(" \\\n\t", sort @values) . "\n";
209 update_file
("$file.in", $new) if $old ne $new;
212 # parse the specified makefile and load the variables
213 sub parse_makefile
($)
218 ($make{"=dir"} = $file) =~ s/[^\/]+$//;
220 open MAKE
, "$file.in" or die "cannot open $file.in\n";
226 while (/\\$/) { chop; $_ .= <MAKE
>; chomp; } # merge continued lines
229 if (/\@[A-Z_]+\@/) # config.status substitution variable
231 die "Configure substitution is not allowed in $file" unless $file eq "Makefile";
233 if (/^\s*(MODULE|IMPORTLIB|TESTDLL|PARENTSRC|APPMODE|EXTRADLLFLAGS)\s*=\s*(.*)/)
239 my $source_vars_regexp = join "|", @source_vars;
240 if (/^\s*($source_vars_regexp|PROGRAMS|EXTRA_TARGETS|EXTRA_OBJS|INSTALL_LIB|INSTALL_DEV)\s*=\s*(.*)/)
243 my @list = split(/\s+/, $2);
244 $make{$var} = \
@list;
247 if (/^\s*(TOPSRCDIR|TOPOBJDIR|SRCDIR|VPATH)\s*=\s*(.*)/)
249 die "Variable $1 in $file.in is obsolete";
256 # read pragma makedep flags from a source file
257 sub get_makedep_flags
($)
262 open FILE
, $file or die "cannot open $file";
263 if ($file =~ /\.sfd$/)
267 next unless /^UComments:\s*\"(.*)\"$/;
268 foreach my $pragma (split /\+AAoA/, $1)
270 next unless $pragma =~ /^#\s*pragma\s+makedep\s+(.*)/;
271 foreach my $flag (split /\s+/, $1)
274 last if $flag eq "font";
283 next unless /^#\s*pragma\s+makedep\s+(.*)/;
284 foreach my $flag (split /\s+/, $1)
286 last if $flag eq "depend";
295 sub get_parent_makefile
($)
298 my %make = %{$makefiles{$file}};
299 my $reldir = $make{"PARENTSRC"} || "";
300 return "" unless $reldir;
301 (my $path = $file) =~ s/\/Makefile$/\
//;
302 while ($reldir =~ /^\.\.\//)
304 $reldir =~ s/^\.\.\///;
305 $path =~ s/[^\/]+\/$//;
307 return "$path$reldir/Makefile";
310 # preserve shared source files that are listed in the existing makefile
311 sub preserve_shared_source_files
($$$)
313 my ($make, $parent, $var) = @_;
316 return unless defined ${$parent}{"=$var"};
317 foreach my $file (@
{${$parent}{"=$var"}}) { $srcs{$file} = 1; }
318 foreach my $file (@
{${$make}{"=$var"}}) { $srcs{$file} = 0; }
320 foreach my $file (@
{${$make}{$var}})
322 next unless defined $srcs{$file} && $srcs{$file} == 1;
323 push @
{${$make}{"=$var"}}, $file;
327 # assign source files to their respective makefile
328 sub assign_sources_to_makefiles
(@
)
330 foreach my $file (@_)
332 next if defined $ignored_source_files{$file};
333 next if $file =~ /Makefile\.in$/;
334 my $dir = dirname
( $file );
337 while ($dir && !defined $makefiles{"$dir/Makefile"}) { $dir = dirname
( $dir ); }
338 $subdir =~ s/^$dir\/?//;
341 die "no makefile found for $file\n" unless defined $makefiles{"$dir/Makefile"};
343 my $make = $makefiles{"$dir/Makefile"};
344 my $name = substr( $file, length($dir) + 1 );
346 next if $file =~ /^include\/wine\
// && !get_makedep_flags
($file) && !$exported_wine_headers{$name};
348 if ($name =~ /\.m$/) { push @
{${$make}{"=OBJC_SRCS"}}, $name; }
349 elsif ($name =~ /\.l$/) { push @
{${$make}{"=LEX_SRCS"}}, $name; }
350 elsif ($name =~ /\.y$/) { push @
{${$make}{"=BISON_SRCS"}}, $name; }
351 elsif ($name =~ /\.svg$/) { push @
{${$make}{"=SVG_SRCS"}}, $name; }
352 elsif ($name =~ /\.sfd$/)
354 push @
{${$make}{"=FONT_SRCS"}}, $name;
356 elsif ($name =~ /\.c$/)
358 push @
{${$make}{"=C_SRCS"}}, $name;
360 elsif ($name =~ /\.h$/ || $name =~ /\.rh$/ || $name =~ /\.inl$/ || $name =~ /\.x$/)
362 next if $dir ne "include";
364 elsif ($name =~ /\.rc$/)
366 push @
{${$make}{"=RC_SRCS"}}, $name;
368 elsif ($name =~ /\.mc$/)
370 push @
{${$make}{"=MC_SRCS"}}, $name;
372 elsif ($name =~ /\.po$/)
374 push @
{${$make}{"=PO_SRCS"}}, $name;
376 elsif ($name =~ /\.idl$/)
378 die "no makedep flags specified in $file" unless $dir eq "include" || get_makedep_flags
($file);
379 push @
{${$make}{"=IDL_SRCS"}}, $name;
381 elsif ($name =~ /\.man\.in$/)
383 push @
{${$make}{"=MANPAGES"}}, $name;
385 elsif ($name =~ /\.inf\.in$/)
387 push @inf_files, $name unless $name eq "wine.inf.in";
389 elsif ($name =~ /\.in$/)
391 push @
{${$make}{"=IN_SRCS"}}, $name;
393 elsif ($name =~ /\.spec$/)
395 next unless defined ${$make}{"TESTDLL"};
397 elsif ($name =~ /\.nls$/)
399 push @nls_files, $name if $dir eq "nls";
401 elsif ($dir ne "loader") # loader dir contains misc files
405 push @
{${$make}{"=SOURCES"}}, $name;
408 # preserve shared source files from the parent makefile
409 foreach my $file (@makefiles)
411 my $make = $makefiles{$file};
412 my $parent = get_parent_makefile
( $file );
414 preserve_shared_source_files
( $makefiles{$file}, $makefiles{$parent}, "C_SRCS" );
415 preserve_shared_source_files
( $makefiles{$file}, $makefiles{$parent}, "RC_SRCS" );
416 preserve_shared_source_files
( $makefiles{$file}, $makefiles{$parent}, "IDL_SRCS" );
417 preserve_shared_source_files
( $makefiles{$file}, $makefiles{$parent}, "LEX_SRCS" );
418 preserve_shared_source_files
( $makefiles{$file}, $makefiles{$parent}, "BISON_SRCS" );
422 ################################################################
423 # update the makefile list in configure.ac
425 sub update_makefiles
(@
)
429 foreach my $file (sort @_)
431 next if $file eq "Makefile";
432 my %make = %{$makefiles{$file}};
433 (my $dir = $file) =~ s/^(.*)\/Makefile/$1/;
435 if (defined($make{"TESTDLL"})) # test
437 die "TESTDLL should not be defined in $file" unless $file =~ /\/tests\
/Makefile$/;
438 die "MODULE should not be defined in $file" if defined $make{"MODULE"};
439 die "STATICLIB should not be defined in $file" if defined $make{"STATICLIB"};
441 elsif (defined($make{"MODULE"}) && $make{"MODULE"} =~ /\.a$/) # import lib
443 die "MODULE should not be defined as static lib in $file" unless $file =~ /^dlls\//;
444 die "APPMODE should not be defined in $file" if defined $make{"APPMODE"};
445 die "STATICLIB should not be defined in $file" if defined $make{"STATICLIB"};
447 elsif (defined($make{"MODULE"})) # dll or program
449 (my $name = $file) =~ s/^(dlls|programs)\/(.*)\/Makefile
/$2/;
450 my $dllflags = $make{"EXTRADLLFLAGS"} || "";
451 if (defined $make{"APPMODE"}) { $dllflags .= " " . $make{"APPMODE"}; }
452 die "MODULE should not be defined in $file" unless $file =~ /^(dlls|programs)\//;
453 die "STATICLIB should not be defined in $file" if defined $make{"STATICLIB"};
454 die "Invalid MODULE in $file" if $name =~ /\./ && $make{"MODULE"} ne $name;
455 if ($file =~ /^programs\//)
457 die "EXTRADLLFLAGS should be defined in $file" unless $dllflags;
458 die "EXTRADLLFLAGS should contain -mconsole or -mwindows in $file" unless $dllflags =~ /-m(console|windows)/;
459 die "Invalid MODULE in $file" unless $name =~ /\./ || $make{"MODULE"} eq "$name.exe";
463 die "APPMODE should not be defined in $file" if defined $make{"APPMODE"} ;
464 die "EXTRADLLFLAGS should not contain -mconsole or -mwindows in $file" if $dllflags =~ /-m(console|windows)/;
465 die "Invalid MODULE in $file" unless $name =~ /\./ || $make{"MODULE"} eq "$name.dll";
467 if (defined $make{"IMPORTLIB"})
469 die "IMPORTLIB not allowed in programs\n" if $file =~ /^programs\//;
470 die "Invalid IMPORTLIB name in $file" if $make{"IMPORTLIB"} =~ /\./;
472 $args = ",enable_win16" if $make{"MODULE"} =~ /16$/ || $modules16{$make{"MODULE"}};
474 elsif ($file =~ /^tools.*\/Makefile
$/)
476 die "APPMODE should not be defined in $file" if defined $make{"APPMODE"};
477 die "EXTRADLLFLAGS should not be defined in $file" if defined $make{"EXTRADLLFLAGS"};
478 die "STATICLIB should not be defined in $file" if defined $make{"STATICLIB"};
479 $args = ",,[test \"x\$enable_tools\" = xno]";
481 push @lines, "WINE_CONFIG_MAKEFILE($dir$args)\n";
484 # update the source variables in all the makefiles
486 foreach my $file (sort @_) { replace_makefile_variables
( $file ); }
488 push @lines, "dnl End of auto-generated output commands\n";
489 replace_in_file
( "configure.ac", '^WINE_CONFIG_MAKEFILE', '^dnl End of auto-generated output commands\n$', @lines);
492 sub update_wine_inf
()
495 push @lines, "[InfFiles]", sort grep { s/\.in$//; } @inf_files;
496 push @lines, "\n[NlsFiles]", sort grep(!/^sort/, @nls_files);
497 push @lines, "\n[SortFiles]", sort grep(/^sort/, @nls_files);
498 push @lines, "\n[WineSourceDirs]\n";
499 replace_in_file
"loader/wine.inf.in", '^\[InfFiles\]', '^\[WineSourceDirs\]', join( "\n", @lines );
502 my $git_dir = $ENV{GIT_DIR
} || ".git";
503 die "needs to be run from a git checkout" unless -e
$git_dir;
505 my @all_files = split /\0/, `git ls-files -c -z`;
506 map { $ignored_source_files{$_} = 1; } split /\0/, `git ls-files -d -z`;
507 @makefiles = map { (my $ret = $_) =~ s/\.in$//; $ret; } grep /Makefile.in$/, @all_files;
509 foreach my $file (sort @makefiles)
511 my %make = parse_makefile
( $file );
512 $makefiles{$file} = \
%make;
515 assign_sources_to_makefiles
( @all_files );
516 update_makefiles
( @makefiles );