C++/CMake installable libraries with conflicting .so names

  apt, c++, cmake, linux

I am having issues with conflicting names of libraries in installed c++ packages on a linux system. Both packages are built into installable apt packages using cpack. There are two packages being installed (A and B).
Do note that although I have control over these packages and so I can change the CMake and whatnot, they are to be compiled down into debian packages and installed as system libraries, not installed under /usr/local/.

Each package have their own utils module.
Each module is installed with namespaces of the parent project (so A::utils and B::utils), and the library .so files are in subfolders of the project name, not directly in /usr/lib – so /usr/lib/A/libutils.so and /usr/lib/B/libutils.so.

As a postinstall script, a file with the name of the project (A or B) is added to /etc/ld.so.conf.d that contains the path to the installed library (/usr/lib/A for example) to the library paths.

In addition to utils project A also has a library foo which depends on A::utils

I have a third project C which has an executable which depends upon A::foo, but (as far as I can tell) does not utilize B at all.

When building C I encounter errors stating that there are undefined references. With some further investigation I determined that when C builds and A::foo has to resolve utils it finds B::utils instead of A::utils causing errors. I’m hoping to get some explanation as to why this is happening/how to fix it? It was my understanding that the namespaces (in addition to putting the libraries in subfolders so the files themselves do not conflict) would solve this issue of naming conflicts of libraries.

Below is an example of the install portion of one of the CMakeLists

set(PROJECT_NAME A)
set(component utils)

add_library(${component} SHARED
        src/UtilsExample.cpp
        )
add_library(${PROJECT_NAME}::${component} ALIAS ${component})
#... stuff with the libraries and whatnot
install(TARGETS ${component} EXPORT ${component}Targets
  COMPONENT ${component}
  LIBRARY DESTINATION lib/${PROJECT_NAME}
  ARCHIVE DESTINATION lib/${PROJECT_NAME}
  RUNTIME DESTINATION bin
  )
install(EXPORT ${component}Targets
  FILE "${PROJECT_NAME}-${component}Targets.cmake"
  NAMESPACE ${PROJECT_NAME}::
  DESTINATION lib/cmake/${PROJECT_NAME}
  COMPONENT ${component}
  )

To ensure that the library names are unique, do I need to prepend the project name or something like that? So the library would be named A_utils? This seems like it would make the alias for external projects quite odd, A::A_utils

Source: Windows Questions C++

LEAVE A COMMENT