Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic linking a library in Ada introduces extra dependencies

I am having trouble with dynamic and static linking a library in Ada. I have prepared a minimum working example. These three files define a library that outputs "Hello world":

helloworld_lib.gpr:

project Helloworld_Lib is

   for Library_Name use "helloworld_lib";
   for Source_Files use ("helloworld_lib.adb", "helloworld_lib.ads");
   for Library_Kind use "static";
   for Library_Dir use "obj";

end Helloworld_Lib;

helloworld_lib.adb:

with Ada.Text_IO;

package body helloworld_lib is

   procedure Hello is
   begin
      Ada.Text_IO.Put_Line("Hello world");
   end Hello;

end helloworld_lib;

helloworld_lib.ads:

with Ada.Text_IO;
use Ada.Text_IO;

package helloworld_lib is

   procedure Hello;

end helloworld_lib;

These two files define a project that imports the library and runs it:

helloworld_interface.gpr:

with "helloworld_lib.gpr";

project Helloworld_Interface is

   for Create_Missing_Dirs use "True";
   for Main use ("helloworld_interface.adb");
   for Source_Files use ("helloworld_interface.adb");
   for Object_Dir use "obj";

end Helloworld_Interface;

helloworld_interface.adb:

with helloworld_lib; use helloworld_lib;

procedure helloworld_interface is

begin

   Hello;

end helloworld_interface;

I am using GPS 19.1 GNAT Community Edition on Windows. If helloworld_interface.gpr is opened and "Build All" run an exe is compiled that works as expected and is fully self contained.

If we change Library_Kind from static to dynamic in helloworld_lib.gpr and build as before an exe and a dll is compiled. However the compiled files now have a dependency on libgnat-2019.dll and libgcc_s_seh-1.dll. The program will not run without these DLLs, which can be copied from C:\GNAT\2019\bin.

Given that a static linked EXE file can be produced that runs with no other dependencies, how can this example be compiled to an EXE and a DLL with no other dependencies? Why are these two extra DLLs now required?

like image 317
Mark MAC Clowes Avatar asked Feb 12 '20 16:02

Mark MAC Clowes


People also ask

What is a dynamic link library in Windows?

In addition to being a generic term for dynamic link libraries, Dynamic Link Library is also the name of Microsoft's version of the shared library concept for Windows. A shared library can exist in any operating system ( OS ). How does a dynamic link library work? Computer programs are rarely written in a one file.

What is dynamic linking in Java?

Dynamic linking allows this single loading to happen. Dynamic Linking: Every dynamically linked program contains a small, statically linked function that is called when the program starts. This static function only maps the link library into memory and runs the code that the function contains.

What is a dynamically linked program?

A dynamically linked program has a small bit of code that maps the DLL into virtual memory, where the program can access it at runtime or load time. With this setup, the dynamically linked program doesn't have to repeatedly access physical memory to access the library.

What are the two types of link libraries?

There are two types of linking -- static and dynamic -- and two types of corresponding link libraries: Object code contains placeholder symbols that tell the operating system which libraries to link to at runtime to create the final executable file. Static links. These are linked earlier in the process and are embedded into the executable.


1 Answers

libgnat-2019.dll is GNAT's implementation of the Ada standard library. libgcc_s_seh-1.dll is a dependency of that standard library.

If you compile a single executable without dynamic libraries, GNAT can link to the standard library statically so you'll end up without a dependency to the dynamic libraries.

If, however, you link to an Ada dynamic library, you have the situation that both the executable's and the library's code require the standard library. If you'd try to link against the standard library statically, you'd end up with a standard library linked into the DLL and another one linked into your executable. So you'd have all the objects in the standard library twice when you load the executable, which is forbidden by Ada language semantics (it would call all package initialization code twice, for example).

Therefore, as soon as you compile Ada code to a DLL file, you have no choice but to link against the standard library dynamically. You can, however, link against C DLL files dynamically while still being able to include the Ada stdlib statically. Theoretically, you could create an Ada DLL with the -nostdlib and -nodefaultlibs but that would severly restrict what you would do inside this library (iirc there would be no exceptions).

like image 71
flyx Avatar answered Oct 29 '22 07:10

flyx