【问题标题】:Why libfoo.so works and libfoo.so.version doesnt?为什么 libfoo.so 有效而 libfoo.so.version 无效?
【发布时间】:2020-04-09 09:19:41
【问题描述】:

我有一个库,直到现在我编译成这种形式的对象:

libalx-module.so

我什至不知道 soname 和所有这些东西,所以我保持简单。一切正常。

现在我转移到这个方案(现在的版本是1.0~b18):

libalx-module.so.1.0~b18
libalx-module.so.1        # which is a symlink to the above file

如您所见,没有/^*.so$/ 文件; al 文件在.so 之后有一些内容

链接器应该知道它们:

$ ls -l /usr/local/lib/libalx/
total 4000
-rw-r--r-- 1 root root 1174626 Apr  9 10:55 libalx-base.a
lrwxrwxrwx 1 root root      22 Apr  9 10:55 libalx-base.so.1 -> libalx-base.so.1.0~b18
-rwxr-xr-x 1 root root  148416 Apr  9 10:55 libalx-base.so.1.0~b18
-rw-r--r-- 1 root root  113738 Apr  9 10:55 libalx-curl.a
lrwxrwxrwx 1 root root      22 Apr  9 10:55 libalx-curl.so.1 -> libalx-curl.so.1.0~b18
-rwxr-xr-x 1 root root   27112 Apr  9 10:55 libalx-curl.so.1.0~b18
-rw-r--r-- 1 root root 1122710 Apr  9 10:55 libalx-cv.a
lrwxrwxrwx 1 root root      20 Apr  9 10:55 libalx-cv.so.1 -> libalx-cv.so.1.0~b18
-rwxr-xr-x 1 root root  162272 Apr  9 10:55 libalx-cv.so.1.0~b18
-rw-r--r-- 1 root root  178620 Apr  9 10:55 libalx-data-structures.a
lrwxrwxrwx 1 root root      33 Apr  9 10:55 libalx-data-structures.so.1 -> libalx-data-structures.so.1.0~b18
-rwxr-xr-x 1 root root   36976 Apr  9 10:55 libalx-data-structures.so.1.0~b18
-rw-r--r-- 1 root root  106816 Apr  9 10:55 libalx-gmp.a
lrwxrwxrwx 1 root root      21 Apr  9 10:55 libalx-gmp.so.1 -> libalx-gmp.so.1.0~b18
-rwxr-xr-x 1 root root   25032 Apr  9 10:55 libalx-gmp.so.1.0~b18
-rw-r--r-- 1 root root  203048 Apr  9 10:55 libalx-gsl.a
lrwxrwxrwx 1 root root      21 Apr  9 10:55 libalx-gsl.so.1 -> libalx-gsl.so.1.0~b18
-rwxr-xr-x 1 root root   39304 Apr  9 10:55 libalx-gsl.so.1.0~b18
-rw-r--r-- 1 root root  115888 Apr  9 10:55 libalx-ncurses.a
lrwxrwxrwx 1 root root      25 Apr  9 10:55 libalx-ncurses.so.1 -> libalx-ncurses.so.1.0~b18
-rwxr-xr-x 1 root root   41952 Apr  9 10:55 libalx-ncurses.so.1.0~b18
-rw-r--r-- 1 root root   10054 Apr  9 10:55 libalx-ocr.a
lrwxrwxrwx 1 root root      21 Apr  9 10:55 libalx-ocr.so.1 -> libalx-ocr.so.1.0~b18
-rwxr-xr-x 1 root root   16736 Apr  9 10:55 libalx-ocr.so.1.0~b18
-rw-r--r-- 1 root root   61370 Apr  9 10:55 libalx-plot.a
lrwxrwxrwx 1 root root      22 Apr  9 10:55 libalx-plot.so.1 -> libalx-plot.so.1.0~b18
-rwxr-xr-x 1 root root   26632 Apr  9 10:55 libalx-plot.so.1.0~b18
-rw-r--r-- 1 root root  165356 Apr  9 10:55 libalx-robot.a
lrwxrwxrwx 1 root root      23 Apr  9 10:55 libalx-robot.so.1 -> libalx-robot.so.1.0~b18
-rwxr-xr-x 1 root root   31840 Apr  9 10:55 libalx-robot.so.1.0~b18
-rw-r--r-- 1 root root   12806 Apr  9 10:55 libalx-telnet-tcp.a
lrwxrwxrwx 1 root root      28 Apr  9 10:55 libalx-telnet-tcp.so.1 -> libalx-telnet-tcp.so.1.0~b18
-rwxr-xr-x 1 root root   16544 Apr  9 10:55 libalx-telnet-tcp.so.1.0~b18
-rw-r--r-- 1 root root    9574 Apr  9 10:55 libalx-zbar.a
lrwxrwxrwx 1 root root      22 Apr  9 10:55 libalx-zbar.so.1 -> libalx-zbar.so.1.0~b18
-rwxr-xr-x 1 root root   16816 Apr  9 10:55 libalx-zbar.so.1.0~b18
drwxr-xr-x 2 root root    4096 Apr  9 10:55 py
drwxr-xr-x 2 root root    4096 Apr  9 10:55 sh
$ sudo ldconfig -v
ldconfig: Can't stat /usr/local/lib/x86_64-linux-gnu: No such file or directory
ldconfig: Path `/usr/lib/x86_64-linux-gnu' given more than once
ldconfig: Path `/lib/x86_64-linux-gnu' given more than once
ldconfig: Path `/usr/lib/x86_64-linux-gnu' given more than once
ldconfig: Path `/usr/lib' given more than once
/usr/lib/x86_64-linux-gnu/libfakeroot:
    libfakeroot-0.so -> libfakeroot-tcp.so
