From dd304d6404c523a8dc77bfbc4daa6e91e4665266 Mon Sep 17 00:00:00 2001
From: Rashad Kanavath <rashad.kanavath@c-s.fr>
Date: Tue, 30 Jun 2015 12:07:10 +0200
Subject: [PATCH] ENH: custom target to create package after cross compilation

---
 CMake/MinGWPackage.cmake | 185 +++++++++++++++++++++++++++++++++++++++
 CMakeLists.txt           |  63 +++++++++++++
 2 files changed, 248 insertions(+)
 create mode 100644 CMake/MinGWPackage.cmake

diff --git a/CMake/MinGWPackage.cmake b/CMake/MinGWPackage.cmake
new file mode 100644
index 0000000000..bb24574cef
--- /dev/null
+++ b/CMake/MinGWPackage.cmake
@@ -0,0 +1,185 @@
+macro(package_mingw)
+  cmake_parse_arguments(PACKAGE  "" "PREFIX_DIR;ARCH;MXEROOT" "SEARCHDIRS;PEFILES" ${ARGN} )
+
+  ###   ${PACKAGE_EXENAME} #name of executable
+  #${PACKAGE_ARCH} #x86/x64
+  #${PACKAGE_SEARCHDIRS}
+  ####set(PACKAGE_PREFIX_DIR "mingw")
+  
+  if("${PACKAGE_ARCH}" STREQUAL "x86")
+    set(MXE_BIN_DIR "${PACKAGE_MXEROOT}/usr/i686-w64-mingw32.shared/bin")
+    set(MXE_OBJDUMP "${PACKAGE_MXEROOT}/usr/bin/i686-w64-mingw32.shared-objdump")
+  elseif("${PACKAGE_ARCH}" STREQUAL "x64")
+    set(MXE_BIN_DIR "${PACKAGE_MXEROOT}/usr/x86_64-w64-mingw32.shared/bin")
+    set(MXE_OBJDUMP "${PACKAGE_MXEROOT}/usr/bin/x86_64-w64-mingw32.shared-objdump")
+  endif()
+
+  list(APPEND PACKAGE_SEARCHDIRS ${MXE_BIN_DIR})
+  list(APPEND PACKAGE_SEARCHDIRS "${MXE_BIN_DIR}/../qt/bin") #Qt
+  list(APPEND PACKAGE_SEARCHDIRS "${MXE_BIN_DIR}/../qt/lib") #Qwt
+  list(APPEND PACKAGE_SEARCHDIRS "${CMAKE_INSTALL_PREFIX}/bin") #mvd
+  list(APPEND PACKAGE_SEARCHDIRS "${CMAKE_INSTALL_PREFIX}/lib/otb/applications") #otb apps
+
+  install_common()
+
+  file(GLOB otbapps_list ${CMAKE_INSTALL_PREFIX}/lib/otb/applications/otbapp_*dll) # /lib/otb
+  list(APPEND PACKAGE_PEFILES ${otbapps_list})
+ 
+  set(alldlls)
+  set(notfound_dlls)
+  foreach(infile ${PACKAGE_PEFILES})
+    get_filename_component(bn ${infile} NAME)
+    process_deps(${bn})
+  endforeach()
+
+  list(LENGTH notfound_dlls nos)
+  if(${nos} GREATER 0)
+    STRING(REPLACE ".dll" ".dll," notfound ${notfound_dlls})
+    message(FATAL_ERROR "Following dlls were not found: ${notfound}
+                   Please consider adding their paths to SEARCHDIRS when calling package_mingw macro.")
+  endif()
+  
+endmacro(package_mingw)
+
+SET(SYSTEM_DLLS
+  msvc.*dll
+  USER32.dll
+  GDI32.dll
+  SHELL32.DLL
+  KERNEL32.dll
+  ADVAPI32.dll
+  CRYPT32.dll
+  WS2_32.dll
+  wldap32.dll
+  ole32.dll
+  OPENGL32.DLL
+  GLU32.DLL
+  COMDLG32.DLL
+  IMM32.DLL
+  OLEAUT32.dll
+  COMCTL32.DLL
+  WINMM.DLL
+
+  SHELL32.dll
+  WLDAP32.dll
+  OPENGL32.dll
+  GLU32.dll
+  comdlg32.dll
+  IMM32.dll
+  WINMM.dll
+  WINSPOOL.DRV)
+
+## http://www.cmake.org/Wiki/CMakeMacroListOperations
+macro(IS_SYSTEM_DLL matched value)
+  set(${matched})
+  foreach (pattern ${SYSTEM_DLLS})
+    if(${value} MATCHES ${pattern})
+      set(${matched} TRUE)
+    endif()
+  endforeach()
+endmacro()
+
+macro(list_contains var value)
+  set(${var})
+  foreach(value2 ${ARGN})
+    if(${value} STREQUAL ${value2})
+      set(${var} TRUE)
+    endif()
+  endforeach(value2)
+endmacro()
+
+function(process_deps infile)
+
+  get_filename_component(bn ${infile} NAME)
+  
+  list_contains(contains "${bn}" "${alldlls}")
+  if(NOT contains)
+    set(DLL_FOUND FALSE)
+    foreach(SEARCHDIR ${PACKAGE_SEARCHDIRS})
+      if(NOT DLL_FOUND)
+        if(EXISTS ${SEARCHDIR}/${infile})
+          set(DLL_FOUND TRUE)
+         
+          message(STATUS "Processing ${SEARCHDIR}/${infile}")
+          if(NOT "${infile}" MATCHES "otbapp")
+            install(
+              FILES "${SEARCHDIR}/${infile}"
+              DESTINATION ${PACKAGE_PREFIX_DIR}/bin)
+          else()
+
+          endif()
+          if(NOT EXISTS ${MXE_OBJDUMP})
+            message(FATAL_ERROR "objdump executable not found. please check MXE_OBJDUMP is set to correct cross compiled executable")
+          endif()
+          execute_process(COMMAND ${MXE_OBJDUMP} "-p" "${SEARCHDIR}/${infile}"  OUTPUT_VARIABLE dlldeps)
+          string(REGEX MATCHALL "DLL.Name..[A-Za-z(0-9\\.0-9)+_\\-]*" OUT "${dlldeps}")
+          string(REGEX REPLACE "DLL.Name.." "" OUT "${OUT}")  
+          foreach(o ${OUT})
+            process_deps(${o})
+          endforeach()
+        endif()
+      endif(NOT DLL_FOUND)
+    endforeach()
+
+    if(NOT DLL_FOUND)
+      is_system_dll(iss "${infile}")
+      if(NOT iss)
+        set(notfound_dlls "${notfound_dlls};${infile}")
+      endif()
+    else(NOT DLL_FOUND)
+      
+      set( alldlls "${alldlls};${bn}" PARENT_SCOPE )  
+    endif(NOT DLL_FOUND)
+    
+    set(notfound_dlls "${notfound_dlls}" PARENT_SCOPE )    
+   endif()
+endfunction()
+
+function(install_common)
+  set(APP_PREFIX_DIR "${PACKAGE_PREFIX_DIR}")
+  set(APP_BIN_DIR "${APP_PREFIX_DIR}/bin")
+  set(APP_OTBLIBS_DIR "${APP_PREFIX_DIR}/lib/otb")
+  set(APP_DATA_DIR "${APP_PREFIX_DIR}/share")
+
+  ####################### install GDAL data #######################
+
+  set(GDAL_DATA ${MXE_BIN_DIR}/../share/gdal)
+  if(NOT EXISTS "${GDAL_DATA}/epsg.wkt")
+    message(FATAL_ERROR "Cannot generate package without GDAL_DATA : ${GDAL_DATA}")
+  endif()
+
+  install(
+    DIRECTORY ${GDAL_DATA}
+    DESTINATION ${APP_DATA_DIR})
+
+  ####################### Check otb applications #######################
+
+  file(GLOB OTB_APPS_LIST ${CMAKE_INSTALL_PREFIX}/lib/otb/applications/otbapp_*dll) # /lib/otb
+  if(NOT OTB_APPS_LIST)
+    message(FATAL_ERROR "No OTB-applications detected")
+  endif()
+  
+  ## otb apps dir /lib/otb/applications
+  install(
+    DIRECTORY "${CMAKE_INSTALL_PREFIX}/lib/otb/applications"
+    DESTINATION ${APP_OTBLIBS_DIR})
+
+  file(GLOB CLI_SCRIPTS ${CMAKE_INSTALL_PREFIX}/bin/otbcli*)
+  foreach(CLI_SCRIPT ${CLI_SCRIPTS})
+    install(
+      FILES "${CLI_SCRIPT}"
+      DESTINATION ${APP_BIN_DIR})
+  endforeach()
+
+  if(OTB_USE_QT4)
+    file(GLOB GUI_SCRIPTS ${CMAKE_INSTALL_PREFIX}/bin/otbgui*)
+    foreach(GUI_SCRIPT ${GUI_SCRIPTS})
+      install(
+        FILES "${GUI_SCRIPT}"
+        DESTINATION ${APP_BIN_DIR})
+    endforeach()
+  endif()
+
+
+endfunction()  
+
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c53bdf9363..9ee78dbf1d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -395,3 +395,66 @@ add_subdirectory(Utilities/Doxygen)
 # TODO cleanup
 # Create target to download data from the OTBData group. This must come after
 # all tests have been added that reference the group, so we put it last.
+
+
+if(WIN32 AND CMAKE_CROSSCOMPILING)
+  if(DEFINED MXE_TARGET_DIR)
+
+    file(GLOB pefiles
+      ${CMAKE_INSTALL_PREFIX}/bin/otbApplication*.exe
+      ${CMAKE_INSTALL_PREFIX}/bin/otbTestDriver.exe)
+
+    message(STATUS "MXE_TARGET_DIR = ${MXE_TARGET_DIR}")
+
+    if(MXE_TARGET_DIR MATCHES "i686")
+      set(mxearch x86)
+    elseif(MXE_TARGET_DIR MATCHES "x86_64")
+      set(mxearch x64)
+    endif()
+
+    set(archive_name ${CMAKE_PROJECT_NAME}-MinGW-${mxearch})
+
+    execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory "${CMAKE_INSTALL_PREFIX}/${archive_name}")
+    
+    get_filename_component(mxeroot ${MXE_TARGET_DIR} PATH)
+    get_filename_component(mxeroot ${mxeroot} PATH)
+
+    file(WRITE "${CMAKE_BINARY_DIR}/_mingw/CMakeLists.txt"
+      "cmake_minimum_required(VERSION 2.6)
+       include(CMakeParseArguments)
+       set(CMAKE_INSTALL_PREFIX \"${CMAKE_INSTALL_PREFIX}\")
+        include(${CMAKE_SOURCE_DIR}/CMake/MinGWPackage.cmake)
+        package_mingw(
+        ARCH \"${mxearch}\"
+        MXEROOT \"${mxeroot}\"
+        PREFIX_DIR \"${archive_name}\"
+        PEFILES \"${pefiles}\"
+        SEARCHDIRS \"\")")
+
+    add_custom_target(configure-mingw
+      COMMAND ${CMAKE_COMMAND}
+      "${CMAKE_BINARY_DIR}/_mingw"
+      WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/_mingw")
+
+    add_custom_target(prepare-mingw
+      COMMAND ${CMAKE_COMMAND}
+      "--build" "${CMAKE_BINARY_DIR}/_mingw" "--target" "install"
+      WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/_mingw"
+      DEPENDS configure-mingw)
+
+    find_program(ZIP_EXECUTABLE zip)
+    
+    if(ZIP_EXECUTABLE)
+      add_custom_target(package-mingw
+        COMMAND ${ZIP_EXECUTABLE} "-r" "${CMAKE_BINARY_DIR}/${archive_name}.zip" "${archive_name}"
+        WORKING_DIRECTORY "${CMAKE_INSTALL_PREFIX}"
+        DEPENDS prepare-mingw)
+    else()
+      message(FATAL_ERROR "Cannot find zip executable. Please add it to your path")
+    endif()
+    
+  else(DEFINED MXE_TARGET_DIR)
+    message(WARNING "MXE_TARGET_DIR must be defined and contains location of mxe root directory")
+  endif(DEFINED MXE_TARGET_DIR)
+
+endif(WIN32 AND CMAKE_CROSSCOMPILING)
-- 
GitLab