castle-bravo
castle-bravo

Reputation: 1429

Import pragmas in Ada: How does GNAT know where to look?

I used this pragma to import getpid from C:

function Get_Process_ID return Process_ID;
pragma Import (C, Get_Process_ID, "getpid");

I expected this to be a little harder. To use getpid in C, I need to explicitly include the header file unistd.h; in the above pragma, I made no reference to a header file. How does GNAT know exactly where to find getpid?

Edit:

Here's a minimum working example:

with Ada.Text_IO;

procedure Main is
   subtype Process_ID is Integer;
   function Get_Process_ID return Process_ID;
   pragma Import (C, Get_Process_ID, "getpid");   
begin
   Ada.Text_IO.Put_Line (Process_ID'Image (Get_Process_ID));
end Main;

Saved as main.adb, this compiles with the following command:

gnat make main.adb

I'm using a fresh install of the gnat package from the Ubuntu 18.04 software repositories with no configuration or project files. The GNAT version is 7.5.0.

Upvotes: 3

Views: 955

Answers (1)

castle-bravo
castle-bravo

Reputation: 1429

A detailed explanation is available in AdaCore's documentation on the GNAT Configurable Runtime Facility. By default, a program compiled with GNAT is linked against libc.a and a few others:

When an Ada program is built, the object code that makes up the final executable may come from the following entities (in addition to the user code itself):

  • GNAT Pro run-time library
  • C library
  • Math library
  • Internal GCC library
  • Startup code

The GNAT and GCC drivers automatically link all these libraries and objects with the final executable, statically or dynamically depending on the target and on some compilation options. The -nostdlib and -nodefaultlibs options may be used to control this automatic behavior.

Compiling my minimum working example with the -nostdlib flag fails with the following error (among many others):

...
main.adb:(.text+0x20): undefined reference to `getpid'
...

Functions provided in libc.a might vary by platform. On Ubuntu, you can find libc.a using locate, and check to see which symbols are defined using nm.

Upvotes: 6

Related Questions