无法将 C 源代码与 Ada 静态库链接(错误:libnewapi.a(unit1.o):unit1.adb:undefined 引用“__gnat_rcheck_CE_Overflow_Check”)

Unable to link C source code with Ada static library (Error: libnewapi.a(unit1.o):unit1.adb:undefined reference to `__gnat_rcheck_CE_Overflow_Check')

提问人:Yadu SS 提问时间:7/21/2023 最后编辑:T.E.D.Yadu SS 更新时间:7/26/2023 访问量:73

问:

我想将我的 Ada 静态库 (libnewapi.a) 与我的 C 源代码 (main.c) 集成。 生成静态库时,我没有任何问题,但是在尝试将其与main.c链接时。 我收到以下链接错误, libnewapi.a(unit1.o):unit1.adb:(.text+0x31):未定义对“__gnat_rcheck_CE_Overflow_Check”的引用 我没有在我的 main.c 中使用此引用,也没有在我的任何 Ada 文件中使用。 我不知道为什么这个引用是自动添加的。 至关重要的是,我需要为我的项目使用静态 Ada 库链接我的 main.c。 我不知道我哪里出了问题。 非常感谢帮助。谢谢!

我正在使用 GPR 生成 libnewapi.a,如下所示,

    -- ada_gen_a.gpr
    project ada_gen_a is
       for Languages use ("Ada");
       for Source_Dirs use ("./");
       for Library_Name use "newapi";
       for Library_Dir use "./Lib/";
       for Library_Kind use "static";

       package Naming is
          for Spec_Suffix ("ada") use ".ads";
          for Body_Suffix ("ada") use ".adb";
          for Separate_Suffix use ".adb";
          for Dot_Replacement use ".";
          for Casing use "mixedcase";
       end Naming;

       Ada_Switches := ("-gnato", "-O2");

       package Compiler is
          for Default_Switches ("ada") use Ada_Switches;
       end Compiler;

       package Binder is
          for Default_Switches ("Ada") use ("-n","-Lada");
       end Binder;
    end ada_gen_a;

Ada 源文件:

    --  unit1.ads
    package Unit1 is
       function Add (A, B : Integer) return Integer;
       pragma Export (C, Add, "ada_add");
    end Unit1;
    -- unit1.adb
    package body Unit1 is
       function Add (A, B : Integer) return Integer is
       begin
          return A + B;
       end Add;
    end Unit1;

C 源文件:

    /* main.c */
    #include <stdio.h>
    extern void ada_add (void);
    int main (int argc, char *argv[])
    {
       int a = 21, b = 7, c = 0;
       printf ("%d", a);
       printf ("%d", b);
       c = ada_add(a,b);
       printf ("%d", c);
       return 0;
    }

我正在使用下面的GPR将上面的main.c与使用ada_gen_a.gpr生成的Ada静态库链接起来。

    -- Ada_Use_A.gpr
    with "newapi.gpr";
    project Ada_Use_A is

       for Languages use ("C");
       for Source_Dirs use (".");
       for Source_Files use ("main.c");

       package Naming is
          for Casing use "mixedcase";
       end Naming;

       Ada_Switches := ("-gnato", "-O2");

       package Compiler is
          for Default_Switches ("C") use ("-O2", "-Wall");
          for Default_Switches ("Ada") use Ada_Switches;
       end Compiler;

       package Binder is
          for Default_Switches ("Ada") use ("-n","-Lada");
       end Binder;

       for Main use ("main.c");

    end Ada_Use_A;
    -- newapi.gpr
    project newapi is
       for Externally_Built use "true";
       for Source_Files use ();
       for Library_Dir use ".\lib\";
       for Library_Name use "newapi";
       for Library_Kind use "static";
    end newapi;

当我尝试构建 Ada_Use_A.gpr GPS 时,出现以下链接器错误,__gnat_rcheck_CE_Overflow_Check' gprbuild:main.c 的链接失败'libnewapi.a(unit1.o):unit1.adb:(.text+0x31): undefined reference to

C GCC 链接器错误 ADA GNAT

评论

0赞 John Bollinger 7/21/2023
我不具体了解 ADA,但编程语言实现通常依赖于运行时支持函数库。对于已编译的语言,编译器可能会插入对此类函数的调用以实现各种语言功能,即使源代码未显式表示此类调用也是如此。鉴于这是 GNU 的 ADA 编译器,我倾向于认为类似的东西解释了调用的来源。据推测,您至少需要链接一个额外的库来解决这些问题。gnat__gnat_rcheck_CE_Overflow_Check
0赞 trashgod 7/22/2023
您可以尝试 ,这“会导致编译器的行为与默认禁止溢出检查的旧版本的默认值相匹配。-gnato0
0赞 Simon Wright 7/24/2023
我想知道这个答案(以及它所回答的问题)是否相关?

答:

1赞 T.E.D. 7/26/2023 #1

一般来说,除了最微不足道的 Ada 例程之外,所有 Ada 例程都需要内部 Ada 运行时库的一些支持。 当然听起来像是其中之一。(我的英文翻译的 SWAG 是“Gnat 运行时检查超出其子类型定义边界的对象的constraint_error异常”)。__gnat_rcheck_CE_Overflow_Check

如果你的主程序在 Ada 中,那么你就会自动链接 RTL,以及为可能需要它的任何包生成的启动详细说明代码,以及关闭清理代码。如果你的主程序是用其他语言的,那么你通常需要手动链接它们,并在调用你的 Ada 例程之前找到一种手动调用 elaboration 的方法。

更具体地说,涉及在混合语言环境中链接和运行的细节,这(我上次检查)并不完全由语言定义。您确实指定了编译器,但如果您要指定要尝试的平台,也可能会有所帮助。

例如,对于带有 Gnat 的 Windows,相关文档是 Gnat 用户指南中有关 Windows 下的混合语言编程的部分。

我特别注意到的一件事是,我在您的 C 主文件中没有看到任何看起来像我在这些文档的相关部分中看到的对 adainit() 和 adafinal() 的调用。