diff options
Diffstat (limited to 'gcc/ada/mdll.adb')
-rw-r--r-- | gcc/ada/mdll.adb | 410 |
1 files changed, 410 insertions, 0 deletions
diff --git a/gcc/ada/mdll.adb b/gcc/ada/mdll.adb new file mode 100644 index 00000000000..b0fca0293c3 --- /dev/null +++ b/gcc/ada/mdll.adb @@ -0,0 +1,410 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT COMPILER COMPONENTS -- +-- -- +-- M D L L -- +-- -- +-- B o d y -- +-- -- +-- $Revision: 1.4 $ +-- -- +-- Copyright (C) 1992-2000 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- -- +-- ware Foundation; either version 2, or (at your option) any later ver- -- +-- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- +-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- +-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- +-- for more details. You should have received a copy of the GNU General -- +-- Public License distributed with GNAT; see file COPYING. If not, write -- +-- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, -- +-- 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). -- +-- -- +------------------------------------------------------------------------------ + +-- This package provides the core high level routines used by GNATDLL +-- to build Windows DLL + +with Ada.Text_IO; + +with MDLL.Tools; +with MDLL.Files; + +package body MDLL is + + use Ada; + use GNAT; + + --------------------------- + -- Build_Dynamic_Library -- + --------------------------- + + procedure Build_Dynamic_Library + (Ofiles : in Argument_List; + Afiles : in Argument_List; + Options : in Argument_List; + Bargs_Options : in Argument_List; + Largs_Options : in Argument_List; + Lib_Filename : in String; + Def_Filename : in String; + Lib_Address : in String := ""; + Build_Import : in Boolean := False; + Relocatable : in Boolean := False) + is + + use type OS_Lib.Argument_List; + + Base_Filename : constant String := MDLL.Files.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"; + + Bas_Opt : aliased String := "-Wl,--base-file," & Bas_File; + Lib_Opt : aliased String := "-mdll"; + Out_Opt : aliased String := "-o"; + + All_Options : constant Argument_List := Options & Largs_Options; + + + procedure Build_Reloc_DLL; + -- build a relocatable DLL with only objects file specified. + -- this use the well known 5 steps build. (see GNAT User's Guide). + + procedure Ada_Build_Reloc_DLL; + -- build a relocatable DLL with Ada code. + -- this use the well known 5 steps build. (see GNAT User's Guide). + + procedure Build_Non_Reloc_DLL; + -- build a non relocatable DLL containing no Ada code. + + procedure Ada_Build_Non_Reloc_DLL; + -- build a non relocatable DLL with Ada code. + + --------------------- + -- Build_Reloc_DLL -- + --------------------- + + procedure Build_Reloc_DLL is + + -- objects plus the export table (.exp) file + + Objects_Exp_File : OS_Lib.Argument_List + := Exp_File'Unchecked_Access & Ofiles; + + begin + if not Quiet then + Text_IO.Put_Line ("building relocatable DLL..."); + Text_IO.Put ("make " & Dll_File); + + if Build_Import then + Text_IO.Put_Line (" and " & Lib_File); + else + Text_IO.New_Line; + end if; + end if; + + -- 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); + + -- 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); + + -- 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); + + -- 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); + + -- 5) build the dynamic library + + Tools.Gcc (Output_File => Dll_File, + Files => Objects_Exp_File, + Options => All_Options, + Build_Lib => True); + + Tools.Delete_File (Exp_File); + Tools.Delete_File (Bas_File); + Tools.Delete_File (Jnk_File); + + exception + when others => + Tools.Delete_File (Exp_File); + Tools.Delete_File (Bas_File); + Tools.Delete_File (Jnk_File); + raise; + end Build_Reloc_DLL; + + ------------------------- + -- Ada_Build_Reloc_DLL -- + ------------------------- + + procedure Ada_Build_Reloc_DLL is + begin + if not Quiet then + Text_IO.Put_Line ("Building relocatable DLL..."); + Text_IO.Put ("make " & Dll_File); + + if Build_Import then + Text_IO.Put_Line (" and " & Lib_File); + else + Text_IO.New_Line; + end if; + end if; + + -- 1) build base file with objects files. + + Tools.Gnatbind (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; + begin + Tools.Gnatlink (Afiles (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); + + -- 3) build base file with exp file and objects files. + + Tools.Gnatbind (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; + begin + Tools.Gnatlink (Afiles (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); + + -- 5) build the dynamic library + + Tools.Gnatbind (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; + begin + Tools.Gnatlink (Afiles (Afiles'Last).all, + Params); + end; + + Tools.Delete_File (Exp_File); + Tools.Delete_File (Bas_File); + Tools.Delete_File (Jnk_File); + + exception + when others => + Tools.Delete_File (Exp_File); + Tools.Delete_File (Bas_File); + Tools.Delete_File (Jnk_File); + raise; + end Ada_Build_Reloc_DLL; + + ------------------------- + -- Build_Non_Reloc_DLL -- + ------------------------- + + procedure Build_Non_Reloc_DLL is + begin + if not Quiet then + Text_IO.Put_Line ("building non relocatable DLL..."); + Text_IO.Put ("make " & Dll_File & + " using address " & Lib_Address); + + if Build_Import then + Text_IO.Put_Line (" and " & Lib_File); + else + Text_IO.New_Line; + end if; + end if; + + -- build exp table and the lib .a file. + + Tools.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); + + Tools.Delete_File (Exp_File); + + exception + when others => + Tools.Delete_File (Exp_File); + raise; + end Build_Non_Reloc_DLL; + + ----------------------------- + -- Ada_Build_Non_Reloc_DLL -- + ----------------------------- + + -- build a non relocatable DLL with Ada code. + + procedure Ada_Build_Non_Reloc_DLL is + begin + if not Quiet then + Text_IO.Put_Line ("building non relocatable DLL..."); + Text_IO.Put ("make " & Dll_File & + " using address " & Lib_Address); + + if Build_Import then + Text_IO.Put_Line (" and " & Lib_File); + else + Text_IO.New_Line; + end if; + end if; + + -- build exp table and the lib .a file. + + Tools.Dlltool (Def_File, Dll_File, Lib_File, + Exp_Table => Exp_File, + Build_Import => Build_Import); + + -- build the DLL + + Tools.Gnatbind (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; + begin + Tools.Gnatlink (Afiles (Afiles'Last).all, + Params); + end; + + Tools.Delete_File (Exp_File); + + exception + when others => + Tools.Delete_File (Exp_File); + raise; + end Ada_Build_Non_Reloc_DLL; + + begin + case Relocatable is + + when True => + if Afiles'Length = 0 then + Build_Reloc_DLL; + else + Ada_Build_Reloc_DLL; + end if; + + when False => + if Afiles'Length = 0 then + Build_Non_Reloc_DLL; + else + Ada_Build_Non_Reloc_DLL; + end if; + + end case; + end Build_Dynamic_Library; + + -------------------------- + -- Build_Import_Library -- + -------------------------- + + procedure Build_Import_Library (Lib_Filename : in String; + Def_Filename : in String) is + + procedure Build_Import_Library (Def_Base_Filename : in String); + -- 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); + + -------------------------- + -- Build_Import_Library -- + -------------------------- + + procedure Build_Import_Library (Def_Base_Filename : in String) is + + Def_File : String renames Def_Filename; + Dll_File : constant String := Def_Base_Filename & ".dll"; + Lib_File : constant String := "lib" & Base_Filename & ".a"; + + begin + + if not Quiet then + Text_IO.Put_Line ("Building import library..."); + Text_IO.Put_Line ("make " & Lib_File & + " to use dynamic library " & Dll_File); + end if; + + Tools.Dlltool (Def_File, Dll_File, Lib_File, + Build_Import => True); + end Build_Import_Library; + + begin + -- if the library has the form lib<name>.a then the def file should + -- be <name>.def and the DLL to link against <name>.dll + -- this is a Windows convention and we try as much as possible to + -- follow the platform convention. + + if Lib_Filename'Length > 3 and then Lib_Filename (1 .. 3) = "lib" then + Build_Import_Library (Base_Filename (4 .. Base_Filename'Last)); + else + Build_Import_Library (Base_Filename); + end if; + end Build_Import_Library; + +end MDLL; |