<p dir="ltr">Sorry for not answering before, cmake generator expressions do not work with "if". It mostly only work with target_*** stuff. <br>
That's why I'm using a custom target to evaluate the current target properties and run a cmake script with those values. </p>
<br><div class="gmail_quote"><div dir="ltr">Le lun. 17 juil. 2017 à 10:47, Louis-Paul CORDIER <<a href="mailto:lp.cordier@dynamixyz.com">lp.cordier@dynamixyz.com</a>> a écrit :<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
  
    
  
  <div text="#000000" bgcolor="#FFFFFF">
    <p>Hi,</p>
    <p>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.<br>
    </p>
    <p>if(NOT TARGET
      "$<$<CONFIG:Release_Production>:Foo_lib>")<br>
        # will never go into this statement<br>
      endif()<br>
    </p>
    <p>Thanks,</p>
    <p>LP<br>
    </p></div><div text="#000000" bgcolor="#FFFFFF">
    <div class="m_-2928018823100871751moz-cite-prefix">Le 04/07/2017 à 10:19, Louis-Paul
      CORDIER a écrit :<br>
    </div>
    <blockquote type="cite">
      
      <p>Hi,</p>
      <p>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.<br>
      </p>
      <p>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.<br>
        Note: I still have an issue with this function. Indeed, if user
        uses Generator expressions for library dependencies, it will not
        work.<br>
        e.g:<br>
        add_library(Foo_lib IMPORTED GLOBAL)<br>
        # ... set location properties<br>
        target_link_libraries(${PROJECT_NAME} optimized
        $<$<CONFIG:Release_Production>:Foo_lib>)</p>
      <p>Any idea for a workaround? What do you think about this CMake
        code?</p>
      <p>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.<br>
      </p>
      <p><br>
      </p>
      <p><br>
      </p>
      <p># This function scan all dependencies of a project recursively,
        and retrieve all shared<br>
        # library associated with it.<br>
        # Prerequisite: your upstream CMakeLists.txt must make use of
        add_library(foo SHARED IMPORTED GLOBAL),<br>
        # and fill the following properties on the imported target:<br>
        # set_target_properties(foo PROPERTIES IMPORTED_IMPLIB
        "path_to_foo.lib")<br>
        # set_target_properties(foo PROPERTIES IMPORTED_LOCATION
        "path_to_foo.dll")<br>
        # set_target_properties(foo PROPERTIES
        IMPORTED_LINK_DEPENDENT_LIBRARIES
        "path_to_dll_on_which_foo_depends.dll")<br>
        # GLOBAL keyword is important as it allows downstream
        CMakeLists.txt to scan dependencies.</p>
      <p># Input parameters:<br>
        # dep_to_scan: your downstream project<br>
        # config_to_scan: configuration to use for the scanning.<br>
        # output_variable: variable in which the function stores the
        result.<br>
        <br>
        # Usage: <br>
        # RECURSIVE_SCAN(my_app Release DLLS)<br>
        #  install(FILES ${DLLS}<br>
        #     DESTINATION release    <br>
        #     CONFIGURATIONS Release)<br>
      </p>
      <p>set(COUNT 0)<br>
        function(RECURSIVE_SCAN dep_to_scan config_to_scan
        output_variable)<br>
        <br>
          MATH(EXPR COUNT "${COUNT}+1")<br>
          string(RANDOM LENGTH ${COUNT} ALPHABET "-" SPACES)<br>
          <br>
          message("${SPACES} Scanning ${dep_to_scan}")<br>
          if(NOT TARGET ${dep_to_scan})<br>
            MATH(EXPR COUNT "${COUNT}-1")<br>
            #message("${dep_to_scan} Is not target")<br>
            return()<br>
          endif()<br>
          <br>
          <br>
          get_target_property(_is_imported ${dep_to_scan} IMPORTED)<br>
          if(_is_imported)<br>
          <br>
            # We need to check if the imported library rely on other
        shared libraries.<br>
            get_target_property(_dependent_dll ${_lib}
        IMPORTED_LINK_DEPENDENT_LIBRARIES_${config_to_scan})<br>
            if(NOT _dependent_dll)<br>
              get_target_property(_dependent_dll ${_lib}
        IMPORTED_LINK_DEPENDENT_LIBRARIES)<br>
            endif()<br>
            <br>
            if(_dependent_dll)<br>
              list(APPEND ${output_variable} ${_dependent_dll})<br>
            endif()<br>
            <br>
            <br>
            #Otherwise, check if it is a shared library. (LOCATION
        variable can be <br>
            # either .lib or DLL regarding of the type of library.)<br>
            get_target_property(_TYPE ${dep_to_scan} TYPE)<br>
            <br>
            if(NOT _TYPE STREQUAL STATIC_LIBRARY)<br>
              get_target_property(_dll_found ${dep_to_scan}
        LOCATION_${config_to_scan})    <br>
              if(_dll_found)<br>
                list(APPEND ${output_variable} ${_dll_found})<br>
              endif()<br>
              <br>
            endif()<br>
            <br>
            message("${SPACES}- DLL found: (${${output_variable}})")<br>
            <br>
          endif(_is_imported)<br>
          <br>
          get_target_property(_libraries ${dep_to_scan}
        INTERFACE_LINK_LIBRARIES)<br>
          <br>
          if(_libraries)<br>
              foreach(_lib ${_libraries})<br>
                RECURSIVE_SCAN(${_lib} ${config_to_scan}
        ${output_variable})<br>
              endforeach()<br>
          endif()<br>
          <br>
          # If we reach our first recursion, we need to clean the list
        of<br>
          # DLL in order to remove duplicates.<br>
          MATH(EXPR COUNT "${COUNT}-1")<br>
          <br>
          if(${COUNT} EQUAL 0)<br>
            list(REMOVE_DUPLICATES ${output_variable})<br>
          endif()<br>
          <br>
          set(${output_variable} ${${output_variable}} PARENT_SCOPE)<br>
        <br>
        endfunction(RECURSIVE_SCAN)<br>
      </p>
      <p><br>
      </p>
      <p>Best regards,</p>
      <p>Louis-Paul CORDIER<br>
      </p>
      <div class="m_-2928018823100871751moz-cite-prefix">Le 04/05/2017 à 09:51, <a class="m_-2928018823100871751moz-txt-link-abbreviated" href="mailto:lectem@gmail.com" target="_blank">lectem@gmail.com</a>
        a écrit :<br>
      </div>
      <blockquote type="cite">
        
        
        
        <div class="m_-2928018823100871751WordSection1">
          <p class="MsoNormal">I managed to get it working by using an
            intermediate script.</p>
          <p class="MsoNormal">One might want to generate the script
            instead of using the « RUN_IT » variable trick.</p>
          <p class="MsoNormal">This was only tested on Windows, but
            seems to work fine.</p>
          <p class="MsoNormal">Put the following code in a xxxxxx.cmake
            file, include it from your CMakeLists.txt and enjoy.</p>
          <p class="MsoNormal"><u></u> <u></u></p>
          <p class="MsoNormal"><u></u> <u></u></p>
          <p class="MsoNormal"># This is a helper script to run
            BundleUtilities fixup_bundle as postbuild</p>
          <p class="MsoNormal"># for a target. The primary use case is
            to copy .DLLs to the build directory for</p>
          <p class="MsoNormal"># the Windows platform. It allows
            generator expressions to be used to determine</p>
          <p class="MsoNormal"># the binary location</p>
          <p class="MsoNormal">#</p>
          <p class="MsoNormal"># Usage : run_fixup(TARGET LIBS DIRS)</p>
          <p class="MsoNormal"># - TARGET : A cmake target</p>
          <p class="MsoNormal"># - See fixup_bundle for LIBS and DIRS
            arguments</p>
          <p class="MsoNormal"><u></u> <u></u></p>
          <p class="MsoNormal">if(RUN_IT)</p>
          <p class="MsoNormal"># Script ran by the add_custom_command</p>
          <p class="MsoNormal">                include(BundleUtilities)</p>
          <p class="MsoNormal">               
            fixup_bundle("${TO_FIXUP_FILE}" "${TO_FIXUP_LIBS}"
            "${TO_FIXUP_DIRS}")</p>
          <p class="MsoNormal"># End of script ran by the
            add_custom_command</p>
          <p class="MsoNormal">else()</p>
          <p class="MsoNormal"><u></u> <u></u></p>
          <p class="MsoNormal">set(THIS_FILE ${CMAKE_CURRENT_LIST_FILE})</p>
          <p class="MsoNormal">message(${THIS_FILE})</p>
          <p class="MsoNormal">function(run_fixup _target _libs _dirs)</p>
          <p class="MsoNormal">                message(${THIS_FILE})</p>
          <p class="MsoNormal">                add_custom_command(</p>
          <p class="MsoNormal">                               TARGET
            ${_target} POST_BUILD</p>
          <p class="MsoNormal">                               COMMAND
            ${CMAKE_COMMAND} -DRUN_IT:BOOL=ON
            -DTO_FIXUP_FILE=$<TARGET_<a class="m_-2928018823100871751moz-txt-link-freetext">FILE:$</a>{_target}>
            -DTO_FIXUP_LIBS=${_libs} -DTO_FIXUP_DIRS=${_dirs}  -P
            ${THIS_FILE}</p>
          <p class="MsoNormal">                               COMMENT
            "Fixing up dependencies for ${_target}"</p>
          <p class="MsoNormal">                               VERBATIM</p>
          <p class="MsoNormal">                )</p>
          <p class="MsoNormal"><u></u> <u></u></p>
          <p class="MsoNormal">endfunction()</p>
          <p class="MsoNormal"><u></u> <u></u></p>
          <p class="MsoNormal">endif()</p>
          <p class="MsoNormal"><u></u> <u></u></p>
          <p class="MsoNormal"><u></u> <u></u></p>
          <div style="border:none;border-top:solid #e1e1e1 1.0pt;padding:3.0pt 0cm 0cm 0cm">
            <p class="MsoNormal" style="border:none;padding:0cm"><b>De :
              </b><a href="mailto:lectem@gmail.com" target="_blank">Clément Gregoire</a><br>
              <b>Envoyé le :</b>jeudi 4 mai 2017 08:37<br>
              <b>À : </b><a href="mailto:post@hendrik-sattler.de" target="_blank">Hendrik Sattler</a>; <a href="mailto:lp.cordier@dynamixyz.com" target="_blank">Louis-Paul CORDIER</a>; <a href="mailto:cmake@cmake.org" target="_blank">Cmake
                Mailing List</a><br>
              <b>Objet :</b>Re: [CMake] DLL handling under CMake</p>
          </div>
          <p class="MsoNormal"><u></u> <u></u></p>
          <p class="MsoNormal">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).<u></u><u></u></p>
          <div>
            <p class="MsoNormal"><u></u> <u></u></p>
          </div>
          <div>
            <p class="MsoNormal">Do you have a sample for this ?</p>
          </div>
          <div>
            <p class="MsoNormal" style="margin-bottom:12.0pt">CMake
              would really benefit from having those features made more
              accessible instead of everyone having to write its own
              script </p>
            <div>
              <div>
                <p class="MsoNormal">Le sam. 29 avr. 2017 22:10, Hendrik
                  Sattler <<a href="mailto:post@hendrik-sattler.de" target="_blank">post@hendrik-sattler.de</a>>
                  a écrit :</p>
              </div>
            </div>
          </div>
          <p class="MsoNormal" style="margin-left:4.8pt"><br>
            <br>
            Am 27. April 2017 10:43:50 MESZ schrieb Louis-Paul CORDIER
            <<a href="mailto:lp.cordier@dynamixyz.com" target="_blank">lp.cordier@dynamixyz.com</a>>:<br>
            >This steps are tedious and I'm wondering if there is a
            mechanism that<br>
            >exists or that have to be imagined to make the DLL
            nightmare end.<br>
            <br>
            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.<br>
            <br>
            I use the same for copying DLL files to the output directory
            to ease debugging.<br>
            <br>
            The advantage is the inspection of the exe for really needed
            DLL files. This AUTOMATICALLY handles the case debug vs.
            release.<br>
            <br>
            HS<br>
            <br>
            --<br>
            Diese Nachricht wurde von meinem Android-Mobiltelefon mit
            K-9 Mail gesendet.<br>
            --<br>
            <br>
            Powered by <a href="http://www.kitware.com" target="_blank">www.kitware.com</a><br>
            <br>
            Please keep messages on-topic and check the CMake FAQ at: <a href="http://www.cmake.org/Wiki/CMake_FAQ" target="_blank">http://www.cmake.org/Wiki/CMake_FAQ</a><br>
            <br>
            Kitware offers various services to support the CMake
            community. For more information on each offering, please
            visit:<br>
            <br>
            CMake Support: <a href="http://cmake.org/cmake/help/support.html" target="_blank">http://cmake.org/cmake/help/support.html</a><br>
            CMake Consulting: <a href="http://cmake.org/cmake/help/consulting.html" target="_blank">http://cmake.org/cmake/help/consulting.html</a><br>
            CMake Training Courses: <a href="http://cmake.org/cmake/help/training.html" target="_blank">http://cmake.org/cmake/help/training.html</a><br>
            <br>
            Visit other Kitware open-source projects at <a href="http://www.kitware.com/opensource/opensource.html" target="_blank">http://www.kitware.com/opensource/opensource.html</a><br>
            <br>
            Follow this link to subscribe/unsubscribe:<br>
            <a href="http://public.kitware.com/mailman/listinfo/cmake" target="_blank">http://public.kitware.com/mailman/listinfo/cmake</a></p>
          <p class="MsoNormal"><u></u> <u></u></p>
        </div>
      </blockquote>
      <br>
    </blockquote>
    <br>
  </div>

