【问题标题】:building c++ code into a shared library将 C++ 代码构建到共享库中
【发布时间】:2016-08-01 08:13:21
【问题描述】:

我有一些 c++ 代码用作 Java 应用程序中的共享库。我的 c++ 代码使用一些库,如 ffmpeg 和 boost。而 ffmpeg 库又依赖于 libx264。我的第一个问题是 - 我可以将我的 c++ 构建到一个“胖”共享库中,其中包含所有使用的库中的所有符号,以便在新机器上如果我只是复制胖 .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 文件时,我看到它尝试使用奇怪命名的文件。例如 - 它试图找到 libavcodec.so.57 、 libavformat.so.57 等来解决这个问题我刚刚创建了这些文件的副本,即复制到 libavcodec.so.57 的 libavcodec.so。

5) 但是这些 ffmpeg 库又使用了一个不同名称的 lib264.so 文件。在我的新机器上,用于 x264 的 apt-get 命令安装了一个名为 libx264.so.148 的文件,但是 ffmpeg 库之一正在搜索文件 libx264.so.142 即使我重命名此 libx264.so 文件我在 ffmpeg 库的位置出现新错误尝试调用附有这些数字的 libx264 的方法。

6) 目前对我来说唯一可行的选择是将 c++ 代码带到每台新机器上并在本地构建 final.so 文件。这是我想避免的事情,因为我想将 .so 文件与 jar 文件一起分发给我的客户,他们可以轻松使用,而无需构建和安装东西。

【问题讨论】:

    标签: java c++ makefile ffmpeg


    【解决方案1】:

    我可能有一个“胖”库的解决方案,但我不能 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 
    

    可视化,您的符号链接指向的位置。

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

    【讨论】:

    • 同意如果我在新机器上手动编译所有内容不会有任何问题。但我试图减少设置新机器所需的工作量,因此需要“胖”库。我将尝试使用上述标志将静态库链接到共享库。
    • 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 --- 当我尝试使用上述命令构建时出现错误。制作共享对象时,不能使用针对“.rodata”的重定位R_X86_64_32;使用 -fPIC 重新编译。
    • 你试过这个选项吗? fPIC 代表位置无关代码。应该在共享库中的所有内容都必须使用该标志进行编译。 Have a brief look here
    • 使用 fPIC 我能够编译库并构建我的最终共享库。但我正在尝试找到一种方法来构建一个“胖”共享库文件。选项 -Wl,--whole-archive 是否适用于共享库(即 .so 文件)?
    猜你喜欢
    • 2018-08-22
    • 1970-01-01
    • 1970-01-01
    • 2012-06-03
    • 1970-01-01
    • 2016-01-28
    • 1970-01-01
    • 2013-04-05
    • 2014-05-27
    相关资源
    最近更新 更多