OSDN Git Service

optimize
[pf3gnuchains/gcc-fork.git] / gcc / ada / mdll.adb
index c07768d..a6c9b23 100644 (file)
@@ -6,9 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---                            $Revision$
---                                                                          --
---          Copyright (C) 1992-2001 Free Software Foundation, Inc.          --
+--          Copyright (C) 1992-2003 Free Software Foundation, Inc.          --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -22,7 +20,7 @@
 -- MA 02111-1307, USA.                                                      --
 --                                                                          --
 -- GNAT was originally developed  by the GNAT team at  New York University. --
--- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
 --                                                                          --
 ------------------------------------------------------------------------------
 
@@ -31,8 +29,9 @@
 
 with Ada.Text_IO;
 
-with MDLL.Tools;
-with MDLL.Files;
+with GNAT.Directory_Operations;
+with MDLL.Utl;
+with MDLL.Fil;
 
 package body MDLL is
 
@@ -58,18 +57,23 @@ package body MDLL is
 
       use type OS_Lib.Argument_List;
 
-      Base_Filename : constant String := MDLL.Files.Ext_To (Lib_Filename);
+      Base_Filename : constant String := MDLL.Fil.Ext_To (Lib_Filename);
 
-      Def_File : aliased String := Def_Filename;
-      Jnk_File : aliased String := Base_Filename & ".jnk";
-      Bas_File : aliased String := Base_Filename & ".base";
-      Dll_File : aliased String := Base_Filename & ".dll";
-      Exp_File : aliased String := Base_Filename & ".exp";
-      Lib_File : aliased String := "lib" & Base_Filename & ".a";
+      Def_File : aliased constant String := Def_Filename;
+      Jnk_File : aliased          String := Base_Filename & ".jnk";
+      Bas_File : aliased constant String := Base_Filename & ".base";
+      Dll_File : aliased          String := Base_Filename & ".dll";
+      Exp_File : aliased          String := Base_Filename & ".exp";
+      Lib_File : aliased constant String := "lib" & Base_Filename & ".a";
 
       Bas_Opt  : aliased String := "-Wl,--base-file," & Bas_File;
       Lib_Opt  : aliased String := "-mdll";
       Out_Opt  : aliased String := "-o";
+      Adr_Opt  : aliased String := "-Wl,--image-base=" & Lib_Address;
+
+      L_Afiles : Argument_List := Afiles;
+      --  Local afiles list. This list can be reordered to ensure that the
+      --  binder ali file is not the first entry in this list.
 
       All_Options : constant Argument_List := Options & Largs_Options;
 
@@ -92,12 +96,13 @@ package body MDLL is
       ---------------------
 
       procedure Build_Reloc_DLL is
-
          --  Objects plus the export table (.exp) file
 
-         Objects_Exp_File : OS_Lib.Argument_List
+         Objects_Exp_File : constant OS_Lib.Argument_List
            := Exp_File'Unchecked_Access & Ofiles;
 
+         Success : Boolean;
+
       begin
          if not Quiet then
             Text_IO.Put_Line ("building relocatable DLL...");
@@ -112,50 +117,50 @@ package body MDLL is
 
          --  1) Build base file with objects files.
 
-         Tools.Gcc (Output_File => Jnk_File,
-                    Files       => Ofiles,
-                    Options     => All_Options,
-                    Base_File   => Bas_File,
-                    Build_Lib   => True);
+         Utl.Gcc (Output_File => Jnk_File,
+                  Files       => Ofiles,
+                  Options     => All_Options,
+                  Base_File   => Bas_File,
+                  Build_Lib   => True);
 
          --  2) Build exp from base file.
 
-         Tools.Dlltool (Def_File, Dll_File, Lib_File,
-                        Base_File    => Bas_File,
-                        Exp_Table    => Exp_File,
-                        Build_Import => False);
+         Utl.Dlltool (Def_File, Dll_File, Lib_File,
+                      Base_File    => Bas_File,
+                      Exp_Table    => Exp_File,
+                      Build_Import => False);
 
          --  3) Build base file with exp file and objects files.
 
