[CMake] Testing and DLLs
Michael Jackson
mike.jackson at bluequartz.net
Wed May 4 12:25:04 EDT 2011
Funny, I did the same thing using pure CMake code because I couldn't figure out batch files.
# --------------------------------------------------------------------
#-- Copy all the dependent DLLs into the current build directory so that the test
#-- can run.
MACRO (CMP_COPY_DEPENDENT_LIBRARIES _libraryList)
# message(STATUS "#--------------------------------------------")
# message(STATUS "CMP_COPY_DEPENDENT_LIBRARIES: ${_libraryList}")
set (_libraryList ${_libraryList})
SET (TYPES Debug Release)
if (MSVC)
# Make all the necessary intermediate directories for Visual Studio
file(MAKE_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Debug)
file(MAKE_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Release)
file(MAKE_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/MinSizeRel)
file(MAKE_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/RelWithDebInfo)
FOREACH(lib ${_libraryList})
STRING(TOUPPER ${lib} upperlib)
# message(STATUS "upperlib: ${upperlib}")
# message(STATUS "${upperlib}_IS_SHARED: ${${upperlib}_IS_SHARED}")
if (${upperlib}_IS_SHARED)
FOREACH(BTYPE ${TYPES} )
# message(STATUS "Looking for ${BTYPE} DLL Version of ${lib}")
STRING(TOUPPER ${BTYPE} TYPE)
get_filename_component(lib_path ${${upperlib}_LIBRARY_${TYPE}} PATH)
get_filename_component(lib_name ${${upperlib}_LIBRARY_${TYPE}} NAME_WE)
# message(STATUS "lib_path: ${lib_path}")
# message(STATUS "lib_name: ${lib_name}")
find_file(${upperlib}_LIBRARY_DLL_${TYPE}
NAMES ${lib_name}.dll
PATHS ${lib_path}/../bin ${lib_path}/.. ${lib_path}/ ${${upperlib}_BIN_DIR}
NO_DEFAULT_PATH )
# message(STATUS "${upperlib}_LIBRARY_DLL_${TYPE}: ${${upperlib}_LIBRARY_DLL_${TYPE}}")
mark_as_advanced(${upperlib}_LIBRARY_DLL_${TYPE})
if ( ${${upperlib}_LIBRARY_DLL_${TYPE}} STREQUAL "${upperlib}_LIBRARY_DLL_${TYPE}-NOTFOUND")
message(FATAL_ERROR "According to how ${upperlib}_LIBRARY_${TYPE} was found the library should"
" have been built as a DLL but no .dll file can be found. I looked in the "
" following locations:\n ${lib_path}\n ${lib_path}/..\n ${lib_path}/../bin\n ${${upperlib}_BIN_DIR}")
endif()
# SET(${upperlib}_LIBRARY_DLL_${TYPE} "${${upperlib}_LIBRARY_DLL_${TYPE}}/${lib_name}.dll" CACHE FILEPATH "The path to the DLL Portion of the library" FORCE)
# message(STATUS "${upperlib}_LIBRARY_DLL_${TYPE}: ${${upperlib}_LIBRARY_DLL_${TYPE}}")
message(STATUS "Generating Copy Rule for ${BTYPE} DLL Library ${${upperlib}_LIBRARY_DLL_${TYPE}}")
ADD_CUSTOM_TARGET(ZZ_${upperlib}_DLL_${TYPE}-Copy ALL
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${${upperlib}_LIBRARY_DLL_${TYPE}}
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${BTYPE}/
COMMENT " Copy: ${${upperlib}_LIBRARY_DLL_${TYPE}}\n To: ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${BTYPE}/")
ENDFOREACH(BTYPE ${TYPES})
ENDIF(${upperlib}_IS_SHARED)
ENDFOREACH(lib ${_libraryList})
ENDIF(MSVC)
endmacro()
This does depend on certain CMake variables being setup correctly though so maybe the batch file solution might work better.
___________________________________________________________
Mike Jackson www.bluequartz.net
Principal Software Engineer mike.jackson at bluequartz.net
BlueQuartz Software Dayton, Ohio
On May 4, 2011, at 11:52 AM, John Drescher wrote:
>> I am curious whether there is a common way of dealing with unit tests
>> when the actual project to be tested is a DLL? The issue I am facing
>> is a common Windows issue where the required DLL is not found in the
>> path.
>>
>> I tried to put all binaries in the same directory by modifying
>> CMAKE_*_OUTPUT_DIRECTORY but that did not affect my tests (added via
>> add_test).
>>
>> Another solution I can think of is running "make INSTALL" before
>> running the tests but that feels like a strange approach since I
>> typically want to test before installing.
>>
>> Its also not really possible to adapt the PATH environment variable -
>> how could I possible guess where somebody is going to build my code!?
>>
>> So again, I am really curious if there is a well working solution.
>>
>
> I now have a custom build script that generates a batch file that
> copies (using cmake commands) the required dlls into the Debug,
> Release, RelWithDebInfo folders for me for the few libraries that
> require dlls (Qt ). For ITK, VTK ... I use static libs so no need to
> copy these.
>
>
>
>
>
> option (GET_RUNTIME "Create a target that will get the runtime" ON)
>
> IF (GET_RUNTIME)
>
> SET (${PROJECT_NAME}_PACKAGING_RUNTIME "")
>
> SET (RUNTIME_BATCH_FILENAME "${PROJECT_BINARY_DIR}/GetRuntime.bat"
> CACHE FILEPATH "${PROJECT_BINARY_DIR}/GetRuntime.bat")
>
> add_custom_target(GetRuntime "${RUNTIME_BATCH_FILENAME}")
>
> #########################################################################################
>
> macro( add_runtime_file BatchFileName RuntimeFile Configuration )
>
> # Test if this is a valid configuration.
> STRING( REGEX MATCH ${Configuration} __MATCHED__ ${CMAKE_CONFIGURATION_TYPES})
> if ( NOT "${__MATCHED__}" STREQUAL "" )
>
> IF (NOT EXISTS "${EXECUTABLE_OUTPUT_PATH}/${Configuration}")
> file( MAKE_DIRECTORY "${EXECUTABLE_OUTPUT_PATH}/${Configuration}" )
> ENDIF (NOT EXISTS "${EXECUTABLE_OUTPUT_PATH}/${Configuration}")
>
> GET_FILENAME_COMPONENT( BatchFile ${BatchFileName} NAME_WE )
>
> #The following will truncate the file on the first call to add_runtime_file.
> if ( NOT DEFINED __add_runtime_file_${BatchFile}__ )
> set ( __add_runtime_file_${BatchFile}__ 1)
> file( WRITE ${BatchFileName} "REM This file will copy the runtimes
> to the Debug and Release binary folders\n" )
> endif ( NOT DEFINED __add_runtime_file_${BatchFile}__)
>
> #The following line will add the entry in the batch file for
> copying the Runtime file to the folder
> ${PROJECT_BINARY_DIR}/${Configuration}/
> file( APPEND ${BatchFileName} "\"${CMAKE_COMMAND}\" -E
> copy_if_different \"${RuntimeFile}\"
> \"${EXECUTABLE_OUTPUT_PATH}/${Configuration}/\"\n" )
> endif( NOT "${__MATCHED__}" STREQUAL "" )
> endmacro( add_runtime_file )
>
> #########################################################################################
>
> macro( add_runtime_file_for_packaging RuntimeFile )
> SET( ${PROJECT_NAME}_PACKAGING_RUNTIME
> ${${PROJECT_NAME}_PACKAGING_RUNTIME} ${RuntimeFile} )
> endmacro( add_runtime_file_for_packaging )
>
> ENDIF(GET_RUNTIME)
> _______________________________________________
> 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
More information about the CMake
mailing list