tags:

views:

87

answers:

3

Hi, 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  A: 

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.

T.E.D.
Hi, Yeah...I'm starting to really be afraid of that. I can't fathom why a pure POSIX interface would be version specific. I'm going to try it on a couple different machines. My gut tells me right now, that it may be a COMPILER version issue not a kernel+distro issue. Since the compiler I'm using is the 4.4 GCC...perhaps I should downgrade to a 4.1 or 4.2? I know some Linux stuff only works with slightly older 4.x GCC compilers...I'll start there.
Josh
What exactly do you need Posix for, anyway? Vanilla Ada can pretty much act as a portability layer on its own. It has just about everything you need.
T.E.D.
I need direct control of the serial port for a device that emulates a Modem's AT command set to control an large machine. Ada can do a lot of things...but not serial ports :-) I've done things like this before in C so it's not the how I'm worried about it's the why the heck this won't link. Basic Termios.h stuff plus the Ada Binding standard contains the routines to translate character byte data out of a TTY to a POSIX String to Ada String very effectively (versus me trying to figure it out). Whether I'm using bluetooth, serial ports, USB emulated serial, etc. I need serial port access.
Josh
Personally I'd be tempted to just go straight to the OS for that. Ada bindings to C libraries aren't *that* tough to write. But I guess if you want some modicum of portability outside of Linux (assuming you're on Linux), I can see where you'd want POSIX. Of course for about 90% of what you want to do, you could probably just open the serial device with one of the *_IO packages. But that won't get you the ability to change the BAUD and number of stop bits, etc.
T.E.D.
Yes, I could program the serial control in C, compile it, and import the functions into Ada. But that's what this POSIX binding is basically doing. The POSIX Ada binding is a standard, documented in IEEE Std 1003.5c-1998. Using this you're portable with POSIX complaint OSes where you have the binding. I know Solaris and Irix have company supplied Bindings for Ada95. Likely it's just something stupid because the maintainers didn't keep up with compiler behavior change. When I get home I'll downgrade my compiler to 4.1 (Linux kernels like that version) and see if GNAT behaves differently.
Josh
Well, what I was actually suggesting was not writing anything in C, but just writing your own bindings to whatever OS routines you need to use. It doesn't have to be complete like POSIX is. You just need the routines you will be using. What's already in the POSIX bindings should suffice to show you how its done. Still, you are right that someone already did this for you and it would be a lot nicer if you could just use that.
T.E.D.
Hi, Thanks for your time on this I have found the answer. I'm posting it below...
Josh
Great! I know it may seem a bit cheesy, but go ahead and accept it too, so the system registers it as answered.
T.E.D.
+2  A: 

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.

Josh
Does florist come with a GNAT project file (.gpr)? Using such a file (by withing it in your own project file) should be simpler.
Simon Wright
It does, but right now at my current level with Ada I don't want to deal with the added complexity with those files. Though you make an accurate point. I didn't bother to check that. Just the INSTALL and README files in the florist source dirs and other README style files. I am inexperienced with the project files so that did not occur to me.
Josh
A: 

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
Simon Wright