将c++代码构建为共享库

building c++ code into a shared library

本文关键字:共享 构建 c++ 代码      更新时间:2023-10-16

我有一些c++代码,在java应用程序中用作共享库。我的c++代码使用了一些库,如ffmpeg和boost。而ffmpeg库又依赖于libx264。我的第一个问题是-我能把我的c++构建成一个"fat"共享库吗?这个库包含了所有使用的库中的所有符号,这样在新机器上,如果我只复制fat.so文件,一切都可以工作。如果这不可能,那么你能帮我修复我目前的构建过程吗。这就是我目前正在做的事情-

1) 在本地VM(ubuntu 64)上,我使用-fPIC标志编译ffmpeg代码,并使用apt-get命令安装h264和boost
2) 在同一个虚拟机上,我使用make文件编译代码,它看起来像这样-

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) 在将运行java应用程序的新机器上。我使用apt-get命令安装h264和boost,并将ffmpeg编译的库文件复制到/usr/local/lib。

4) 将final.so文件复制到这台新机器上。但是当java代码尝试使用final.so文件时,我看到它尝试使用wierdly命名的文件。例如,它试图找到libavcodec.so.57、libavformat.so.57等。为了解决这个问题,我刚刚创建了这些文件的副本,即libavcodec.so复制到libavcodec.so.57。

5) 但这些ffmpeg库反过来使用了一个不同名称的lib264.so文件。在我的新机器上,x264的apt-get命令安装了一个名为libx264.so.148的文件,但其中一个ffmpeg库正在搜索文件libx264.so.142,即使我重命名了这个libx264文件,我也会收到新的错误,因为ffmpeg程序库试图调用带有这些数字的libx264方法。

6) 此时,对我来说,唯一可行的选择是在每台新机器上使用c++代码,并在本地构建final.so文件。这是我想避免的事情,因为我想把.so文件和jar文件一起分发给我的客户端,他们可以很容易地使用,而不必构建和安装东西。

我可能有一个"fat"库的解决方案,但我不能100%确定它是否有效。

通常,可以通过指定这些链接器标志将静态库链接到共享库中。

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

因此,您必须将所有库编译为静态库。如果你认为这样做是值得的,你可以尝试一下。

第二部分:您的另一台计算机似乎正在使用不同版本的库。在示例中,libx264.so.148可能被引用到1.4.8版本或类似的版本。因此,您的libx264.so应该是指向libx264.so.148的符号链接。你可以用来验证

ln -l 

为了可视化,您的符号链接引用到哪里。

我建议在两台机器上手动编译所有需要的库。那么这些问题就应该得到解决。