Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

ada

gnat

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.

like image 627
Josh Avatar asked Dec 21 '22 22:12

Josh


1 Answers

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.

like image 82
Josh Avatar answered Apr 26 '23 03:04

Josh