msvcrt: Add _fstat64 and _stat64 to msvcrt.spec.
[wine] / dlls / make_dlls
index fddb3cd..7969c52 100755 (executable)
@@ -1,7 +1,6 @@
 #!/usr/bin/perl -w
 #
 # Update the dll dependencies in the dlls main Makefile.in.
-# Must be run in the dlls/ directory of the Wine tree.
 #
 # Copyright 2001 Alexandre Julliard
 #
 #
 # You should have received a copy of the GNU Lesser General Public
 # License along with this library; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 #
 
 use strict;
 
-my $makefiles = `find . -name Makefile.in -print`;
-
-my %imports = ();
 my %directories = ();
+my %testdirs = ();
+my %importlibs = ();
+my %static_implibs = ();
+my %staticlib_dirs = ();
 my %altnames = ();
-my %linked_dlls = ();
 
 # list of special dlls that can be switched on or off by configure
 my %special_dlls =
 (
-  "ddraw"    => "XFILES",
   "glu32"    => "GLU32FILES",
+  "glut32"   => "GLUT32FILES",
   "opengl32" => "OPENGLFILES",
-  "d3d8"     => "OPENGLFILES",
-  "x11drv"   => "XFILES"
+  "wined3d"  => "OPENGLFILES",
+  "winex11.drv" => "XFILES",
+  "winequartz.drv" => "QUARTZFILES"
 );
 
-foreach my $i (split(/\s/,$makefiles))
+sub needs_symlink($)
+{
+    (my $mod = $_[0]) =~ s/\.dll$//;
+    return $mod ne $directories{$_[0]};
+}
+
+sub update_file($)
 {
-    my $module;
+    my $file = shift;
+    if (!system "cmp $file $file.new >/dev/null")
+    {
+        unlink "$file.new";
+        print "$file is unchanged\n";
+    }
+    else
+    {
+        rename "$file.new", "$file";
+        print "$file updated\n";
+        if (-x "./config.status" && $file =~ /(.*Makefile)\.in$/)
+        {
+            system "./config.status", $1;
+        }
+    }
+}
 
-    next if $i =~ /\/tests\/Makefile.in/;
+# if we are inside the dlls dir, go up one level
+if (! -f "configure.ac" && -f "../configure.ac") { chdir(".."); }
 
-    open MAKE,$i;
+my @args = @ARGV;
+if (!@args) { @args = map { s/^(.*)\.in/$1/; $_; } split(/\s/,`find dlls -name Makefile.in -print`); }
+
+foreach my $i (@args)
+{
+    if ($i =~ /dlls\/(.*)\/tests\/Makefile/)
+    {
+        $testdirs{$1} = "$1/tests";
+        next;
+    }
+
+    open MAKE, "$i.in" or die "cannot open $i.in\n";
+
+    my $module = undef;
+    my $dir = $i;
 
-    $module = undef;
     while (<MAKE>)
     {
         chop;
@@ -58,34 +93,41 @@ foreach my $i (split(/\s/,$makefiles))
         if (/^MODULE\s*=\s*([a-zA-Z0-9_.]+)/)
         {
             $module = $1;
-            $imports{$module} = [ ];
-            ($directories{$module} = $i) =~ s/^\.\/(.*)\/[^\/]+$/$1/;
+            if ($module =~ /^lib.*\.a$/)
+            {
+                ($staticlib_dirs{$module} = $i) =~ s/^dlls\/(.*)\/[^\/]+$/$1/;
+                die "invalid module $module in dir $staticlib_dirs{$module}\n" if "lib$staticlib_dirs{$module}.a" ne $module;
+            }
+            else
+            {
+                ($directories{$module} = $i) =~ s/^dlls\/(.*)\/[^\/]+$/$1/;
+            }
             next;
         }
-        if (/^ALTNAMES\s*=\s*(.*)/)
+        if (/^IMPORTLIB\s*=\s*([a-zA-Z0-9_.]+)\.\$\(IMPLIBEXT\)/)
         {
-            my @list = split(/\s/,$1);
-            $altnames{$module} = \@list;
+            $importlibs{$module} = $1;
             next;
         }
-        if (/^(DELAYIMPORTS|IMPORTS)\s*=\s*(.*)/)
+        if (/^IMPLIB_SRCS\s*=/)
         {
-            my @list = map { /\./ ? $_ : $_ . ".dll"; } split(/\s/,$2);
-            push @{$imports{$module}}, @list;
+            $static_implibs{$module} = 1;
             next;
         }
-        if (/^LDIMPORTS\s*=\s*(.*)/)
+        if (/^SPEC_SRCS16\s*=\s*(.*)/)
         {
-            my @list = map { /\./ ? $_ : $_ . ".dll"; } split(/\s/,$1);
-            $linked_dlls{$module} = \@list;
+            my $specs = $1;
+            while ($specs =~ /\s*(.*)\\$/) { $specs = $1 . <MAKE>; }
+            my @list = split(/\s+/,$specs);
+            @list = map { $_ =~ s/\.spec$//; $_ .= ".dll" unless $_ =~ /\./; $_; } @list;
+            $altnames{$module} = \@list;
             next;
         }
     }
     close MAKE;
-    push @{$imports{$module}}, "kernel32.dll" unless !defined($module) || @{$imports{$module}} || $module eq "ntdll.dll";
 }
 
-open NEWMAKE,">Makefile.in.new" or die "cannot create Makefile.in.new";
+open NEWMAKE,">dlls/Makefile.in.new" or die "cannot create dlls/Makefile.in.new";
 
 ################################################################
 # makefile header
@@ -128,17 +170,21 @@ foreach my $dir (sort values %directories)
     printf NEWMAKE " \\\n\t%s", $dir;
 }
 
