[CMake] DLL handling under CMake
Louis-Paul CORDIER
lp.cordier at dynamixyz.com
Mon Jul 17 04:41:13 EDT 2017
Hi,
I bump this question again for DLL library handling. Still I have the
issue with my dependency "scanner" in my previous email that can't
evaluate if a target with a generator expression is a valid one or not.
if(NOT TARGET "$<$<CONFIG:Release_Production>:Foo_lib>")
# will never go into this statement
endif()
Thanks,
LP
Le 04/07/2017 à 10:19, Louis-Paul CORDIER a écrit :
>
> Hi,
>
> Thank you very much for this code snippet. However I don't like the
> fixup_bundle function, as it takes the first dll that it found to be
> linked against.
>
> I also did a try with a dependency scanning function. It is quiet long
> to write, but I guess it is the cleanest way to handle DLL under Windows.
> Note: I still have an issue with this function. Indeed, if user uses
> Generator expressions for library dependencies, it will not work.
> e.g:
> add_library(Foo_lib IMPORTED GLOBAL)
> # ... set location properties
> target_link_libraries(${PROJECT_NAME} optimized
> $<$<CONFIG:Release_Production>:Foo_lib>)
>
> Any idea for a workaround? What do you think about this CMake code?
>
> Also, I would see a real benefit to add a LINK_DEPENDENT_LIBRARIES
> property (inspired of IMPORTED_LINK_DEPENDENT_LIBRARIES) to each
> target that could be automatically filled by each
> target_link_libraries() calls.
>
>
>
> # This function scan all dependencies of a project recursively, and
> retrieve all shared
> # library associated with it.
> # Prerequisite: your upstream CMakeLists.txt must make use of
> add_library(foo SHARED IMPORTED GLOBAL),
> # and fill the following properties on the imported target:
> # set_target_properties(foo PROPERTIES IMPORTED_IMPLIB "path_to_foo.lib")
> # set_target_properties(foo PROPERTIES IMPORTED_LOCATION
> "path_to_foo.dll")
> # set_target_properties(foo PROPERTIES
> IMPORTED_LINK_DEPENDENT_LIBRARIES "path_to_dll_on_which_foo_depends.dll")
> # GLOBAL keyword is important as it allows downstream CMakeLists.txt
> to scan dependencies.
>
> # Input parameters:
> # dep_to_scan: your downstream project
> # config_to_scan: configuration to use for the scanning.
> # output_variable: variable in which the function stores the result.
>
> # Usage:
> # RECURSIVE_SCAN(my_app Release DLLS)
> # install(FILES ${DLLS}
> # DESTINATION release
> # CONFIGURATIONS Release)
>
> set(COUNT 0)
> function(RECURSIVE_SCAN dep_to_scan config_to_scan output_variable)
>
> MATH(EXPR COUNT "${COUNT}+1")
> string(RANDOM LENGTH ${COUNT} ALPHABET "-" SPACES)
>
> message("${SPACES} Scanning ${dep_to_scan}")
> if(NOT TARGET ${dep_to_scan})
> MATH(EXPR COUNT "${COUNT}-1")
> #message("${dep_to_scan} Is not target")
> return()
> endif()
>
>
> get_target_property(_is_imported ${dep_to_scan} IMPORTED)
> if(_is_imported)
>
> # We need to check if the imported library rely on other shared
> libraries.
> get_target_property(_dependent_dll ${_lib}
> IMPORTED_LINK_DEPENDENT_LIBRARIES_${config_to_scan})
> if(NOT _dependent_dll)
> get_target_property(_dependent_dll ${_lib}
> IMPORTED_LINK_DEPENDENT_LIBRARIES)
> endif()
>
> if(_dependent_dll)
> list(APPEND ${output_variable} ${_dependent_dll})
> endif()
>
>
> #Otherwise, check if it is a shared library. (LOCATION variable
> can be
> # either .lib or DLL regarding of the type of library.)
> get_target_property(_TYPE ${dep_to_scan} TYPE)
>
> if(NOT _TYPE STREQUAL STATIC_LIBRARY)
> get_target_property(_dll_found ${dep_to_scan}
> LOCATION_${config_to_scan})
> if(_dll_found)
> list(APPEND ${output_variable} ${_dll_found})
> endif()
>
> endif()
>
> message("${SPACES}- DLL found: (${${output_variable}})")
>
> endif(_is_imported)
>
> get_target_property(_libraries ${dep_to_scan} INTERFACE_LINK_LIBRARIES)
>
> if(_libraries)
> foreach(_lib ${_libraries})
> RECURSIVE_SCAN(${_lib} ${config_to_scan} ${output_variable})
> endforeach()
> endif()
>
> # If we reach our first recursion, we need to clean the list of
> # DLL in order to remove duplicates.
> MATH(EXPR COUNT "${COUNT}-1")
>
> if(${COUNT} EQUAL 0)
> list(REMOVE_DUPLICATES ${output_variable})
> endif()
>
> set(${output_variable} ${${output_variable}} PARENT_SCOPE)
>
> endfunction(RECURSIVE_SCAN)
>
>
> Best regards,
>
> Louis-Paul CORDIER
>
> Le 04/05/2017 à 09:51, lectem at gmail.com a écrit :
>>
>> I managed to get it working by using an intermediate script.
>>
>> One might want to generate the script instead of using the « RUN_IT »
>> variable trick.
>>
>> This was only tested on Windows, but seems to work fine.
>>
>> Put the following code in a xxxxxx.cmake file, include it from your
>> CMakeLists.txt and enjoy.
>>
>> # This is a helper script to run BundleUtilities fixup_bundle as
>> postbuild
>>
>> # for a target. The primary use case is to copy .DLLs to the build
>> directory for
>>
>> # the Windows platform. It allows generator expressions to be used to
>> determine
>>
>> # the binary location
>>
>> #
>>
>> # Usage : run_fixup(TARGET LIBS DIRS)
>>
>> # - TARGET : A cmake target
>>
>> # - See fixup_bundle for LIBS and DIRS arguments
>>
>> if(RUN_IT)
>>
>> # Script ran by the add_custom_command
>>
>> include(BundleUtilities)
>>
>> fixup_bundle("${TO_FIXUP_FILE}" "${TO_FIXUP_LIBS}" "${TO_FIXUP_DIRS}")
>>
>> # End of script ran by the add_custom_command
>>
>> else()
>>
>> set(THIS_FILE ${CMAKE_CURRENT_LIST_FILE})
>>
>> message(${THIS_FILE})
>>
>> function(run_fixup _target _libs _dirs)
>>
>> message(${THIS_FILE})
>>
>> add_custom_command(
>>
>> TARGET ${_target} POST_BUILD
>>
>> COMMAND ${CMAKE_COMMAND}
>> -DRUN_IT:BOOL=ON -DTO_FIXUP_FILE=$<TARGET_FILE:${_target}>
>> -DTO_FIXUP_LIBS=${_libs} -DTO_FIXUP_DIRS=${_dirs} -P ${THIS_FILE}
>>
>> COMMENT "Fixing up dependencies for
>> ${_target}"
>>
>> VERBATIM
>>
>> )
>>
>> endfunction()
>>
>> endif()
>>
>> *De : *Clément Gregoire <mailto:lectem at gmail.com>
>> *Envoyé le :*jeudi 4 mai 2017 08:37
>> *À : *Hendrik Sattler <mailto:post at hendrik-sattler.de>; Louis-Paul
>> CORDIER <mailto:lp.cordier at dynamixyz.com>; Cmake Mailing List
>> <mailto:cmake at cmake.org>
>> *Objet :*Re: [CMake] DLL handling under CMake
>>
>> I'd also be interested in this. I saw an old mail in the ML about
>> this, but it seems fixup_bundle is old and cant use generator
>> expressions, making it hard to use (I don't want to hardcode the
>> executable path).
>>
>> Do you have a sample for this ?
>>
>> CMake would really benefit from having those features made more
>> accessible instead of everyone having to write its own script
>>
>> Le sam. 29 avr. 2017 22:10, Hendrik Sattler <post at hendrik-sattler.de
>> <mailto:post at hendrik-sattler.de>> a écrit :
>>
>>
>>
>> Am 27. April 2017 10:43:50 MESZ schrieb Louis-Paul CORDIER
>> <lp.cordier at dynamixyz.com <mailto:lp.cordier at dynamixyz.com>>:
>> >This steps are tedious and I'm wondering if there is a mechanism that
>> >exists or that have to be imagined to make the DLL nightmare end.
>>
>> I use BundleUtilities to achieve the copying of DLL files to the
>> installation directory. The main problem for this is to enumerate the
>> needed directories.
>>
>> I use the same for copying DLL files to the output directory to ease
>> debugging.
>>
>> The advantage is the inspection of the exe for really needed DLL
>> files. This AUTOMATICALLY handles the case debug vs. release.
>>
>> HS
>>
>> --
>> Diese Nachricht wurde von meinem Android-Mobiltelefon mit K-9 Mail
>> gesendet.
>> --
>>
>> Powered by www.kitware.com <http://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
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/cmake/attachments/20170717/f60c65be/attachment.html>
More information about the CMake
mailing list