Andy Hefner ahefner@gmail.com writes:
(define-foreign-library librt (:linux (:or "librt.so" "/usr/lib/librt.so"))) (use-foreign-library librt)
Despite my uncertain understanding of the rules for shared library naming (and for that matter, where librt is expected to reside), I think the following definition is preferable:
(define-foreign-library librt (:linux (:or "librt.so.1" "/lib/librt.so.1"))) (use-foreign-library librt)
It used to be librt.so.1, but it was changed to librt.so, not sure why. Is there any system where "librt.so.1" doesn't work but "/lib/librt.so.1" would?
Wouldn't (:or "librt.so" "librt.so.1") work best?
By the way, I've been thinking off and on about how to handle this library reloading business automatically.
Would two new CFFI functions -- PREPARE-LIBRARIES-FOR-DELIVERY and RELOAD-LIBRARIES -- be enough for most delivery purposes? The former would close all the open libraries and store them somewhere so that the former can reopen them later when loading the core.
Not all Lisps seem to offer equivalents to sb-ext:*save-hooks* and sb-ext:*init-hooks*, but in those that do we could could even push those two functions in there.
I suppose there's the question of what to do with libraries distributed with the executable since that dlopen() won't find those on its own and we need to bind cffi:*foreign-library-directories* to something appropriate (E.g. osicat's wrapper.so.) Something like (pushnew '(merge-pathnames #p"libs/" (get-core-pathname)) *foreign-library-directories*) would work since, similarly to ASDF:*CENTRAL-REGISTRY*, the elements of *FOREIGN-LIBRARY-DIRECTORIES* are quasi-evaluated[1]. How are you dealing with that right now?
Cheers,
[1] Ugh, or they would be if a call to MINI-EVAL weren't missing in FIND-FILE in libraries.lisp.
On 7/3/09, Luis Oliveira luismbo@gmail.com wrote:
It used to be librt.so.1, but it was changed to librt.so, not sure why. Is there any system where "librt.so.1" doesn't work but "/lib/librt.so.1" would?
Changing /usr/lib to /lib was random flailing around on my part. I'm not sure where it's supposed to live. On the older kubuntu VM I've been doing some tests in, it has:
/lib/librt-2.6.1.so /lib/librt.so.1 -> /lib/librt-2.6.1.so /usr/lib/librt.so -> /lib/librt.so.1
For reasons unknown to me, despite the /usr/lib/librt.so existing, it couldn't find librt until I changed it to librt.so.1.
As for distributing libraries with the executable, so far I haven't needed to (recall the strange efforts I took to avoid distributing the osicat wrapper.so), but I've just been thinking about out how to do it in order to distribute a version of libmpg123 with known compilation options. I was going to give it name (like libshuffletron-mpg123) and copy it into /usr/local/lib where it will be found automatically, but the trouble then is to also make the program runnable after untarring it without doing a 'make install'. I hadn't thought of cffi:*foreign-library-directories* but that sounds useful.
So far as CFFI is concerned, its problems at present are that it seems to forget entirely the existence of libraries loaded directly by pathname (such as wrapper.so), and these are precisely the ones that cause trouble with deployment.
On Fri, 3 Jul 2009, Andy Hefner wrote:
On 7/3/09, Luis Oliveira luismbo@gmail.com wrote:
It used to be librt.so.1, but it was changed to librt.so, not sure why. Is there any system where "librt.so.1" doesn't work but "/lib/librt.so.1" would?
Possibly, but only on perverse systems. For example /usr/local/lib/librt.so.1 is broken but found before the functional /lib/librt.so.1.
Changing /usr/lib to /lib was random flailing around on my part. I'm not sure where it's supposed to live. On the older kubuntu VM I've been doing some tests in, it has:
/lib/librt-2.6.1.so /lib/librt.so.1 -> /lib/librt-2.6.1.so /usr/lib/librt.so -> /lib/librt.so.1
For reasons unknown to me, despite the /usr/lib/librt.so existing, it couldn't find librt until I changed it to librt.so.1.
Some points wrt C/C++ linking: - Libraries don't "belong" anywhere; the distro/end user gets to choose which libs go where. Shadowing system libs is a feature. - librt.so.1 is more specific than librt.so; for example librt.so could point to librt.so.2. - Different unix OSs have different ways of versioning libraries. - On linux, shared libraries are usually loaded by ld.so; see `man ld.so`. CL probably couldn't find librt.so because it was in the less standard /usr/lib directory whereas librt.so.1 was in /lib.
Later, Daniel
On Sat, Jul 4, 2009 at 3:53 AM, Daniel Herringdherring@tentpost.com wrote:
- On linux, shared libraries are usually loaded by ld.so; see `man ld.so`.
CL probably couldn't find librt.so because it was in the less standard /usr/lib directory whereas librt.so.1 was in /lib.
IIUC, the problem is that the system in question had a librt.so.1 but not a librt.so. Wherever those might be -- /lib or /usr/lib -- doesn't seem to be relevant, dlopen() should find them in either place.
So, I don't the patch Stelian pushed fixes things: (define-foreign-library librt - (:linux (:or "librt.so" "/usr/lib/librt.so"))) + (:linux (:or "librt.so" "/lib/librt.so.1")))
(:or "librt.so" "librt.so.1") seems to be the right way to go. Actually, make that (:or "librt.so.1" "librt.so") since version 1 is what we've been testing with and that's probably the version we'd rather load should a potentially incompatible version 2 appear at some point.
On Sat, 4 Jul 2009 15:35:56 +0100, Luís Oliveira said:
On Sat, Jul 4, 2009 at 3:53 AM, Daniel Herringdherring@tentpost.com wrote:
- On linux, shared libraries are usually loaded by ld.so; see `man ld.so`.
CL probably couldn't find librt.so because it was in the less standard /usr/lib directory whereas librt.so.1 was in /lib.
IIUC, the problem is that the system in question had a librt.so.1 but not a librt.so.
That's quite normal on Linux. Libraries with no numbers such as librt.so typically come from an optional "devel" package, which would only be installed on development a machine, whereas librt.so.1 is the runtime library.
__Martin