Back to home page

Wine source

 
 

    


File indexing completed on 2023-11-24 23:29:38

34618113f Alex*0001 #!/usr/bin/perl -w
                0002 #
                0003 # Build the auto-generated parts of the Wine makefiles.
                0004 #
                0005 # Copyright 2006 Alexandre Julliard
                0006 #
                0007 # This library is free software; you can redistribute it and/or
                0008 # modify it under the terms of the GNU Lesser General Public
                0009 # License as published by the Free Software Foundation; either
                0010 # version 2.1 of the License, or (at your option) any later version.
                0011 #
                0012 # This library is distributed in the hope that it will be useful,
                0013 # but WITHOUT ANY WARRANTY; without even the implied warranty of
                0014 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                0015 # Lesser General Public License for more details.
                0016 #
                0017 # You should have received a copy of the GNU Lesser General Public
                0018 # License along with this library; if not, write to the Free Software
                0019 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
                0020 #
                0021 
44eb0090d Fran*0022 use strict;
                0023 
8e9050ba0 Alex*0024 # Dlls and programs that are 16-bit specific
                0025 my %modules16 =
                0026 (
                0027   "ifsmgr.vxd" => 1,
                0028   "mmdevldr.vxd" => 1,
                0029   "monodebg.vxd" => 1,
                0030   "vdhcp.vxd" => 1,
                0031   "vmm.vxd" => 1,
                0032   "vnbt.vxd" => 1,
                0033   "vnetbios.vxd" => 1,
                0034   "vtdapi.vxd" => 1,
                0035   "vwin32.vxd" => 1,
                0036   "w32skrnl.dll" => 1,
                0037   "winevdm.exe" => 1,
                0038   "wow32.dll" => 1,
                0039 );
                0040 
88b74519a Alex*0041 my %ignored_source_files = (
                0042     "dlls/wineps.drv/afm2c.c" => 1,
                0043     "dlls/wineps.drv/mkagl.c" => 1,
7626728b5 Alex*0044     "tools/makedep.c" => 1,
88b74519a Alex*0045 );
                0046 
f7a239a50 Alex*0047 my (@makefiles, %makefiles);
42a30a693 Alex*0048 my @nls_files;
88b74519a Alex*0049 
                0050 sub dirname($)
                0051 {
                0052     my $ret = shift;
                0053     return "" unless $ret =~ /\//;
                0054     $ret =~ s!/[^/]*$!!;
                0055     return $ret;
                0056 }
44db04c01 Alex*0057 
34618113f Alex*0058 # update a file if changed
af91122ca Alex*0059 sub update_file($$)
34618113f Alex*0060 {
                0061     my $file = shift;
af91122ca Alex*0062     my $new = shift;
                0063 
                0064     open FILE, ">$file.new" or die "cannot create $file.new";
                0065     print FILE $new;
                0066     close FILE;
                0067     rename "$file.new", "$file";
                0068     print "$file updated\n";
                0069     if ($file eq "configure.ac")
34618113f Alex*0070     {
af91122ca Alex*0071         system "autoconf";
                0072         print "configure updated\n";
34618113f Alex*0073     }
                0074 }
                0075 
                0076 # replace some lines in a file between two markers
                0077 sub replace_in_file($$$@)
                0078 {
                0079     my $file = shift;
                0080     my $start = shift;
                0081     my $end = shift;
af91122ca Alex*0082     my ($old, $new);
34618113f Alex*0083 
af91122ca Alex*0084     open OLD_FILE, "$file" or die "cannot open $file";
                0085     while (<OLD_FILE>)
34618113f Alex*0086     {
af91122ca Alex*0087         $old .= $_;
                0088         last if /$start/;
                0089         $new .= $_;
34618113f Alex*0090     }
                0091 
af91122ca Alex*0092     $new .= join "", @_;
34618113f Alex*0093 
af91122ca Alex*0094     my $skip = 1;
                0095     while (<OLD_FILE>)
34618113f Alex*0096     {
af91122ca Alex*0097         $old .= $_;
                0098         $new .= $_ unless $skip;
                0099         $skip = 0 if /$end/;
34618113f Alex*0100     }
                0101 
af91122ca Alex*0102     close OLD_FILE;
                0103     update_file($file, $new) if $old ne $new;
34618113f Alex*0104 }
                0105 
c6cded746 Alex*0106 # replace all source variables in a makefile
                0107 sub replace_makefile_variables($)