-printf NEWMAKE "\n\nSUBDIRS = \\\n\t\$(BASEDIRS)";
-foreach my $dir (sort keys %special_dlls)
-{
-    printf NEWMAKE " \\\n\t%s", $dir;
-}
-printf NEWMAKE <<EOF;
+print NEWMAKE "\n\nIMPLIBSUBDIRS = \\\n\t";
+print NEWMAKE join " \\\n\t", sort values %staticlib_dirs;
+
+print NEWMAKE "\n\nTESTSUBDIRS = \\\n\t";
+print NEWMAKE join " \\\n\t", sort values %testdirs;
 
+print NEWMAKE "\n\nSUBDIRS = \\\n\t";
+print NEWMAKE join " \\\n\t", "\$(BASEDIRS)", "\$(IMPLIBSUBDIRS)", "\$(TESTSUBDIRS)",
+                              sort keys %special_dlls;
+print NEWMAKE <<EOF;
 
-BUILDSUBDIRS = \$(BASEDIRS) \$(EXTRADIRS)
 
-INSTALLSUBDIRS = \$(BUILDSUBDIRS)
+BUILDSUBDIRS   = \$(BASEDIRS) \$(EXTRADIRS) \$(TESTSUBDIRS)
+INSTALLSUBDIRS = \$(BASEDIRS) \$(EXTRADIRS) \$(IMPLIBSUBDIRS)
+DOCSUBDIRS     = \$(BASEDIRS) \$(EXTRADIRS)
 EOF
 
 ################################################################
@@ -149,98 +195,122 @@ my %targets16 = ();
 foreach my $mod (sort keys %directories)
 {
     next if defined($special_dlls{$directories{$mod}});  # skip special dlls
-    $targets{sprintf("%s\$(DLLEXT)",$mod)} = 1;
+    $targets{$mod . ".so"} = 1 if needs_symlink($mod);
     next unless defined $altnames{$mod};
     foreach my $i (sort @{$altnames{$mod}})
     {
-        $targets16{sprintf("%s\$(DLLEXT)",$i)} = 1;
+        $targets16{$i . "16"} = $mod;
     }
 }
-print NEWMAKE <<EOF;
 
-# Main target
+print NEWMAKE <<EOF;
 
 \@MAKE_RULES\@
 
+# Symbolic links
+
 WIN16_FILES = \\
 EOF
 printf NEWMAKE "\t%s\n", join( " \\\n\t", sort keys %targets16 );
 
 print NEWMAKE <<EOF;
 
-all: \\
-       \$(EXTRADIRS:%=%.dll\$(DLLEXT)) \\
+SYMLINKS_SO = \\
        \@WIN16_FILES\@ \\
 EOF
 printf NEWMAKE "\t%s\n", join( " \\\n\t", sort keys %targets );
 
+print NEWMAKE <<EOF;
 
