[CMake] Poor performance of copy_if_different

Clinton Stimpson clinton at elemtech.com
Tue Nov 6 12:54:31 EST 2012


Try this:

    add_custom_command(
        OUTPUT ${bin_outputs}
        COMMAND ${copy_commands}
        DEPENDS ....
    )

On Tuesday, November 06, 2012 11:50:54 AM Robert Dailey wrote:
> Thanks Clinton,
> 
> Here is what I have so far:
> 
> 
> project( copy_dlls )
> 
> set( copycmd "${CMAKE_COMMAND}" ARGS "-E" "copy_if_different" )
> 
> set( configurations debug release )
> foreach( config ${configurations} )
>     string( TOUPPER ${config} upper_config )
> 
>     get_property( binarydirs GLOBAL PROPERTY
> THIRD_PARTY_DIRS_${upper_config} ) foreach( dir ${binarydirs} )
>         file( GLOB binaries "${dir}/*${CMAKE_SHARED_LIBRARY_SUFFIX}" )
> 
>         if( WIN32 AND config STREQUAL "debug" )
>             file( GLOB pdbs "${dir}/*.pdb" )
>             list( APPEND binaries ${pdbs} )
>         endif()
> 
>         foreach( bin ${binaries} )
>             get_filename_component( bin_file ${bin} NAME )
> 
>             list( APPEND bin_outputs ${bin} )
>             list( APPEND copy_commands
>                 COMMAND ${copycmd} "${bin}"
> "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${bin_file}"
>             )
>         endforeach()
>     endforeach()
> 
>     add_custom_command(
>         OUTPUT ${bin_outputs}
>         ${copy_commands}
>     )
> 
>     add_custom_target( copy_dlls_${config}
>         COMMENT "Copying ${config} binaries..."
>         DEPENDS ${bin_outputs}
>     )
> endforeach()
> 
> 
> This doesn't seem to work though, CMake tells me:
> 
> CMake Error: Attempt to add a custom rule to output
> "C:/Work/rdailey-hp/dpd-cmake/build-nmake-vc9/third_party/bdb/4.7.25/vc9sp1/
> debug/bin/libdb47d.dll.rule" which already has a custom rule.
> 
> I'm trying to stuff all the copy commands and output files into 1
> custom command, and wrap that with a custom target, so I can make
> other targets depend on the custom target.
> 
> On Tue, Nov 6, 2012 at 11:44 AM, Clinton Stimpson <clinton at elemtech.com> 
wrote:
> > add_custom_command(
> > 
> >   OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/my.dll
> >   COMMAND cmake -E copy ${CMAKE_CURRENT_SOURCE_DIR}/my.dll
> > 
> > ${CMAKE_CURRENT_BINARY_DIR}/my.dll
> > 
> >   DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/my.dll
> >   )
> > 
> > add_custom_target(copy_dll ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/my.dll)
> > 
> > Whether you use 1 custom command per dll, or 1 for all dlls, is up to you.
> >  If they usually change together, then you could have fewer custom
> > commands.  In that case, the OUTPUT would have multiple files and both
> > DEPENDS would have multiple files.
> > 
> > Another alternative is to use add_custom_command(TARGET POST_BUILD ...) if
> > these are dlls that you compile yourself and need to copy after the build
> > step.
> > 
> > On Tuesday, November 06, 2012 11:23:03 AM Robert Dailey wrote:
> >> Also, is it safe to add 1 custom command for each DLL copy? Or would
> >> you somehow only use 1 custom command and copy them all with it? Also
> >> would I add the custom commands to the custom target?
> >> 
> >> On Tue, Nov 6, 2012 at 11:11 AM, Clinton Stimpson <clinton at elemtech.com>
> > 
> > wrote:
> >> > On Tuesday, November 06, 2012 11:06:45 AM Robert Dailey wrote:
> >> >> I use ${CMAKE_COMMAND} -E copy_if_different to copy DLL files to my
> >> >> binary output directory. The custom target runs this command about
> >> >> 50-100 times (for that many files).
> >> >> 
> >> >> I notice that when all files are already copied, the commands still
> >> >> run extremely slowly. It takes just as long to copy all the files as
> >> >> it does to copy none of them.
> >> >> 
> >> >> I used the Sysinternals tool called Process Monitor to see what CMake
> >> >> is doing as it runs copy_if_different. It's opening the full file and
> >> >> seems to be comparing actual contents instead of something simple,
> >> >> such as timestamp.
> >> >> 
> >> >> I do not need such a thorough check, I simply want the check to see
> >> >> which timestamp is higher and copy if the source is newer than the
> >> >> target.
> >> >> 
> >> >> Any reason why copy_if_different is so slow? Is my assumption correct?
> >> >> How can I make it faster?
> >> > 
> >> > How about using plain "cmake -E copy ..." and rely on the timestamp
> >> > check
> >> > done by a custom command (add_custom_command()).
> >> > You need to make sure the input/ouput parts of the custom command are
> >> > set
> >> > correctly so it can do a timestamp check.
> >> > 
> >> > --
> >> > Clinton Stimpson
> >> > Elemental Technologies, Inc
> >> > Computational Simulation Software, LLC
> >> > www.csimsoft.com
> >> > --
> >> > 
> >> > Powered by www.kitware.com
> >> > 
> >> > Visit other Kitware open-source projects at
> >> > http://www.kitware.com/opensource/opensource.html
> >> > 
> >> > Please keep messages on-topic and check the CMake FAQ at:
> >> > http://www.cmake.org/Wiki/CMake_FAQ
> >> > 
> >> > Follow this link to subscribe/unsubscribe:
> >> > http://www.cmake.org/mailman/listinfo/cmake
> > 
> > --
> > Clinton Stimpson
> > Elemental Technologies, Inc
> > Computational Simulation Software, LLC
> > www.csimsoft.com
> > --
> > 
> > Powered by www.kitware.com
> > 
> > Visit other Kitware open-source projects at
> > http://www.kitware.com/opensource/opensource.html
> > 
> > Please keep messages on-topic and check the CMake FAQ at:
> > http://www.cmake.org/Wiki/CMake_FAQ
> > 
> > Follow this link to subscribe/unsubscribe:
> > http://www.cmake.org/mailman/listinfo/cmake
-- 
Clinton Stimpson
Elemental Technologies, Inc
Computational Simulation Software, LLC
www.csimsoft.com


More information about the CMake mailing list