88b74519a Alex*0108 {
c6cded746 Alex*0109     my $file = shift;
88b74519a Alex*0110     my $make = $makefiles{$file};
af91122ca Alex*0111     my $old;
                0112     my $new;
440771ed4 Alex*0113     my $replaced = 0;
                0114     my $value = "";
                0115 
                0116     $value = "\\\n\t" . join(" \\\n\t", sort @{${$make}{"=SOURCES"}}) if defined ${$make}{"=SOURCES"};
88b74519a Alex*0117 
56fea67c5 Alex*0118     open OLD_FILE, $file or die "cannot open $file";
88b74519a Alex*0119     while (<OLD_FILE>)
                0120     {
af91122ca Alex*0121         $old .= $_;
440771ed4 Alex*0122         if (/^\s*SOURCES\s*=/)
88b74519a Alex*0123         {
c6cded746 Alex*0124             my $old_str = $_;
88b74519a Alex*0125             while (/\\$/)
                0126             {
                0127                 $_ = <OLD_FILE>;
                0128                 last unless $_;
af91122ca Alex*0129                 $old .= $_;
c6cded746 Alex*0130                 $old_str .= $_;
88b74519a Alex*0131             }
440771ed4 Alex*0132             $new .= "SOURCES = $value\n" if $value;
                0133             $replaced = 1;
88b74519a Alex*0134             next;
                0135         }
af91122ca Alex*0136         $new .= $_;
88b74519a Alex*0137     }
440771ed4 Alex*0138     unless ($replaced)
c6cded746 Alex*0139     {
440771ed4 Alex*0140         $new .= "\nSOURCES = $value\n" if $value;
c6cded746 Alex*0141     }
88b74519a Alex*0142     close OLD_FILE;
56fea67c5 Alex*0143     update_file($file, $new) if $old ne $new;
88b74519a Alex*0144 }
                0145 
