Hi folks!
I have a problem with SqueakDBX and FFI. I install openDBX from a .deb and I get this: ldconfig -p | grep opendbx show the same as you: libopendbxplus.so.1 (libc6) => /usr/lib/libopendbxplus.so.1 libopendbx.so.1 (libc6) => /usr/lib/libopendbx.so.1 In this case, was searching libopendbx.so. But, my file was named libopendbx.so.1. And of course, I got a 'unable to find function address'. Solution: copy and rename (or just rename) libopendbx.so.1 to libopendbx.so and worked like a charm. But, the question is, shouldn't FFI resolve this ? is this a matter of the linker ? Thanks for the help! Mariano ---------- Forwarded message ---------- From: Mariano Martinez Peck <[hidden email]> Date: Tue, Apr 28, 2009 at 10:40 PM Subject: Re: [Pharo-project] squeakopendbx, which VM? To: [hidden email] I think I fix it :) I took a clean Ubuntu. I did: sudo dpkg -i libopendbx1_1.4.0-1_i386.deb libopendbx1-mysql_1.4.0-1_i386.deb Then ldconfig -p | grep opendbx show the same as you: libopendbxplus.so.1 (libc6) => /usr/lib/libopendbxplus.so.1 libopendbx.so.1 (libc6) => /usr/lib/libopendbx.so.1 In this case, was searching libopendbx.so. But, your (and my) file was named libopendbx.so.1. Solution: copy and rename (or just rename) libopendbx.so.1 to libopendbx.so and should work like a charm. Thanks for your testing Hilaire. We want SqueakDBX to be as much easier as possible. So, documenting the wiki with several cases will definitively help us. I add this information to the wiki. Let me know if that work. Cheers, Mariano On Tue, Apr 28, 2009 at 2:56 PM, Mariano Martinez Peck <[hidden email]> wrote:
|
You are right that the "linker" normally resolves this. If you install
the "opendbx-devel" package, it contains a symlink from libopendbx.so to libopendbx.so.1. When you normally link your program, the linker will examine the link and actually put a reference to libopendbx.so.1 in the executable. See "3.1.1. Shared Library Names" in http://www.faqs.org/docs/Linux-HOWTO/Program-Library-HOWTO.html#AEN49 Now, when FFI needs to do the task of the linker, it needs the same libopendbx.so symlink, too, but it does not normally store the libopendbx.so.1 name. This is because in Squeak we usually do not distinguish between "compile/link time" and "run time". If we did this, the same image would not run on a different platform anymore. However, you can of course manually do the "linking" step - in the ffi function declarations, use "libopendbx.so.1" as module instead of just "opendbx". This will then only work on Linux of course, since other Unix platforms use different schemes of versioning libraries. - Bert - On 30.04.2009, at 17:01, Mariano Martinez Peck wrote: > Hi folks! > > I have a problem with SqueakDBX and FFI. I install openDBX from > a .deb and I get this: > > ldconfig -p | grep opendbx show the same as you: > > libopendbxplus.so.1 (libc6) => /usr/lib/libopendbxplus.so.1 > libopendbx.so.1 (libc6) => /usr/lib/libopendbx.so.1 > > The problem is that we (in squeakDBX) have as module: opendbx. Linux > looks for libMODULE_NAME.so. > > In this case, was searching libopendbx.so. But, my file was named > libopendbx.so.1. And of course, I got a 'unable to find function > address'. > > Solution: copy and rename (or just rename) libopendbx.so.1 to > libopendbx.so and worked like a charm. > > But, the question is, shouldn't FFI resolve this ? is this a matter > of the linker ? > > Thanks for the help! > > Mariano > > > > ---------- Forwarded message ---------- > From: Mariano Martinez Peck <[hidden email]> > Date: Tue, Apr 28, 2009 at 10:40 PM > Subject: Re: [Pharo-project] squeakopendbx, which VM? > To: [hidden email] > > > I think I fix it :) > > I took a clean Ubuntu. I did: > > sudo dpkg -i libopendbx1_1.4.0-1_i386.deb libopendbx1- > mysql_1.4.0-1_i386.deb > > Then ldconfig -p | grep opendbx show the same as you: > > > libopendbxplus.so.1 (libc6) => /usr/lib/libopendbxplus.so.1 > libopendbx.so.1 (libc6) => /usr/lib/libopendbx.so.1 > > The problem is that we have as module: opendbx. Ubuntu looks for > libMODULE_NAME.so. > > In this case, was searching libopendbx.so. But, your (and my) file > was named libopendbx.so.1. > > Solution: copy and rename (or just rename) libopendbx.so.1 to > libopendbx.so and should work like a charm. > > Thanks for your testing Hilaire. We want SqueakDBX to be as much > easier as possible. So, documenting the wiki with several cases will > definitively help us. I add this information to the wiki. > > Let me know if that work. > > Cheers, > > Mariano > > > > > On Tue, Apr 28, 2009 at 2:56 PM, Mariano Martinez Peck <[hidden email] > > wrote: > > > 2009/4/28 Hilaire Fernandes <[hidden email]> > > > 2009/4/28 Mariano Martinez Peck <[hidden email]> > > > I don't have it in my version of Pharo. I don't know if I can update > it without going through a full pharo image which I don't want to do > now. > > > Ok. Doesn't matter. Your current problem is not about FFI but you > will have that problem then (when you get squeakDBX working). You > only need to get the latests FFI version from MC to work in pharo > with closure VM. > > I am pretty sure the VM I used is not with the fixed closure. I am > note sure about the image, I can tell you tomorrow the version > number of the image when at the office. > Is the fixed closure mandatory to get SqueakDBX working? > Which Pharo # image and VM should be used? > > SqueakDBX works with both. If you use a closure image you must use a > VM with closure an latest FFI (from MC). But, you can also use > Squeak in older version (non closure) with FFI from Universes. So, > no problem for you. > > > > I haven't my linux machine here, I will look tonight in my home, but: > > > 1) what do you have /usr/lib in PATH ? > No it points only to binary as it should. > Does FFI looks at PATH for the libraries? If so it is a buggy > behavior. > I am really currious to know how FFI find the libraries... > > I am not sure about this. Perhaps someone (Andreas) can help us. > > > > 2) Just for testing, can you put the openDBX libraries in the same > directory where the pharo > image is. > > 3) The same as 2) but where the VM is. > > I will try tomorrow morning. > > Which Linux are you using? Perhaps there is a problem trying to > resolve the library. The last test you can do (just to see if it > works) is this: > > Go t class OpenDBXUnix and change the methods > > apiBind: handle database: databaseName name: userName password: > password method: method > > and > > apiInitialize: handle backend: backend host: host port: port > > In both, put module: 'libopendbx.so.1' or module: 'libopendbx.so' > instead of module: 'opendbx' > > I hope you get it working. Ask all what you want. > > Greetings, > > Mariano > > > > Thanks! > > > Hilaire > > > -- > http://blog.ofset.org/hilaire > |
On Thu, Apr 30, 2009 at 8:16 PM, Bert Freudenberg <[hidden email]> wrote: You are right that the "linker" normally resolves this. If you install the "opendbx-devel" package, it contains a symlink from libopendbx.so symlink from libopendbx.so Yes. OpenDBX author told me exactly the same. If I also install opendbx-dev it will install the symlink from libopendbx.so symlink from libopendbx.so. I think this is the best approach to my problem. When you normally link your program, the linker will examine the link and actually put a reference to libopendbx.so.1 in the executable. Thanks for the link :)
Indeed. That's why I don't want to change the module name. Thanks for the explanation! Cheers, Mariano
|
On 30.04.2009, at 23:22, Mariano Martinez Peck wrote:
Well, you can also automate this "pseudo-linking". When starting up, just patch the right module name for the current platform into all the FFI declarations. That's how the OpenGL FFI bindings in Croquet work ... - Bert - |
Bert Freudenberg wrote:
> On 30.04.2009, at 23:22, Mariano Martinez Peck wrote: > >> However, you can of course manually do the "linking" step - in the >> ffi function declarations, use "libopendbx.so.1" as module instead >> of just "opendbx". This will then only work on Linux of course, >> since other Unix platforms use different schemes of versioning >> libraries. >> >> >> Indeed. That's why I don't want to change the module name. > > Well, you can also automate this "pseudo-linking". When starting up, > just patch the right module name for the current platform into all the > FFI declarations. That's how the OpenGL FFI bindings in Croquet work ... The way this is done is purely for historical reasons (and an *extremely* bad example that should not be taught to anyone). The Right Way to do this is to have a subclass of ExternalLibrary and implement the class-side method #moduleName along the lines of: MyLibrary class>>moduleName "Answer the module name to use for this library" Smalltalk platformName = 'Win32' ifTrue:[^'MyLibrary32.dll']. Smalltalk platformName = 'unix' ifTrue:[ "check various locations and versions" #('/usr/lib/libMyLibrary.so' '/usr/lib/libMyLibrary.so.1' '/usr/lib/libMyLibrary.so.2' '/usr/share/libMyLibrary.so.1' '/usr/share/libMyLibrary.so.2') do:[:location| (FileDirectory fileExists: location) ifTrue:[^location]. ]. ^self error:'MyLibrary is not installed' ]. etc. Cheers, - Andreas |
On 30.04.2009, at 23:55, Andreas Raab wrote: > Bert Freudenberg wrote: >> On 30.04.2009, at 23:22, Mariano Martinez Peck wrote: >>> However, you can of course manually do the "linking" step - in >>> the >>> ffi function declarations, use "libopendbx.so.1" as module >>> instead >>> of just "opendbx". This will then only work on Linux of course, >>> since other Unix platforms use different schemes of versioning >>> libraries. >>> >>> >>> Indeed. That's why I don't want to change the module name. >> Well, you can also automate this "pseudo-linking". When starting >> up, just patch the right module name for the current platform into >> all the FFI declarations. That's how the OpenGL FFI bindings in >> Croquet work ... > > The way this is done is purely for historical reasons (and an > *extremely* bad example that should not be taught to anyone). The > Right Way to do this is to have a subclass of ExternalLibrary and > implement the class-side method #moduleName along the lines of: > > MyLibrary class>>moduleName > "Answer the module name to use for this library" > Smalltalk platformName = 'Win32' ifTrue:[^'MyLibrary32.dll']. > Smalltalk platformName = 'unix' ifTrue:[ > "check various locations and versions" > #('/usr/lib/libMyLibrary.so' > '/usr/lib/libMyLibrary.so.1' > '/usr/lib/libMyLibrary.so.2' > '/usr/share/libMyLibrary.so.1' > '/usr/share/libMyLibrary.so.2') do:[:location| > (FileDirectory fileExists: location) ifTrue:[^location]. > ]. > ^self error:'MyLibrary is not installed' > ]. > > etc. Interesting. I thought the module in an FFI function declaration needed to be a literal string. How would you declare it to use MyLibrary instead? - Bert - |
Bert Freudenberg wrote:
> > On 30.04.2009, at 23:55, Andreas Raab wrote: > >> Bert Freudenberg wrote: >>> On 30.04.2009, at 23:22, Mariano Martinez Peck wrote: >>>> However, you can of course manually do the "linking" step - in the >>>> ffi function declarations, use "libopendbx.so.1" as module instead >>>> of just "opendbx". This will then only work on Linux of course, >>>> since other Unix platforms use different schemes of versioning >>>> libraries. >>>> >>>> >>>> Indeed. That's why I don't want to change the module name. >>> Well, you can also automate this "pseudo-linking". When starting up, >>> just patch the right module name for the current platform into all >>> the FFI declarations. That's how the OpenGL FFI bindings in Croquet >>> work ... >> >> The way this is done is purely for historical reasons (and an >> *extremely* bad example that should not be taught to anyone). The >> Right Way to do this is to have a subclass of ExternalLibrary and >> implement the class-side method #moduleName along the lines of: >> >> MyLibrary class>>moduleName >> "Answer the module name to use for this library" >> Smalltalk platformName = 'Win32' ifTrue:[^'MyLibrary32.dll']. >> Smalltalk platformName = 'unix' ifTrue:[ >> "check various locations and versions" >> #('/usr/lib/libMyLibrary.so' >> '/usr/lib/libMyLibrary.so.1' >> '/usr/lib/libMyLibrary.so.2' >> '/usr/share/libMyLibrary.so.1' >> '/usr/share/libMyLibrary.so.2') do:[:location| >> (FileDirectory fileExists: location) ifTrue:[^location]. >> ]. >> ^self error:'MyLibrary is not installed' >> ]. >> >> etc. > > > Interesting. I thought the module in an FFI function declaration needed > to be a literal string. How would you declare it to use MyLibrary instead? Define it in a subclass of ExternalLibrary. Functions defined in a subclass of ExternalLibrary without a module: string use the moduleName from the time the library is instantiated. The module: string was really only intended for convenience such that one could declare FFI functions where it is most convenient instead of having to use ExternalLibrary subclasses. Cheers, - Andreas |
On 01.05.2009, at 17:48, Andreas Raab wrote: > Bert Freudenberg wrote: >> On 30.04.2009, at 23:55, Andreas Raab wrote: >>> Bert Freudenberg wrote: >>>> On 30.04.2009, at 23:22, Mariano Martinez Peck wrote: >>>>> However, you can of course manually do the "linking" step - in >>>>> the >>>>> ffi function declarations, use "libopendbx.so.1" as module >>>>> instead >>>>> of just "opendbx". This will then only work on Linux of course, >>>>> since other Unix platforms use different schemes of versioning >>>>> libraries. >>>>> >>>>> >>>>> Indeed. That's why I don't want to change the module name. >>>> Well, you can also automate this "pseudo-linking". When starting >>>> up, just patch the right module name for the current platform >>>> into all the FFI declarations. That's how the OpenGL FFI bindings >>>> in Croquet work ... >>> >>> The way this is done is purely for historical reasons (and an >>> *extremely* bad example that should not be taught to anyone). The >>> Right Way to do this is to have a subclass of ExternalLibrary and >>> implement the class-side method #moduleName along the lines of: >>> >>> MyLibrary class>>moduleName >>> "Answer the module name to use for this library" >>> Smalltalk platformName = 'Win32' ifTrue:[^'MyLibrary32.dll']. >>> Smalltalk platformName = 'unix' ifTrue:[ >>> "check various locations and versions" >>> #('/usr/lib/libMyLibrary.so' >>> '/usr/lib/libMyLibrary.so.1' >>> '/usr/lib/libMyLibrary.so.2' >>> '/usr/share/libMyLibrary.so.1' >>> '/usr/share/libMyLibrary.so.2') do:[:location| >>> (FileDirectory fileExists: location) ifTrue:[^location]. >>> ]. >>> ^self error:'MyLibrary is not installed' >>> ]. >>> >>> etc. >> Interesting. I thought the module in an FFI function declaration >> needed to be a literal string. How would you declare it to use >> MyLibrary instead? > > Define it in a subclass of ExternalLibrary. Functions defined in a > subclass of ExternalLibrary without a module: string use the > moduleName from the time the library is instantiated. The module: > string was really only intended for convenience such that one could > declare FFI functions where it is most convenient instead of having > to use ExternalLibrary subclasses. > That's a useful trick, thanks. Have not ever seen it before. - Bert - |
Andreas: Thanks for the replies. I did all of what you told me but I got this error when trying to call the api:
'External library is invalid' I even try to execute: ExternalLibrary initialize. However, I am not convinced why this way is better than having module: aString. Disadvantages of this new way: - I am "coupling" or "hardcoding" not only the library name but also the location in the file system. Perhaps I rather this be automatically done by FFI. Advantages of this new way: - I can add as many names or paths as I want to my library. what do you think? can you help me with the advantages and disadvantages from both alternatives? Thanks! Mariano On Fri, May 1, 2009 at 5:44 PM, Bert Freudenberg <[hidden email]> wrote:
|
Mariano Martinez Peck wrote:
> Andreas: Thanks for the replies. I did all of what you told me but I got > this error when trying to call the api: > > 'External library is invalid' I think this means the name is wrong. Try using #forceLoading before you call any functions - this will help you to find out whether there is anything wrong with the name. > I even try to execute: ExternalLibrary initialize. > > However, I am not convinced why this way is better than having module: > aString. It's not. That's why the alternatives exists. But if you have to provide a more flexible way of deciding which library to use there is really not much of an alternative. > Disadvantages of this new way: > > - I am "coupling" or "hardcoding" not only the library name but also the > location in the file system. Perhaps I rather this be automatically done > by FFI. The FFI does some of this (using the default system search paths etc) and to the extent the FFI does it, you can use it from ExternalLibrary. In other words, you don't *have to* provide a full path, but you can. > Advantages of this new way: > > - I can add as many names or paths as I want to my library. > > what do you think? can you help me with the advantages and disadvantages > from both alternatives? The rule of thumb should be that unless you have to switch between library names dynamically, you should be using the simple module: modifier in FFI calls. Only if this isn't sufficient for specifying the name you should be thinking about ExternalLibrary. Cheers, - Andreas |
On Sun, May 3, 2009 at 5:44 PM, Andreas Raab <[hidden email]> wrote:
Ok. Now I get it. I think that in my situation is better to have module: aString. Thanks for the comments! Mariano
|
Free forum by Nabble | Edit this page |