/usr/local/lib/libalx:
    libalx-cv.so.1 -> libalx-cv.so.1.0~b18
    libalx-telnet-tcp.so.1 -> libalx-telnet-tcp.so.1.0~b18
    libalx-gmp.so.1 -> libalx-gmp.so.1.0~b18
    libalx-base.so.1 -> libalx-base.so.1.0~b18
    libalx-gsl.so.1 -> libalx-gsl.so.1.0~b18
    libalx-ocr.so.1 -> libalx-ocr.so.1.0~b18
    libalx-ncurses.so.1 -> libalx-ncurses.so.1.0~b18
    libalx-zbar.so.1 -> libalx-zbar.so.1.0~b18
    libalx-plot.so.1 -> libalx-plot.so.1.0~b18
    libalx-curl.so.1 -> libalx-curl.so.1.0~b18
    libalx-robot.so.1 -> libalx-robot.so.1.0~b18
    libalx-data-structures.so.1 -> libalx-data-structures.so.1.0~b18
[...]

但是依赖这个库的程序的编译(实际上链接失败;编译工作)失败(仅适用于某些程序,这使得它更加奇怪)。我使用 pkg-config 文件,所以所有程序中的标志都是完全相同的。

失败不是因为在我的库中找不到符号,而是因为找不到我的库所依赖的其他库的符号,这些符号如下(对于其中一个模块):

$ objdump -x /usr/local/lib/libalx/libalx-cv.so.1
[...]
Dynamic Section:
  NEEDED               libopencv_highgui.so.4.2
  NEEDED               libopencv_videoio.so.4.2
  NEEDED               libopencv_ximgproc.so.4.2
  NEEDED               libopencv_calib3d.so.4.2
  NEEDED               libopencv_imgcodecs.so.4.2
  NEEDED               libopencv_features2d.so.4.2
  NEEDED               libopencv_imgproc.so.4.2
  NEEDED               libopencv_core.so.4.2
  NEEDED               libgsl.so.23
  NEEDED               libstdc++.so.6
  NEEDED               libm.so.6
  NEEDED               libgcc_s.so.1
  NEEDED               libc.so.6
  SONAME               libalx-cv.so.1
[...]

失败:

