【问题标题】:How do I compile and link using gnatmake with an Ada shared library?如何使用 gnatmake 与 Ada 共享库进行编译和链接?
【发布时间】:2010-10-10 23:09:23
【问题描述】:

我在花店库中再次编译申请人时遇到问题。原来我对花店有一个更大的问题(最新的 2010 Adacore GPL 下载和 Debian 存档中的 2009 版本都产生了相同的错误)。 Florist 有一些低级问题,但是当我查看生成的文件时,它似乎正确地包含了 errno.h。

当我建立花店时会发生以下情况:

gcc-4.4 -c -I/usr/share/ada/adainclude/florist demo.adb gcc-4.4 -c -I./ -I/usr/share/ada/adainclude/florist -I- /usr/share/ada/adainclude/florist/posix.adb gcc-4.4 -c -I./ -I/usr/share/ada/adainclude/florist -I- /usr/share/ada/adainclude/florist/posix-io.adb gcc-4.4 -c -I./ -I/usr/share/ada/adainclude/florist -I- /usr/share/ada/adainclude/florist/posix-terminal_functions.adb gcc-4.4 -c -I./ -I/usr/share/ada/adainclude/florist -I- /usr/share/ada/adainclude/florist/posix-c.adb gcc-4.4 -c -I./ -I/usr/share/ada/adainclude/florist -I- /usr/share/ada/adainclude/florist/posix-implementation.adb posix-implementation.gpb:45:06:警告:“SYSTEM.INTERRUPT_MANAGEMENT.OPERATIONS”是一个内部 GNAT 单元 posix-implementation.gpb:45:06: 警告:使用这个单元是不可移植的和版本相关的 posix-implementation.gpb:47:06:警告:“SYSTEM.SOFT_LINKS”是一个内部 GNAT 单元 posix-implementation.gpb:47:06: 警告:使用这个单元是不可移植的并且依赖于版本 gcc-4.4 -c -I./ -I/usr/share/ada/adainclude/florist -I- /usr/share/ada/adainclude/florist/ada_streams.ads gcc-4.4 -c -I./ -I/usr/share/ada/adainclude/florist -I- /usr/share/ada/adainclude/florist/posix-permissions.adb gcc-4.4 -c -I./ -I/usr/share/ada/adainclude/florist -I- /usr/share/ada/adainclude/florist/posix-permissions-implementation.adb gcc-4.4 -c -I./ -I/usr/share/ada/adainclude/florist -I- /usr/share/ada/adainclude/florist/posix-process_identification.adb gnatbind -I/usr/share/ada/adainclude/florist -x demo.ali gnatlink demo.ali -o demoapp ./posix-implementation.o:在函数“posix__implementation__set_ada_error_code”中: posix-implementation.adb:(.text+0x19e): undefined reference to `store_errno' ./posix-implementation.o:在函数“posix__implementation__get_ada_error_code”中: posix-implementation.adb:(.text+0x1ab): undefined reference to `fetch_errno' ./posix-implementation.o:在函数“posix__implementation__raise_posix_error”中: posix-implementation.adb:(.text+0x234): undefined reference to `fetch_errno' ./posix-implementation.o:在函数`posix__implementation__check__2'中: posix-implementation.adb:(.text+0x2e5): undefined reference to `fetch_errno' ./posix-implementation.o:在函数`posix__implementation__check__3'中: posix-implementation.adb:(.text+0x313): undefined reference to `fetch_errno' ./posix-implementation.o:在函数“posix__implementation__check_nneg”中: posix-implementation.adb:(.text+0x332): undefined reference to `fetch_errno' ./posix-implementation.o:posix-implementation.adb:(.text+0x34e): 更多未定义的对 `fetch_errno' 的引用如下 ./posix-implementation.o:在函数“nosys_neg_one”中: posix-implementation.adb:(.text+0xaef): undefined reference to `store_errno' ./posix-implementation.o:在函数“notsup_neg_one”中: posix-implementation.adb:(.text+0xb15): undefined reference to `store_errno' ./posix-implementation.o:在函数“posix__implementation__restore_signals_and_raise_posix_error”中: posix-implementation.adb:(.text+0xc88): undefined reference to `fetch_errno' ./posix.o:在函数“posix__system_name”中: posix.adb:(.text+0x2f98): undefined reference to `__gnat_florist_uname' ./posix.o:在函数“posix__node_name”中: posix.adb:(.text+0x2fef): 对 `__gnat_florist_uname' 的未定义引用 ./posix.o:在函数“posix__release”中: posix.adb:(.text+0x3049): undefined reference to `__gnat_florist_uname' ./posix.o:在函数“posix__version”中: posix.adb:(.text+0x30a6): undefined reference to `__gnat_florist_uname' ./posix.o:在函数“posix__machine”中: posix.adb:(.text+0x3103): undefined reference to `__gnat_florist_uname' ./posix.o:在函数“posix__host_to_network_byte_order”中: posix.adb:(.text+0x4627): undefined reference to `c_htonl' ./posix.o:在函数“posix__host_to_network_byte_order__2”中: posix.adb:(.text+0x4642): undefined reference to `c_htons' ./posix.o:在函数“posix__network_to_host_byte_order”中: posix.adb:(.text+0x4655): undefined reference to `c_ntohl' ./posix.o:在函数“posix__network_to_host_byte_order__2”中: posix.adb:(.text+0x4670): undefined reference to `c_ntohs' ./posix-io.o:在函数“posix__io__open”中: posix-io.adb:(.text+0x4d1): undefined reference to `__gnat_florist_open' ./posix-io.o:在函数“posix__io__open_or_create”中: posix-io.adb:(.text+0xfca): undefined reference to `__gnat_florist_open' collect2: ld 返回 1 个退出状态 gnatlink:调用 /usr/bin/gcc-4.4 时出错 gnatmake:***链接失败。 josh@Mini10:~/Demo$ gnatbind -I/usr/share/ada/adainclude/florist -I/usr/include 演示 josh@Mini10:~/Demo$ gnatlink 演示 ./posix-implementation.o:在函数“posix__implementation__set_ada_error_code”中: posix-implementation.adb:(.text+0x19e): undefined reference to `store_errno' ./posix-implementation.o:在函数“posix__implementation__get_ada_error_code”中: posix-implementation.adb:(.text+0x1ab): undefined reference to `fetch_errno' ./posix-implementation.o:在函数“posix__implementation__raise_posix_error”中: posix-implementation.adb:(.text+0x234): undefined reference to `fetch_errno' ./posix-implementation.o:在函数`posix__implementation__check__2'中: posix-implementation.adb:(.text+0x2e5): undefined reference to `fetch_errno' ./posix-implementation.o:在函数`posix__implementation__check__3'中: posix-implementation.adb:(.text+0x313): undefined reference to `fetch_errno' ./posix-implementation.o:在函数“posix__implementation__check_nneg”中: posix-implementation.adb:(.text+0x332): undefined reference to `fetch_errno' ./posix-implementation.o:posix-implementation.adb:(.text+0x34e): 更多未定义的对 `fetch_errno' 的引用如下 ./posix-implementation.o:在函数“nosys_neg_one”中: posix-implementation.adb:(.text+0xaef): undefined reference to `store_errno' ./posix-implementation.o:在函数“notsup_neg_one”中: posix-implementation.adb:(.text+0xb15): undefined reference to `store_errno' ./posix-implementation.o:在函数“posix__implementation__restore_signals_and_raise_posix_error”中: posix-implementation.adb:(.text+0xc88): undefined reference to `fetch_errno' ./posix.o:在函数“posix__system_name”中: posix.adb:(.text+0x2f98): undefined reference to `__gnat_florist_uname' ./posix.o:在函数“posix__node_name”中: posix.adb:(.text+0x2fef): 对 `__gnat_florist_uname' 的未定义引用 ./posix.o:在函数“posix__release”中: posix.adb:(.text+0x3049): undefined reference to `__gnat_florist_uname' ./posix.o:在函数“posix__version”中: posix.adb:(.text+0x30a6): undefined reference to `__gnat_florist_uname' ./posix.o:在函数“posix__machine”中: posix.adb:(.text+0x3103): undefined reference to `__gnat_florist_uname' ./posix.o:在函数“posix__host_to_network_byte_order”中: posix.adb:(.text+0x4627): undefined reference to `c_htonl' ./posix.o:在函数“posix__host_to_network_byte_order__2”中: posix.adb:(.text+0x4642): undefined reference to `c_htons' ./posix.o:在函数“posix__network_to_host_byte_order”中: posix.adb:(.text+0x4655): undefined reference to `c_ntohl' ./posix.o:在函数“posix__network_to_host_byte_order__2”中: posix.adb:(.text+0x4670): undefined reference to `c_ntohs' ./posix-io.o:在函数“posix__io__open”中: posix-io.adb:(.text+0x4d1): undefined reference to `__gnat_florist_open' ./posix-io.o:在函数“posix__io__open_or_create”中: posix-io.adb:(.text+0xfca): undefined reference to `__gnat_florist_open' collect2: ld 返回 1 个退出状态 gnatlink:调用 /usr/bin/gcc-4.4 时出错

如果正确包含 errno.h 存在问题,则此错误似乎很常见。但据我从 posix-c.c 文件中可以看出,这一切看起来都是正确的。有人对如何解决这个问题有任何建议吗? Florist 的 make 文件构建正确,所以我不知道这是从哪里来的。

【问题讨论】:

  • 重新标记为 gnat,因为这个问题完全是 gnat-specific。

标签: ada gnat


【解决方案1】:

好的,结果证明这很痛苦,但我找到了。

Florist 绑定既可用作共享库,也可用作静态库(均已安装)。您需要链接库以解析所有引用(我永远无法将库源实际编译到我的应用程序中)。一旦您传递参数以告知编译阶段有关库的信息,您必须提供(至少)要解析的 .ads 文件。

最终的解决方案是这样的:

gnatmake -aI/usr/share/ada/adainclude/florist -aO/usr/lib/ada/adalib/florist demo.adb -largs -lflorist

-aI 提供库的广告文件的路径。 -aO 提供了(在这种情况下)libflorist.so 库文件的路径,最后(这是棘手的)你必须通过 -lflorist 告诉它这一切是什么共享库......但是传递它不会工作。您必须在其前面放置一个-largs(用于编译和链接器),以便编译阶段传递参数!没有它,这些阶段永远不会看到争论!

所以你就是所有人!为了在 Linux (GCC) 下针对共享 Ada 库编译和链接代码,您需要提供库的标头/规范、库位置和 -llibname 参数以及 -largs 以将它们传递到正确的位置!

我现在很开心。希望这对其他人有帮助。

【讨论】:

  • 花店是否附带 GNAT 项目文件 (.gpr)?使用这样的文件(通过在您自己的项目文件中使用)应该更简单。
  • 确实如此,但就我目前的 Ada 水平而言,我不想处理这些文件所增加的复杂性。虽然你提出了一个准确的观点。我没有费心去检查。只是花店源目录中的 INSTALL 和 README 文件以及其他 README 样式文件。我对项目文件没有经验,所以我没有想到。
【解决方案2】:

这是一个使用 GNAT 项目通过 Florist 构建的简单示例。我假设$ADA_PROJECT_PATH 包括安装florist.gpr 的目录(在我的情况下为$HOME/local/lib/gnat)。

示例程序(我在网上找不到任何简单的花店演示,有吗?),id.adb

with POSIX.Process_Identification;
with Ada.Text_IO; use Ada.Text_IO;
procedure Id is
begin
   Put_Line (POSIX.To_String (POSIX.Process_Identification.Get_Login_Name));
end Id;

项目文件(id.gpr),与id.adb在同一目录下:

with "florist";
project Id is
   for Main use ("id.adb");
   for Object_Dir use ".build_id";
   for Exec_Dir use ".";
end Id;

使用构建

$ gnatmake -p -P id.gpr
object directory "/Users/simon/florist-gpl-2010-src/demo/.build_id" created for project id
gcc -c -I- -gnatA /Users/simon/florist-gpl-2010-src/demo/id.adb
gnatbind -I- -x /Users/simon/florist-gpl-2010-src/demo/.build_id/id.ali
gnatlink /Users/simon/florist-gpl-2010-src/demo/.build_id/id.ali -lflorist -o /Users/simon/florist-gpl-2010-src/demo/id

然后运行:

$ ./id
simon

【讨论】:

    【解决方案3】:

    看起来很像普通的链接错误。您的 .h 文件、您的 Ada 目标文件和您的 C 链接库之间的某些内容并不完全匹配。很难说是什么。

    您最好寻找可能遇到相同问题的其他 Florist 用户。他们的项目页面是on SourceForge here,但它看起来在过去 6 年里并没有非常活跃。由于最新版本有那么旧,因此您可能需要一个那么旧的编译器(和操作系统?)才能使用它。艾克。

    【讨论】:

    • 嗨,是的...我开始真的害怕了。我无法理解为什么纯 POSIX 接口会是特定于版本的。我打算在几台不同的机器上试一试。我的直觉现在告诉我,这可能是编译器版本问题,而不是内核+发行版问题。由于我使用的编译器是 4.4 GCC...也许我应该降级到 4.1 或 4.2?我知道一些 Linux 的东西只适用于稍旧的 4.x GCC 编译器......我会从那里开始。
    • 您到底需要 Posix 做什么? Vanilla Ada 本身几乎可以充当可移植层。它几乎拥有您需要的一切。
    • 我需要直接控制模拟调制解调器的 AT 命令集以控制大型机器的设备的串行端口。 Ada 可以做很多事情……但不是串行端口 :-) 我以前在 C 语言中做过这样的事情,所以这不是我担心的原因,而是为什么这不会链接。基本的 Termios.h 内容加上 Ada 绑定标准包含非常有效地将字符字节数据从 TTY 转换为 POSIX 字符串到 Ada 字符串的例程(而不是我试图弄清楚)。无论我使用的是蓝牙、串口、USB仿真串口等,我都需要串口访问。
    • 就我个人而言,我很想直接进入操作系统。与 C 库的 Ada 绑定并不是那么难以编写。但我想如果你想要 Linux 之外的一些可移植性(假设你在 Linux 上),我可以看到你想要 POSIX 的地方。当然,对于大约 90% 的您想要做的事情,您可能只需使用 *_IO 包之一打开串行设备。但这不会让您能够更改波特率和停止位的数量等。
    • 是的,我可以用 C 对串行控件进行编程,编译它,然后将函数导入 Ada。但这就是这个 POSIX 绑定基本上在做的事情。 POSIX Ada 绑定是一个标准,记录在 IEEE Std 1003.5c-1998 中。使用它,您可以在具有绑定的 POSIX 投诉操作系统中移植。我知道 Solaris 和 Irix 有公司为 Ada95 提供绑定。可能这只是一些愚蠢的事情,因为维护人员没有跟上编译器行为的变化。当我回到家时,我会将我的编译器降级到 4.1(类似那个版本的 Linux 内核),看看 GNAT 的行为是否有所不同。
    猜你喜欢
    • 2019-08-02
    • 1970-01-01
    • 1970-01-01
    • 2016-01-02
    • 2014-04-29
    • 2018-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多