I have a library which until now I compiled into objects of this form:
libalx-module.so
I didn't even know about soname and all that stuff, so I kept it simple. Everything worked.
Now I moved to this scheme (the version right now is 1.0~b18
):
libalx-module.so.1.0~b18libalx-module.so.1 # which is a symlink to the above file
As you can see there's no /^*.so$/
file; al files have something after .so
The linker supposedly knows about them:
$ ls -l /usr/local/lib/libalx/total 4000-rw-r--r-- 1 root root 1174626 Apr 9 10:55 libalx-base.alrwxrwxrwx 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.alrwxrwxrwx 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.alrwxrwxrwx 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.alrwxrwxrwx 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.alrwxrwxrwx 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.alrwxrwxrwx 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.alrwxrwxrwx 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.alrwxrwxrwx 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.alrwxrwxrwx 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.alrwxrwxrwx 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.alrwxrwxrwx 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.alrwxrwxrwx 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~b18drwxr-xr-x 2 root root 4096 Apr 9 10:55 pydrwxr-xr-x 2 root root 4096 Apr 9 10:55 sh
$ sudo ldconfig -vldconfig: Can't stat /usr/local/lib/x86_64-linux-gnu: No such file or directoryldconfig: Path `/usr/lib/x86_64-linux-gnu' given more than onceldconfig: Path `/lib/x86_64-linux-gnu' given more than onceldconfig: Path `/usr/lib/x86_64-linux-gnu' given more than onceldconfig: 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[...]
But compilation (actually linkage fails; compilation works) of programs that depend on this library fails (only for some programs, which makes it even weirder). I use pkg-config files, so the flags in all programs are exactly the same.
It fails not by not finding the symbols in my library, but by not finding the symbols of other libraries which my library depends on, which are the following (for one of the modules):
$ 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[...]
The failure:
/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()'[...]
An example of pkg-config file is:
$ cat /usr/local/lib/pkgconfig/libalx-cv.pc Name: libalx-cvDescription: The libalx C/C++ library (openCV extension)URL: https://github.com/alejandro-colomar/libalxVersion: 1.0~b18Requires:Requires.private: opencv4 libalx-base libalx-gslprefix=/usr/local/includedir=${prefix}/include/libdir=${prefix}/lib/Cflags: -I${includedir} -D_GNU_SOURCE -D_POSIX_C_SOURCE=200809LLibs: -L${libdir}/libalx/ -lalx-cvLibs.private: -lm -lstdc++
It's curious that it only fails finding C++ symbols, and finds all C symbols.
I found out that C programs that depend on C symbols compile.
C++ programs compile.
But C programs that depend on C++ symbols fail.
After doing this, everything works, but I don't understand why:
sudo cp libalx-cv.so.1.0~b18 libalx-cv.so
Another workaround is to move all private libs and requires in the pkg-config to the non-private ones. But I think it shouldn't be needed.
System:
$ uname -aLinux 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=debianHOME_URL="https://www.debian.org/"SUPPORT_URL="https://www.debian.org/support"BUG_REPORT_URL="https://bugs.debian.org/"$ gcc --versiongcc (Debian 9.3.0-8) 9.3.0Copyright (C) 2019 Free Software Foundation, Inc.This is free software; see the source for copying conditions. There is NOwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.$ ld --versionGNU ld (GNU Binutils for Debian) 2.34Copyright (C) 2020 Free Software Foundation, Inc.This program is free software; you may redistribute it under the terms ofthe GNU General Public License version 3 or (at your option) a later version.This program has absolutely no warranty.