--<br>
<br>
Powered by <a href="http://www.kitware.com" rel="noreferrer" target="_blank">www.kitware.com</a><br>
<br>
Please keep messages on-topic and check the CMake FAQ at: <a href="http://www.cmake.org/Wiki/CMake_FAQ" rel="noreferrer" target="_blank">http://www.cmake.org/Wiki/CMake_FAQ</a><br>
<br>
Kitware offers various services to support the CMake community. For more information on each offering, please visit:<br>
<br>
CMake Support: <a href="http://cmake.org/cmake/help/support.html" rel="noreferrer" target="_blank">http://cmake.org/cmake/help/support.html</a><br>
CMake Consulting: <a href="http://cmake.org/cmake/help/consulting.html" rel="noreferrer" target="_blank">http://cmake.org/cmake/help/consulting.html</a><br>
CMake Training Courses: <a href="http://cmake.org/cmake/help/training.html" rel="noreferrer" target="_blank">http://cmake.org/cmake/help/training.html</a><br>
<br>
Visit other Kitware open-source projects at <a href="http://www.kitware.com/opensource/opensource.html" rel="noreferrer" target="_blank">http://www.kitware.com/opensource/opensource.html</a><br>
<br>
Follow this link to subscribe/unsubscribe:<br>
<a href="http://public.kitware.com/mailman/listinfo/cmake" rel="noreferrer" target="_blank">http://public.kitware.com/mailman/listinfo/cmake</a></blockquote></div>