How do I compile and link using gnatmake with an Ada shared library?

感情迁移 提交于 2019-12-22 08:15:54

问题


I am having trouble compile an applicant again the Florist library. Turns out I have a larger issue with florist (same error results from both newest 2010 Adacore GPL download and 2009 version in Debian's archive). Florist has some low-level issues but when I look through the generated files it seems to be including errno.h correctly.

Here is what happens when I build florist:

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: warning: "SYSTEM.INTERRUPT_MANAGEMENT.OPERATIONS" is an internal GNAT unit posix-implementation.gpb:45:06: warning: use of this unit is non-portable and version-dependent posix-implementation.gpb:47:06: warning: "SYSTEM.SOFT_LINKS" is an internal GNAT unit posix-implementation.gpb:47:06: warning: use of this unit is non-portable and version-dependent 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: In function `posix__implementation__set_ada_error_code': posix-implementation.adb:(.text+0x19e): undefined reference to `store_errno' ./posix-implementation.o: In function `posix__implementation__get_ada_error_code': posix-implementation.adb:(.text+0x1ab): undefined reference to `fetch_errno' ./posix-implementation.o: In function `posix__implementation__raise_posix_error': posix-implementation.adb:(.text+0x234): undefined reference to `fetch_errno' ./posix-implementation.o: In function `posix__implementation__check__2': posix-implementation.adb:(.text+0x2e5): undefined reference to `fetch_errno' ./posix-implementation.o: In function `posix__implementation__check__3': posix-implementation.adb:(.text+0x313): undefined reference to `fetch_errno' ./posix-implementation.o: In function `posix__implementation__check_nneg': posix-implementation.adb:(.text+0x332): undefined reference to `fetch_errno' ./posix-implementation.o:posix-implementation.adb:(.text+0x34e): more undefined references to `fetch_errno' follow ./posix-implementation.o: In function `nosys_neg_one': posix-implementation.adb:(.text+0xaef): undefined reference to `store_errno' ./posix-implementation.o: In function `notsup_neg_one': posix-implementation.adb:(.text+0xb15): undefined reference to `store_errno' ./posix-implementation.o: In function `posix__implementation__restore_signals_and_raise_posix_error': posix-implementation.adb:(.text+0xc88): undefined reference to `fetch_errno' ./posix.o: In function `posix__system_name': posix.adb:(.text+0x2f98): undefined reference to `__gnat_florist_uname' ./posix.o: In function `posix__node_name': posix.adb:(.text+0x2fef): undefined reference to `__gnat_florist_uname' ./posix.o: In function `posix__release': posix.adb:(.text+0x3049): undefined reference to `__gnat_florist_uname' ./posix.o: In function `posix__version': posix.adb:(.text+0x30a6): undefined reference to `__gnat_florist_uname' ./posix.o: In function `posix__machine': posix.adb:(.text+0x3103): undefined reference to `__gnat_florist_uname' ./posix.o: In function `posix__host_to_network_byte_order': posix.adb:(.text+0x4627): undefined reference to `c_htonl' ./posix.o: In function `posix__host_to_network_byte_order__2': posix.adb:(.text+0x4642): undefined reference to `c_htons' ./posix.o: In function `posix__network_to_host_byte_order': posix.adb:(.text+0x4655): undefined reference to `c_ntohl' ./posix.o: In function `posix__network_to_host_byte_order__2': posix.adb:(.text+0x4670): undefined reference to `c_ntohs' ./posix-io.o: In function `posix__io__open': posix-io.adb:(.text+0x4d1): undefined reference to `__gnat_florist_open' ./posix-io.o: In function `posix__io__open_or_create': posix-io.adb:(.text+0xfca): undefined reference to `__gnat_florist_open' collect2: ld returned 1 exit status gnatlink: error when calling /usr/bin/gcc-4.4 gnatmake: *** link failed. josh@Mini10:~/Demo$ gnatbind -I/usr/share/ada/adainclude/florist -I/usr/include demo josh@Mini10:~/Demo$ gnatlink demo ./posix-implementation.o: In function `posix__implementation__set_ada_error_code': posix-implementation.adb:(.text+0x19e): undefined reference to `store_errno' ./posix-implementation.o: In function `posix__implementation__get_ada_error_code': posix-implementation.adb:(.text+0x1ab): undefined reference to `fetch_errno' ./posix-implementation.o: In function `posix__implementation__raise_posix_error': posix-implementation.adb:(.text+0x234): undefined reference to `fetch_errno' ./posix-implementation.o: In function `posix__implementation__check__2': posix-implementation.adb:(.text+0x2e5): undefined reference to `fetch_errno' ./posix-implementation.o: In function `posix__implementation__check__3': posix-implementation.adb:(.text+0x313): undefined reference to `fetch_errno' ./posix-implementation.o: In function `posix__implementation__check_nneg': posix-implementation.adb:(.text+0x332): undefined reference to `fetch_errno' ./posix-implementation.o:posix-implementation.adb:(.text+0x34e): more undefined references to `fetch_errno' follow ./posix-implementation.o: In function `nosys_neg_one': posix-implementation.adb:(.text+0xaef): undefined reference to `store_errno' ./posix-implementation.o: In function `notsup_neg_one': posix-implementation.adb:(.text+0xb15): undefined reference to `store_errno' ./posix-implementation.o: In function `posix__implementation__restore_signals_and_raise_posix_error': posix-implementation.adb:(.text+0xc88): undefined reference to `fetch_errno' ./posix.o: In function `posix__system_name': posix.adb:(.text+0x2f98): undefined reference to `__gnat_florist_uname' ./posix.o: In function `posix__node_name': posix.adb:(.text+0x2fef): undefined reference to `__gnat_florist_uname' ./posix.o: In function `posix__release': posix.adb:(.text+0x3049): undefined reference to `__gnat_florist_uname' ./posix.o: In function `posix__version': posix.adb:(.text+0x30a6): undefined reference to `__gnat_florist_uname' ./posix.o: In function `posix__machine': posix.adb:(.text+0x3103): undefined reference to `__gnat_florist_uname' ./posix.o: In function `posix__host_to_network_byte_order': posix.adb:(.text+0x4627): undefined reference to `c_htonl' ./posix.o: In function `posix__host_to_network_byte_order__2': posix.adb:(.text+0x4642): undefined reference to `c_htons' ./posix.o: In function `posix__network_to_host_byte_order': posix.adb:(.text+0x4655): undefined reference to `c_ntohl' ./posix.o: In function `posix__network_to_host_byte_order__2': posix.adb:(.text+0x4670): undefined reference to `c_ntohs' ./posix-io.o: In function `posix__io__open': posix-io.adb:(.text+0x4d1): undefined reference to `__gnat_florist_open' ./posix-io.o: In function `posix__io__open_or_create': posix-io.adb:(.text+0xfca): undefined reference to `__gnat_florist_open' collect2: ld returned 1 exit status gnatlink: error when calling /usr/bin/gcc-4.4

It seems that this error is common if there is an issue with errno.h being correctly included. But as far as I can tell from the posix-c.c file it all looks correct. Anybody have any suggestions on how to resolve this? Florist's make file builds correctly so I don't know where this is coming from.


回答1:


OK, this turned out to be big pain but I found it.

The Florist binding is available both as a shared library and a static library (both are installed). You need to link against the library to resolve all references (I could never actually compile the library source into my application). Once you pass the argument to tell the compilation stage about the library you have to provide the .ads (at least) files to resolve against.

The final solution ended being this:

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

-aI provides the path to the library's ads files. -aO provides the path to the (in this case) libflorist.so library file and finally (and this is the tricky one) you have to pass -lflorist to tell it what shared library this all is...but passing it won't work. You have to place a -largs in front of it (for the compile and linker) in order for the compilation phase to be passed the parameter! Without it those phases never see the argument!

So there you are everyone! In order to compile and link code against a shared Ada library under Linux (GCC) you need to provide the Library's Headers/Specs, the Library location, and the -llibname argument along with the -largs to pass those into the right places!

I'm happy now. Hope this helps someone else.




回答2:


This is a simple example of using a GNAT Project to build with Florist. I assume that $ADA_PROJECT_PATH includes the directory where florist.gpr is installed (in my case, $HOME/local/lib/gnat).

The sample program (I couldn't find any simple Florist demos on the web, are there any?), in 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;

The project file (id.gpr), in the same directory as id.adb:

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

Build with

$ 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

and run:

$ ./id
simon



回答3:


It looks like pretty garden-variety link errors. Something between your .h files, your Ada object files, and your C link libraries isn't quite mating up. Tough to tell what though.

Your best bet is going to be looking for other Florist users who may have run into the same issue. Their project page is on SourceForge here, but it looks like it hasn't been horribly active for the last 6 years. Since the latest version there is that old, it could be that you need a compiler (and OS?) that old for it to work with. Ick.



来源:https://stackoverflow.com/questions/3902597/how-do-i-compile-and-link-using-gnatmake-with-an-ada-shared-library

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!