From 0392887f250ff942cd0b1cd43f32f2348ec84c89 Mon Sep 17 00:00:00 2001
From: Rashad Kanavath <rashad.kanavath@c-s.fr>
Date: Thu, 2 Jul 2015 16:54:12 +0200
Subject: [PATCH] WIP: linux portable binaries

---
 SuperBuild/CMake/External_package.cmake |  36 ++++++
 SuperBuild/CMake/Package_Macro.cmake    | 157 ++++++++++++++++++++++++
 SuperBuild/CMakeLists.txt               |  26 ++--
 3 files changed, 204 insertions(+), 15 deletions(-)
 create mode 100644 SuperBuild/CMake/External_package.cmake
 create mode 100644 SuperBuild/CMake/Package_Macro.cmake

diff --git a/SuperBuild/CMake/External_package.cmake b/SuperBuild/CMake/External_package.cmake
new file mode 100644
index 0000000000..1bc0f65597
--- /dev/null
+++ b/SuperBuild/CMake/External_package.cmake
@@ -0,0 +1,36 @@
+set(proj PACKAGE-OTB)
+
+if(NOT __EXTERNAL_${proj}__)
+set(__EXTERNAL_${proj}__ 1)
+
+message(STATUS "Setup OTB Packaging...")
+
+SETUP_SUPERBUILD(PROJECT ${proj})
+
+execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/${proj}/src/")
+
+# declare dependencies
+#set(${proj}_DEPENDENCIES OTB)
+#INCLUDE_SUPERBUILD_DEPENDENCIES(${${proj}_DEPENDENCIES})
+
+#message(FATAL_ERROR "PACKAGE_SB_BUILD_DIR=${PACKAGE_SB_BUILD_DIR}")
+
+
+ExternalProject_Add(${proj}
+  PREFIX ${proj}
+  SOURCE_DIR ${PACKAGE-OTB_SB_SRC_DIR}
+  BINARY_DIR ${PACKAGE-OTB_SB_BUILD_DIR}
+  INSTALL_DIR ${SB_INSTALL_PREFIX}
+  DOWNLOAD_COMMAND ""
+  CMAKE_CACHE_ARGS
+  -DCMAKE_INSTALL_PREFIX:STRING=${SB_INSTALL_PREFIX}
+  -DCMAKE_BUILD_TYPE:STRING=Release
+  CMAKE_COMMAND ${SB_CMAKE_COMMAND}
+  DEPENDS OTB)
+
+# ExternalProject_Add_Step(${proj} set_rpath
+#   COMMAND ${PATCHELF_PROGRAM} "--set-rpath" "../lib" ""
+#   DEPENDEES install)
+
+
+endif()
diff --git a/SuperBuild/CMake/Package_Macro.cmake b/SuperBuild/CMake/Package_Macro.cmake
new file mode 100644
index 0000000000..859788f941
--- /dev/null
+++ b/SuperBuild/CMake/Package_Macro.cmake
@@ -0,0 +1,157 @@
+macro(superbuild_package)
+  cmake_parse_arguments(PACKAGE  "" "OUTDIR;INSTALLDIR" "SEARCHDIRS;PEFILES" ${ARGN} )
+
+  find_program(OBJDUMP_PROGRAM "objdump")
+  set(PATCHELF_PROGRAM "/home/mrashad/build/patchelf-0.8/src/patchelf")
+
+  list(APPEND PACKAGE_SEARCHDIRS "${PACKAGE_INSTALLDIR}/bin") #exe
+  list(APPEND PACKAGE_SEARCHDIRS "${PACKAGE_INSTALLDIR}/lib") #so
+  list(APPEND PACKAGE_SEARCHDIRS "${PACKAGE_INSTALLDIR}/lib/otb/applications") #otb apps
+
+  install_common()
+
+  execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory "${PACKAGE_INSTALLDIR}/${PACKAGE_OUTDIR}")
+
+  file(GLOB otbapps_list ${PACKAGE_INSTALLDIR}/lib/otb/applications/otbapp_*so) # /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 ".so;" ".so," notfound ${notfound_dlls})
+     message(FATAL_ERROR "Following dlls were not found: ${notfound_dlls}
+Please consider adding their paths to SEARCHDIRS when calling superbuild_package macro.")
+  endif()
+
+endmacro(superbuild_package)
+
+
+SET(SYSTEM_DLLS
+  libm.so
+  libc.so
+  libstdc*
+  libgcc_s.so
+  librt.so
+  libdl.so
+  libpthread.so
+  libidn.so
+  )
+
+## 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}")
+          add_custom_target(RPATH_${bn}
+            INSTALL
+            POST_BUILD
+            COMMAND ${PATCHELF_PROGRAM} "--set-rpath" "../lib" "${PACKAGE_OUTDIR}/lib/${infile}")
+
+          file(GLOB sofiles "${SEARCHDIR}/${bn}*")
+            foreach(sofile ${sofiles})
+            install(FILES "${sofile}"
+              DESTINATION ${PACKAGE_OUTDIR}/bin)
+            endforeach()
+
+          if(NOT EXISTS ${OBJDUMP_PROGRAM})
+            message(FATAL_ERROR "objdump executable not found. please check OBJDUMP_PROGRAM is set to correct cross compiled executable")
+          endif()
+          execute_process(COMMAND ${OBJDUMP_PROGRAM} "-p" "${SEARCHDIR}/${infile}"  OUTPUT_VARIABLE dump_out)
+          string(REGEX MATCHALL "NEEDED\\ *[A-Za-z(0-9\\.0-9)+_\\-]*" needed_dlls "${dump_out}")
+          string(REGEX REPLACE "NEEDED" "" needed_dlls "${needed_dlls}")
+          foreach(needed_dll ${needed_dlls})
+            string(STRIP ${needed_dll} needed_dll)
+            process_deps(${needed_dll})
+          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(OUT_DIR "${PACKAGE_OUTDIR}")
+  set(BIN_DIR "${OUTDIR}/bin")
+  set(OTBLIBS_DIR "${OUTDIR}/lib/otb")
+  set(DATA_DIR "${OUTDIR}/share")
+
+  ####################### install GDAL data #######################
+  find_path(GDAL_DATA epsg.wkt ${PACKAGE_INSTALLDIR}/share/gdal)
+  install(DIRECTORY ${GDAL_DATA}
+    DESTINATION ${DATA_DIR})
+
+  ####################### Check otb applications #######################
+
+  file(GLOB OTB_APPS_LIST ${PACKAGE_INSTALLDIR}/lib/otb/applications/otbapp_*so) # /lib/otb
+  if(NOT OTB_APPS_LIST)
+    message(FATAL_ERROR "No OTB-applications detected")
+  endif()
+
+  ####################### install otb applications #######################
+  install(DIRECTORY "${PACKAGE_INSTALLDIR}/lib/otb/applications"
+    DESTINATION ${OTBLIBS_DIR})
+
+  ####################### install otbcli scripts #######################
+  file(GLOB CLI_SCRIPTS ${SB_INSTALL_DIR}/bin/otbcli*)
+  foreach(CLI_SCRIPT ${CLI_SCRIPTS})
+    install(FILES "${CLI_SCRIPT}"
+      DESTINATION ${BIN_DIR})
+  endforeach()
+
+  ####################### install otbgui scripts #######################
+  if(OTB_USE_QT4)
+    file(GLOB GUI_SCRIPTS ${SB_INSTALL_DIR}/bin/otbgui*)
+    foreach(GUI_SCRIPT ${GUI_SCRIPTS})
+      install(FILES "${GUI_SCRIPT}"
+        DESTINATION ${BIN_DIR})
+    endforeach()
+  endif()
+
+
+endfunction()
diff --git a/SuperBuild/CMakeLists.txt b/SuperBuild/CMakeLists.txt
index ae7fc66e4b..1a8ad75234 100644
--- a/SuperBuild/CMakeLists.txt
+++ b/SuperBuild/CMakeLists.txt
@@ -70,7 +70,7 @@ if(WIN32)
     set(SB_CMAKE_COMMAND ${CMAKE_COMMAND})
      set(SB_BUILD_SHARED_LIBS OFF)
     set(SB_PRIOR_INCLUDE_FLAGS "/I ${CMAKE_INSTALL_PREFIX}/include")
-  endif()      
+  endif()
 else(UNIX)
   if(APPLE)
     set(LDLIBVAR DYLD_LIBRARY_PATH)
@@ -160,26 +160,22 @@ include(External_otb)
 #check compiler is gnu?
 if(UNIX AND NOT APPLE)
 
-#  include(External_package)
-  set(archive_name ${CMAKE_PROJECT_NAME}-${OTB_VERSION_STRING}-Linux64)
+  include(External_package)
+  set(ARCHIVE_NAME OTB-5.0.0-Linux64)
 
-  execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory "${CMAKE_INSTALL_PREFIX}/${archive_name}")
-  execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/PACKAGE_OTB/src/")
-  #should we add otbiceviewer.exe?
-  file(GLOB pefiles
+  file(GLOB PEFILES
     ${CMAKE_INSTALL_PREFIX}/bin/otbApplicationLaunch*
     ${CMAKE_INSTALL_PREFIX}/bin/otbTestDriver )
 
-  file(WRITE "${CMAKE_BINARY_DIR}/PACKAGE_OTB/src/PACKAGE_OTB/CMakeLists.txt"
+  file(WRITE "${CMAKE_BINARY_DIR}/PACKAGE-OTB/src/PACKAGE-OTB/CMakeLists.txt"
     "cmake_minimum_required(VERSION 2.6)
        include(CMakeParseArguments)
-       set(QT_PLUGINS_DIR \"${QT_PLUGINS_DIR}\")
        set(CMAKE_INSTALL_PREFIX \"${SB_INSTALL_PREFIX}\")
-        include(${CMAKE_SOURCE_DIR}/CMake/Package_Macro.cmake)
-        superbuild_package(
-        OUTDIR \"${archive_name}\"
-        INSTALLDIR \"${SB_INSTALL_PREFIX}\"
-        PEFILES \"${pefiles}\"
-        SEARCHDIRS \"\")")
+       include(${CMAKE_SOURCE_DIR}/CMake/Package_Macro.cmake)
+       superbuild_package(
+       OUTDIR \"${ARCHIVE_NAME}\"
+       INSTALLDIR \"${SB_INSTALL_PREFIX}\"
+       PEFILES \"${PEFILES}\"
+       SEARCHDIRS \"\")")
 
 endif(UNIX AND NOT APPLE)
-- 
GitLab