1

Description

I have the following problem:

  • I am developing the library libmy_code.so

  • I need to link against a closed source library libclosed_source.so over which I have no control

  • libclosed_source.so is statically linked against opencv 3.2.0

  • libclosed_source.so has exported all symbols (also those from opencv 3.2.0 which I do not want)

  • My library libmy_code.so also needs the newer version opencv 3.4.11

  • I use CMake as the build system

See the following diagram



                                           +-------------+
                                      +--->|libmy_code.so+<-------+
                                      |    +-------------+        |
                                      |                           |
                    Statically linked |                           |dynamically linked
                                      |                           |
                                      |                           |
                                      |                           |
                                      |                           |
                                      |                   +-------+-----------+
                                      |                   |libclosed_source.so|
                                      |                   +-------------------+
                                      |                           ^
                                      |                           | Statically linked
                                      |                           |
                                  +---+---------+           +-----+------+
                                  |OpenCV 3.4.11|           |Opencv 3.2.0|
                                  +-------------+           +------------+

Problem

  • My library libmy_code.so uses cv::resize. The CMake build system correctly locates cv::resize in the headers of OpenCV 3.4.11 (I use find_package(OpenCV) and point it to the opencv 3.4.11 install).

  • However the linker links cv::resize to libclosed_source.so (which contains the Opencv3.2.0 version of cv::resize statically).

  • My build system runs in a docker container which definitely does not have opencv 3.2.0.

  • The closest question I have found is this

How can I tell the linker not to linker opencv functions libmy_code.so to libclosed_source.so but directly to Opencv 3.4.11 ??

  • 1
    If you're using CMake you can use HINTS to direct it to pick a specific location when importing a library - see https://stackoverflow.com/questions/12075371/cmake-find-library-custom-library-location – Den-Jason Nov 18 '20 at 10:59
  • 1
    Similar problem solved, see https://stackoverflow.com/questions/21783761/how-do-i-link-different-versions-of-the-same-library-in-g?rq=1 – Milind Deore Nov 18 '20 at 11:07
  • @Den-Jason I only have OpenCV 3.4.11 in the build container. OpenCV 3.2 enters in by being statically linked to libclosed_source.so. Will HINTS still work?? – Gerald Mwangi Nov 18 '20 at 11:12
  • 1
    @MilindDeore Thanks this looks good – Gerald Mwangi Nov 18 '20 at 11:13
  • 1
    Does this answer your question? [How do I link different versions of the same library in g++?](https://stackoverflow.com/questions/21783761/how-do-i-link-different-versions-of-the-same-library-in-g) – Adrian Mole Nov 18 '20 at 11:33
  • @AdrianMole : Sorry for the late answer. The suggested link from @Milind Deore didn't help, I got `ld --relocatable -o libclosed-source-prelinked.so libclosed-source.so ../../opencv-3.2.0/lib/libopencv_core.a ld: attempted static link of dynamic object ` libclosed-source.so'` – Gerald Mwangi Jul 02 '21 at 11:32

1 Answers1

2

Solution

My solution to the problem is to load libclosed_source.so dynamically per dlopen with RTLD_DEEPBIND|RTLD_LOCAL into libmy_code.so. This way libmy_code.so can use opencv 3.4.11 and libclosed_source.so can still use opencv 3.2.0.

The executable that was linked against libmy_code.so had to be compiled with -fPIC to prevent problems with libstdc++, more to that in Weird interaction of RTLD_DEEPBIND, Position independent Code (PIC) and C++ STL (std::cout)