如何使二进制文件兼容不同的发行版

3
我需要创建一个可执行文件,它能够与尽可能多的Linux发行版兼容。我查阅了大量相关信息,并发现有两种方法:静态链接和动态链接。第一种解决方案可以避免在可执行文件中携带库,但是会存在一些许可证问题。第二种解决方案似乎更为适合。
使用动态链接时,链接器会将所需库的所有引用添加到可执行文件的ELF头,并且操作系统在执行二进制文件之前就会加载这些库。
命令readelf -d <binary>显示所需的库:
Dynamic section at offset 0x149d80 contains 33 entries:
Tag        Type                         Name/Value
0x0000000000000001 (NEEDED)             Shared library: [libopencv_highgui.so.2.4]
0x0000000000000001 (NEEDED)             Shared library: [libopencv_imgproc.so.2.4]
0x0000000000000001 (NEEDED)             Shared library: [libopencv_core.so.2.4]
0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]
0x0000000000000001 (NEEDED)             Shared library: [libpthread.so.0]
0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
0x000000000000000f (RPATH)              Library rpath: [$ORIGIN/lib]

当执行命令 ldd <binary> 时,会显示从我的可执行文件调用的所有库:

linux-vdso.so.1 =>  (0x00007fffbb14c000)
libopencv_highgui.so.2.4 => /home/user/./lib/libopencv_highgui.so.2.4 (0x00007f19398d0000)
libopencv_imgproc.so.2.4 => /home/user/./lib/libopencv_imgproc.so.2.4 (0x00007f1939410000)
libopencv_core.so.2.4 => /home/user/./lib/libopencv_core.so.2.4 (0x00007f1938fb7000)
libstdc++.so.6 => /home/user/./lib/libstdc++.so.6 (0x00007f1938cb3000)
libm.so.6 => /home/user/./lib/libm.so.6 (0x00007f19389b7000)
libgcc_s.so.1 => /home/user/./lib/libgcc_s.so.1 (0x00007f19387a0000)
libpthread.so.0 => /home/user/./lib/libpthread.so.0 (0x00007f1938583000)
libc.so.6 => /home/user/./lib/libc.so.6 (0x00007f19381c3000)
libtiff.so.4 => /usr/lib/x86_64-linux-gnu/libtiff.so.4 (0x00007f1937f49000)
libgstreamer-0.10.so.0 => /usr/lib/x86_64-linux-gnu/libgstreamer-0.10.so.0 (0x00007f1937c62000)
libgobject-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0 (0x00007f1937a13000)
libglib-2.0.so.0 => /lib/x86_64-linux-gnu/libglib-2.0.so.0 (0x00007f193771d000)
libgstapp-0.10.so.0 => /usr/lib/x86_64-linux-gnu/libgstapp-0.10.so.0 (0x00007f1937511000)
libgstvideo-0.10.so.0 => /usr/lib/x86_64-linux-gnu/libgstvideo-0.10.so.0 (0x00007f19372f5000)
libdc1394.so.22 => /usr/lib/x86_64-linux-gnu/libdc1394.so.22 (0x00007f1937081000)
libv4l1.so.0 => /usr/lib/x86_64-linux-gnu/libv4l1.so.0 (0x00007f1936e7b000)
libavcodec.so.53 => /usr/lib/x86_64-linux-gnu/libavcodec.so.53 (0x00007f193606b000)
libavformat.so.53 => /usr/lib/x86_64-linux-gnu/libavformat.so.53 (0x00007f1935d6a000)
libavutil.so.51 => /usr/lib/x86_64-linux-gnu/libavutil.so.51 (0x00007f1935b4a000)
libswscale.so.2 => /usr/lib/x86_64-linux-gnu/libswscale.so.2 (0x00007f1935904000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f19356fb000)
libgomp.so.1 => /usr/lib/x86_64-linux-gnu/libgomp.so.1 (0x00007f19354ec000)
/lib64/ld-linux-x86-64.so.2 (0x00007f1939bca000)
libjpeg.so.8 => /usr/lib/x86_64-linux-gnu/libjpeg.so.8 (0x00007f193529b000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f1935084000)
libgmodule-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgmodule-2.0.so.0 (0x00007f1934e80000)
libxml2.so.2 => /usr/lib/x86_64-linux-gnu/libxml2.so.2 (0x00007f1934b23000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f193491f000)
libffi.so.6 => /usr/lib/x86_64-linux-gnu/libffi.so.6 (0x00007f1934717000)
libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f19344d9000)
libgstbase-0.10.so.0 => /usr/lib/x86_64-linux-gnu/libgstbase-0.10.so.0 (0x00007f1934286000)
liborc-0.4.so.0 => /usr/lib/x86_64-linux-gnu/liborc-0.4.so.0 (0x00007f193400b000)
libraw1394.so.11 => /usr/lib/x86_64-linux-gnu/libraw1394.so.11 (0x00007f1933dfb000)
libusb-1.0.so.0 => /lib/x86_64-linux-gnu/libusb-1.0.so.0 (0x00007f1933bec000)
libv4l2.so.0 => /usr/lib/x86_64-linux-gnu/libv4l2.so.0 (0x00007f19339e0000)
libvpx.so.1 => /usr/lib/libvpx.so.1 (0x00007f193373a000)
libvorbisenc.so.2 => /usr/lib/x86_64-linux-gnu/libvorbisenc.so.2 (0x00007f193326b000)
libvorbis.so.0 => /usr/lib/x86_64-linux-gnu/libvorbis.so.0 (0x00007f193303f000)
libtheoraenc.so.1 => /usr/lib/x86_64-linux-gnu/libtheoraenc.so.1 (0x00007f1932e01000)
libtheoradec.so.1 => /usr/lib/x86_64-linux-gnu/libtheoradec.so.1 (0x00007f1932be6000)
libspeex.so.1 => /usr/lib/x86_64-linux-gnu/libspeex.so.1 (0x00007f19329cd000)
libschroedinger-1.0.so.0 => /usr/lib/libschroedinger-1.0.so.0 (0x00007f1932719000)
libgsm.so.1 => /usr/lib/libgsm.so.1 (0x00007f193250b000)
libva.so.1 => /usr/lib/x86_64-linux-gnu/libva.so.1 (0x00007f19322f5000)
libbz2.so.1.0 => /lib/x86_64-linux-gnu/libbz2.so.1.0 (0x00007f19320e4000)
libv4lconvert.so.0 => /usr/lib/x86_64-linux-gnu/libv4lconvert.so.0 (0x00007f1931e6f000)
libogg.so.0 => /usr/lib/x86_64-linux-gnu/libogg.so.0 (0x00007f1931c67000)