-         Tools.Gcc (Output_File => Jnk_File,
-                    Files       => Objects_Exp_File,
-                    Options     => All_Options,
-                    Base_File   => Bas_File,
-                    Build_Lib   => True);
+         Utl.Gcc (Output_File => Jnk_File,
+                  Files       => Objects_Exp_File,
+                  Options     => All_Options,
+                  Base_File   => Bas_File,
+                  Build_Lib   => True);
 
          --  4) Build new exp from base file and the lib file (.a)
 
-         Tools.Dlltool (Def_File, Dll_File, Lib_File,
-                        Base_File    => Bas_File,
-                        Exp_Table    => Exp_File,
-                        Build_Import => Build_Import);
+         Utl.Dlltool (Def_File, Dll_File, Lib_File,
+                      Base_File    => Bas_File,
+                      Exp_Table    => Exp_File,
+                      Build_Import => Build_Import);
 
          --  5) Build the dynamic library
 
-         Tools.Gcc (Output_File => Dll_File,
-                    Files       => Objects_Exp_File,
-                    Options     => All_Options,
-                    Build_Lib   => True);
+         Utl.Gcc (Output_File => Dll_File,
+                  Files       => Objects_Exp_File,
+                  Options     => Adr_Opt'Unchecked_Access & All_Options,
+                  Build_Lib   => True);
 
-         Tools.Delete_File (Exp_File);
-         Tools.Delete_File (Bas_File);
-         Tools.Delete_File (Jnk_File);
+         OS_Lib.Delete_File (Exp_File, Success);
+         OS_Lib.Delete_File (Bas_File, Success);
+         OS_Lib.Delete_File (Jnk_File, Success);
 
       exception
          when others =>
-            Tools.Delete_File (Exp_File);
-            Tools.Delete_File (Bas_File);
-            Tools.Delete_File (Jnk_File);
+            OS_Lib.Delete_File (Exp_File, Success);
+            OS_Lib.Delete_File (Bas_File, Success);
+            OS_Lib.Delete_File (Jnk_File, Success);
             raise;
       end Build_Reloc_DLL;
 
@@ -164,6 +169,7 @@ package body MDLL is
       -------------------------
 
       procedure Ada_Build_Reloc_DLL is
+         Success : Boolean;
       begin
          if not Quiet then
             Text_IO.Put_Line ("Building relocatable DLL...");
@@ -178,74 +184,77 @@ package body MDLL is
 
          --  1) Build base file with objects files.
 
-         Tools.Gnatbind (Afiles, Options & Bargs_Options);
+         Utl.Gnatbind (L_Afiles, Options & Bargs_Options);
 
          declare
-            Params : OS_Lib.Argument_List :=
-              Out_Opt'Unchecked_Access & Jnk_File'Unchecked_Access &
-              Lib_Opt'Unchecked_Access &
-              Bas_Opt'Unchecked_Access & Ofiles & All_Options;
+            Params : constant OS_Lib.Argument_List :=
+                       Out_Opt'Unchecked_Access &
+                       Jnk_File'Unchecked_Access &
+                       Lib_Opt'Unchecked_Access &
+                       Bas_Opt'Unchecked_Access &
+                       Ofiles &
+                       All_Options;
          begin