-################################################################
-# output the lib name -> directory rules
+# Main target
 
-print NEWMAKE <<EOF;
+all: \$(BUILDSUBDIRS) symlinks\$(DLLEXT)
+
+.PHONY: symlinks symlinks.so implib
 
-# Map symlink name to the corresponding library
+symlinks.so: \$(SYMLINKS_SO)
+
+symlinks: \$(BUILDSUBDIRS)
 
 EOF
 
+################################################################
+# output the lib name -> directory rules
+
+print NEWMAKE "# Map symlink name to the corresponding library\n\n";
 foreach my $mod (sort keys %directories)
 {
-    printf NEWMAKE "%s\$(DLLEXT)", $mod;
-    if (defined $altnames{$mod})
-    {
-        my $count = 1;
-        foreach my $i (sort @{$altnames{$mod}})
-        {
-            if (!($count++ % 3)) { printf NEWMAKE " \\\n "; }
-            printf NEWMAKE " %s\$(DLLEXT)", $i;
-        }
-    }
-    printf NEWMAKE ": %s/%s\$(DLLEXT)\n", $directories{$mod}, $mod;
-    printf NEWMAKE "\t\$(RM) \$@ && \$(LN_S) %s/%s\$(DLLEXT) \$@\n\n", $directories{$mod}, $mod;
+    next unless needs_symlink($mod);
+    printf NEWMAKE "%s.so: %s/%s.so\n", $mod, $directories{$mod}, $mod;
+    printf NEWMAKE "\t\$(RM) \$@ && \$(LN_S) %s/%s.so \$@\n\n", $directories{$mod}, $mod;
 }
 
+print NEWMAKE "# Placeholders for 16-bit libraries\n\n";
+foreach my $mod (sort keys %directories)
+{
+    next unless defined $altnames{$mod};
+    printf NEWMAKE "%s:\n", join(" ", map { $_ . "16"; } sort @{$altnames{$mod}});
+    printf NEWMAKE "\techo \"%s\" >\$\@\n\n", $mod;
+}
 
 ################################################################
 # output the import libraries rules
 
-my @implibs = grep /\.dll$/, keys %directories;
-push @implibs, "winspool.drv";
+print NEWMAKE "# Import libraries\n\n";
+print NEWMAKE "STATIC_IMPLIBEXT = \$(IMPLIBEXT:def=def.a)\n\n";
 
-print NEWMAKE "\n# Import libraries\n\nIMPORT_LIBS =";
-foreach my $mod (sort @implibs)
+my @lib_symlinks = ();
+foreach my $mod (sort keys %importlibs)
+{
+    my $dir = $directories{$mod};
+    my $lib = $importlibs{$mod};
+    if ($lib ne "lib" . $dir) { push @lib_symlinks, $mod; }
+}
+print NEWMAKE "IMPORT_SYMLINKS =";
+foreach my $mod (sort @lib_symlinks)
+{
+    printf NEWMAKE " \\\n\t%s.\$(IMPLIBEXT)", $importlibs{$mod};
+}
+
+print NEWMAKE "\n\nIMPORT_LIBS = \\\n\t\$(IMPORT_SYMLINKS)";
+foreach my $mod (sort keys %staticlib_dirs)
+{
+    printf NEWMAKE " \\\n\t%s/%s", $staticlib_dirs{$mod}, $mod;
+}
+foreach my $mod (sort keys %importlibs)
 {
+    my $dir = $directories{$mod};
     my $def = $mod;
     $def =~ s/\.(dll|drv)$//;
-    printf NEWMAKE " \\\n\tlib%s", $def;
+    printf NEWMAKE " \\\n\t%s/lib%s.\$(IMPLIBEXT)", $dir, $def;
+    printf NEWMAKE " \\\n\t%s/lib%s.\$(STATIC_IMPLIBEXT)", $dir, $def if $static_implibs{$mod};
 }
 print NEWMAKE "\n\n";
+print NEWMAKE "implib: \$(IMPORT_LIBS)\n\n";
 
