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?
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.
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.
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.
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.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With