Hey All -
I'm trying to add a custom command to some targets to copy files using a usage requirements kind of pattern, but I'm running into some limitations in CMake that seem somewhat arbitrary. To set the stage, imagine the following toy example:

DirectoryA's CMakeLists File:
include_directory(B)
include_directory(C)

DirectoryB's CMakeLists File:
add_executable(TestEXE ...)
target_link_libraries(TestEXE PUBLIC TestLibrary)
#for each dependency of TestEXE
    add_custom_command(TARGET TestEXE POST_BUILD ...)
    #for each dependency of the dependency...

DirectoryC's CMakeLists File:
add_library(TestLibrary STATIC ...)
find_packge(SharedLib REQUIRED)
target_link_libraries(TestLibrary PUBLIC TestSharedLib::TestSharedLib)

Somewhere in the SharedLib find module:
add_library(TestSharedLib::TestSharedLib SHARED IMPORTED) #A library with a dll component that must be copied set_property(TARGET TestSharedLib::TestSharedLib PROPERTY IMPORTED_LOCATION path/to/my/library.dll)

Things I tried:
-Iterate over all the target's link libraries, and for every dependant shared library target, add a custom command to copy the dll. This failed because at the point of DirectoryB, it may be that there are dependencies (such as TestLibrary in the above example) which are not yet defined. One could impose a strict ordering requirement, but nothing else in CMake (AFIK) imposes such a requirement. -Add a resolve_dependencies() function call after each library is declared, or just once at the very end of the root cmakelists file. Using a global property, it keeps track of all exe targets which want dll's copied and traverses that list, adding copy commands to targets that depend on the newly declared library. Fails because you cannot call add_custom_command on a target outside of it's declaration file. Also crappy because it imposes a requirement on the user to call said function. -As above, but make the custom command reference a property on the target in a generator expression, then append any files that need copying to that property. So far the most workable, but the property cannot contain generator expressions which may present a problem.

The core of the problem is that within the directory where the exe is defined, TestLibrary is unknown, and in DirectoryC or even DirectoryA, I cannot call add_custom_command on the TestEXE due to an arbitrary limitation cmake imposes (the target is defined, you can edit it, but you can't add commands to it. This means that I can't look up any property of TestLibrary to discover it's dependencies, and I can't find out that it depends on TestSharedLib, which references a .dll file I want to copy into TestEXE's TARGET_DIR. What I *can* do is make the TestEXE's custom command reference a property on TestEXE in a generator expression to get the list of dlls it depends on, but that property cannot itself contain any generator expressions (as would be ideal to deal with differing dlls for debug and release mode or the like). As it stands, I have something that kinda works, but feels kinda ugly. Any one of several different things would give me the functionality I need. In order of usefulness:

1) Allow recursive generator expression resolution: $<TARGET_PROPERTY:tgt,MY_PROP> where MY_PROP=$<$<CONFIG:DEBUG>:mything_d.dll>$<$<CONFIG:RELEASE>:mything.dll>. I cannot tell you how many headaches this kind of functionality would save me and unless I'm very mistaken I don't think it would involve very much work. 2) Generic support for INTERFACE_* properties. Only kinda works, since you can't link with MODULE libraries, which contain .dll files I'd want to copy. Could be exposed by an extra argument in define_property() Definitely a crappier version of 1, since with 1 I could just append $<TARGET_PROPERTY:dependency,MY_PROP> to MY_PROP on the original target. 3) Allow add_custom_command wherever the target is defined. If you can get and set properties on it, it seems weird that you can't do this. 4) Make custom commands inheritable as usage requirements. This would be very weird, but would get the job done.

If anyone has any other ideas or feedback, it would be very welcome. I'd be very, very interested in seeing 1) make it into a future cmake release regardless though.
--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more 
information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake

Reply via email to