Managing shared objects

Hi,

I am writing a C++ application that is split up into several shared objects. It seems the Linux convention is to prepend 'lib' to the name of the library (like 'libfoo.so'), and then linking to it via '-L path_to_libfoo -l foo'.

I want to use shared objects, but I do not want to name them with the lib prefix (if I had wanted to do that, I would have named them that way to begin with). I also want the executable to look explicitly in it's working directory for the shared objects, wherever that might be. This works great on Windows, how do I get it to work on Linux? I've tried messing with the '-rpath' and '-soname' compiler options, but I'm kind of confused on how they work.

Thanks!
Last edited on
Ok, let's start again because your terms are confusing.

You have created a bunch of Shared Libraries, not shared objects, there's no such thing. Having done so, don't try to change their names to something else. It's better to create what you want to begin with.

You clearly understand Windows terms, so, please describe using Windows terms what it is you want to create and we'll see what we can do.
On windows I have an application (App.exe) that depends on the "modules" A and B. B also depends on A.

A and B are compiled as DLLs, so the output of the compiler is 'A.dll' and 'B.dll' (plus the .lib files generated, but that's just for linking).

The program runs in a directory containing:
- App.exe
- A.dll
- B.dll

And it just works. I'm trying to create the same thing on linux, and I think I've figured out a system that does it. It seems to work, but I'm not experienced enough with linux to know if I'm doing it the right way.

A's makefile looks like:
# A.makefile

CXX=clang++
CFLAGS=-std=c++11 -Ofast -Wall
LFLAGS=-fPIC -shared -Wl,-soname=A.so
DEPS=
OUT=-o bin/A.so

all: setup
	$(CXX) $(CFLAGS) source/*.cpp $(LFLAGS) $(DEPS) $(OUT)

setup:
	mkdir -p bin

clean:
	rm -rf bin


B's makefile looks like:
# B.makefile

CXX=clang++
CFLAGS=-std=c++11 -Ofast -Wall -I ../A/include
LFLAGS=-fPIC -shared -Wl,-soname=B.so,-rpath=./
DEPS=../A/bin/A.so
OUT=-o bin/B.so

all: A setup
	$(CXX) $(CFLAGS) source/*.cpp $(LFLAGS) $(DEPS) $(OUT)

A:
	make -C ../A/ -f A.makefile

setup:
	mkdir -p bin

clean:
	rm -rf bin


And App's makefile:
# App.makefile

CXX=clang++
CFLAGS=-std=c++11 -Ofast -Wall -I ../Modules/A/include -I ../Modules/B/include
LFLAGS=-Wl,-rpath=./
DEPS=../Modules/A/bin/A.so ../Modules/B/bin/B.so
OUT=-o bin/App.out

all: B setup
	$(CXX) $(CFLAGS) source/*.cpp $(LFLAGS) $(DEPS) $(OUT)

B:
	 make -C ../Modules/B -f B.makefile

setup:
	mkdir -p bin

clean:
	rm -rf bin


If I then copy 'A.so', 'B.so', and 'App.out' into the same directory and then execute 'App.out', it all seems to work. Is this the best approach?
Last edited on
Ok. The real difference in the platforms is the rules the loader uses when looking for stuff.

This is current bonkers version: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682586%28v=vs.85%29.aspx

It used to be just this:https://msdn.microsoft.com/en-us/library/windows/desktop/ff919712%28v=vs.85%29.aspx

POSIX defines these together: dlopen (LoadLibrary), and ld .so.
http://man7.org/linux/man-pages/man3/dlopen.3.html
http://man7.org/linux/man-pages/man8/ld.so.8.html

So let's start again.
1. Don't rename the library names, stick to the convention and call them libXX.so. You can also use the version convention extension later on.

2. Your make files need a tweak. Add this to them:
 
.PHONY: setup A B

all and clean are marked .PHONY by default.

To be honest the project should be reorganised and the makefiles rewritten. See: http://www.cplusplus.com/articles/jTbCpfjN/

3. Your get out of jail free card is in man ld.so
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Rpath token expansion
       ld.so understands certain strings in an rpath specification (DT_RPATH
       or DT_RUNPATH); those strings are substituted as follows

       $ORIGIN (or equivalently ${ORIGIN})
              This expands to the directory containing the program or shared
              library.  Thus, an application located in somedir/app could be
              compiled with

                  gcc -Wl,-rpath,'$ORIGIN/../lib'

              so that it finds an associated shared library in somedir/lib
              no matter where somedir is located in the directory hierarchy.
              This facilitates the creation of "turn-key" applications that
              do not need to be installed into special directories, but can
              instead be unpacked into any directory and still find their
              own shared libraries.


Also, you can test this stuff on Cygwin, you don't need a seperate POSIX box.
Last edited on
Thanks! I followed all your advice above.

To be honest the project should be reorganised and the makefiles rewritten.

How do you mean?
Last edited on
It's best if you project is organised as:
1
2
3
4
5
MyCoolProj
    MainProg
    CommonStuff
    Lib1
    Lib2


Yours appears to be arranged as:
1
2
3
4
MainProg
    CommonStuff
    Lib1
    Lib2


It allows the build to be more standard.
Last edited on
Topic archived. No new replies allowed.