| ------------------------------------------------------------------------------ |
| -- -- |
| -- GNAT COMPILER COMPONENTS -- |
| -- -- |
| -- M D L L -- |
| -- -- |
| -- B o d y -- |
| -- -- |
| -- $Revision$ |
| -- -- |
| -- Copyright (C) 1992-2001 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 : Argument_List; |
| Afiles : Argument_List; |
| Options : Argument_List; |
| Bargs_Options : Argument_List; |
| Largs_Options : Argument_List; |
| Lib_Filename : String; |
| Def_Filename : String; |
| Lib_Address : String := ""; |
| Build_Import : Boolean := False; |
| Relocatable : 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 : String; |
| Def_Filename : String) |
| is |
| |
| procedure Build_Import_Library (Def_Base_Filename : 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 : 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; |