简体   繁体   中英

CMake dependencies and Dll copies

I did wrote some CMake code to transitively get all library dependencies of a given executable target and copy dlls next to it (yes Windows World)

Then I got an external library that does not support CMake. That have a single implib lets call it a.lib with an a.dll, this library also depends on another dll without any available implib (b.dll)

So I wrote a aConfig.cmake like this:

set(a_FOUND TRUE)

add_library(a SHARED IMPORTED)
set_target_properties(a PROPERTIES
    IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
    IMPORTED_LOCATION "${a_DIR}/bin/a.dll"
    IMPORTED_IMPLIB "${a_DIR}/lib/a.lib"
)

add_library(b SHARED IMPORTED)
set_target_properties(b PROPERTIES
    IMPORTED_LOCATION "${a_DIR}/bin/b.dll"
)

# to express a dependency without requiring implib at link time
target_link_library(a PRIVATE b)

I end up with this (expected) error

IMPORTED library can only be used with the INTERFACE keyword of
  target_link_libraries

Then I modified b to become an INTERFACE (It feels strange here):

add_library(b INTERFACE IMPORTED)
set_target_properties(b PROPERTIES
    IMPORTED_LOCATION "${a_DIR}/bin/b.dll"
)
target_link_library(a INTERFACE b)

with CMake 3.18 my transitive loop does not want to ask for an IMPORTED_LOCATION on an INTERFACE

  INTERFACE_LIBRARY targets may only have whitelisted properties.  The
  property "IMPORTED_LOCATION" is not allowed.

but with CMake 3.19 it works and do exactly what I am expecting. So I read the Release Note and except this statement :

Interface Libraries may now have source files added via add_library() or target_sources(). Those with sources will be generated as part of the build system.

nothing seems related to this.

Since I found the CMake 3.18 error, I feel that what I am doing is wrong but I cannot find a better way to express this runtime dependency.

Does anyone have a better idea on how to express this dependency or does it feels right like this?

In CMake 3.19 and after you could create b target for a dll without a lib in a single line:

add_library(b INTERFACE "${a_DIR}/bin/b.dll")

So when you link a with b , a will get a dependency from the file ${a_DIR}/bin/b.dll .

This is what CMake 3.19 introduces: a dependency of INTERFACE library from the file.

For implement that dependency in CMake pre-3.19, one need to create additional custom target:

add_custom_target(b_files DEPENDS "${a_DIR}/bin/b.dll")

add_library(b INTERFACE)
add_dependencies(b b_files)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM