qa-ffi: On finding libc on Linux

Started by rickyboy, August 14, 2013, 09:58:01 AM

Previous topic - Next topic

rickyboy

In a recent newlisp build on Linux by user hartrock (Stephan), the test qa-ffi failed because it couldn't find where libc was located on hartrock's Linux system.  hartrock was building on a 64 bit system and qa-ffi was looking for the 32 bit libc (which naturally didn't exist on his system).  The discussion was fleshed out a little here: http://www.newlispfanclub.alh.net/forum/viewtopic.php?f=16&t=4377">http://www.newlispfanclub.alh.net/forum/viewtopic.php?f=16&t=4377.



The upshot is that the current expression which establishes the libc pointer is now the following.


(define LIBC (case ostype
               ("Win32" "msvcrt.dll")
               ("OSX" "libc.dylib")
               ("Linux" (if is64bit
                            "/lib/x86_64-linux-gnu/libc.so.6"
                            "/lib/i386-linux-gnu/libc.so.6"))
             ))

But hartrock suggested that the definition might be changed to be more robust ("Works for me (Debian 64-bit), but should be checked for other Linuxes, too").  He's right, of course.



So, here are two methods I found which seem more robust than the current method.  I wonder if you Linux gearheads here would scrutinize these.



One method is to ask gcc where libc is located.  This method is discussed here: http://stackoverflow.com/questions/9705660/check-glibc-version-for-a-particular-gcc-compiler#9706172">http://stackoverflow.com/questions/9705 ... er#9706172">http://stackoverflow.com/questions/9705660/check-glibc-version-for-a-particular-gcc-compiler#9706172.  Here it is implemented.


(define LIBC
  (case ostype
    ("Win32" "msvcrt.dll")
    ("OSX" "libc.dylib")
    ("Linux"
     (letn (libc-name (first (exec "gcc -print-file-name=libc.so"))
            libc-filetype (first (exec (string "file -b " libc-name))))
       (if (find "ASCII" libc-filetype)
           (first (regex "[^ t]+/libc\.so\.*[0-9]*" (read-file libc-name)))
           libc-name)))
    ))

Another method is to call ldd on the newlisp executable.  This resource talks about this: http://mylinuxbook.com/how-to-determine-gnu-c-library-glibc-version-on-linux-system/">http://mylinuxbook.com/how-to-determine ... ux-system/">http://mylinuxbook.com/how-to-determine-gnu-c-library-glibc-version-on-linux-system/. Here is that one implemented.  It assumes that the user has built the newlisp executable in the build directory.


(define LIBC
  (case ostype
    ("Win32" "msvcrt.dll")
    ("OSX" "libc.dylib")
    ("Linux"
     (nth 2
      (parse
       (first
        (filter (curry find "libc.so")
                (if (ends-with (real-path) "qa-specific-tests")
                    (exec "ldd ../newlisp")
                    (exec "ldd ./newlisp")))))))
    ))

I've only tested these on an Ubuntu 12.04 system.  I favor the first method.  Thoughts?  Thanks!
(λx. x x) (λx. x x)

Lutz

#1
Thanks Rick. Also runs fine on the next version UBUNTU 13.04 32-bits.