Link to .so file?

Archives Forums/Linux Discussion/Link to .so file?

JoshK(Posted 2014) [#1]
I need to link to an .so file (the Steamworks SDK) in a BlitzMax program. How is this done?


JoshK(Posted 2014) [#2]
Figured it out myself.
1. Open terminal.
2. Type "sudo nautilus".
3. Copy .so file to /usr/lib32
4. Add 'Import "-l(libname without extension)"'


JoshK(Posted 2014) [#3]
Now it is complaining it can't locate a shared object file, even though the .so file is in the same directory as the application:
./MaxIDE: error while loading shared libraries: libsteam_api.so: cannot open shared object file: No such file or directory


I opened up the source to bmk and added " -rpath=." to bcc_opts, recompiled bmk, copied it over to the bin folder, and recompiled my application, but I still get the same error.


Derron(Posted 2014) [#4]


I have all my required files available. If one misses, the part after the arrow will be empty.
Please ignore "linux-gate.so" - this is a non-existent file on EVERY linux system. It is a so called "virtual DSO". Similar exception for an entry called "ld-linux.so".

"Nautilus" is not installed in every system.
use "cp /source/path/file /target/path/file". Prefix it with "sudo " in case of writing to a system path.
Nautilus shouldn't be able to write to system paths without been started with "sudo nautilus" (thought you get a red band on top of the window then).

That ".number" after an "library.so" means, that it is linked to a specific version of that file. If that file is missing, you might have a good chance to get it work with symlinking another version of that file.

example: programme wants: "libMyLib.so.1" but it seems not to find it

$ locate libMyLib.so.*
/path/libMyLib.so.1.6

now use "ln -s" to generate a soft link
ln -s /path/libMyLib.so.1 /path/libMyLib.so.1.6

afterwards a "virtual" file "libMyLib.so.1" exists in that folder and links to libMyLib.so.1.6

This is done to enable multiple versions of a library to coexist on a system (like the vbrun200.dll, vbrun300.dll - but even for minor version increments).


Concerning "libsteam.so" - pay attention to 32bit/64bit. If you installed the 64bit version you might not get the 32bit lib automatically - and when compiling blitzmax thingies... you need that 32bit libs.
I neither have Steam installed nor do I develope or it, so I cannot give specific instructions.

bye
Ron


juankprada(Posted 2014) [#5]
I had a similar problem before, although it was with a C app (no BM). I stoped using the /usr/lib, /usr/lib32 and /usr/lib64 to place the shared objects I would eventually distribute with my application.

What worked for me was to make a directory (I called it libs... how original eh?) in the root of my project, placed all my shared objects there. Added that directory to the gcc lib path (-Llibs/) and set rpath to point to the libs dir (-rpath=libs/). At the end, when distribuiting, I had to make sure that libs folder was actually at the same directory level as the executable.


Also using ldd as Derron said is a great way to see what is actually linked to your app.


JoshK(Posted 2014) [#6]
What worked for me was to make a directory (I called it libs... how original eh?) in the root of my project, placed all my shared objects there. Added that directory to the gcc lib path (-Llibs/) and set rpath to point to the libs dir (-rpath=libs/). At the end, when distribuiting, I had to make sure that libs folder was actually at the same directory level as the executable.

Yes, that is what I want. How do I do it???


juankprada(Posted 2014) [#7]
@JoshK,
Well, I dont know anything about building BMK and about its build options, but if you are able to set the rpath from the sources as you said in your third post, then just set rpath like this: -rpath=./libs
Also, you must tell the compiler to look for your library in the ./libs directory. It should be done with the -L parameter, like this: -L./libs


That should work if your .so file is in ./libs directory.

Now,(as I said i know nothing about building bmk) if setting that rpath is for building bmk, then bmk will be dynamically linked to the so file, but I am not sure if your BM program will also be linked to it. Perhaps looking at some of bruceys modules sources might help you better thatn what I am telling you here


Schnuff(Posted 2014) [#8]
I don't know much about .so linking but brucey is using:

?linux
ModuleInfo "LD_OPTS: -L%PWD%/../lib/linux"
?

in his WxWidgets module. So if I have got anything right in this thread, you should be able to use this (at least if you are writing a module).
However Brucey includes .cpp and .h files via this way.

If you don't want to write a Module, the following will (temporarily) enable you to include your .so file:

However you can add a Path via a environment Variable.
# BMK_CC_OPTS=-L/home/josh/leadwerkers ./BlitzMax/MaxIDE
should help you including your path for this session using MaxIDE
you can compile a file including this Directory like so (if you don't want to use the MaxIDE):
# BMK_CC_OPTS=-L/home/josh/leadwerkers ./BlitzMax/bin/bmk -d -x myapp.bmx


JoshK(Posted 2014) [#9]
I'm still stuck on this and I'm trying to get a product out the door. My attempt at setting rpath did not work. (This is what I had to do with C++ in Code::Blocks for another app to look in its own directory for libraries.)


skidracer(Posted 2014) [#10]
Please tell me you are using a 32 bit linux for this task.


JoshK(Posted 2014) [#11]
I am targeting Ubuntu 12.04 64-bit.

I can make it work if I copy the .so files into the /lib folder (yes I know that should use a sym link to /lib32), but I what I really want to do is include the .so files in the application directory so the user doesn't have to deal with any of this.

In C++ I was able to do this by just setting an "rpath" value to "./" in the compiler options.


skidracer(Posted 2014) [#12]
BlitzMax does not support 64 bit builds. To keep things proper I advise you to use a 32 bit install of Linux to build BlitzMax binaries that run correctly on 32 and 64 bit targets.

Such a step should allow you for instance to verify that the Steam library is in fact a 32 bit library that is compatible with BlitzMax build chain rather than floundering around possibly sticking 64 bits objects where they do not belong...


JoshK(Posted 2014) [#13]
That's not really an issue. I know the Steam library works perfectly. I am trying to make deployment easy on the user; I want the Steam library to be loaded from my application's directory, instead of making the user copy a file into a system folder. (This isn't something they can download from the package manager.)


Derron(Posted 2014) [#14]
- use a .deb/.rpm and let requirements automatically get installed (if they are available as packages)
- let the user care themselves how to install the required files on their system (so that it can get loaded dynamically)
- load requirements dynamical - maybe this works like in This Post from Brucey
- link them statically during compilation/building (so during deployment the file wont be needed)

Is none of the above is an option for you?


I especially ask because of your statement "I want the Steam library to be loaded from my application's directory" - you should either use the one provided by the current steam installation, link the one you want statically (if allowed) or avoid steam integration at all. Don't see a point shipping a "specific version" if this then wouldn't be compatible with the rest of Steams libraries.


bye
Ron


JoshK(Posted 2014) [#15]
It isn't something that Steam ever installs in the user's library. It's a shared object that cannot be linked statically. I just want the BlitzMax executable to be able to find the shared object in the executable's own directory.


Brucey(Posted 2014) [#16]
There's a Linux Stream game on my box that seems to manage fine with shared objects in the same directory as the binary.

The shared object is compile-time linked (as shown by ldd), and if you try to run the game outside of the Steam environment the game fails to start because it can't find the shared object.

Leading one to make the assumption that Steam's environment adds the local directory to LD_LIBRARY_PATH.

I'm sure the documentation/Valve/Value forums could confirm this if you asked them - rather than asking such things here where no-one actually knows the answer.


...

A man walks into a Golf equipment shop.
"Can you tell me why my car won't start?"

...


JoshK(Posted 2014) [#17]
This isn't a Steam question. It's a general BMX/Linux question. I found two ways to set the library path for a precompiled executable.

1) Launch the program with a script that sets the library path env variable.

2) PatchElf supposedly can add an rpath value to any compiled executable:
https://nixos.org/patchelf.html


Brucey(Posted 2014) [#18]
I'd generally use option 1, and add "." to LD_LIBRARY_PATH.

But anyway, since Steam probably sets the environment correctly, this becomes a non-issue.


dawlane(Posted 2014) [#19]
@JoshK: Did you ever solve this?


dawlane(Posted 2014) [#20]
@Josh: If you didn't and wish to do this from BlitzMax you will need to make a minor alteration to bmk.

Open up bmk_utils.bmx in the bmk source directory and somewhere around line 332 there should be a line that reads
cmd:+" -m32 -s -Os -pthread"

For this example all the libraries I want to link to, will be in a directory named libs where the executable is located.
Add -Wl,--rpath=./libs so the line reads
cmd:+" -m32 -s -Os -pthread -Wl,--rpath=./libs"

Now so that the applications will compile you need to place the shared libraries into the lib directory inside your BlitzMax install. Remember the compile-link will be looking for a .so, so if you have multiple shared libraries versions e.g <your_lib-123.so>, you will need to make a system link and name it <your_lib>.so.
Now in your projects directory where the binary will be built. You will need to create a directory named libs and copy the actual shared library you are going to use e.g <your_lib-123.so>.
After this you should be able to compile and run the BlitzMax application as normal. With the added bonus of running the project as a stand alone application.

NOTE: For any of the rpath tools to be of any use, rpath has to be added to the compile process. A long with patchelf there are two standard tools that are usually in the repositories. These are readelf and chrpath. You can use readelf -d <your_app> to check that RPATH is set correctly. If you do a web search; you tend to come across a variable named $ORIGIN. Using this variable can cause complications as explained here. They also don't tell you you may need to write it with a dot on the end.


Brucey(Posted 2014) [#21]
Fortunately, you don't need to do this for Steam, as Steam already adds your app directory to LD_LIBRARY_PATH anyway :o)


dawlane(Posted 2014) [#22]
@Brucey: I've only briefly played around with Steam and Steamworks SDk so I will look into how Steam sets up the environment for running Steam based application.