0

I have some c++ code which i use as shared library in a java application.My c++ code uses some libraries like ffmpeg and boost. and ffmpeg libraries in turn depend on libx264. my first question is - can i build my c++ into a "fat" shared library which contains all the symbols from all libraries used so that on a new machine if i just copy the fat .so file everything works. If thats not possible then can you help me fix my current build process. This is what i am doing currently -

1)on a local VM(ubuntu 64) i compile ffmpeg code using -fPIC flag and install h264 and boost using apt-get commands.
2) on the same VM i compile my code using make file which looks like this-

INCLUDES =   -I/opt/ffmpeg/include -I/usr/lib/jvm/java-7-openjdk-   amd64/include -I/usr/lib/jvm/java-7-openjdk-amd64/include/linux

LDFLAGS =   -L/home/ubuntu/ffmpeg_shared

LIBRARIES = -lavformat -lavcodec -lswscale -lavutil -lpthread  -lx264 -lboost_system -lboost_thread -lboost_chrono 

CC = g++ -std=c++11 -fPIC

all:clean final

final:Api.o ImageSequence.o OverlayAnimation.o Utils.o ImageFrame.o 
$(CC)  -o final.so Api.o ImageSequence.o OverlayAnimation.o Utils.o  ImageFrame.o $(LDFLAGS) $(LIBRARIES) -shared 

3) on a new machine where java app will run. i install h264 and boost using apt-get commands and copy ffmpeg's compiled library files to /usr/local/lib.

4) copy the final.so file to this new machine. but when the java code tries to use the final.so file i see it tries to use wierdly named files. for example - it tries to find libavcodec.so.57 , libavformat.so.57 etc. to fix this i just created a copy of these files ie libavcodec.so copied to libavcodec.so.57.

5)But these ffmpeg libraries in turn uses a differently named lib264.so file. on my new machine the apt-get command for x264 installed a file named libx264.so.148 but one of ffmpeg libraries is searching for file libx264.so.142 even if i rename this libx264.so file i get new errors where ffmpeg libraries tries to call libx264's methods which has these numbers attached.

6) at this time the only working option for me is to bring the c++ code on every new machine and build final.so file locally. this is something i want to avoid since i want to distribute the .so file along with jar file to my clients which they can easily use without having to build and install stuff.

gaurav
  • 365
  • 5
  • 14

1 Answers1

0

I may have a solution for a 'fat' library, but I'm not 100% sure if it will work.

In general, it is possible to link together static libraries into a shared library by specifying these linker flags.

g++ -Wl,--whole-archive some_static_lib.a -Wl,--no-whole-archive

Therefore you would have to compile all your libraries into static libraries. If you think it's worth the effort to do this, you can give it a try.

To the second part: It seems that your other machine is using different versions of the libraries. In example libx264.so.148 might be reffering to version 1.4.8 or something like that. Therefore your libx264.so should be a symbolic link to libx264.so.148. You can verify that with

ln -l 

to visualize, where your symbolic link is reffering to.

I recommend to manually compile all needed libraries on both machines. Then these problems should be solved.

Cr3at0rX
  • 36
  • 7
  • agreed that if i manually compile everything on a new machine there wont be any problems. but i am trying to reduce the effort needed to setup a new machine hence the requirement of 'fat' library. i will try the above flags for linking static libraries into shared library. – gaurav Apr 11 '16 at 13:07
  • g++ -o final.so Api.o ImageSequence.o OverlayAnimation.o Utils.o ImageFrame.o -Wl,--whole-archive libavformat.a libavcodec.a libswscale.a libavutil.a libx264.a -shared --- i am getting a error when i am trying to build using above command. relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC . – gaurav Apr 11 '16 at 14:17
  • Have you tried this option? fPIC stands for position independend code. Everything that should be in your shared library has to be compiled with that flag. [Have a brief look here](http://stackoverflow.com/questions/966960/what-does-fpic-mean-when-building-a-shared-library) – Cr3at0rX Apr 13 '16 at 14:39
  • using fPIC i am able to compile the libraries and build my final shared lib.But I am trying to find a way to build a 'fat' shared lib file . will the option -Wl,--whole-archive work with shared libraries (ie .so files) ? – gaurav Apr 14 '16 at 17:42