0

I'm trying to build a library (with a xerces dependency) with cmake that will be run in a container that does not have Xerces installed.

add_library(MyLib STATIC <files...>)

I can find similar questions with answers. For example:

and the answers indicate that I CAN do something like:

add_library(xercesc STATIC IMPORTED)
set_target_properties(xercesc PROPERTIES IMPORTED_LOCATION /usr/lib/x86_64-linux-gnu/libxerces-c.a)
set_target_properties(xercesc PROPERTIES INTERFACE_INCLUDE_DIRECTORIES /usr/include)

target_link_libraries(MyLib xercesc)

or maybe just

target_link_libraries(MyLib /usr/lib/x86_64-linux-gnu/libxerces-c.a)

but there's always a reply somewhere that you SHOULDN'T really do it that way, and that the RIGHT way looks more like:

find_package(XercesC 3.2.0 REQUIRED)

target_link_libraries(MyLib PRIVATE XercesC::XercesC)

however that results in an ImportError: libxerces-c-3.2.so: cannot open shared object file: No such file or directory once I try to run in a container without xerces installed.

I think a main part of why the first two methods are discouraged is the hardcoding of the path. find_package(XercesC 3.2.0 REQUIRED) exposes two variables pointing to the .so but none pointing to the .a or folder where they both reside. There's a CMAKE_FIND_LIBRARY_SUFFIXES variable that I could use if find_library worked, but no such thing that applies to find_package.

So ultimately my question is what is the right or idiomatic way to statically import an external library (xerces in this case) with cmake?

Dale
  • 393
  • 1
  • 3
  • 15
  • The error message "ImportError: libxerces-c-3.2.so: cannot open shared object file: No such file or directory" means that your library is linked with **shared** Xerces library, and that library is absent in the container. You could instead link with **static** Xerces library (probably, you need to manually build Xerces library in static variant). Or you could **ship** your library installation with the **shared** Xerces library. It is up to you. – Tsyvarev Oct 26 '21 at 17:02
  • @Tsyvarev Yes like I said I *am* trying to statically link it instead. I have a `.a` of the xerces lib already, installed right next to the `.so`. Unfortunately I'm finding that when I try to link it by manually importing I am ultimately encountering the issue that apparently you can't link a static library to a dynamic one. Shipping the shared xerces library would be an option but only if they didn't have to do extra steps to add it to the LD path – Dale Oct 26 '21 at 17:24
  • 1
    "if they didn't have to do extra steps to add it to the LD path" - In CMake you have control over RPATH embedded into the created libraries/executables. It should eliminate needs to setup LD path on the target machine. See e.g. that wiki: https://gitlab.kitware.com/cmake/community/-/wikis/doc/cmake/RPATH-handling. – Tsyvarev Oct 26 '21 at 18:17
  • @Tsyvarev thanks this got me on the right path. It's led me to another question and maybe you have the answer - if I'm shipping the .so I ideally want to find it without hardcoding its location. `find_package(XercesC 3.2.0 REQUIRED)` gives me `${XercesC_LIBRARY)` which is `libxerces-c.so`, but the library built with `XercesC::XercesC` in `target_link_libraries` is looking for `libxerces-c-3.2.so`. – Dale Oct 26 '21 at 21:53
  • It seems that `libxerces-c.so` is just a **symlink** to `libxerces-c-3.2.so`. For use the library, you need the real library file - `libxerces-c-3.2.so`. – Tsyvarev Oct 26 '21 at 22:00

1 Answers1

0

when the problem was occured, i solved it with two ways:

  1. to run command sudo apt-get install libxerces-c3.2

  2. to download the appropriate installation package from https://pkgs.org/download/libxerces-c3.2 , and then install it.