/usr/bin/ld: /tmp/laundry-symbol-reader.xKItRp.ltrans0.ltrans.o: in function `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<std::allocator<char> >(char const*, std::allocator<char> const&) [clone .constprop.0]':
<artificial>:(.text+0x1ab): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_create(unsigned long&, unsigned long)'
/usr/bin/ld: /tmp/laundry-symbol-reader.xKItRp.ltrans0.ltrans.o: in function `alx_cv_conts_largest_p.constprop.0':
<artificial>:(.text+0x273): undefined reference to `cv::arcLength(cv::_InputArray const&, bool)'
/usr/bin/ld: /tmp/laundry-symbol-reader.xKItRp.ltrans0.ltrans.o: in function `alx_cv_adaptive_thr.constprop.0':
<artificial>:(.text+0x32f): undefined reference to `cv::adaptiveThreshold(cv::_InputArray const&, cv::_OutputArray const&, double, int, int, int, double)'
/usr/bin/ld: /tmp/laundry-symbol-reader.xKItRp.ltrans0.ltrans.o: in function `alx_cv_smooth.constprop.0':
<artificial>:(.text+0x39d): undefined reference to `cv::medianBlur(cv::_InputArray const&, cv::_OutputArray const&, int)'
/usr/bin/ld: /tmp/laundry-symbol-reader.xKItRp.ltrans0.ltrans.o: in function `alx_cv_clone':
<artificial>:(.text+0x3e3): undefined reference to `cv::Mat::copyTo(cv::_OutputArray const&) const'
/usr/bin/ld: /tmp/laundry-symbol-reader.xKItRp.ltrans0.ltrans.o: in function `cv::Mat::release()':
<artificial>:(.text+0x446): undefined reference to `cv::Mat::deallocate()'
/usr/bin/ld: /tmp/laundry-symbol-reader.xKItRp.ltrans0.ltrans.o: in function `cv::Mat::~Mat()':
<artificial>:(.text+0x4c0): undefined reference to `cv::fastFree(void*)'
/usr/bin/ld: <artificial>:(.text+0x4e1): undefined reference to `cv::Mat::deallocate()'
/usr/bin/ld: /tmp/laundry-symbol-reader.xKItRp.ltrans0.ltrans.o: in function `alx_cv_component.constprop.0':
<artificial>:(.text+0x610): undefined reference to `cv::fastFree(void*)'
/usr/bin/ld: <artificial>:(.text+0x647): undefined reference to `cv::Mat::deallocate()'
/usr/bin/ld: <artificial>:(.text+0x65a): undefined reference to `cv::split(cv::Mat const&, cv::Mat*)'
/usr/bin/ld: <artificial>:(.text+0x685): undefined reference to `cv::Mat::copyTo(cv::_OutputArray const&) const'
/usr/bin/ld: <artificial>:(.text+0x701): undefined reference to `cv::Mat::deallocate()'
[...]

pkg-config 文件的一个例子是:

$ cat /usr/local/lib/pkgconfig/libalx-cv.pc 
Name: libalx-cv
Description: The libalx C/C++ library (openCV extension)
URL: https://github.com/alejandro-colomar/libalx
Version: 1.0~b18
Requires:
Requires.private: opencv4 libalx-base libalx-gsl

prefix=/usr/local/
includedir=${prefix}/include/
libdir=${prefix}/lib/

Cflags: -I${includedir} -D_GNU_SOURCE -D_POSIX_C_SOURCE=200809L
Libs: -L${libdir}/libalx/ -lalx-cv
Libs.private: -lm -lstdc++

奇怪的是,它只查找 C++ 符号失败,并查找所有 C 符号。

我发现依赖 C 符号的 C 程序可以编译。

C++ 程序编译。

但是依赖于 C++ 符号的 C 程序会失败。


这样做之后,一切正常,但我不明白为什么:

sudo cp libalx-cv.so.1.0~b18 libalx-cv.so

另一种解决方法是将 pkg-config 中的所有私有库和要求移动到非私有库。但我认为它不应该是必需的。


系统:

$ uname -a
Linux ADY-debian-11 5.4.0-4-amd64 #1 SMP Debian 5.4.19-1 (2020-02-13) x86_64 GNU/Linux

$ cat /etc/os-release 
PRETTY_NAME="Debian GNU/Linux bullseye/sid"
NAME="Debian GNU/Linux"
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

$ gcc --version
gcc (Debian 9.3.0-8) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ ld --version
GNU ld (GNU Binutils for Debian) 2.34
Copyright (C) 2020 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) a later version.
This program has absolutely no warranty.

【问题讨论】:

    标签: gcc linker g++ shared-libraries ld


    【解决方案1】:

    有很多因素结合在一起导致它失败:

    在同一目录中同时存在静态库和共享库,因此由于某种原因,使用新命名时,编译器会忽略新的共享库名称并始终链接到静态库(libalx-cv.so.1.0~b18 链接到 @ 987654322@ 而不是 libalx-base.so.1.0~b18)。

    我在编译库期间创建了软链接,以便链接器可以找到它们:

    libalx-module.so.1
    libalx-module.so
    

    我还在-l alx-base 之前指定了-L$(BUILD_SO_DIR)(之前我不需要,因为某些我不知道的原因)。

    pkg-config 文件中也可能存在问题:存在可能无法正确解释的重复斜杠;比如变量展开后:-L/usr/local//lib//libalx/

    但是,所有这些修复并没有完全修复它,我需要将没有任何版本号的符号链接安装到系统中才能使其正常工作。

    【讨论】:

      猜你喜欢
      • 2020-03-09
      • 2011-07-05
      • 2012-01-15
      • 2013-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多