Re: Version 181: 'make tests' fails in x86_64 Arch Linux bec…

 new new list compose Reply to this message Top page
Attachments:
+ (text/plain)
+ (text/html)
+ fix_libffi_conf.patch (text/x-patch)

Delete this message
Author: Joe Eib
Date:  
To: TXR Users
Subject: Re: Version 181: 'make tests' fails in x86_64 Arch Linux because of non-standard libffi include location
No, you're right -- It is pkg-config. I guess my mind was automatically rejecting kebab case after looking at so much C code. Anyway, whoever maintains the libffi package for Arch is a butt for not just throwing a link to ffi.h into /usr/include/ like a sane person.

A couple things in your patch needed to be changed to get the new test to work properly on my system.
First, I had to alter the conftest for libffi. On my system, the return result of a true boolean is 1 (which is EXIT_FAILURE in GNU libc) so I altered it to use the POSIX success/failure macros defined in stdlib.h. EXTRA_CFLAFGS also needed to be changed to EXTRA_FLAGS and I removed the 'set -x' error trace line. With these changes, the configure script finds my libffi and everything passes during 'make tests'.

I'm including my patch as an attachment because I had a little trouble getting the one you sent me to work properly after copying and pasting. Thanks for addressing my issue so quickly! I'm looking forward to playing what looks like an amazing pair of languages. 

On Tue, Jul 4, 2017 at 7:04 PM, Kaz Kylheku <kaz@kylheku.com> wrote:

[This is a fwd; the original reply went to the mailing list but bounced when trying to reach you.]

[I set Reply-To: which I normally wouldn't do.]

Hi Joe,

Thanks for the report.

I will fix the double definition of ffi_sint.  I regularly build TXR as C++, but I didn't test the combination "g++ and libffi missing"!

The configure script currently doesn't test for anything other than whether -lffi is needed for linking; the test program is hard coded to #include <ffi.h>. That's the include syntax used in all the libffi documentation, so I didn't bother detecting the location.

TXR hasn't used anything so far that would require a big hammer like pkg-config. (Is it really called pkg_config on Arch, by the way?)

In the future, hopefully, we can avoid bogging down TXR with dependencies by using this nice FFI I developed.

I will change the test so it tries things exactly as it does now, and then falls back on pkg-config if those approaches fail to compile and link the test program.

Cheers ...

On 04.07.2017 14:37, Joe Eib wrote:

After receiving the following error during 'make_tests'
 
...
 TXR tests/017/glob-carray.tl-> tst/tests/017/glob-carray.out
./txr: unhandled exception of type error:
./txr: ffi-type-compile: unrecognized type specifier: closure
./txr: during evaluation at tests/017/glob-carray.tl:30 of form [mapcar ffi-type-compile
                                                                  '(str int closure
                                                                    (ptr-out glob-t))]
make: *** [Makefile:356: tst/tests/017/glob-carray.out] Error 1
 
After a little digging I noticed that your configure script fails to detect my libffi because Arch Linux installs libffi.h in a nonstandard location. I don't know exactly what you're testing for there on line 2845 of configure but why not just use 'pkg_config --exists libffi' or the PKG_CHECK_EXISTS macro and then get the compiler and linker flags directly from pkg_config?
 
Also, when I was trying to find the source of the issue, I compiled txr with g++ just for the hell of it and discovered that ffi_type_sint is declared twice on lines 141 and 144 which throws an error in g++.

 

 

diff --git a/Makefile b/Makefile
index ae3c7fd3..50ee7cdb 100644
--- a/Makefile
+++ b/Makefile
@@ -257,6 +257,10 @@ y.tab.c: $(top_srcdir)parser.y
# Bison-generated parser also tests for this lint define.
$(call EACH_CONF,y.tab.o): TXR_CFLAGS += -Dlint

+opt/ffi.o: TXR_CFLAGS += $(LIBFFI_CFLAGS)
+
+dbg/ffi.o: TXR_CFLAGS += $(LIBFFI_CFLAGS)
+
# txr.c needs to know the relative datadir path to do some sysroot
# calculations.

diff --git a/configure b/configure
index c372c80e..b4da1c8a 100755
--- a/configure
+++ b/configure
@@ -143,6 +143,8 @@ have_alloca=
have_termios=
have_winsize=
termios_define=
+have_pkgconfig=
+libffi_cflags=

#
# Parse configuration variables
@@ -710,6 +712,8 @@ CONF_LDFLAGS := $conf_ldflags
REMOVE_FLAGS := $remove_flags
LEX_DBG_FLAGS := $lex_dbg_flags
TXR_DBG_OPTS := $txr_dbg_opts
+
+LIBFFI_CFLAGS := $libffi_cflags
!
}

@@ -2828,10 +2832,20 @@ else
printf "no\n"
fi

+printf "Checking for pkg-config ... "
+
+if pkg-config --version > /dev/null 2>&1 ; then
+ printf "present\n"
+ have_pkgconfig=y
+else
+ printf "absent\n"
+fi
+
printf "Checking for libffi ... "

cat > conftest.c <<!
#include <stdio.h>
+#include <stdlib.h>
#include <ffi.h>

 int main(void)
@@ -2842,7 +2856,10 @@ int main(void)
   char *s;
   args[0] = &ffi_type_pointer;
   values[0] = &s;
-  return ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_sint, args) == FFI_OK;
+  if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_sint, args) == FFI_OK)
+    return EXIT_SUCCESS;
+  else
+    return EXIT_FAILURE;
 }
 !


@@ -2853,6 +2870,17 @@ elif conftest EXTRA_LDFLAGS=-lffi ; then
   printf "yes\n"
   printf "#define HAVE_LIBFFI 1\n" >> config.h
   conf_ldflags="${conf_ldflags:+"$conf_ldflags "}-lffi"
+elif [ -n "$have_pkgconfig" ] && pkg-config --exists libffi ; then
+  libffi_cflags=$(pkg-config --cflags libffi)
+  libffi_ldflags=$(pkg-config --libs libffi)
+  if conftest EXTRA_FLAGS="$libffi_cflags" EXTRA_LDFLAGS="$libffi_ldflags" ; then
+    printf "yes\n"
+    printf "#define HAVE_LIBFFI 1\n" >> config.h
+    conf_ldflags="${conf_ldflags:+"$conf_ldflags "}$libffi_ldflags"
+  else
+    printf "no\n"
+    libffi_cflags=
+  fi
 else
   printf "no\n"
 fi