Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make static imported library dependent on another static imported library in CMake?

Tags:

c++

cmake

I want some parts of my project, which are very rarely changed, to be compiled statically and "installed" in separate directory. It is necessary because due to some specifics of project quite often it must be recompiled from scratch (with removing entire build directory). "Installing" that statically linked libraries in separate directory will allow to significantly reduce building time.

What I had at the beginning. Let's say LibA is changed very rarely and I want it to be installed once and not to be rebuild during most of the project builds. LibA depends on some 3rd party imported library LibC. Project also contains LibB which changes frequently and depends on LibA.

CMakeLists.tst (LibB):
  target_link_libraries("LibB" LibA_build)

CMakeLists.tst (LibA):
  add_library(LibA_build ...)
  add_library(LibC STATIC IMPORTED)
  add_dependencies(LibA_build LibC)

In this case during linking LibB we will have dependencies on LibA and LibC. And every time before building LibB we will rebuild LibA.

To avoid unnecessary rebuilds I made new target "LibA" (not "LibA_build). So now LibB depends on "LibA".

CMakeLists.tst (LibB):
  target_link_libraries("LibB" LibA)

This new target I declared as imported library.

CMakeLists.tst (LibA):
  # This target is for building and installing
  add_library(LibA_build ...)
  SET_TARGET_PROPERTIES(LibA_build PROPERTIES OUTPUT_NAME LibA)
  install(
    FILES /build/path/to/LibA.lib
    DESTINATION /installed/path/to/LibA
  )

  # This target is for linking LibA with another libraries
  add_library(LibA STATIC IMPORTED GLOBAL)
  set_property(TARGET LibA PROPERTY IMPORTED_LOCATION /installed/path/to/LibA)

  add_library(LibC STATIC IMPORTED)
  add_dependencies(LibA LibC)

Result: now before building of LibB we are not rebuilding LibA.

Problem: because now LibA became imported library, CMake refuses to see dependency of LibA on LibC. In fact linking instruction for LibB contains dependency only on LibA, but not on LibC. In case of buildign under Windows it leads to unresolved external linking errors.

Question: How to make static imported library LibA dependent on another static imported library LibC? So in case of linking LibB instruction for linking will contain dependencies on both - LibA and LibC.

P.S. I know this way is not proper way. I used it only because I didn't find any other way. I would really appreciate if you help me to add this dependency on static import library or suggest another way how to rich goal which I described at the begginning.

like image 764
Alex Avatar asked Oct 19 '22 18:10

Alex


1 Answers

The feature which I was looking for (add dependency of static import library on other import libraries) is called transitive linking. It is implemented by setting target property IMPORTED_LINK_INTERFACE_LIBRARIES. They say this property is depricated and recommend using INTERFACE_LINK_LIBRARIES, but in my case (cmake version 2.8.11.2) only IMPORTED_LINK_INTERFACE_LIBRARIES is working.

So for example above the end of CMakeLists.tst for LibA should look like this:

  add_library(LibC STATIC IMPORTED)
  a̶d̶d̶_̶d̶e̶p̶e̶n̶d̶e̶n̶c̶i̶e̶s̶(̶L̶i̶b̶A̶ ̶L̶i̶b̶C̶)̶
  set_property(TARGET LibC PROPERTY IMPORTED_LOCATION /path/to/LibC)

  set_property(TARGET LibA PROPERTY IMPORTED_LINK_INTERFACE_LIBRARIES LibC)

Hope this information will be useful for someone.

like image 148
Alex Avatar answered Nov 01 '22 11:11

Alex