From 68a468f98f30b48b0abbc5bd8022593afda464b9 Mon Sep 17 00:00:00 2001 From: Rashad Kanavath <rashad.kanavath@c-s.fr> Date: Tue, 3 May 2016 16:57:51 +0200 Subject: [PATCH] PKG: finally automatic generation of windows XDK with cmake --- SuperBuild/Packaging/PackageHelper.cmake | 872 ++++++++++++++--------- 1 file changed, 523 insertions(+), 349 deletions(-) diff --git a/SuperBuild/Packaging/PackageHelper.cmake b/SuperBuild/Packaging/PackageHelper.cmake index d3785f9288..7efe5260b8 100644 --- a/SuperBuild/Packaging/PackageHelper.cmake +++ b/SuperBuild/Packaging/PackageHelper.cmake @@ -1,4 +1,4 @@ -macro(super_package) +macro(macro_super_package) cmake_parse_arguments(PKG "" "STAGE_DIR" "SEARCHDIRS" ${ARGN} ) if(${PKG_STAGE_DIR} STREQUAL "") @@ -6,7 +6,7 @@ macro(super_package) endif() set(loader_program_PATHS) - if(WIN32 OR CMAKE_CROSSCOMPILING) + if(WIN32) set(loader_program_names "${MXE_ARCH}-w64-mingw32.shared-objdump") set(loader_program_PATHS "${MXE_MXEROOT}/usr/bin") set(LOADER_PROGRAM_ARGS "-p") @@ -33,8 +33,7 @@ macro(super_package) include(GetPrerequisites) set(PKG_SEARCHDIRS) - - if(WIN32 OR CMAKE_CROSSCOMPILING) + if(WIN32) file(GLOB MXE_GCC_LIB_DIR "${DEPENDENCIES_INSTALL_DIR}/bin/gcc*") list(APPEND PKG_SEARCHDIRS ${MXE_GCC_LIB_DIR}) list(APPEND PKG_SEARCHDIRS "${DEPENDENCIES_INSTALL_DIR}/qt/bin") #Qt @@ -57,20 +56,51 @@ macro(super_package) list(APPEND EXE_SEARCHDIRS ${MONTEVERDI_INSTALL_DIR}/bin) list(APPEND EXE_SEARCHDIRS ${DEPENDENCIES_INSTALL_DIR}/bin) - empty_package_staging_directory() + macro_empty_package_staging_directory() set(PKG_PEFILES) - if(NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) + if(NOT WIN32) file(WRITE ${CMAKE_BINARY_DIR}/make_symlinks "#!/bin/sh\n") #NOTE: VAR_IN_PKGSETUP_CONFIGURE is copied to linux_pkgsetup.in during configure_file set(VAR_IN_PKGSETUP_CONFIGURE) set(PKG_SO_FILES) - endif() # if(NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) + endif() # if(NOT WIN32) + + func_prepare_package() + + func_prepare_install_list( + "${CMAKE_BINARY_DIR}/install_to_bin" + ${PKG_GENERATE_XDK} + bin_install_list + ) + + func_prepare_install_list( + "${CMAKE_BINARY_DIR}/install_to_lib" + ${PKG_GENERATE_XDK} + lib_install_list + ) + + foreach(installable_item_in_bin ${bin_install_list}) + if(WIN32) + #only install .exe files with install(PROGRAMS .. + if("${installable_item_in_bin}" MATCHES "\\.exe$") + install(PROGRAMS "${installable_item_in_bin}" DESTINATION ${PKG_STAGE_DIR}/bin) + else() + install(FILES "${installable_item_in_bin}" DESTINATION ${PKG_STAGE_DIR}/bin) + endif() + else() + #install all executable with install(PROGRAMS on unix like + install(PROGRAMS "${installable_item_in_bin}" DESTINATION ${PKG_STAGE_DIR}/bin) + endif() + endforeach() - configure_package() + #install lib files into lib as install(FILES .. + foreach(installable_item_in_lib ${lib_install_list}) + install(FILES "${installable_item_in_bin}" DESTINATION ${PKG_STAGE_DIR}/lib) + endforeach() - if(NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) - ############# install client configure script ################ + ############# install package configure script ################ + if(UNIX AND NOT WIN32) set(PKGSETUP_IN_FILENAME linux_pkgsetup.in) if(APPLE) set(PKGSETUP_IN_FILENAME macx_pkgsetup.in) @@ -78,176 +108,147 @@ macro(super_package) configure_file(${PACKAGE_SUPPORT_FILES_DIR}/${PKGSETUP_IN_FILENAME} ${CMAKE_BINARY_DIR}/pkgsetup @ONLY) - install(FILES + install(PROGRAMS ${CMAKE_BINARY_DIR}/pkgsetup ${CMAKE_BINARY_DIR}/make_symlinks - DESTINATION ${PKG_STAGE_DIR} - PERMISSIONS - OWNER_READ OWNER_WRITE OWNER_EXECUTE - GROUP_READ GROUP_EXECUTE - WORLD_READ WORLD_EXECUTE) - - if(UNIX) - if(NOT APPLE) - ####################### install patchelf ##################### - install(FILES ${CMAKE_INSTALL_PREFIX}/tools/patchelf - DESTINATION ${PKG_STAGE_DIR}/tools - PERMISSIONS - OWNER_EXECUTE OWNER_WRITE OWNER_READ - GROUP_EXECUTE GROUP_READ) - endif() + DESTINATION ${PKG_STAGE_DIR}) + + ########### install patchelf( linux only) ################## + if(NOT APPLE) + install(PROGRAMS ${CMAKE_INSTALL_PREFIX}/tools/patchelf + DESTINATION ${PKG_STAGE_DIR}/tools) endif() - endif() # if(NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) + endif() # if(UNIX) if(PKG_GENERATE_XDK) - install_xdk_files() + func_install_xdk_files() endif() -endmacro(super_package) - -function(install_xdk_files) - install(DIRECTORY ${DEPENDENCIES_INSTALL_DIR}/share - DESTINATION ${PKG_STAGE_DIR}) - - install(DIRECTORY ${DEPENDENCIES_INSTALL_DIR}/include - DESTINATION ${PKG_STAGE_DIR} - PATTERN "include/OTB*" EXCLUDE ) +endmacro(macro_super_package) + +function(func_install_xdk_files) + + #The list of REQ_SHARE_DIR is made up from <mxe-target-dir>/share/ + #It may vary in future. I prefer not to glob on the share dir and + #end up distributing man, info etc.. which ar irrelvant for windows + foreach(REQ_SHARE_DIR + aclocal + Armadillo + applications + cmake + dbus-1 + fontconfig + libgta + locale + xml + applications + cmake + icons + OpenCV + pixmaps + pkgconfig + ) + if(EXISTS "${DEPENDENCIES_INSTALL_DIR}/share/${REQ_SHARE_DIR}") + func_install_without_message("${DEPENDENCIES_INSTALL_DIR}/share/${REQ_SHARE_DIR}" "share") + endif() + endforeach() - install(DIRECTORY ${DEPENDENCIES_INSTALL_DIR}/lib/cmake - DESTINATION ${PKG_STAGE_DIR}/lib/ - PATTERN "lib/cmake/OTB*" EXCLUDE) -endfunction() + file(GLOB LIB_CMAKE_DIRS "${DEPENDENCIES_INSTALL_DIR}/lib/cmake/*") + foreach(LIB_CMAKE_DIR ${LIB_CMAKE_DIRS}) + get_filename_component(LIB_CMAKE_DIR_name_we ${LIB_CMAKE_DIR} NAME_WE) + if(NOT "${LIB_CMAKE_DIR_name_we}" MATCHES "OTB") + func_install_without_message("${LIB_CMAKE_DIR}" "lib/cmake") + endif() + endforeach() + # #install ${DEPENDENCIES_INSTALL_DIR}/include silently + func_install_without_message("${DEPENDENCIES_INSTALL_DIR}/include" "" "(may take a while)..") -set(WINDOWS_SYSTEM_DLLS - msvc.*dll - user32.dll - gdi32.dll - shell32.dll - kernel32.dll - ws2_32.dll - wldap32.dll - ole32.dll - comdlg32.dll - shfolder.dll - secur32.dll - wsock32.dll - advapi32.dll - crypt32.dll - imm32.dll - oleaut32.dll - winmm.dll - opengl32.dll - glu32.dll - winspool.drv) + if(WIN32) + #only affects windows due to regex on dll + file(GLOB LIB_FILES "${DEPENDENCIES_INSTALL_DIR}/lib/*dll.*") + install(FILES ${LIB_FILES} DESTINATION ${PKG_STAGE_DIR}/lib ) -set(LINUX_SYSTEM_DLLS - libm.so - libc.so - libstdc* - libgcc_s.so - librt.so - libdl.so - libpthread.so - libidn.so - libgomp.so* - ld-linux-x86-64.so* - libX11.so* - libXext.so* - libXau.so* - libXdmcp.so* - libXxf86vm.so* - libdrm.so.2 - libGL.so* - libGLU.so* - ) + file(GLOB ITK_EXTRA_DLL_FILES_1 "${DEPENDENCIES_INSTALL_DIR}/bin/libITK*.dll") + install(FILES ${ITK_EXTRA_DLL_FILES_1} DESTINATION ${PKG_STAGE_DIR}/bin) -# libgcc_s.*dylib and other *.framework are dragged by QT -set(APPLE_SYSTEM_DLLS - libSystem.*dylib - libiconv.*dylib - libc\\+\\+.*dylib - libstdc.*dylib - libobjc.*dylib - ApplicationServices.framework - CoreFoundation.framework - CoreServices.framework - Security.framework - Carbon.framework - AppKit.framework - Foundation.framework - AGL.framework - OpenGL.framework - libgcc_s.*dylib - ) + file(GLOB ITK_EXTRA_DLL_FILES_2 "${DEPENDENCIES_INSTALL_DIR}/bin/libitk*.dll") + install(FILES ${ITK_EXTRA_DLL_FILES_2} DESTINATION ${PKG_STAGE_DIR}/bin) -if(WIN32 OR CMAKE_CROSSCOMPILING) - set(SYSTEM_DLLS "${WINDOWS_SYSTEM_DLLS}") -else() #case for unixes - if(APPLE) - set(SYSTEM_DLLS "${APPLE_SYSTEM_DLLS}") - else() - set(SYSTEM_DLLS "${LINUX_SYSTEM_DLLS}") - endif() -endif(WIN32 OR CMAKE_CROSSCOMPILING) + file(GLOB OPENCV_EXTRA_DLL_FILES "${DEPENDENCIES_INSTALL_DIR}/bin/libopencv*.dll") + install(FILES ${OPENCV_EXTRA_DLL_FILES} DESTINATION ${PKG_STAGE_DIR}/bin) -macro(is_system_dll matched value) - set(${matched}) - string(TOLOWER ${value} value_) - foreach (pattern ${SYSTEM_DLLS}) - string(TOLOWER ${pattern} pattern_) - if("${value_}" MATCHES "${pattern_}") - set(${matched} TRUE) - endif() - endforeach() -endmacro() + file(GLOB OPENCV_EXTRA_A_FILES "${DEPENDENCIES_INSTALL_DIR}/lib/libopencv*.a") + install(FILES ${OPENCV_EXTRA_A_FILES} DESTINATION ${PKG_STAGE_DIR}/lib) -macro(list_contains var value) - set(${var}) - foreach(value2 ${ARGN}) - if(${value} STREQUAL ${value2}) - set(${var} TRUE) - endif() - endforeach(value2) -endmacro() + #opencv cmake config files in two directories. + # ${PKG_STAGE_DIR}/lib and ${PKG_STAGE_DIR} + file(GLOB OPENCV_CONFIG_FILES_1 "${DEPENDENCIES_INSTALL_DIR}/lib/OpenCV*.cmake") + install(FILES ${OPENCV_CONFIG_FILES_1} DESTINATION ${PKG_STAGE_DIR}/lib) -# Get the translation files coming with Qt, and install them in the bundle -# They are loaded by Monteverdi. -function(get_qt_translation_files RESULT) - # These files are the "qt_<localename>.qm" files - # They are located in QT_TRANSLATIONS_DIR, which comes from FindQt4 - file(GLOB translation_files ${QT_TRANSLATIONS_DIR}/qt_*) + file(GLOB OPENCV_CONFIG_FILES_2 "${DEPENDENCIES_INSTALL_DIR}/OpenCV*.cmake") + install(FILES ${OPENCV_CONFIG_FILES_2} DESTINATION ${PKG_STAGE_DIR}) - # We need to remove the "qt_help_<localename>.qm" files from this list - foreach(translation_item ${translation_files}) - if(${translation_item} MATCHES "qt_help") - list(REMOVE_ITEM translation_files ${translation_item}) + #mxe install qt in a seperate directory under install prefix. So.. + foreach(REQ_DIR + lib + mkspecs + include + imports + plugins + translations + ) + if(EXISTS "${DEPENDENCIES_INSTALL_DIR}/qt/${REQ_DIR}") + func_install_without_message("${DEPENDENCIES_INSTALL_DIR}/qt/${REQ_DIR}" "") endif() endforeach() - set(${RESULT} ${translation_files} PARENT_SCOPE) -endfunction() + #qt/bin is a special case here. + file(GLOB QT_EXTRA_DLL_FILES "${DEPENDENCIES_INSTALL_DIR}/qt/bin/*.dll") + install(FILES ${QT_EXTRA_DLL_FILES} DESTINATION ${PKG_STAGE_DIR}/bin) + + file(GLOB QT_EXECUTABLES "${DEPENDENCIES_INSTALL_DIR}/qt/bin/*.exe") + install(FILES ${QT_EXECUTABLES} DESTINATION ${PKG_STAGE_DIR}/bin) + + file(GLOB QT_EXTRA_EXECUTABLES "${Monteverdi_BINARY_DIR}/PACKAGE-TOOLS/src/PACKAGE-TOOLS/*.exe") + install(FILES ${QT_EXTRA_EXECUTABLES} DESTINATION ${PKG_STAGE_DIR}/bin) + + endif(WIN32) + +endfunction() #func_install_xdk_files + +function(func_install_without_message src_dir dst_dir_suffix) + set (extra_func_args ${ARGN}) + list(LENGTH extra_func_args num_extra_args) + if (${num_extra_args} GREATER 0) + list(GET extra_func_args 0 optional_msg) + endif() + + if( "${dst_dir_suffix}" STREQUAL "") + set(dst_dir "${PKG_STAGE_DIR}") + else() + set(dst_dir "${PKG_STAGE_DIR}/${dst_dir_suffix}") + endif() -function(install_common include_mvd) + get_filename_component(src_dir_name ${src_dir} NAME) + set(install_msg "message(STATUS \"Installing: ${CMAKE_INSTALL_PREFIX}/${dst_dir}/${src_dir_name} ${optional_msg}\")") + install(CODE "${install_msg}" ) + install( + DIRECTORY ${src_dir} + DESTINATION ${dst_dir} + MESSAGE_NEVER ) +endfunction() - #a convenient cmake var for storing <prefix> -# set(PKG_STAGE_DIR "${stage_dir}") +function(func_install_support_files include_mvd) #a convenient cmake var for storing <prefix>/bin set(PKG_STAGE_BIN_DIR "${PKG_STAGE_DIR}/bin") - #root folder where otb applications are installed - set(PKG_OTBLIBS_DIR "${PKG_STAGE_DIR}/lib/otb") - #<prefix>/share for gdal data files set(PKG_SHARE_DEST_DIR ${PKG_STAGE_DIR}/share) set(PKG_SHARE_SOURCE_DIR ${DEPENDENCIES_INSTALL_DIR}/share) - if(NOT OTB_APPS_LIST) - message(FATAL_ERROR "you must set 'OTB_APPS_LIST' before calling this method") - endif() - # Just check if required variables are defined. foreach(req DEPENDENCIES_INSTALL_DIR @@ -264,42 +265,15 @@ function(install_common include_mvd) endforeach(req) # one for debugging.. - # install(CODE "message(\"CMake/PackageHelper.cmake:install_common(${outdir})\n${vars}\n\")") - - set(PKG_OTB_SHARE_SOURCE_DIR "${PKG_SHARE_SOURCE_DIR}") - - #For Unixes we make them in the *pkgsetup.in - ##################### install environment source ########################## - if(WIN32 OR CMAKE_CROSSCOMPILING) - foreach(ENV_SOURCE_FILE - "${PACKAGE_SUPPORT_FILES_DIR}/otbenv.cmd" - "${PACKAGE_SUPPORT_FILES_DIR}/otbenv.profile") - if(EXISTS ${ENV_SOURCE_FILE}) - install(FILES ${ENV_SOURCE_FILE} DESTINATION ${PKG_STAGE_DIR}) - endif() - endforeach() - #MONTEVERDI_INSTALL_DIR/share has otb/i18N directory - set(PKG_OTB_SHARE_SOURCE_DIR "${MONTEVERDI_INSTALL_DIR}/share") - endif() - ####################### install cli and gui scripts ########################### - file(GLOB PKG_APP_SCRIPTS - ${OTB_INSTALL_DIR}/bin/otbcli* - ${OTB_INSTALL_DIR}/bin/otbgui*) # - - list(LENGTH PKG_APP_SCRIPTS PKG_APP_SCRIPTS_LENGTH) - if (PKG_APP_SCRIPTS_LENGTH LESS 1) - message(WARNING "PKG_APP_SCRIPTS is empty: ${PKG_APP_SCRIPTS}") - endif() + # install(CODE "message(\"CMake/PackageHelper.cmake:install_supoport_files(${outdir})\n${vars}\n\")") + if(NOT PKG_GENERATE_XDK) + func_install_otb_support_files() - ##################### install cli and gui scripts ####################### - install(PROGRAMS ${PKG_APP_SCRIPTS} DESTINATION ${PKG_STAGE_BIN_DIR}) + if(include_mvd) + func_install_monteverdi_support_files() + endif(include_mvd) - if(include_mvd) - install_monteverdi_files() - if(NOT EXISTS "${PKG_OTB_SHARE_SOURCE_DIR}/otb/i18n") - message(FATAL_ERROR "error ${PKG_OTB_SHARE_SOURCE_DIR}/otb not exists") - endif() - endif() + endif() #NOT PKG_GENERATE_XDK ####################### install GDAL data ############################ set(GDAL_DATA ${PKG_SHARE_SOURCE_DIR}/gdal) @@ -315,19 +289,13 @@ function(install_common include_mvd) ####################### install OSSIM data ########################## install(DIRECTORY ${PKG_SHARE_SOURCE_DIR}/ossim DESTINATION ${PKG_SHARE_DEST_DIR}) - ####################### install otb share ########################### - install(DIRECTORY ${PKG_OTB_SHARE_SOURCE_DIR}/otb DESTINATION ${PKG_SHARE_DEST_DIR}) - ####################### install proj share ########################## if(EXISTS ${PKG_SHARE_SOURCE_DIR}/proj) install(DIRECTORY ${PKG_SHARE_SOURCE_DIR}/proj DESTINATION ${PKG_SHARE_DEST_DIR}) endif() - ####################### Install otb applications #################### - install(DIRECTORY "${OTB_APPLICATIONS_DIR}" DESTINATION ${PKG_OTBLIBS_DIR}) - ####################### Install copyrights ########################## - if(WIN32 OR CMAKE_CROSSCOMPILING) + if(WIN32) #do install license for windows package else() install(DIRECTORY ${PKG_SHARE_SOURCE_DIR}/copyright DESTINATION ${PKG_SHARE_DEST_DIR}) @@ -336,17 +304,81 @@ function(install_common include_mvd) endfunction() -function(install_monteverdi_files) +function(func_install_otb_support_files) + foreach(req + PKG_STAGE_DIR + OTB_INSTALL_DIR + MONTEVERDI_INSTALL_DIR + DEPENDENCIES_INSTALL_DIR + OTB_APPLICATIONS_DIR + ) + if(NOT DEFINED ${req}) + message(FATAL_ERROR "you must set ${req} before calling this method") + endif() + set(vars "${vars} ${req}=[${${req}}]\n") + endforeach(req) + + #a convenient cmake var for storing <prefix>/bin + set(PKG_STAGE_BIN_DIR "${PKG_STAGE_DIR}/bin") + + #root folder where otb applications are installed + set(PKG_OTBLIBS_DIR "${PKG_STAGE_DIR}/lib/otb") + + #<prefix>/share for gdal data files + set(PKG_SHARE_DEST_DIR ${PKG_STAGE_DIR}/share) + + set(PKG_SHARE_SOURCE_DIR ${DEPENDENCIES_INSTALL_DIR}/share) + + #For Unixes we make them in the *pkgsetup.in + ##################### install environment source ########################## + if(WIN32) + foreach(ENV_SOURCE_FILE + "${PACKAGE_SUPPORT_FILES_DIR}/otbenv.cmd" + "${PACKAGE_SUPPORT_FILES_DIR}/otbenv.profile") + if(EXISTS ${ENV_SOURCE_FILE}) + install(FILES ${ENV_SOURCE_FILE} DESTINATION ${PKG_STAGE_DIR}) + endif() + endforeach() + + #we need startup files for mapla monteverdi in the root directory + #For Unixes, we make them inside pkgsetup script! + foreach(exe_file mapla monteverdi) + install( + PROGRAMS ${PACKAGE_SUPPORT_FILES_DIR}/${exe_file}.bat + DESTINATION "${PKG_STAGE_DIR}" + ) + endforeach() + endif() + + ####################### install cli and gui scripts ########################### + file(GLOB PKG_APP_SCRIPTS + ${OTB_INSTALL_DIR}/bin/otbcli* + ${OTB_INSTALL_DIR}/bin/otbgui*) # + + list(LENGTH PKG_APP_SCRIPTS PKG_APP_SCRIPTS_LENGTH) + if (PKG_APP_SCRIPTS_LENGTH LESS 1) + message(WARNING "PKG_APP_SCRIPTS is empty: ${PKG_APP_SCRIPTS}") + endif() + + ##################### install cli and gui scripts ####################### + install(PROGRAMS ${PKG_APP_SCRIPTS} DESTINATION ${PKG_STAGE_BIN_DIR}) + + ####################### Install otb applications #################### + install(DIRECTORY "${OTB_APPLICATIONS_DIR}" DESTINATION ${PKG_OTBLIBS_DIR}) + +endfunction() + +function(func_install_monteverdi_support_files) #name/ext of qt's sqlite plugin. Varies with platform/OS - if(WIN32 OR CMAKE_CROSSCOMPILING) + if(WIN32) set(PKG_QTSQLITE_FILENAME "qsqlite4.dll") elseif(APPLE) set(PKG_QTSQLITE_FILENAME "libqsqlite.dylib") - elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux" AND NOT CMAKE_CROSSCOMPILING) + elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux") set(PKG_QTSQLITE_FILENAME "libqsqlite.so") else() - message(FATAL_ERROR "install_monteverdi_files: Unknown OS/Platform") + message(FATAL_ERROR "func_install_monteverdi_support_files: Unknown OS/Platform") endif() #root folder where qt plugins are installed @@ -384,7 +416,7 @@ function(install_monteverdi_files) DESTINATION ${PKG_STAGE_DIR}) endif() - if(WIN32 OR CMAKE_CROSSCOMPILING) + if(WIN32) ####################### install mingw qt.conf ########################## if(EXISTS ${PACKAGE_SUPPORT_FILES_DIR}/qt.conf) install(FILES ${PACKAGE_SUPPORT_FILES_DIR}/qt.conf @@ -408,39 +440,51 @@ function(install_monteverdi_files) foreach(APP_TS_FILE ${APP_TS_FILES}) get_filename_component(APP_TS_FILENAME ${APP_TS_FILE} NAME_WE) install(FILES ${Monteverdi_BINARY_DIR}/i18n/${APP_TS_FILENAME}.qm - DESTINATION ${PKG_OTB_I18N_DIR}) + DESTINATION ${PKG_OTB_I18N_DIR} + ) endforeach() + #set(PKG_OTB_ccSHARE_SOURCE_DIR "${MONTEVERDI_INSTALL_DIR}") + # if(WIN32) + # set(PKG_OTB_ccSHARE_SOURCE_DIR "${MONTEVERDI_INSTALL_DIR}/share") + # endif() + if(NOT EXISTS "${MONTEVERDI_INSTALL_DIR}/share/otb/i18n") + message(FATAL_ERROR "error ${MONTEVERDI_INSTALL_DIR}/share/otb/i18n not exists") + endif() + ####################### install otb share ########################### + install(DIRECTORY ${MONTEVERDI_INSTALL_DIR}/share/otb DESTINATION ${PKG_SHARE_DEST_DIR}) + endfunction() -macro(empty_package_staging_directory) +macro(macro_empty_package_staging_directory) message(STATUS "Empty package staging directory: ${CMAKE_INSTALL_PREFIX}/${PKG_STAGE_DIR}") execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory "${CMAKE_INSTALL_PREFIX}/${PKG_STAGE_DIR}") -endmacro() +endmacro() #macro_empty_package_staging_directory #NOTE: # VAR_IN_PKGSETUP_CONFIGURE cmake variable is set below. # This is important and useful running configure_file() # over *pkgsetup.in -function(configure_package) +function(func_prepare_package) - if(WIN32 OR CMAKE_CROSSCOMPILING) + set(DEST_LIB_DIR lib) + set(DEST_BIN_DIR bin) + set(DEST_APP_DIR lib/otb/applications) + set(EXE_EXT "") + set(SCR_EXT ".sh") + set(LIB_EXT "*so") + if(WIN32) set(EXE_EXT ".exe") set(LIB_EXT "*dll") set(SCR_EXT ".bat") - else() #(WIN32 OR CMAKE_CROSSCOMPILING) - if(UNIX) - set(EXE_EXT "") - set(SCR_EXT ".sh") - set(LIB_EXT "*so") - #Q: why apple changed this one? - #A: To break compatibility with others and make money! - if(APPLE) - set(LIB_EXT "*dylib") - endif() #APPLE - endif() #UNIX - endif() #(WIN32 OR CMAKE_CROSSCOMPILING) + set(DEST_LIB_DIR bin) + elseif(APPLE) + set(LIB_EXT "*dylib") + endif() + + file(WRITE ${CMAKE_BINARY_DIR}/install_to_bin "") + file(WRITE ${CMAKE_BINARY_DIR}/install_to_lib "") #This must exist in any OTB Installation minimal or full set(VAR_IN_PKGSETUP_CONFIGURE "bin/otbApplicationLauncherCommandLine") @@ -453,6 +497,16 @@ function(configure_package) list(APPEND EXE_FILES "otbApplicationLauncherQt") list(APPEND EXE_FILES "iceViewer") list(APPEND EXE_FILES "otbTestDriver") + + #Q: why we need itkTestDriver?. + #A: Because we need to get all dlls from ITK via itkTestDriver linkage. + # itkvnl and itkvnl_algo are referenced in its lib/cmake/ITK-4.8/ITKTargets.cmake + # But OTB didn't use them and hence not counted. However an erro has been observed when + # using XDK on windows that the file is missing or damaged + if(PKG_GENERATE_XDK) + list(APPEND EXE_FILES "itkTestDriver") + endif() + list(APPEND EXE_FILES "monteverdi") list(APPEND EXE_FILES "mapla") @@ -477,21 +531,10 @@ function(configure_package) endif() endforeach() - #For Unixes we write the startup script in the *pkgsetup.in - if(WIN32 OR CMAKE_CROSSCOMPILING) - install( - PROGRAMS "${PACKAGE_SUPPORT_FILES_DIR}/monteverdi.bat" - DESTINATION "${PKG_STAGE_DIR}" - ) - install( - PROGRAMS "${PACKAGE_SUPPORT_FILES_DIR}/mapla.bat" - DESTINATION "${PKG_STAGE_DIR}" - ) - endif(WIN32 OR CMAKE_CROSSCOMPILING) - file(GLOB OTB_APPS_LIST ${OTB_APPLICATIONS_DIR}/otbapp_${LIB_EXT}) # /lib/otb #see the first comment about VAR_IN_PKGSETUP_CONFIGURE + #NOTE: this is not used in windows yet.. foreach(OTB_APP_SO ${OTB_APPS_LIST}) get_filename_component(OTB_APP_SO_NAME ${OTB_APP_SO} NAME) set(VAR_IN_PKGSETUP_CONFIGURE "${VAR_IN_PKGSETUP_CONFIGURE} lib/otb/applications/${OTB_APP_SO_NAME}") @@ -504,17 +547,19 @@ function(configure_package) list(APPEND PKG_PEFILES ${OTB_APPS_LIST}) - install_common(${include_mvd}) + func_install_support_files(${include_mvd}) execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory "${CMAKE_BINARY_DIR}/temp_so_names_dir") execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/temp_so_names_dir") set(alldlls) set(notfound_dlls) + #message(STATUS "Processing start") foreach(infile ${PKG_PEFILES}) get_filename_component(bn ${infile} NAME) - process_deps(${bn}) + func_process_deps(${bn}) endforeach() + #message(STATUS "Processing done") list(LENGTH notfound_dlls nos) if(${nos} GREATER 0) @@ -534,110 +579,16 @@ function(configure_package) set(VAR_IN_PKGSETUP_CONFIGURE "${VAR_IN_PKGSETUP_CONFIGURE}" PARENT_SCOPE) -endfunction() - -# The below function is modified from GetPrerequisities.cmake -# which is distributed with CMake. -function(is_file_a_symbolic_link file result_var1 result_var2) - # - # A file is not executable until proven otherwise: - # - set(${result_var1} 0 PARENT_SCOPE) - set(${result_var2} "" PARENT_SCOPE) +endfunction() #func_prepare_package - get_filename_component(file_full "${file}" ABSOLUTE) - string(TOLOWER "${file_full}" file_full_lower) +function(func_process_deps infile) - # If file name ends in .exe on Windows, *assume* executable: - # - if(WIN32 AND NOT UNIX) - if("${file_full_lower}" MATCHES "\\.lnk$") - set(${result_var1} 1 PARENT_SCOPE) - #Assuming the file is linked to a file with same name without .lnk extension - get_filename_component(name_we_lnk "${file_full_lower}" NAME_WE) - set(${result_var2} "${name_we_lnk}" PARENT_SCOPE) - return() - endif() - - # A clause could be added here that uses output or return value of dumpbin - # to determine ${result_var}. In 99%+? practical cases, the exe name - # match will be sufficient... - # - endif() - - # Use the information returned from the Unix shell command "file" to - # determine if ${file_full} should be considered an executable file... - # - # If the file command's output contains "executable" and does *not* contain - # "text" then it is likely an executable suitable for prerequisite analysis - # via the get_prerequisites macro. - # - if(UNIX) - if(NOT file_cmd) - find_program(file_cmd "file") - mark_as_advanced(file_cmd) - endif() - - if(file_cmd) - execute_process(COMMAND "${file_cmd}" "${file_full}" - RESULT_VARIABLE file_rv - OUTPUT_VARIABLE file_ov - ERROR_VARIABLE file_ev - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - if(NOT file_rv STREQUAL "0") - message(FATAL_ERROR "${file_cmd} failed: ${file_rv}\n${file_ev}") - endif() - - # Replace the name of the file in the output with a placeholder token - # (the string " _file_full_ ") so that just in case the path name of - # the file contains the word "text" or "executable" we are not fooled - # into thinking "the wrong thing" because the file name matches the - # other 'file' command output we are looking for... - # - string(REPLACE "${file_full}" " _file_full_ " file_ov "${file_ov}") - string(TOLOWER "${file_ov}" file_ov_lower) - - #message(FATAL_ERROR "file_ov='${file_ov}'") - if("${file_ov_lower}" MATCHES "symbolic link") - #message(STATUS "symbolic link!") - set(${result_var1} 1 PARENT_SCOPE) - #Now find where the symlink is linked to. - #Do a regex replace - if(UNIX) - if(APPLE) - string(REGEX REPLACE "_file_full_*.*symbolic.link.to." - "" symlinked_to ${file_ov}) - else(APPLE) - string(REGEX REPLACE "_file_full_*.*symbolic.link.to.." - "" symlinked_to ${file_ov}) - endif(APPLE) - endif(UNIX) - #Take out last character which is a single quote - string(REPLACE "'" "" symlinked_to "${symlinked_to}") - #strip for our own sanity - string(STRIP ${symlinked_to} symlinked_to) - set(${result_var2} "${symlinked_to}" PARENT_SCOPE) - #message(FATAL_ERROR "${file_full} is symlinked_to ${symlinked_to}") - return() - endif() - - else() - message(STATUS "warning: No 'file' command, skipping execute_process...") + if(APPLE) + if( "${infile}" MATCHES "@rpath") + string(REGEX REPLACE "@rpath." "" infile "${infile}") endif() endif() -endfunction() - - - -function(process_deps infile) - - if(APPLE) - if( "${infile}" MATCHES "@rpath") - string(REGEX REPLACE "@rpath." "" infile "${infile}") - endif() - endif() - if(WIN32 OR CMAKE_CROSSCOMPILING) + if(WIN32) string(TOLOWER "${infile}" infile_lower ) endif() get_filename_component(bn ${infile} NAME) @@ -648,7 +599,7 @@ function(process_deps infile) foreach(SEARCHDIR ${PKG_SEARCHDIRS}) if(NOT DLL_FOUND) - if(WIN32 OR CMAKE_CROSSCOMPILING) + if(WIN32) if(NOT EXISTS ${SEARCHDIR}/${infile} ) if(EXISTS ${SEARCHDIR}/${infile_lower} ) set(infile ${infile_lower}) @@ -660,8 +611,8 @@ function(process_deps infile) message(STATUS "Processing ${SEARCHDIR}/${infile}") is_file_executable("${SEARCHDIR}/${infile}" is_executable) if(is_executable) - install(PROGRAMS "${SEARCHDIR}/${infile}" - DESTINATION ${PKG_STAGE_DIR}/bin) + #install(PROGRAMS "${SEARCHDIR}/${infile}" DESTINATION ${PKG_STAGE_DIR}/bin) + file(APPEND ${CMAKE_BINARY_DIR}/install_to_${DEST_BIN_DIR} "${SEARCHDIR}/${infile}\n") else(is_executable) get_filename_component(bn_we ${infile} NAME_WE) file(GLOB sofiles "${SEARCHDIR}/${bn_we}*") @@ -673,10 +624,9 @@ function(process_deps infile) OR "${sofile_ext}" MATCHES ".a") set(is_valid FALSE) endif() - if(is_valid) get_filename_component(basename_of_sofile ${sofile} NAME) - is_file_a_symbolic_link("${sofile}" is_symlink linked_to_file) + func_is_file_a_symbolic_link("${sofile}" is_symlink linked_to_file) if(is_symlink) # NOTE: $OUT_DIR is set actually in pkgsetup.in. So don't try # any pre-mature optimization on that variable names @@ -686,22 +636,10 @@ function(process_deps infile) ) #message("${sofile} is a symlink to ${linked_to_file}") else() # is_symlink - if("${basename_of_sofile}" MATCHES "otbapp_") - if(NOT PKG_GENERATE_XDK) - install(FILES "${sofile}" DESTINATION ${PKG_STAGE_DIR}/lib/otb/applications) - endif() - else() #if(.. MATCHES "otbapp_") - #if we are making xdk. skill all those starting with libotb case insensitively - if(PKG_GENERATE_XDK) - string(TOLOWER "${basename_of_sofile}" sofile_lower ) - if(NOT "${sofile_lower}" MATCHES "libotb") - install(FILES "${sofile}" DESTINATION ${PKG_STAGE_DIR}/lib) - endif() - else() #PKG_GENERATE_XDK - #just install the so file to <staging-dir>/lib - install(FILES "${sofile}" DESTINATION ${PKG_STAGE_DIR}/lib) - endif() #PKG_GENERATE_XDK - + if(NOT "${basename_of_sofile}" MATCHES "otbapp_") + file(APPEND ${CMAKE_BINARY_DIR}/install_to_${DEST_LIB_DIR} "${sofile}\n") + #just install the so file to <staging-dir>/lib + #install(FILES "${sofile}" DESTINATION ${PKG_STAGE_DIR}/lib MESSAGE_NEVER) # Finally touch a file in temp directory for globbing later # message("touching ${basename_of_sofile}") execute_process(COMMAND ${CMAKE_COMMAND} -E touch "${CMAKE_BINARY_DIR}/temp_so_names_dir/${basename_of_sofile}") @@ -720,7 +658,7 @@ function(process_deps infile) message(FATAL_ERROR "loader_ev=${loader_ev}\n PACKAGE-OTB: result_variable is '${loader_rv}'") endif() - if(WIN32 OR CMAKE_CROSSCOMPILING) + if(WIN32) string(REGEX MATCHALL "DLL.Name..[A-Za-z(0-9\\.0-9)+_\\-]*" loader_ov "${loader_ov}") string(REGEX REPLACE "DLL.Name.." "" needed_dlls "${loader_ov}") else() #case for unixes @@ -736,7 +674,7 @@ function(process_deps infile) foreach(needed_dll ${needed_dlls}) string(STRIP ${needed_dll} needed_dll) - process_deps(${needed_dll}) + func_process_deps(${needed_dll}) endforeach() endif() endif(NOT DLL_FOUND) @@ -752,4 +690,240 @@ function(process_deps infile) endif(NOT DLL_FOUND) set(notfound_dlls "${notfound_dlls}" PARENT_SCOPE ) endif() + +endfunction() + +# The below function is modified from GetPrerequisities.cmake +# which is distributed with CMake. +function(func_is_file_a_symbolic_link file result_var1 result_var2) + # + # A file is not executable until proven otherwise: + # + set(${result_var1} 0 PARENT_SCOPE) + set(${result_var2} "" PARENT_SCOPE) + + get_filename_component(file_full "${file}" ABSOLUTE) + string(TOLOWER "${file_full}" file_full_lower) + + # If file name ends in .exe on Windows, *assume* executable: + # + if(WIN32 AND NOT UNIX) + if("${file_full_lower}" MATCHES "\\.lnk$") + set(${result_var1} 1 PARENT_SCOPE) + #Assuming the file is linked to a file with same name without .lnk extension + get_filename_component(name_we_lnk "${file_full_lower}" NAME_WE) + set(${result_var2} "${name_we_lnk}" PARENT_SCOPE) + return() + endif() + + # A clause could be added here that uses output or return value of dumpbin + # to determine ${result_var}. In 99%+? practical cases, the exe name + # match will be sufficient... + # + endif() + + # Use the information returned from the Unix shell command "file" to + # determine if ${file_full} should be considered an executable file... + # + # If the file command's output contains "executable" and does *not* contain + # "text" then it is likely an executable suitable for prerequisite analysis + # via the get_prerequisites macro. + # + if(UNIX) + if(NOT file_cmd) + find_program(file_cmd "file") + mark_as_advanced(file_cmd) + endif() + + if(file_cmd) + execute_process(COMMAND "${file_cmd}" "${file_full}" + RESULT_VARIABLE file_rv + OUTPUT_VARIABLE file_ov + ERROR_VARIABLE file_ev + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if(NOT file_rv STREQUAL "0") + message(FATAL_ERROR "${file_cmd} failed: ${file_rv}\n${file_ev}") + endif() + + # Replace the name of the file in the output with a placeholder token + # (the string " _file_full_ ") so that just in case the path name of + # the file contains the word "text" or "executable" we are not fooled + # into thinking "the wrong thing" because the file name matches the + # other 'file' command output we are looking for... + # + string(REPLACE "${file_full}" " _file_full_ " file_ov "${file_ov}") + string(TOLOWER "${file_ov}" file_ov_lower) + + #message(FATAL_ERROR "file_ov='${file_ov}'") + if("${file_ov_lower}" MATCHES "symbolic link") + #message(STATUS "symbolic link!") + set(${result_var1} 1 PARENT_SCOPE) + #Now find where the symlink is linked to. + #Do a regex replace + if(UNIX) + if(APPLE) + string(REGEX REPLACE "_file_full_*.*symbolic.link.to." + "" symlinked_to ${file_ov}) + else(APPLE) + string(REGEX REPLACE "_file_full_*.*symbolic.link.to.." + "" symlinked_to ${file_ov}) + endif(APPLE) + endif(UNIX) + #Take out last character which is a single quote + string(REPLACE "'" "" symlinked_to "${symlinked_to}") + #strip for our own sanity + string(STRIP ${symlinked_to} symlinked_to) + set(${result_var2} "${symlinked_to}" PARENT_SCOPE) + #message(FATAL_ERROR "${file_full} is symlinked_to ${symlinked_to}") + return() + endif() + + else() + message(STATUS "warning: No 'file' command, skipping execute_process...") + endif() + endif() +endfunction() + + +#function to prepare list of install files to bin and lib directory +#input_file is written by func_process_deps() macro +#with_xdk is flag to indicate wheather we are build xdk or not. +#Its value is same as PKG_GENERATE_XDK +# install_list_variable -output variable that store the final list +# This list is looped and all install() command are created there. +function(func_prepare_install_list input_file with_xdk install_list_variable ) + #message("-- input_file = '${input_file}'") + set(install_to_ITEMS) + file(STRINGS "${input_file}" install_to_ITEMS) + foreach(install_to_ITEM ${install_to_ITEMS}) + get_filename_component(install_to_ITEM_BASENAME ${install_to_ITEM} NAME_WE) + #MUST remove otb applications. Installed in other macro later + if ("${install_to_ITEM_BASENAME}" MATCHES "otbapp_*") + list(REMOVE_ITEM install_to_ITEMS "${install_to_ITEM}") + endif() + + if(with_xdk) + if ("${install_to_ITEM_BASENAME}" + MATCHES + "libOTB|libotb|otbApp|otbTest|libMonteverdi|monteverdi|mapla|iceViewer" + ) + list(REMOVE_ITEM install_to_ITEMS "${install_to_ITEM}") + endif() + endif() #with_xdk + endforeach() + + set(${install_list_variable} "${install_to_ITEMS}" PARENT_SCOPE) + +endfunction() # func_prepare_install_list + + +set(WINDOWS_SYSTEM_DLLS + msvc.*dll + user32.dll + gdi32.dll + shell32.dll + kernel32.dll + ws2_32.dll + wldap32.dll + ole32.dll + comdlg32.dll + shfolder.dll + secur32.dll + wsock32.dll + advapi32.dll + crypt32.dll + imm32.dll + oleaut32.dll + winmm.dll + opengl32.dll + glu32.dll + rpcrt4.dll + winspool.drv) + +set(LINUX_SYSTEM_DLLS + libm.so + libc.so + libstdc* + libgcc_s.so + librt.so + libdl.so + libpthread.so + libidn.so + libgomp.so* + ld-linux-x86-64.so* + libX11.so* + libXext.so* + libXau.so* + libXdmcp.so* + libXxf86vm.so* + libdrm.so.2 + libGL.so* + libGLU.so* + ) + +# libgcc_s.*dylib and other *.framework are dragged by QT +set(APPLE_SYSTEM_DLLS + libSystem.*dylib + libiconv.*dylib + libc\\+\\+.*dylib + libstdc.*dylib + libobjc.*dylib + ApplicationServices.framework + CoreFoundation.framework + CoreServices.framework + Security.framework + Carbon.framework + AppKit.framework + Foundation.framework + AGL.framework + OpenGL.framework + libgcc_s.*dylib + ) + +if(WIN32) + set(SYSTEM_DLLS "${WINDOWS_SYSTEM_DLLS}") +else() #case for unixes + if(APPLE) + set(SYSTEM_DLLS "${APPLE_SYSTEM_DLLS}") + else() + set(SYSTEM_DLLS "${LINUX_SYSTEM_DLLS}") + endif() +endif(WIN32) + +macro(is_system_dll matched value) + set(${matched}) + string(TOLOWER ${value} value_) + foreach (pattern ${SYSTEM_DLLS}) + string(TOLOWER ${pattern} pattern_) + 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() + +# Get the translation files coming with Qt, and install them in the bundle +# They are loaded by Monteverdi. +function(get_qt_translation_files RESULT) + # These files are the "qt_<localename>.qm" files + # They are located in QT_TRANSLATIONS_DIR, which comes from FindQt4 + file(GLOB translation_files ${QT_TRANSLATIONS_DIR}/qt_*) + + # We need to remove the "qt_help_<localename>.qm" files from this list + foreach(translation_item ${translation_files}) + if(${translation_item} MATCHES "qt_help") + list(REMOVE_ITEM translation_files ${translation_item}) + endif() + endforeach() + + set(${RESULT} ${translation_files} PARENT_SCOPE) endfunction() -- GitLab