9

My target linked with several libraries using TARGET_LINK_LIBRARIES with PUBLIC keyword, The INSTALL command looks like INSTALL(TARGETS foo DESTINATION ${CMAKE_INSTALL_PREFIX}/bin). I want somehow to force the cmake to include all (preferably excluding system libraries) libraries (SOs only) I link with to be included in the installation process. I've tried EXPORT keyword but looks like it affects only libraries which I build with in my project and marked with the same EXPORT as foo library.
Is it possible?
EDIT001: Additional information that may affect answer. I'm using vcpkg to manage third parties. So the TARGET_LINK_LIBRARIES looks like

TARGET_LINK_LIBRARIES(foo PUBLIC
                      GTest::GTest
                      GTest::Main
                      ${GOOGLE_MOCK}
                      event
                      ${THRIFT_LIBRARIES}
                      ${Boost_LIBRARIES}
                      lzo2
                      sqlite3
                      ${ZeroMQ_LIBRARY}
                      gRPC::grpc
                      gRPC::grpc++
                      xml2
                      stdc++fs
                      bfd
                      -l:libisal.so.2
                      sgutils2
                      pthread
                      uuid
                      rt
                      )

So, essentially what I want to achieve is to take all these libraries which are macro'ed by vcpkg, like ${THRIFT_LIBRARIES}, ${Boost_LIBRARIES} and gRPC::grpc and so on

kreuzerkrieg
  • 3,009
  • 3
  • 28
  • 59
  • You need to list everything you need to install separately. AFAIK, CMake doesn't make any analysis which will automagically install all the dependencies. Besides, you have only one target: `foo` and the command install *targets*. Of course, there are other install commands but they aren't close to the `TARGET_LINK_LIBRARIES` command either. – ixSci Aug 30 '18 at 14:30
  • if there is no other option it sounds good enough, other question is, can I access all dependencies added via `target_link_libraries` as they generated into `make` files, since it already has full path to the SO – kreuzerkrieg Aug 30 '18 at 14:38

2 Answers2

6

As of cmake 3.21, you can now do with:

install(IMPORTED_RUNTIME_ARTIFACTS gRPC::grpc)
install(IMPORTED_RUNTIME_ARTIFACTS ${Boost_LIBRARIES})

etc.

See new Install command.

Steve Broberg
  • 4,255
  • 3
  • 28
  • 40
  • 4
    I've tried to do this with spdlog by doing: `install(IMPORTED_RUNTIME_ARTIFACTS spdlog::spdlog)`, however, I get the message: "install IMPORTED_RUNTIME_ARTIFACTS given target "spdlog::spdlog" which is not an executable, library, or module." Like the OP I'm using vcpkg and importing spdlog using find_package. Any ideas? – Anthony Calandra Jul 28 '21 at 21:20
  • @anthony-calandra: I'm not familiar with spdlog, but doing an "apt search" on it says that it's a header-only library. So there shouldn't be any runtime artifacts that you need to install. – Steve Broberg Aug 04 '21 at 19:18
  • I think they are working on this bug you mentioned @Antony Calandra. https://gitlab.kitware.com/cmake/cmake/-/issues/22406 They didn't anticipate people using it in this fashion when they wrote it. But the users think otherwise. To be short: cmake doesn't know whether the lib is .so or .a. – hasdrubal Oct 03 '21 at 18:32
4

CMake itself does not allow to install dependencies automatically. This would be a rather hard task, because it would have to consider a lot of corner cases.

Just think of transitive dependencies (I don't know if this is the right word), like: Your libA depends on libB, which depends on libC. How should CMake get this from the CMakeLists, where only libB is listed?

Or: What do you consider a system library? Everything that is not in PATH? How do you know which libraries are installed system-wide on the client's machine?

You see, there are some really tricky things to consider.

Here are some possibilities you have:

  • Ask your users to install the dependencies.
  • Statically link libraries into your binary.
  • Copy library files using install(FILES files... DESTINATION <dir>). Maybe your dependency manager can help creating the list of files.
  • Write a script that does something like windeployqt for Qt-based applications on Windows: Analyze the binary file (e.g. using ldd myApp) and automatically copy over the required dependencies.
Stanley F.
  • 1,846
  • 16
  • 29
  • you definitely right about corner cases, but your item three nails the point, give me the list of stuff my library linked with and I will pick whatever needed from this list. Unfortunately, I didnt find way to get aforementioned list – kreuzerkrieg Aug 31 '18 at 17:01