I can report progress but no solution.
1. Since ffi-test-main failed to build with a simple "make" I had assumed I needed to use libffi. I added a print statement to show the values at the point of failure at line 361, the CHECK statement:
ffiInitialize(); for (ul= 0; ul < 15; ++ul) ffiPushSingleFloat(fa[ul]); GO(FFITypeSingleFloat, many); f= ffiReturnFloatValue(); ffiCleanup(); printf("%g %g %g %g\n", f, ff, f - ff, FLT_EPSILON); CHECK(f - ff < FLT_EPSILON);
It gave f and ff to be identical, f - ff zero, and FLT_EPSILON a very small value. The strange thing was that the test did not fail. I commented out my print statement and it failed. Weird.
I noticed I was not seeing the output from puts statements. Recalling that this is typically a macro I looked to see if it had been defined, and found this near the top of the file:
#if 0 # define dprintf(ARGS) printf ARGS # define puts(ARG) puts(ARG) #else # define dprintf(ARGS) # define puts(ARG) #endif
I changed the zero to one and the output was verbose. No failure, even with my print statement commented out.
I suspect there is some tricky coding here that works on some versions of C and not others. The preprocessor, especially.
So I got to wondering why make without args failed. I traced the problem to these lines from the Makefile
CPU= $(shell ./ffi-config -cpu) ABI= $(shell ./ffi-config -abi) LIB= $(shell ./ffi-config -lib)
Running them manually gave x86, sysv and blank, but
OBJ= ffi-test-main.o ffi-test.o $(CPU)-$(ABI).o $(CPU)-$(ABI)-asm.o
resolved to ffi-test-main.o ffi-test.o -.o --asm.o
which caused make to complain that it did not know how to make -.o.
I substituted like this
#OBJ= ffi-test-main.o ffi-test.o $(CPU)-$(ABI).o $(CPU)-$(ABI)-asm.o OBJ= ffi-test-main.o ffi-test.o x86-sysv.o x86-sysv-asm.o
and the build completed.
Eventually I figured out that the shell construct works in gnu make. FreeBSD does not use gnu make. It is available as gmake. I put back the Makefile and used gmake and got a good build.
The results are inconclusive. The output is
slate01# ./main passed ffi assertions (0 failed) Problem passing 64bit structures
Is that because I am not using a 64bit CPU? Is that a show stopper? Apparently not.
The thing is, this does not fix the real problem. If I load my 3.9 image and install the FFI package from SqueakMap, then run the FFI-Tests in SUnit runner I get 21 run, 0 passes, 0 expected failures, 0 failures, 21 errors, 0 unexpected passes. When I click on a result and open a debugger I find
Error: Unable to find function address
invokeWithArguments: argArray "Manually invoke the receiver, representing an external function." <primitive: 'primitiveCalloutWithArgs' module:'SqueakFFIPrims'> ^self externalCallFailed
externalCallFailed "Raise an error after a failed call to an external function" | errCode | errCode := ExternalFunction getLastError. "this allows us to look at the actual error code" ^self error: (ExternalFunction errorMessageFor: errCode).
error: aString "Throw a generic Error exception."
^Error new signal: aString
If the ffi-test-main.c tests are passing, why are the SUnit tests all failing? Is that 64bit thing a big deal?