-foreach my $mod (sort @implibs)
+foreach my $mod (sort keys %importlibs)
 {
     my $dir = $directories{$mod};
-    my $def = $mod;
+    my $lib = $importlibs{$mod};
     my $spec = $mod;
     $spec =~ s/\.dll$//;
-    $def =~ s/\.(dll|drv)$//;
-    printf NEWMAKE "lib%s.def: %s/%s.spec.def\n", $def, $dir, $spec;
-    printf NEWMAKE "\t\$(RM) \$@ && \$(LN_S) %s/%s.spec.def \$@\n", $dir, $spec;
-    printf NEWMAKE "lib%s.a: %s/%s.spec.def\n", $def, $dir, $spec;
-    printf NEWMAKE "\t\$(DLLTOOL) -k -l \$@ -d %s/%s.spec.def\n\n", $dir, $spec;
+    printf NEWMAKE "%s/%s.\$(IMPLIBEXT): %s/%s.spec \$(WINEBUILD)\n", $dir, $lib, $dir, $spec;
+    printf NEWMAKE "\t\@cd %s && \$(MAKE) %s.\$(IMPLIBEXT)\n\n", $dir, $lib;
+    next unless $static_implibs{$mod};
+    printf NEWMAKE "%s/%s.\$(STATIC_IMPLIBEXT): dummy\n", $dir, $lib, $dir, $spec;
+    printf NEWMAKE "\t\@cd %s && \$(MAKE) %s.\$(STATIC_IMPLIBEXT)\n\n", $dir, $lib;
 }
-foreach my $mod (sort @implibs)
+foreach my $mod (sort @lib_symlinks)
 {
     my $dir = $directories{$mod};
-    my $spec = $mod;
-    $spec =~ s/\.dll$//;
-    printf NEWMAKE "%s/%s.spec.def: \$(WINEBUILD)\n", $dir, $spec;
+    my $lib = $importlibs{$mod} . ".\$(IMPLIBEXT)";
+    printf NEWMAKE "%s: %s/%s\n", $lib, $dir, $lib;
+    printf NEWMAKE "\t\$(RM) \$@ && \$(LN_S) %s/%s \$@\n\n", $dir, $lib;
 }
 
-
 print NEWMAKE <<EOF;
-
-\$(SUBDIRS): \$(IMPORT_LIBS:%=%.\$(IMPLIBEXT))
-\$(SUBDIRS:%=%/__crosstest__): \$(IMPORT_LIBS:%=%.a)
+\$(BUILDSUBDIRS): \$(IMPORT_LIBS)
+\$(INSTALLSUBDIRS:%=%/__install__) \$(INSTALLSUBDIRS:%=%/__install-lib__): \$(IMPORT_LIBS)
 
 EOF
 
@@ -251,90 +321,68 @@ print NEWMAKE "# Map library name to the corresponding directory\n\n";
 
 foreach my $mod (sort keys %directories)
 {
-    printf NEWMAKE "%s/%s\$(DLLEXT): %s\n", $directories{$mod}, $mod, $directories{$mod};
+    next unless needs_symlink($mod);
+    printf NEWMAKE "%s/%s.so: %s\n", $directories{$mod}, $mod, $directories{$mod};
 }
-
-print NEWMAKE "\n# Install dependencies\n\n";
-
-foreach my $mod (sort keys %directories)
+foreach my $mod (sort keys %staticlib_dirs)
 {
-    printf NEWMAKE "%s/__install__: %s\$(DLLEXT)\n", $directories{$mod}, $mod;
+    printf NEWMAKE "%s/%s: %s\n", $staticlib_dirs{$mod}, $mod, $staticlib_dirs{$mod};
 }
 
