# # Functions for detection and usage of Wine # Used when cross compiling # # # Tries to detect the required executables and libraries automatically and emits an # error that will halt the configuration process if that is not possible. # All arguments will be ignored. # function(DCMTK_SETUP_WINE) find_program(WINE_WINE_PROGRAM wine) find_program(WINE_WINEPATH_PROGRAM winepath) if(NOT WINE_CPP_RUNTIME) set(v 1) unset(CMAKE_FIND_LIBRARY_SUFFIXES) while(${v} LESS 14) list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES "-${v}.dll") math(EXPR v "${v} + 1") endwhile() find_library(CPP_RUNTIME stdc++ DOC "Location of the C++ runtime library used during target emulation") if(NOT CPP_RUNTIME) message(FATAL_ERROR "Please set the C++ runtime location (required for running applications targeting Windows).") else() get_filename_component(CPP_RUNTIME_LOCATION ${CPP_RUNTIME} PATH) UNIX_TO_WINE_PATH(RT ${CPP_RUNTIME_LOCATION}) set(WINE_CPP_RUNTIME ${RT} CACHE INTERNAL "C++ RT in Wine path format") endif() endif() if(NOT WINE_WINE_PROGRAM OR NOT WINE_WINEPATH_PROGRAM) message(FATAL_ERROR "Some wine related executables could not be detected automatically. " "Please set WINE_WINE_PROGRAM and WINE_WINEPATH_PROGRAM appropriately." ) endif() # prepare wine prefix for configure and unit tests if(NOT DCMTK_WINEPREFIX) set(DCMTK_WINEPREFIX "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/wineprefix" CACHE INTERNALE "the path of the wineprefix to use for configuration and unit tests") message(STATUS "Info: Preparing wine prefix for configuration and unit tests: ${DCMTK_WINEPREFIX}") string(REPLACE "\\" "\\\\" WINE_CPP_RUNTIME "${WINE_CPP_RUNTIME}") set(WINE_PATH_REG "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/dcmtkWinePath.reg") configure_file("${DCMTK_SOURCE_DIR}/CMake/dcmtkWinePath.reg.in" "${WINE_PATH_REG}" ESCAPE_QUOTES @ONLY) set(ENV{WINEPREFIX} "${DCMTK_WINEPREFIX}") execute_process(COMMAND "${WINE_WINE_PROGRAM}" "regedit" "${WINE_PATH_REG}" OUTPUT_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/wineprefix.log" ERROR_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/wineprefix.log" OUTPUT_VARIABLE RESULT ) if(RESULT) set(DCMTK_WINEPREFIX CACHE INTERNAL "error, see ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/wineprefix.log") message(FATAL_ERROR "Failed to setup the wineprefix, see \"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/wineprefix.log\"") endif() else() set(ENV{WINEPREFIX} "${DCMTK_WINEPREFIX}") endif() endfunction() # # Helper function to detach the output and error streams from a wine process, so # that CMake doesn't wait for the wineserver to quit before continuing execution. # VAR - the variable that will hold the exit code of the launched process. # OUTPUT_VAR - the variable that will hold the standard output of the launched process. # ERROR_VAR - the variable that will hold the error output of the launched process. # ARGN - the command to execute. # function(WINE_DETACHED VAR OUTPUT_VAR ERROR_VAR) # Prefix to prevent collision of output capturing files if(CMAKE_VERSION VERSION_LESS 2.8.7) string(RANDOM LENGTH 20 ALPHABET "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" PREFIX) else() string(MD5 PREFIX "${ARGN}") endif() set(OUTPUT_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${PREFIX}_output") if(OUTPUT_VAR STREQUAL ERROR_VAR) set(ERROR_FILE "${OUTPUT_FILE}") else() set(ERROR_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${PREFIX}_error") endif() execute_process( COMMAND ${ARGN} OUTPUT_FILE "${OUTPUT_FILE}" ERROR_FILE "${ERROR_FILE}" RESULT_VARIABLE RESULT ) file(READ "${OUTPUT_FILE}" OUTPUT) set("${OUTPUT_VAR}" ${OUTPUT} PARENT_SCOPE) if(OUTPUT_VAR STREQUAL ERROR_VAR) file(REMOVE "${OUTPUT_FILE}") else() file(READ "${ERROR_FILE}" ERROR) set("${ERROR_VAR}" ${ERROR} PARENT_SCOPE) file(REMOVE "${OUTPUT_FILE}" "${ERROR_FILE}") endif() set("${VAR}" ${RESULT} PARENT_SCOPE) endfunction() # # Uses 'winepath' to translate a host path or filename to the location it can be # accessed from within the emulated Windows environment (e. g. replaces '/' by '\'). # VAR - name of the variable to store the result in # PATH - the path to be translated # Will unset VAR if an error occurred. # Additional arguments will be ignored. # function(UNIX_TO_WINE_PATH VAR PATH) WINE_DETACHED(ERROR RESULT STDERR "${WINE_WINEPATH_PROGRAM}" "-w" "${PATH}") if(NOT ERROR) string(REPLACE "\n" "" RESULT ${RESULT}) set(${VAR} ${RESULT} PARENT_SCOPE) else() unset(${VAR} PARENT_SCOPE) message(WARNING "Unable to convert path to Wine format: ${STDERR}") endif() endfunction() # # Create a command (as string) to run a given command in the emulated Windows # environment by using 'wine'. # VAR - name of the variable to store the resulting command in # COMMAND - the command to run, e. g. 'dir' # Additional arguments will be appended to the command. # function(WINE_COMMAND VAR COMMAND) UNIX_TO_WINE_PATH(CMD ${COMMAND}) separate_arguments(ARGS WINDOWS_COMMAND "${ARGN}") set(${VAR} "${CMD}" ${ARGS} PARENT_SCOPE) endfunction()