80d12c358 Alex*0146 # parse the specified makefile and load the variables
44db04c01 Alex*0147 sub parse_makefile($)
                0148 {
                0149     my $file = shift;
48c14238b Alex*0150     my %make;
44db04c01 Alex*0151 
7035aa504 Alex*0152     ($make{"=dir"} = $file) =~ s/[^\/]+$//;
                0153 
56fea67c5 Alex*0154     open MAKE, $file or die "cannot open $file\n";
44db04c01 Alex*0155 
                0156     while (<MAKE>)
                0157     {
                0158         chomp;
88b74519a Alex*0159         next if (/^\s*#/);
44db04c01 Alex*0160         while (/\\$/) { chop; $_ .= <MAKE>; chomp; }  # merge continued lines
88b74519a Alex*0161         next if (/^\s*$/);
44db04c01 Alex*0162 
dec6a946d Alex*0163         if (/\@[A-Z_]+\@/)  # config.status substitution variable
                0164         {
56fea67c5 Alex*0165             die "Configure substitution is not allowed in $file" unless $file eq "Makefile.in";
dec6a946d Alex*0166         }
518f9a12c Alex*0167         if (/^\s*(MODULE|IMPORTLIB|TESTDLL|STATICLIB|PARENTSRC|EXTRADLLFLAGS)\s*=\s*(.*)/)
48c14238b Alex*0168         {
e2db79463 Alex*0169             my $var = $1;
                0170             $make{$var} = $2;
48c14238b Alex*0171             next;
                0172         }
440771ed4 Alex*0173         if (/^\s*(SOURCES|PROGRAMS|EXTRA_TARGETS|EXTRA_OBJS|INSTALL_LIB|INSTALL_DEV)\s*=\s*(.*)/)
365a463b1 Alex*0174         {
e2db79463 Alex*0175             my $var = $1;
365a463b1 Alex*0176             my @list = split(/\s+/, $2);
e2db79463 Alex*0177             $make{$var} = \@list;
da340169d Alex*0178             next;
                0179         }
845047eeb Alex*0180         if (/^\s*(TOPSRCDIR|TOPOBJDIR|SRCDIR|VPATH)\s*=\s*(.*)/)
                0181         {
56fea67c5 Alex*0182             die "Variable $1 in $file is obsolete";
845047eeb Alex*0183         }
44db04c01 Alex*0184     }
e2db79463 Alex*0185 
48c14238b Alex*0186     return %make;
44db04c01 Alex*0187 }
34618113f Alex*0188 
27534a09c Alex*0189 # read pragma makedep flags from a source file
                0190 sub get_makedep_flags($)
                0191 {
                0192     my $file = shift;
                0193     my %flags;
                0194 
                0195     open FILE, $file or die "cannot open $file";
fabc25d8b Alex*0196     if ($file =~ /\.sfd$/)
27534a09c Alex*0197     {
fabc25d8b Alex*0198         while (<FILE>)
27534a09c Alex*0199         {
fabc25d8b Alex*0200             next unless /^UComments:\s*\"(.*)\"$/;
                0201             foreach my $pragma (split /\+AAoA/, $1)
                0202             {
                0203                 next unless $pragma =~ /^#\s*pragma\s+makedep\s+(.*)/;
                0204                 foreach my $flag (split /\s+/, $1)
                0205                 {
                0206                     $flags{$flag} = 1;
                0207                     last if $flag eq "font";
                0208                 }
                0209             }
                0210         }
                0211     }
                0212     else
                0213     {
                0214         while (<FILE>)
                0215         {
                0216             next unless /^#\s*pragma\s+makedep\s+(.*)/;
                0217             foreach my $flag (split /\s+/, $1)
                0218             {
                0219                 last if $flag eq "depend";
                0220                 $flags{$flag} = 1;
                0221             }
27534a09c Alex*0222         }
                0223     }
                0224     close FILE;
                0225     return %flags;
                0226 }
                0227 
517d274e3 Alex*0228 sub get_parent_makefile($)
                0229 {
                0230     my $file = shift;
                0231     my %make = %{$makefiles{$file}};
                0232     my $reldir = $make{"PARENTSRC"} || "";
                0233     return "" unless $reldir;
56fea67c5 Alex*0234     (my $path = $file) =~ s/\/Makefile\.in$/\//;
517d274e3 Alex*0235     while ($reldir =~ /^\.\.\//)
                0236     {
                0237         $reldir =~ s/^\.\.\///;
                0238         $path =~ s/[^\/]+\/$//;
                0239     }
56fea67c5 Alex*0240     return "$path$reldir/Makefile.in";
517d274e3 Alex*0241 }
                0242 
                0243 # preserve shared source files that are listed in the existing makefile
440771ed4 Alex*0244 sub preserve_shared_source_files($$)
517d274e3 Alex*0245 {
440771ed4 Alex*0246     my ($make, $parent) = @_;
517d274e3 Alex*0247     my %srcs;
                0248 
440771ed4 Alex*0249     return unless defined ${$parent}{"=SOURCES"};
                0250     foreach my $file (@{${$parent}{"=SOURCES"}}) { $srcs{$file} = 1; }
                0251     foreach my $file (@{${$make}{"=SOURCES"}}) { $srcs{$file} = 0; }
517d274e3 Alex*0252 
440771ed4 Alex*0253     foreach my $file (@{${$make}{SOURCES}})
517d274e3 Alex*0254     {
                0255         next unless defined $srcs{$file} && $srcs{$file} == 1;
440771ed4 Alex*0256         push @{${$make}{"=SOURCES"}}, $file;
517d274e3 Alex*0257     }
                0258 }
                0259 
88b74519a Alex*0260 # assign source files to their respective makefile
80d12c358 Alex*0261 sub assign_sources_to_makefiles(@)
88b74519a Alex*0262 {
80d12c358 Alex*0263     foreach my $file (@_)
88b74519a Alex*0264     {
                0265         next if defined $ignored_source_files{$file};
c2efb3b38 Alex*0266         next if $file =~ /Makefile\.in$/;
88b74519a Alex*0267         my $dir = dirname( $file );
80d12c358 Alex*0268         my $subdir = $dir;
88b74519a Alex*0269 
56fea67c5 Alex*0270         while ($dir && !defined $makefiles{"$dir/Makefile.in"}) { $dir = dirname( $dir ); }
80d12c358 Alex*0271         $subdir =~ s/^$dir\/?//;
88b74519a Alex*0272         next unless $dir;
                0273 
56fea67c5 Alex*0274         die "no makefile found for $file\n" unless defined $makefiles{"$dir/Makefile.in"};
88b74519a Alex*0275 
56fea67c5 Alex*0276         my $make = $makefiles{"$dir/Makefile.in"};
80d12c358 Alex*0277         my $name = substr( $file, length($dir) + 1 );
a1a0139d4 Alex*0278 
440771ed4 Alex*0279         if ($name =~ /\.h$/)
80d12c358 Alex*0280         {
a1a0139d4 Alex*0281             next if $dir ne "include";
                0282         }
                0283         elsif ($name =~ /\.idl$/)
                0284         {
3aecaf1da Alex*0285             die "no makedep flags specified in $file" unless $dir eq "include" || get_makedep_flags($file);
a1a0139d4 Alex*0286         }
2435357d6 Alex*0287         elsif ($name =~ /\.spec$/)
                0288         {
f1ff3179a Alex*0289             my $dllflags = ${$make}{"EXTRADLLFLAGS"} || "";
aa15f41d0 Alex*0290             next unless defined ${$make}{"TESTDLL"} ||
                0291                 ($dllflags =~ /-Wb,--data-only/) ||
                0292                 ($dllflags =~ /-Wl,--subsystem,native/);
2435357d6 Alex*0293         }
42a30a693 Alex*0294         elsif ($name =~ /\.nls$/)
                0295         {
                0296             push @nls_files, $name if $dir eq "nls";
                0297         }
440771ed4 Alex*0298         elsif ($name =~ /\.xml$/)
857001678 Alex*0299         {
440771ed4 Alex*0300             next unless $dir eq "dlls/winewayland.drv";
857001678 Alex*0301         }
440771ed4 Alex*0302         elsif ($name !~ /\.(c|in|inl|l|m|mc|po|rc|rh|sfd|svg|x|y)$/)
54a123f4e Alex*0303         {
440771ed4 Alex*0304             next unless $dir eq "loader";  # loader dir contains misc files
54a123f4e Alex*0305         }
                0306         push @{${$make}{"=SOURCES"}}, $name;
80d12c358 Alex*0307     }
                0308 
517d274e3 Alex*0309     # preserve shared source files from the parent makefile
                0310     foreach my $file (@makefiles)
                0311     {
a2db8bc13 Alex*0312         my $make = $makefiles{$file};
517d274e3 Alex*0313         my $parent = get_parent_makefile( $file );
                0314         next unless $parent;
440771ed4 Alex*0315         preserve_shared_source_files( $makefiles{$file}, $makefiles{$parent} );
517d274e3 Alex*0316     }
88b74519a Alex*0317 }
34618113f Alex*0318 
5ea4e5ba4 Alex*0319 ################################################################
a360e9343 Alex*0320 # update the makefile list in configure.ac
5ea4e5ba4 Alex*0321 
5eb38cf93 Alex*0322 sub update_makefiles(@)
5ea4e5ba4 Alex*0323 {
a360e9343 Alex*0324     my (@lines);
ac91ffd7f Alex*0325 
5eb38cf93 Alex*0326     foreach my $file (sort @_)
                0327     {
56fea67c5 Alex*0328         next if $file eq "Makefile.in";
a360e9343 Alex*0329         my %make = %{$makefiles{$file}};
56fea67c5 Alex*0330         (my $dir = $file) =~ s/^(.*)\/Makefile\.in/$1/;
49163da1d Alex*0331         my $args = "";
45104d9cb Alex*0332         if (defined($make{"TESTDLL"}))  # test
a37d88973 Alex*0333         {
56fea67c5 Alex*0334             die "TESTDLL should not be defined in $file" unless $file =~ /\/tests\/Makefile\.in$/;
45104d9cb Alex*0335             die "MODULE should not be defined in $file" if defined $make{"MODULE"};
                0336             die "STATICLIB should not be defined in $file" if defined $make{"STATICLIB"};
                0337         }
518f9a12c Alex*0338         elsif (defined($make{"STATICLIB"}))
45104d9cb Alex*0339         {
518f9a12c Alex*0340             die "MODULE should not be defined in $file" if defined $make{"MODULE"};
                0341             die "invalid STATICLIB name" unless $make{"STATICLIB"} =~ /\.a$/;
45104d9cb Alex*0342         }
3aecaf1da Alex*0343         elsif (defined($make{"MODULE"}))  # dll or program
45104d9cb Alex*0344         {
56fea67c5 Alex*0345             (my $name = $file) =~ s/^(dlls|programs)\/(.*)\/Makefile\.in/$2/;
a58f4abc0 Alex*0346             my $dllflags = $make{"EXTRADLLFLAGS"} || "";
518f9a12c Alex*0347             die "invalid MODULE name" if $make{"MODULE"} =~ /\.a$/;
3aecaf1da Alex*0348             die "MODULE should not be defined in $file" unless $file =~ /^(dlls|programs)\//;
45104d9cb Alex*0349             die "STATICLIB should not be defined in $file" if defined $make{"STATICLIB"};
3aecaf1da Alex*0350             if ($file =~ /^programs\//)
845047eeb Alex*0351             {
a58f4abc0 Alex*0352                 die "EXTRADLLFLAGS should be defined in $file" unless $dllflags;
                0353                 die "EXTRADLLFLAGS should contain -mconsole or -mwindows in $file" unless $dllflags =~ /-m(console|windows)/;
a6f214d75 Rémi*0354                 die "Invalid MODULE in $file" unless ($name =~ /\./ && $make{"MODULE"} eq $name) || $make{"MODULE"} eq "$name.exe";
845047eeb Alex*0355             }
                0356             else
                0357             {
a58f4abc0 Alex*0358                 die "EXTRADLLFLAGS should not contain -mconsole or -mwindows in $file" if $dllflags =~ /-m(console|windows)/;
a6f214d75 Rémi*0359                 die "Invalid MODULE in $file" unless ($name =~ /\./ && $make{"MODULE"} eq $name) || $make{"MODULE"} eq "$name.dll";
845047eeb Alex*0360             }
3aecaf1da Alex*0361             if (defined $make{"IMPORTLIB"})
845047eeb Alex*0362             {
3aecaf1da Alex*0363                 die "IMPORTLIB not allowed in programs\n" if $file =~ /^programs\//;
                0364                 die "Invalid IMPORTLIB name in $file" if $make{"IMPORTLIB"} =~ /\./;
845047eeb Alex*0365             }
3aecaf1da Alex*0366             $args = ",enable_win16" if $make{"MODULE"} =~ /16$/ || $modules16{$make{"MODULE"}};
aa6c4d4e9 Alex*0367         }
56fea67c5 Alex*0368         elsif ($file =~ /^tools.*\/Makefile\.in$/)
4d3b0205f Alex*0369         {
518f9a12c Alex*0370             die "MODULE should not be defined in $file" if defined $make{"MODULE"};
45104d9cb Alex*0371             die "STATICLIB should not be defined in $file" if defined $make{"STATICLIB"};
518f9a12c Alex*0372             die "EXTRADLLFLAGS should not be defined in $file" if defined $make{"EXTRADLLFLAGS"};
3aecaf1da Alex*0373             $args = ",,[test \"x\$enable_tools\" = xno]";
4d3b0205f Alex*0374         }
3aecaf1da Alex*0375         push @lines, "WINE_CONFIG_MAKEFILE($dir$args)\n";
5eb38cf93 Alex*0376     }
                0377 
88b74519a Alex*0378     # update the source variables in all the makefiles
                0379 
c6cded746 Alex*0380     foreach my $file (sort @_) { replace_makefile_variables( $file ); }
88b74519a Alex*0381 
d5addea27 Alex*0382     push @lines, "dnl End of auto-generated output commands\n";
3aecaf1da Alex*0383     replace_in_file( "configure.ac", '^WINE_CONFIG_MAKEFILE', '^dnl End of auto-generated output commands\n$', @lines);
5ea4e5ba4 Alex*0384 }
                0385 
42a30a693 Alex*0386 sub update_wine_inf()
                0387 {
95aeb41c8 Alex*0388     my @lines;
4650dff5c Alex*0389     push @lines, "[NlsFiles]", sort grep(!/^sort/, @nls_files);
95aeb41c8 Alex*0390     push @lines, "\n[SortFiles]", sort grep(/^sort/, @nls_files);
                0391     push @lines, "\n[WineSourceDirs]\n";
4650dff5c Alex*0392     replace_in_file "loader/wine.inf.in", '^\[NlsFiles\]', '^\[WineSourceDirs\]', join( "\n", @lines );
42a30a693 Alex*0393 }
5eb38cf93 Alex*0394 
b03606c5e Alex*0395 my $git_dir = $ENV{GIT_DIR} || ".git";
f78fe960b Zebe*0396 die "needs to be run from a git checkout" unless -e $git_dir;
88b74519a Alex*0397 
ce8023ea1 Alex*0398 my @all_files = split /\0/, `git ls-files -c -z` or die "cannot get files list";
bfc863474 Alex*0399 map { $ignored_source_files{$_} = 1; } split /\0/, `git ls-files -d -z`;
56fea67c5 Alex*0400 @makefiles = grep /Makefile.in$/, @all_files;
ac91ffd7f Alex*0401 
509364e1d Alex*0402 foreach my $file (sort @makefiles)
ac91ffd7f Alex*0403 {
                0404     my %make = parse_makefile( $file );
                0405     $makefiles{$file} = \%make;
                0406 }
                0407 
80d12c358 Alex*0408 assign_sources_to_makefiles( @all_files );
5eb38cf93 Alex*0409 update_makefiles( @makefiles );
42a30a693 Alex*0410 update_wine_inf();