现在我已经使用链接器选项设置了RPATH -Wl,-rpath,\$$ORIGIN/lib (http://en.wikipedia.org/wiki/Rpath),因此在执行之前,链接器将首先查看RPATH。如果未设置DT_RUNPATH,则这是正确的 (https://wiki.debian.org/RpathIssue)。在我的Ubuntu 12.04 64位系统上,如果我使用ldd检查,所有库都指向正确的路径。在Debian 7 64位系统上,openCV库不存在,ldd返回:
linux-vdso.so.1 =>  (0x00007fffcf157000)
linux-vdso.so.1 =>  (0x00007fffcf157000)
libopencv_highgui.so.2.4 => /home/user/./lib/libopencv_highgui.so.2.4 (0x00007fd15d4a1000)
libopencv_imgproc.so.2.4 => /home/user/./lib/libopencv_imgproc.so.2.4 (0x00007fd15cfe1000)
libopencv_core.so.2.4 => /home/user/./lib/libopencv_core.so.2.4 (0x00007fd15cb88000)
libstdc++.so.6 => /home/user/./lib/libstdc++.so.6 (0x00007fd15c884000)
libm.so.6 => /home/user/./lib/libm.so.6 (0x00007fd15c588000)
libgcc_s.so.1 => /home/user/./lib/libgcc_s.so.1 (0x00007fd15c371000)
libpthread.so.0 => /home/user/./lib/libpthread.so.0 (0x00007fd15c154000)
libc.so.6 => /home/user/./lib/libc.so.6 (0x00007fd15bd94000)
libtiff.so.4 => /home/user/./lib/libtiff.so.4 (0x00007fd15bb2f000)
libgstreamer-0.10.so.0 => /home/user/./lib/libgstreamer-0.10.so.0 (0x00007fd15b848000)
libgobject-2.0.so.0 => /home/user/./lib/libgobject-2.0.so.0 (0x00007fd15b5f9000)
libglib-2.0.so.0 => /home/user/./lib/libglib-2.0.so.0 (0x00007fd15b303000)
libgstapp-0.10.so.0 => /home/user/./lib/libgstapp-0.10.so.0 (0x00007fd15b0f7000)
libgstvideo-0.10.so.0 => /home/user/./lib/libgstvideo-0.10.so.0 (0x00007fd15aedb000)
libdc1394.so.22 => /home/user/./lib/libdc1394.so.22 (0x00007fd15ac67000)
libv4l1.so.0 => /home/user/./lib/libv4l1.so.0 (0x00007fd15aa61000)
libavcodec.so.53 => /home/user/./lib/libavcodec.so.53 (0x00007fd159c51000)
libavformat.so.53 => /home/user/./lib/libavformat.so.53 (0x00007fd159950000)
libavutil.so.51 => /home/user/./lib/libavutil.so.51 (0x00007fd159730000)
libswscale.so.2 => /home/user/./lib/libswscale.so.2 (0x00007fd1594ea000)
librt.so.1 => /home/user/./lib/librt.so.1 (0x00007fd1592e1000)
libgomp.so.1 => /home/user/./lib/libgomp.so.1 (0x00007fd1590d2000)
/lib64/ld-linux-x86-64.so.2 (0x00007fd15d79b000)
libjpeg.so.8 => /home/user/./lib/libjpeg.so.8 (0x00007fd158e81000)
libz.so.1 => /home/user/./lib/libz.so.1 (0x00007fd158c6a000)
libgmodule-2.0.so.0 => /home/user/./lib/libgmodule-2.0.so.0 (0x00007fd158a66000)
libxml2.so.2 => /home/user/./lib/libxml2.so.2 (0x00007fd158709000)
libdl.so.2 => /home/user/./lib/libdl.so.2 (0x00007fd158505000)
libffi.so.6 => /home/user/./lib/libffi.so.6 (0x00007fd1582fd000)
libpcre.so.3 => /home/user/./lib/libpcre.so.3 (0x00007fd1580bf000)
libgstbase-0.10.so.0 => /home/user/./lib/libgstbase-0.10.so.0 (0x00007fd157e6c000)
liborc-0.4.so.0 => /home/user/./lib/liborc-0.4.so.0 (0x00007fd157bf1000)
libraw1394.so.11 => /home/user/./lib/libraw1394.so.11 (0x00007fd1579e1000)
libusb-1.0.so.0 => /home/user/./lib/libusb-1.0.so.0 (0x00007fd1577d2000)
libv4l2.so.0 => /home/user/./lib/libv4l2.so.0 (0x00007fd1575c6000)
libvpx.so.1 => /home/user/./lib/libvpx.so.1 (0x00007fd157320000)
libvorbisenc.so.2 => /home/user/./lib/libvorbisenc.so.2 (0x00007fd156e51000)
libvorbis.so.0 => /home/user/./lib/libvorbis.so.0 (0x00007fd156c25000)
libtheoraenc.so.1 => /home/user/./lib/libtheoraenc.so.1 (0x00007fd1569e7000)
libtheoradec.so.1 => /home/user/./lib/libtheoradec.so.1 (0x00007fd1567cc000)
libspeex.so.1 => /home/user/./lib/libspeex.so.1 (0x00007fd1565b3000)
libschroedinger-1.0.so.0 => /home/user/./lib/libschroedinger-1.0.so.0 (0x00007fd1562ff000)
libgsm.so.1 => /home/user/./lib/libgsm.so.1 (0x00007fd1560f1000)
libva.so.1 => /home/user/./lib/libva.so.1 (0x00007fd155edb000)
libbz2.so.1.0 => /home/user/./lib/libbz2.so.1.0 (0x00007fd155cca000)
libv4lconvert.so.0 => /home/user/./lib/libv4lconvert.so.0 (0x00007fd155a55000)
libogg.so.0 => /home/user/./lib/libogg.so.0 (0x00007fd15584d000)

在我安装openCV的openSuse 12.3 64位系统上,似乎没有问题。但是有一些库(libogg)不在路径$ORIGIN/lib中。

linux-vdso.so.1 =>  (0x00007fff25fff000)
libopencv_highgui.so.2.4 => /home/user/lib/libopencv_highgui.so.2.4 (0x00007feb4a50c000)
libopencv_imgproc.so.2.4 => /home/user/lib/libopencv_imgproc.so.2.4 (0x00007feb4a04c000)
libopencv_core.so.2.4 => /home/user/lib/libopencv_core.so.2.4 (0x00007feb49bf4000)
libstdc++.so.6 => /home/user/lib/libstdc++.so.6 (0x00007feb498f0000)
libm.so.6 => /home/user/lib/libm.so.6 (0x00007feb495f4000)
libgcc_s.so.1 => /home/user/lib/libgcc_s.so.1 (0x00007feb493de000)
libpthread.so.0 => /home/user/lib/libpthread.so.0 (0x00007feb491c1000)
libc.so.6 => /home/user/lib/libc.so.6 (0x00007feb48e01000)
libtiff.so.4 => /home/user/lib/libtiff.so.4 (0x00007feb48b9d000)
libgstreamer-0.10.so.0 => /home/user/lib/libgstreamer-0.10.so.0 (0x00007feb488b6000)
libgobject-2.0.so.0 => /home/user/lib/libgobject-2.0.so.0 (0x00007feb48667000)
libglib-2.0.so.0 => /home/user/lib/libglib-2.0.so.0 (0x00007feb48372000)
libgstapp-0.10.so.0 => /home/user/lib/libgstapp-0.10.so.0 (0x00007feb48166000)
libgstvideo-0.10.so.0 => /home/user/lib/libgstvideo-0.10.so.0 (0x00007feb47f4a000)
libdc1394.so.22 => /home/user/lib/libdc1394.so.22 (0x00007feb47cd7000)
libv4l1.so.0 => /home/user/lib/libv4l1.so.0 (0x00007feb47ad1000)
libavcodec.so.53 => /usr/local/lib/libavcodec.so.53 (0x00007feb46a00000)
libavformat.so.53 => /usr/local/lib/libavformat.so.53 (0x00007feb46702000)
libavutil.so.51 => /usr/local/lib/libavutil.so.51 (0x00007feb464e2000)
libswscale.so.2 => /usr/local/lib/libswscale.so.2 (0x00007feb462af000)
librt.so.1 => /home/user/lib/librt.so.1 (0x00007feb460a7000)
libgomp.so.1 => /home/user/lib/libgomp.so.1 (0x00007feb45e98000)
/lib64/ld-linux-x86-64.so.2 (0x00007feb4a804000)
libjpeg.so.8 => /home/user/lib/libjpeg.so.8 (0x00007feb45c48000)
libz.so.1 => /home/user/lib/libz.so.1 (0x00007feb45a31000)
libgmodule-2.0.so.0 => /home/user/lib/libgmodule-2.0.so.0 (0x00007feb4582d000)
libxml2.so.2 => /home/user/lib/libxml2.so.2 (0x00007feb454d1000)
libdl.so.2 => /home/user/lib/libdl.so.2 (0x00007feb452cd000)
libffi.so.6 => /home/user/lib/libffi.so.6 (0x00007feb450c5000)
libpcre.so.3 => /home/user/lib/libpcre.so.3 (0x00007feb44e88000)
libgstbase-0.10.so.0 => /home/user/lib/libgstbase-0.10.so.0 (0x00007feb44c35000)
liborc-0.4.so.0 => /home/user/lib/liborc-0.4.so.0 (0x00007feb449ba000)
libraw1394.so.11 => /home/user/lib/libraw1394.so.11 (0x00007feb447ab000)
libusb-1.0.so.0 => /home/user/lib/libusb-1.0.so.0 (0x00007feb4459c000)
libv4l2.so.0 => /home/user/lib/libv4l2.so.0 (0x00007feb44390000)
libvo-amrwbenc.so.0 => /usr/local/lib/libvo-amrwbenc.so.0 (0x00007feb44176000)
libvo-aacenc.so.0 => /usr/local/lib/libvo-aacenc.so.0 (0x00007feb43f58000)
libtheoraenc.so.1 => /usr/local/lib/libtheoraenc.so.1 (0x00007feb43d1d000)
libtheoradec.so.1 => /usr/local/lib/libtheoradec.so.1 (0x00007feb43b04000)
libspeex.so.1 => /usr/local/lib/libspeex.so.1 (0x00007feb438ea000)
libopencore-amrwb.so.0 => /usr/local/lib/libopencore-amrwb.so.0 (0x00007feb436d6000)
libopencore-amrnb.so.0 => /usr/local/lib/libopencore-amrnb.so.0 (0x00007feb434ac000)
libmp3lame.so.0 => /usr/local/lib/libmp3lame.so.0 (0x00007feb43224000)
libfaac.so.0 => /usr/local/lib/libfaac.so.0 (0x00007feb43011000)
libv4lconvert.so.0 => /home/user/lib/libv4lconvert.so.0 (0x00007feb42d9c000)
libogg.so.0 => /usr/local/lib/libogg.so.0 (0x00007feb42b95000)

$ORIGIN/lib文件夹中的每个库都可以与其他库链接,并且它们可以不同于文件夹内的库。例如,如果从Debian 7输入ldd,则会得到:

./libavformat.so.53: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.14' not found (required by ./libavformat.so.53)
linux-vdso.so.1 =>  (0x00007fff31499000)
libavcodec.so.53 => /usr/lib/x86_64-linux-gnu/libavcodec.so.53 (0x00007f5dfe09b000)
libavutil.so.51 => /usr/lib/x86_64-linux-gnu/libavutil.so.51 (0x00007f5dfde7a000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f5dfdbf7000)
libbz2.so.1.0 => /lib/x86_64-linux-gnu/libbz2.so.1.0 (0x00007f5dfd9e7000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f5dfd7d0000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f5dfd5b3000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5dfd229000)
libxvidcore.so.4 => /usr/lib/x86_64-linux-gnu/libxvidcore.so.4 (0x00007f5dfcef2000)
libx264.so.123 => /usr/lib/x86_64-linux-gnu/libx264.so.123 (0x00007f5dfcb69000)
libvpx.so.1 => /usr/lib/x86_64-linux-gnu/libvpx.so.1 (0x00007f5dfc8ca000)
libvorbisenc.so.2 => /usr/lib/x86_64-linux-gnu/libvorbisenc.so.2 (0x00007f5dfc3fb000)
libvorbis.so.0 => /usr/lib/x86_64-linux-gnu/libvorbis.so.0 (0x00007f5dfc1cd000)
libtheoraenc.so.1 => /usr/lib/x86_64-linux-gnu/libtheoraenc.so.1 (0x00007f5dfbf8c000)
libtheoradec.so.1 => /usr/lib/x86_64-linux-gnu/libtheoradec.so.1 (0x00007f5dfbd70000)
libspeex.so.1 => /usr/lib/x86_64-linux-gnu/libspeex.so.1 (0x00007f5dfbb57000)
libschroedinger-1.0.so.0 => /usr/lib/x86_64-linux-gnu/libschroedinger-1.0.so.0 (0x00007f5dfb88a000)
libopenjpeg.so.2 => /usr/lib/x86_64-linux-gnu/libopenjpeg.so.2 (0x00007f5dfb668000)
libmp3lame.so.0 => /usr/lib/x86_64-linux-gnu/libmp3lame.so.0 (0x00007f5dfb3dd000)
libgsm.so.1 => /usr/lib/x86_64-linux-gnu/libgsm.so.1 (0x00007f5dfb1d0000)
libdirac_encoder.so.0 => /usr/lib/x86_64-linux-gnu/libdirac_encoder.so.0 (0x00007f5dfaf40000)
libva.so.1 => /usr/lib/x86_64-linux-gnu/libva.so.1 (0x00007f5dfad28000)
/lib64/ld-linux-x86-64.so.2 (0x00007f5dff22e000)
libogg.so.0 => /usr/lib/x86_64-linux-gnu/libogg.so.0 (0x00007f5dfab22000)
liborc-0.4.so.0 => /usr/lib/x86_64-linux-gnu/liborc-0.4.so.0 (0x00007f5dfa8a4000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f5dfa59d000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f5dfa387000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f5dfa182000)

因此,是否可能得到一个仅依赖于 $ORIGIN/lib 库的可执行文件?我是在 Ubuntu 12.04 64位上编译的,但如果我尝试在 Debian 7 64位上执行,链接器 ld-linux-x86-64.so.2 会导致分段错误。而在 openSuse 12.3 64位上也会出现问题。
./binary: relocation error: /home/user/lib/libopencv_highgui.so.2.4: symbol avformat_network_init, version LIBAVFORMAT_53 not defined in file libavformat.so.53 with link time reference

ldd libavformat

ldd libavformat.so.53
linux-vdso.so.1 =>  (0x00007fff8c3c5000)
libavcodec.so.53 => /usr/local/lib/libavcodec.so.53 (0x00007f3634b37000)
libavutil.so.51 => /usr/local/lib/libavutil.so.51 (0x00007f3634916000)
libm.so.6 => /lib64/libm.so.6 (0x00007f36346bf000)
libbz2.so.1.0 => not found
libz.so.1 => /lib64/libz.so.1 (0x00007f36344a7000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f3634289000)
libc.so.6 => /lib64/libc.so.6 (0x00007f3633ef9000)
libvo-amrwbenc.so.0 => /usr/local/lib/libvo-amrwbenc.so.0 (0x00007f3633cdf000)
libvo-aacenc.so.0 => /usr/local/lib/libvo-aacenc.so.0 (0x00007f3633ac0000)
libtheoraenc.so.1 => /usr/local/lib/libtheoraenc.so.1 (0x00007f3633885000)
libtheoradec.so.1 => /usr/local/lib/libtheoradec.so.1 (0x00007f363366c000)
libspeex.so.1 => /usr/local/lib/libspeex.so.1 (0x00007f3633451000)
libopencore-amrwb.so.0 => /usr/local/lib/libopencore-amrwb.so.0 (0x00007f363323d000)
libopencore-amrnb.so.0 => /usr/local/lib/libopencore-amrnb.so.0 (0x00007f3633013000)
libmp3lame.so.0 => /usr/local/lib/libmp3lame.so.0 (0x00007f3632d8a000)
libfaac.so.0 => /usr/local/lib/libfaac.so.0 (0x00007f3632b77000)
/lib64/ld-linux-x86-64.so.2 (0x00007f3635f35000)
libogg.so.0 => /usr/local/lib/libogg.so.0 (0x00007f363296f000)

二进制文件在 /home/user/ 目录下。 除了源代码,还有其他分发二进制文件的解决方案吗?

可能是二进制兼容性覆盖的机器范围?的重复问题。 - Nicholas Wilson
1
你能在自己的机器上编译,但在目标机器上链接吗?你可以带上所需的库,检查它们是否存在,并在需要时使用你自己的库。 - Vadim
嗨,感谢您的提示。目前我通过在我的机器上编译一个单一的静态库,并在每台目标机器上进行链接来解决了这个问题。 - erotavlas
1个回答

2
哎呀!这是一个惊人的依赖数量!你将会遇到很大的困难,使所有这些依赖在各种发行版中都能正常工作,尤其是因为你可能对其中一些依赖版本有严格的要求(例如,如果你想动态链接到OpenCV,那么至少你只支持那些提供相同主要版本的发行版)。
正如你所指出的,你绝不能创建一个完全静态的二进制文件(这仅在非常特定的情况下有用,因为静态编译的二进制文件最不可移植)。规则是:永远不要静态链接libc(如果你这样做了,就禁止调用dlopen)。你可以静态链接libstdc++,这样做可以在更广泛的发行版上获得兼容性,但代价是稍微增加了二进制文件的大小。libm、libpthread基本上和libc一样的规则,而像libz这样的古老库是安全的,因为它们有非常稳定的ABI。
对于其余的部分,你需要将依赖树分离开来,并尝试静态链接运行时依赖项中最糟糕的部分,记住你还必须链接它们的依赖项!所以如果你发现必须静态链接libavcodec,你很可能还需要提供libspeex(除非它有非常稳定的ABI,我不知道这个库的情况)。
关于Debian 7 libc问题:这可能是你要解决的最容易的问题。你只需要在你想要支持的最老的发行版上编译即可。如果你在更新的Ubuntu或Suse版本上编译,你将会得到一个对于Debian 7版本的glibc更高版本的依赖。在旧机器上进行编译将是没有问题的(它可以在新的发行版上正常运行)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接