diff --git a/SuperBuild/Packaging/PackageHelper.cmake b/SuperBuild/Packaging/PackageHelper.cmake index dcb07fd2cbd55c33347770739ebc0bde8d84bd40..f6e670522f2c4aec213eacd7f0e86b216a7149c5 100644 --- a/SuperBuild/Packaging/PackageHelper.cmake +++ b/SuperBuild/Packaging/PackageHelper.cmake @@ -52,20 +52,23 @@ macro(macro_super_package) include(GetPrerequisites) set(LOADER_PROGRAM_ARGS ${loader_program_args}) - - set(DEST_LIB_DIR lib) + set(DEST_BIN_DIR bin) set(DEST_APP_DIR lib/otb/applications) + + set(LIB_PREFIX lib) + set(DEST_LIB_DIR lib) set(EXE_EXT "") set(SCR_EXT ".sh") set(LIB_EXT ".so") set(PYMODULE_EXT ".so") if(WIN32) + set(LIB_PREFIX) + set(DEST_LIB_DIR bin) set(EXE_EXT ".exe") set(LIB_EXT ".dll") set(SCR_EXT ".bat") set(PYMODULE_EXT ".pyd") - set(DEST_LIB_DIR bin) elseif(APPLE) set(LIB_EXT ".dylib") endif() @@ -242,25 +245,30 @@ function(func_prepare_package) list(APPEND PKG_PEFILES "qmake${EXE_EXT}") list(APPEND PKG_PEFILES "rcc${EXE_EXT}") list(APPEND PKG_PEFILES "uic${EXE_EXT}") - list(APPEND PKG_PEFILES "sharkVersion${EXE_EXT}") list(APPEND PKG_PEFILES "proj${EXE_EXT}") list(APPEND PKG_PEFILES "cs2cs${EXE_EXT}") + + #shark is optional + if(EXISTS "${DEPENDENCIES_INSTALL_DIR}/bin/sharkVersion${EXE_EXT}") + list(APPEND PKG_PEFILES "sharkVersion${EXE_EXT}") + endif() #RK: there is a bug in itk cmake files in install tree #we workaround with below code #start hack - file(GLOB itk_lib_files - "${DEPENDENCIES_INSTALL_DIR}/bin/itk*${LIB_EXT}" - "${DEPENDENCIES_INSTALL_DIR}/bin/ITK*${LIB_EXT}" + file(GLOB itk_all_lib_files + "${DEPENDENCIES_INSTALL_DIR}/${DEST_LIB_DIR}/${LIB_PREFIX}itk*${LIB_EXT}*" + "${DEPENDENCIES_INSTALL_DIR}/${DEST_LIB_DIR}/${LIB_PREFIX}ITK*${LIB_EXT}*" ) - foreach(itk_lib_file ${itk_lib_files}) - if(NOT EXISTS "${itk_lib_file}") - message(FATAL_ERROR "{itk_lib_file} does not exist") - endif() + + foreach(itk_lib_file ${itk_all_lib_files}) + func_is_file_a_symbolic_link("${itk_lib_file}" a_symlink itk_lib_file_target) + if(NOT a_symlink) list(APPEND PKG_PEFILES "${itk_lib_file}") + endif() endforeach() #end hack - + file(GLOB otb_test_exe_list "${DEPENDENCIES_INSTALL_DIR}/bin/gdal*${EXE_EXT}" "${OTB_BINARY_DIR}/bin/*Test*${EXE_EXT}" @@ -321,46 +329,48 @@ function(func_process_deps input_file) endif() message("Processing ${input_file_full_path}") - - is_file_executable("${input_file_full_path}" is_executable) - if(is_executable) - file(APPEND ${CMAKE_BINARY_DIR}/install_to_${DEST_BIN_DIR} "${input_file_full_path}\n") - else(is_executable) + + set(is_executable FALSE) + is_file_executable2("${input_file_full_path}" is_executable) + if(NOT is_executable) + pkg_install_rule(${input_file_full_path}) + message("not is_executable ${input_file_full_path}") + return() + endif() #NOT is_executable + + if(UNIX) + # Deal with symlinks. + # For any valid symlinks, (see 'not_valid' below) + # we append ln -s source target commands to a file + # That file is executed during installation. + get_filename_component(bn_we ${input_file_full_path} NAME_WE) + get_filename_component(bn_path ${input_file_full_path} PATH) - if(UNIX) - # Deal with symlinks. - # For any valid symlinks, (see 'not_valid' below) - # we append ln -s source target commands to a file - # That file is executed during installation. - get_filename_component(bn_we ${input_file_full_path} NAME_WE) - get_filename_component(bn_path ${input_file_full_path} PATH) + file(GLOB sofiles "${bn_path}/${bn_we}*") + foreach(sofile ${sofiles}) + get_filename_component(basename_of_sofile ${sofile} NAME) + get_filename_component(sofile_ext ${sofile} EXT) + set(not_valid FALSE) + if( "${sofile_ext}" MATCHES ".la" + OR "${sofile_ext}" MATCHES ".prl" + OR "${sofile_ext}" MATCHES ".a" + OR IS_DIRECTORY "${sofile}" ) + set(not_valid TRUE) + endif() - file(GLOB sofiles "${bn_path}/${bn_we}*") - foreach(sofile ${sofiles}) - get_filename_component(basename_of_sofile ${sofile} NAME) - get_filename_component(sofile_ext ${sofile} EXT) - set(not_valid FALSE) - if( "${sofile_ext}" MATCHES ".la" - OR "${sofile_ext}" MATCHES ".prl" - OR "${sofile_ext}" MATCHES ".a" - OR IS_DIRECTORY "${sofile}" ) - set(not_valid TRUE) - endif() - - if(not_valid) - continue() - endif() - - func_is_file_a_symbolic_link("${sofile}" is_symlink linked_to_file) - - if(is_symlink) - add_to_symlink_list("${linked_to_file}" "${basename_of_sofile}") - endif() # is_symlink - - endforeach() + if(not_valid) + continue() + endif() + + func_is_file_a_symbolic_link("${sofile}" is_symlink linked_to_file) + + if(is_symlink) + add_to_symlink_list("${linked_to_file}" "${basename_of_sofile}") + endif() # is_symlink + + endforeach() - endif(UNIX) - endif(is_executable) + endif(UNIX) set(raw_items) diff --git a/SuperBuild/Packaging/PackageMacros.cmake b/SuperBuild/Packaging/PackageMacros.cmake index a2283f28807f9ef8f6b9ac45788ea8b2b5fef2f5..eea19d1d0293c7d8e7672f89e4cacfbacce604d8 100755 --- a/SuperBuild/Packaging/PackageMacros.cmake +++ b/SuperBuild/Packaging/PackageMacros.cmake @@ -98,7 +98,7 @@ macro(add_to_symlink_list src_file target_file) if(NOT SKIP_INSTALL) file(APPEND ${CMAKE_BINARY_DIR}/make_symlinks_temp - "if [ -f \"\$OUT_DIR/lib/${src_file}\" ]; then \n ln -sf \"$OUT_DIR/lib/${src_file}\" \"$OUT_DIR/lib/${target_file}\" \n fi;\n" + "ln -sf \"$OUT_DIR/lib/${src_file}\" \"$OUT_DIR/lib/${target_file}\" \n" ) endif() endmacro() @@ -131,6 +131,129 @@ function(check_for_gtk_libs input_file result) endfunction() +function(is_file_executable2 file result_var) + # + # A file is not executable until proven otherwise: + # + set(${result_var} 0 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 "\\.exe$") + set(${result_var} 1 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) + + #message(STATUS "file_ov='${file_ov}'") + #below executable check works for both mac osx and linux + if("${file_ov}" MATCHES "executable") + #message(STATUS "executable!") + if("${file_ov}" MATCHES "text") + set(${result_var} 0 PARENT_SCOPE) + #message(FATAL_ERROR "but text, so *not* a binary executable!") + else() + set(${result_var} 1 PARENT_SCOPE) + return() + endif() + endif() + + # Also detect position independent executables on Linux, + # where "file" gives "dynamically linked (uses shared libraries)" + if("${file_ov}" MATCHES "dynamically linked.*\(uses shared libs\)") + set(${result_var} 1 PARENT_SCOPE) + return() + endif() + + # Also detect position independent executables on Linux, + # where "file" gives "shared object ... (uses shared libraries)" + if("${file_ov}" MATCHES "shared object.*\(uses shared libs\)") + set(${result_var} 1 PARENT_SCOPE) + return() + endif() + + # Also detect shared libraries on Linux, + # where "file" gives "ELF 64-bit LSB shared object, AMD x86-64, version 1 (SYSV), not stripped" + if("${file_ov}" MATCHES "elf.*shared object.*version") + set(${result_var} 1 PARENT_SCOPE) + return() + endif() + + # "file" version 5.22 does not print "(used shared libraries)" + # but uses "interpreter" + if("${file_ov}" MATCHES "shared object.*interpreter") + set(${result_var} 1 PARENT_SCOPE) + return() + endif() + + if(APPLE) + # detect shared libraries on Mac OSX + # where "file" gives "Mach-O 64-bit x86_64 dynamically linked shared library" + if("${file_ov}" MATCHES "mach-o.*dynamically linked shared library") + set(${result_var} 1 PARENT_SCOPE) + return() + endif() + + + #below check is redundant. + # detect executables on Mac OSX + # where "file" gives "Mach-O 64-bit x86_64 executable" + if("${file_ov}" MATCHES "mach-o.*executable") + set(${result_var} 1 PARENT_SCOPE) + return() + endif() + + endif(APPLE) + + else() + message(STATUS "warning: No 'file' command, skipping execute_process...") + endif() + 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) @@ -195,7 +318,6 @@ function(func_is_file_a_symbolic_link file result_var1 result_var2) #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