-################################################################
-# output the linkable dlls special links
-
-my %linkable_dlls = ();
-foreach my $mod (keys %imports)
-{
-    foreach my $i (@{$linked_dlls{$mod}}) { $linkable_dlls{$i} = 1; }
-}
-
-print NEWMAKE "\n# Special targets for dlls that we need to link to\n\n";
-printf NEWMAKE "LINKABLE_DLLS = %s\n\n", join( " ", keys %linkable_dlls );
-
-foreach my $mod (keys %linkable_dlls)
-{
-    printf NEWMAKE "lib%s.\$(LIBEXT): %s/%s\$(DLLEXT)\n", $mod, $directories{$mod}, $mod;
-    printf NEWMAKE "\t\$(RM) \$@ && \$(LN_S) %s/%s\$(DLLEXT) \$@\n\n", $directories{$mod}, $mod;
-}
-
-foreach my $mod (keys %imports)
-{
-    my $deps = "";
-    foreach my $i (@{$linked_dlls{$mod}}) { $deps .= " lib$i.\$(LIBEXT)"; }
-    if ($deps) { printf NEWMAKE "%s:%s\n", $directories{$mod}, $deps; }
-}
-
-print NEWMAKE <<EOF;
-
-uninstall::
-       \$(RM) \$(LINKABLE_DLLS:%=\$(libdir)/lib%.\$(LIBEXT))
-
-install install-lib::
-       \$(RM) \$(LINKABLE_DLLS:%=\$(libdir)/lib%.\$(LIBEXT))
-       cd \$(libdir) && if [ "\$(dlldir)" = "\$(libdir)/wine" ]; \\
-       then \\
-EOF
-foreach my $mod (keys %linkable_dlls)
-{
-    printf NEWMAKE "\t  \$(LN_S) wine/%s\$(DLLEXT) lib%s.\$(LIBEXT); \\\n", $mod, $mod;
-}
-print NEWMAKE "\telse \\\n";
-foreach my $mod (keys %linkable_dlls)
-{
-    printf NEWMAKE "\t  \$(LN_S) \$(dlldir)/%s\$(DLLEXT) lib%s.\$(LIBEXT); \\\n", $mod, $mod;
-}
-print NEWMAKE "\tfi\n\n";
-
 ################################################################
 # makefile trailer
 
 print NEWMAKE <<EOF;
+
 # Misc rules
 
-install install-dev:: \$(IMPORT_LIBS:%=%.\$(IMPLIBEXT))
-       \$(MKINSTALLDIRS) \$(dlldir)
-       for f in \$(IMPORT_LIBS:%=%.\$(IMPLIBEXT)); do \$(INSTALL_DATA) \$\$f \$(dlldir)/\$\$f; done
+install-lib:: \$(INSTALLSUBDIRS:%=%/__install-lib__)
 
-install install-lib:: \$(INSTALLSUBDIRS:%=%/__install__)
+install-dev:: \$(INSTALLSUBDIRS:%=%/__install-dev__)
 
 uninstall::
-       \$(RM) \$(IMPORT_LIBS:%=\$(dlldir)/%.\$(IMPLIBEXT))
-       -rmdir \$(dlldir)
+       -rmdir \$(DESTDIR)\$(dlldir)
 
 clean::
-       \$(RM) \$(IMPORT_LIBS:%=%.a) \$(IMPORT_LIBS:%=%.def)
+       \$(RM) \$(IMPORT_SYMLINKS) \$(WIN16_FILES)
+EOF
 
-check test:: \$(BUILDSUBDIRS:%=%/__test__)
+close NEWMAKE;
+update_file("dlls/Makefile.in");
 
-crosstest:: \$(BUILDSUBDIRS:%=%/__crosstest__)
+################################################################
+# .gitignore file
 
-checklink:: \$(BUILDSUBDIRS:%=%/__checklink__)
+open GITIGNORE, ">dlls/.gitignore.new" or die "cannot create dlls/.gitignore.new";
+print GITIGNORE "# Automatically generated by make_dlls; DO NOT EDIT!!\n";
 
-### Dependencies:
-EOF
+my @ignores =
+(
+ "/Makedll.rules",
+ "/Makeimplib.rules",
+ "/Maketest.rules",
+ "*/tests/testlist.c",
+ "*/tests/*.ok",
+);
 
-close NEWMAKE;
-rename "Makefile.in.new", "Makefile.in";
-printf "Successfully updated Makefile.in\n";
+foreach my $mod (sort @lib_symlinks)
+{
+    push @ignores, "/$importlibs{$mod}.def";
+}
+foreach my $mod (sort keys %directories)
+{
+    next unless defined $altnames{$mod};
+    push @ignores, map { "/" . $_ . "16"; } @{$altnames{$mod}};
+}
+foreach my $mod (sort keys %importlibs)
+{
+    my $dir = $directories{$mod};
+    my $def = $mod;
+    $def =~ s/\.(dll|drv)$//;
+    push @ignores, "$dir/lib$def.def";
+}
+
+print GITIGNORE join("\n", sort @ignores) . "\n";
+
+close GITIGNORE;
+update_file("dlls/.gitignore");