-            Tools.Gnatlink (Afiles (Afiles'Last).all,
-                            Params);
+            Utl.Gnatlink (L_Afiles (L_Afiles'Last).all, Params);
          end;
 
          --  2) Build exp from base file.
 
-         Tools.Dlltool (Def_File, Dll_File, Lib_File,
-                        Base_File    => Bas_File,
-                        Exp_Table    => Exp_File,
-                        Build_Import => False);
+         Utl.Dlltool (Def_File, Dll_File, Lib_File,
+                      Base_File    => Bas_File,
+                      Exp_Table    => Exp_File,
+                      Build_Import => False);
 
          --  3) Build base file with exp file and objects files.
 
-         Tools.Gnatbind (Afiles, Options & Bargs_Options);
+         Utl.Gnatbind (L_Afiles, Options & Bargs_Options);
 
          declare
-            Params : OS_Lib.Argument_List :=
-              Out_Opt'Unchecked_Access & Jnk_File'Unchecked_Access &
-              Lib_Opt'Unchecked_Access &
-              Bas_Opt'Unchecked_Access &
-              Exp_File'Unchecked_Access &
-              Ofiles &
-              All_Options;
+            Params : constant OS_Lib.Argument_List :=
+                       Out_Opt'Unchecked_Access &
+                       Jnk_File'Unchecked_Access &
+                       Lib_Opt'Unchecked_Access &
+                       Bas_Opt'Unchecked_Access &
+                       Exp_File'Unchecked_Access &
+                       Ofiles &
+                       All_Options;
          begin
-            Tools.Gnatlink (Afiles (Afiles'Last).all,
-                            Params);
+            Utl.Gnatlink (L_Afiles (L_Afiles'Last).all, Params);
          end;
 
          --  4) Build new exp from base file and the lib file (.a)
 
-         Tools.Dlltool (Def_File, Dll_File, Lib_File,
-                        Base_File    => Bas_File,
-                        Exp_Table    => Exp_File,
-                        Build_Import => Build_Import);
+         Utl.Dlltool (Def_File, Dll_File, Lib_File,
+                      Base_File    => Bas_File,
+                      Exp_Table    => Exp_File,
+                      Build_Import => Build_Import);
 
          --  5) Build the dynamic library
 
-         Tools.Gnatbind (Afiles, Options & Bargs_Options);
+         Utl.Gnatbind (L_Afiles, Options & Bargs_Options);
 
          declare
-            Params : OS_Lib.Argument_List :=
-              Out_Opt'Unchecked_Access & Dll_File'Unchecked_Access &
-              Lib_Opt'Unchecked_Access &
-              Exp_File'Unchecked_Access &
-              Ofiles &
-              All_Options;
+            Params : constant OS_Lib.Argument_List :=
+                       Out_Opt'Unchecked_Access &
+                       Dll_File'Unchecked_Access &
+                       Lib_Opt'Unchecked_Access &
+                       Exp_File'Unchecked_Access &
+                       Adr_Opt'Unchecked_Access &
+                       Ofiles &
+                       All_Options;
          begin
-            Tools.Gnatlink (Afiles (Afiles'Last).all,
-                            Params);
+            Utl.Gnatlink (L_Afiles (L_Afiles'Last).all, Params);
          end;
 
-         Tools.Delete_File (Exp_File);
-         Tools.Delete_File (Bas_File);
-         Tools.Delete_File (Jnk_File);
+         OS_Lib.Delete_File (Exp_File, Success);
+         OS_Lib.Delete_File (Bas_File, Success);
+         OS_Lib.Delete_File (Jnk_File, Success);
 
       exception
          when others =>
-            Tools.Delete_File (Exp_File);
-            Tools.Delete_File (Bas_File);
-            Tools.Delete_File (Jnk_File);
+            OS_Lib.Delete_File (Exp_File, Success);
+            OS_Lib.Delete_File (Bas_File, Success);
+            OS_Lib.Delete_File (Jnk_File, Success);
             raise;
       end Ada_Build_Reloc_DLL;
 
@@ -254,6 +263,7 @@ package body MDLL is
       -------------------------
 
       procedure Build_Non_Reloc_DLL is
+         Success : Boolean;
       begin
          if not Quiet then
             Text_IO.Put_Line ("building non relocatable DLL...");
@@ -269,22 +279,22 @@ package body MDLL is
 
          --  Build exp table and the lib .a file.
 
-         Tools.Dlltool (Def_File, Dll_File, Lib_File,
-                        Exp_Table    => Exp_File,
-                        Build_Import => Build_Import);
+         Utl.Dlltool (Def_File, Dll_File, Lib_File,
+                      Exp_Table    => Exp_File,
+                      Build_Import => Build_Import);
 
          --  Build the DLL
 
-         Tools.Gcc (Output_File => Dll_File,
-                    Files       => Exp_File'Unchecked_Access & Ofiles,
-                    Options     => All_Options,
-                    Build_Lib   => True);
+         Utl.Gcc (Output_File => Dll_File,
+                  Files       => Exp_File'Unchecked_Access & Ofiles,
+                  Options     => Adr_Opt'Unchecked_Access & All_Options,
+                  Build_Lib   => True);
 
-         Tools.Delete_File (Exp_File);
+         OS_Lib.Delete_File (Exp_File, Success);
 
       exception
          when others =>
-            Tools.Delete_File (Exp_File);
+            OS_Lib.Delete_File (Exp_File, Success);
             raise;
       end Build_Non_Reloc_DLL;
 
@@ -295,6 +305,7 @@ package body MDLL is
       --  Build a non relocatable DLL with Ada code.
 
       procedure Ada_Build_Non_Reloc_DLL is
+         Success : Boolean;
       begin
          if not Quiet then
             Text_IO.Put_Line ("building non relocatable DLL...");
@@ -310,46 +321,65 @@ package body MDLL is
 
          --  Build exp table and the lib .a file.
 
-         Tools.Dlltool (Def_File, Dll_File, Lib_File,
-                        Exp_Table    => Exp_File,
-                        Build_Import => Build_Import);
+         Utl.Dlltool (Def_File, Dll_File, Lib_File,
+                      Exp_Table    => Exp_File,
+                      Build_Import => Build_Import);
 
          --  Build the DLL
 
-         Tools.Gnatbind (Afiles, Options & Bargs_Options);
+         Utl.Gnatbind (L_Afiles, Options & Bargs_Options);
 
          declare
-            Params : OS_Lib.Argument_List :=
-              Out_Opt'Unchecked_Access & Dll_File'Unchecked_Access &
-              Lib_Opt'Unchecked_Access &
-              Exp_File'Unchecked_Access &
-              Ofiles &
-              All_Options;
+            Params : constant OS_Lib.Argument_List :=
+                       Out_Opt'Unchecked_Access &
+                       Dll_File'Unchecked_Access &
+                       Lib_Opt'Unchecked_Access &
+                       Exp_File'Unchecked_Access &
+                       Adr_Opt'Unchecked_Access &
+                       Ofiles &
+                       All_Options;
          begin
-            Tools.Gnatlink (Afiles (Afiles'Last).all,
-                            Params);
+            Utl.Gnatlink (L_Afiles (L_Afiles'Last).all, Params);
          end;
 
-         Tools.Delete_File (Exp_File);
+         OS_Lib.Delete_File (Exp_File, Success);
 
       exception
          when others =>
-            Tools.Delete_File (Exp_File);
+            OS_Lib.Delete_File (Exp_File, Success);
             raise;
       end Ada_Build_Non_Reloc_DLL;
 
    begin
+      --  On Windows the binder file must not be in the first position
+      --  in the list. This is due to the way DLL's are built on Windows.
+      --  We swap the first ali with the last one if it is the case.
+
+      if L_Afiles'Length > 1 then
+         declare
+            Filename : constant String :=
+                         Directory_Operations.Base_Name (L_Afiles (1).all);
+            First    : constant Positive := Filename'First;
+
+         begin
+            if Filename (First .. First + 1) = "b~" then
+               L_Afiles (L_Afiles'Last) := Afiles (1);
+               L_Afiles (1) := Afiles (Afiles'Last);
+            end if;
+         end;
+      end if;
+
       case Relocatable is
 
          when True =>
-            if Afiles'Length = 0 then
+            if L_Afiles'Length = 0 then
                Build_Reloc_DLL;
             else
                Ada_Build_Reloc_DLL;
             end if;
 
          when False =>
-            if Afiles'Length = 0 then
+            if L_Afiles'Length = 0 then
                Build_Non_Reloc_DLL;
             else
                Ada_Build_Non_Reloc_DLL;
@@ -371,7 +401,7 @@ package body MDLL is
       --  Build an import library.
       --  this is to build only a .a library to link against a DLL.
 
-      Base_Filename : constant String := MDLL.Files.Ext_To (Lib_Filename);
+      Base_Filename : constant String := MDLL.Fil.Ext_To (Lib_Filename);
 
       --------------------------
       -- Build_Import_Library --
@@ -391,8 +421,8 @@ package body MDLL is
                               " to use dynamic library " & Dll_File);
          end if;
 
-         Tools.Dlltool (Def_File, Dll_File, Lib_File,
-                        Build_Import => True);
+         Utl.Dlltool (Def_File, Dll_File, Lib_File,
+                      Build_Import => True);
       end Build_Import_Library;
 
    begin