在Ada中导入pragmas:GNAT如何知道在哪里查找?

在Ada中导入pragmas:GNAT如何知道在哪里查找?,ada,Ada,我使用这个pragma从C导入getpid: function Get_Process_ID return Process_ID; pragma Import (C, Get_Process_ID, "getpid"); 我以为这会更难一点。要在C中使用getpid,我需要显式地包含头文件unistd.h;在上面的pragma中,我没有引用头文件。GNAT如何确切地知道在哪里可以找到getpid 编辑: 下面是一个最低限度的工作示例: with Ada.Text_IO; procedure

我使用这个pragma从C导入
getpid

function Get_Process_ID return Process_ID;
pragma Import (C, Get_Process_ID, "getpid");
我以为这会更难一点。要在C中使用
getpid
,我需要显式地包含头文件unistd.h;在上面的pragma中,我没有引用头文件。GNAT如何确切地知道在哪里可以找到
getpid

编辑:

下面是一个最低限度的工作示例:

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;
保存为main.adb,使用以下命令进行编译:

gnat make main.adb

我正在使用Ubuntu 18.04软件存储库中新安装的
gnat
包,没有配置或项目文件。GNAT版本是7.5.0。

有关详细说明,请参阅AdaCore的文档。默认情况下,使用GNAT编译的程序链接到libc.a和其他一些程序:

当一个Ada程序被构建时,组成最终程序的目标代码 可执行文件可能来自以下实体(除了 用户代码本身):

  • GNAT Pro运行时库
  • C库
  • 数学图书馆
  • 内部GCC库
  • 启动代码
GNAT和GCC驱动程序自动链接所有这些库和 具有最终可执行文件的对象,静态或动态取决于 关于目标和一些编译选项。
-nostlib
-nodefaultlibs
选项可用于控制此自动行为

使用
-nostlib
标志编译我的最小工作示例失败,并出现以下错误(以及其他许多错误):


libc.a中提供的函数可能因平台而异。在Ubuntu上,您可以使用
locate
找到libc.a,并检查哪些符号是使用
nm

定义的。您必须以某种方式,通过Gnatmake的参数或项目(.GPR)文件中的设置,向链接器提供它需要的任何信息(链接哪些库或.o文件,如何找到它们)。值得一提的是Gnat的哪个版本,以及您使用的是gprbuild还是gnatmake。@BrianDrummond请参阅我的编辑。我没有向链接器提供任何信息。GNATMake可能有一些默认配置,指向常用的C头文件。我想glibc是gcc中的一个特例。有关其他任何内容中的函数,请参阅前面的注释。谢谢您的提示。AdaCore文档中提供了详细的解释:只是作为一般说明,在C语言中,您不“需要”该头文件。头文件通常只提供函数的声明。您可以创建自己的头文件,也可以在C文件中使用外部文件。在Ada中,具有过程/函数声明+用于导入的pragma或aspect类似于需要头文件的期望。只要您有一些使用语言工具将其链接到外部符号的声明,您就可以链接到您的项目可以“看到”的任何可用代码,以强调您的答案和@Brian Drummond注释,我相信这个链接对于如何链接默认库以外的库可能很有用。
...
main.adb:(.text+0x20): undefined reference to `getpid'
...