1 # Special version of GetPrerequisites that implements a caching mechanism. 2 # Thank you to Daniel Maleike for the contribution 4 message(
"Using MITK version of GetPrerequisites.cmake")
7 # Distributed under the OSI-approved BSD 3-Clause License. See accompanying 8 # file Copyright.txt or https://cmake.org/licensing for details. 14 # Functions to analyze and list executable file prerequisites. 16 # This module provides functions to list the .dll, .dylib or .so files 17 # that an executable or shared library file depends on. (Its 20 # It uses various tools to obtain the list of required shared library 29 # The following functions are provided by this module: 35 # list_prerequisites_by_glob 38 # gp_item_default_embedded_path 39 # (projects can override with gp_item_default_embedded_path_override) 41 # (projects can override with gp_resolve_item_override) 42 # gp_resolved_file_type 43 # (projects can override with gp_resolved_file_type_override) 46 # Requires CMake 2.6 or greater because it uses function, break, return 51 # GET_PREREQUISITES(<target> <prerequisites_var> <exclude_system> <recurse> 52 # <exepath> <dirs> [<rpaths>]) 54 # Get the list of shared library files required by <target>. The list 55 # in the variable named <prerequisites_var> should be empty on first 56 # entry to this function. On exit, <prerequisites_var> will contain the 57 # list of required shared library files. 59 # <target> is the full path to an executable file. <prerequisites_var> 60 # is the name of a CMake variable to contain the results. 61 # <exclude_system> must be 0 or 1 indicating whether to include or 62 # exclude "system" prerequisites. If <recurse> is set to 1 all 63 # prerequisites will be found recursively, if set to 0 only direct 64 # prerequisites are listed. <exepath> is the path to the top level 65 # executable used for @executable_path replacment on the Mac. <dirs> is 66 # a list of paths where libraries might be found: these paths are 67 # searched first when a target without any path info is given. Then 68 # standard system locations are also searched: PATH, Framework 69 # locations, /usr/lib... 73 # LIST_PREREQUISITES(<target> [<recurse> [<exclude_system> [<verbose>]]]) 75 # Print a message listing the prerequisites of <target>. 77 # <target> is the name of a shared library or executable target or the 78 # full path to a shared library or executable file. If <recurse> is set 79 # to 1 all prerequisites will be found recursively, if set to 0 only 80 # direct prerequisites are listed. <exclude_system> must be 0 or 1 81 # indicating whether to include or exclude "system" prerequisites. With 82 # <verbose> set to 0 only the full path names of the prerequisites are 83 # printed, set to 1 extra informatin will be displayed. 87 # LIST_PREREQUISITES_BY_GLOB(<glob_arg> <glob_exp>) 89 # Print the prerequisites of shared library and executable files 90 # matching a globbing pattern. <glob_arg> is GLOB or GLOB_RECURSE and 91 # <glob_exp> is a globbing expression used with "file(GLOB" or 92 # "file(GLOB_RECURSE" to retrieve a list of matching files. If a 93 # matching file is executable, its prerequisites are listed. 95 # Any additional (optional) arguments provided are passed along as the 96 # optional arguments to the list_prerequisites calls. 100 # GP_APPEND_UNIQUE(<list_var> <value>) 102 # Append <value> to the list variable <list_var> only if the value is 103 # not already in the list. 107 # IS_FILE_EXECUTABLE(<file> <result_var>) 109 # Return 1 in <result_var> if <file> is a binary executable, 0 114 # GP_ITEM_DEFAULT_EMBEDDED_PATH(<item> <default_embedded_path_var>) 116 # Return the path that others should refer to the item by when the item 117 # is embedded inside a bundle. 119 # Override on a per-project basis by providing a project-specific 120 # gp_item_default_embedded_path_override function. 124 # GP_RESOLVE_ITEM(<context> <item> <exepath> <dirs> <resolved_item_var> 127 # Resolve an item into an existing full path file. 129 # Override on a per-project basis by providing a project-specific 130 # gp_resolve_item_override function. 134 # GP_RESOLVED_FILE_TYPE(<original_file> <file> <exepath> <dirs> <type_var> 137 # Return the type of <file> with respect to <original_file>. String 138 # describing type of prerequisite is returned in variable named 141 # Use <exepath> and <dirs> if necessary to resolve non-absolute <file> 142 # values -- but only for non-embedded items. 144 # Possible types are: 153 # Override on a per-project basis by providing a project-specific 154 # gp_resolved_file_type_override function. 158 # GP_FILE_TYPE(<original_file> <file> <type_var>) 160 # Return the type of <file> with respect to <original_file>. String 161 # describing type of prerequisite is returned in variable named 164 # Possible types are: 176 foreach(item ${${list_var}})
177 if(item STREQUAL
"${value}")
184 set(${list_var} ${${list_var}}
"${value}" PARENT_SCOPE)
191 # A file is not executable until proven otherwise: 193 set(${result_var} 0 PARENT_SCOPE)
195 get_filename_component(file_full
"${file}" ABSOLUTE)
196 string(TOLOWER
"${file_full}" file_full_lower)
198 # If file name ends in .exe on Windows, *assume* executable: 200 if(WIN32 AND NOT UNIX)
201 if(
"${file_full_lower}" MATCHES
"\\.exe$")
202 set(${result_var} 1 PARENT_SCOPE)
206 # A clause could be added here that uses output or return value of dumpbin 207 # to determine ${result_var}. In 99%+? practical cases, the exe name 208 # match will be sufficient... 212 # Use the information returned from the Unix shell command "file" to 213 # determine if ${file_full} should be considered an executable file... 215 # If the file command's output contains "executable" and does *not* contain 216 # "text" then it is likely an executable suitable for prerequisite analysis 217 # via the get_prerequisites macro. 221 find_program(file_cmd
"file")
222 mark_as_advanced(file_cmd)
226 execute_process(COMMAND "${file_cmd}
" "${file_full}
" 227 RESULT_VARIABLE file_rv 228 OUTPUT_VARIABLE file_ov 229 ERROR_VARIABLE file_ev 230 OUTPUT_STRIP_TRAILING_WHITESPACE 232 if(NOT file_rv STREQUAL "0
") 233 message(FATAL_ERROR "${file_cmd} failed: ${file_rv}\n${file_ev}
") 236 # Replace the name of the file in the output with a placeholder token 237 # (the string " _file_full_
") so that just in case the path name of 238 # the file contains the word "text
" or "executable
" we are not fooled 239 # into thinking "the wrong thing
" because the file name matches the 240 # other 'file' command output we are looking for... 242 string(REPLACE "${file_full}
" " _file_full_
" file_ov "${file_ov}
") 243 string(TOLOWER "${file_ov}
" file_ov) 245 #message(STATUS "file_ov=
'${file_ov}'") 246 if("${file_ov}
" MATCHES "executable
") 247 #message(STATUS "executable!
") 248 if("${file_ov}
" MATCHES "text
") 249 #message(STATUS "but text, so *not* a binary executable!
") 251 set(${result_var} 1 PARENT_SCOPE) 256 # Also detect position independent executables on Linux, 257 # where "file
" gives "shared
object ... (uses shared libraries)
" 258 if("${file_ov}
" MATCHES "shared
object.*\(uses shared libs\)
") 259 set(${result_var} 1 PARENT_SCOPE) 263 # "file
" version 5.22 does not print "(used shared libraries)
" 264 # but uses "interpreter
" 265 if("${file_ov}
" MATCHES "shared
object.*interpreter
") 266 set(${result_var} 1 PARENT_SCOPE) 271 message(STATUS "warning: No
'file' command, skipping execute_process...
") 277 function(gp_item_default_embedded_path item default_embedded_path_var) 279 # On Windows and Linux, "embed
" prerequisites in the same directory 280 # as the executable by default: 282 set(path "@executable_path
") 285 # On the Mac, relative to the executable depending on the type 286 # of the thing we are embedding: 290 # The assumption here is that all executables in the bundle will be 291 # in same-level-directories inside the bundle. The parent directory 292 # of an executable inside the bundle should be MacOS or a sibling of 293 # MacOS and all embedded paths returned from here will begin with 294 # "@executable_path/../
" and will work from all executables in all 295 # such same-level-directories inside the bundle. 298 # By default, embed things right next to the main bundle executable: 300 set(path "@executable_path/../../Contents/MacOS
") 302 # Embed .dylibs right next to the main bundle executable: 304 if(item MATCHES "\\.dylib$
") 305 set(path "@executable_path/../MacOS
") 309 # Embed frameworks in the embedded "Frameworks
" directory (sibling of MacOS): 312 if(item MATCHES "[^/]+\\.framework/
") 313 set(path "@executable_path/../Frameworks
") 319 # Provide a hook so that projects can override the default embedded location 320 # of any given library by whatever logic they choose: 322 if(COMMAND gp_item_default_embedded_path_override) 323 gp_item_default_embedded_path_override("${item}
" path) 326 set(${default_embedded_path_var} "${path}
" PARENT_SCOPE) 330 function(gp_resolve_item context item exepath dirs resolved_item_var) 332 set(resolved_item "${item}
") 334 set(rpaths "${ARGV5}
") 339 # Is it already resolved? 341 if(IS_ABSOLUTE "${resolved_item}
" AND EXISTS "${resolved_item}
") 346 if(item MATCHES "^@executable_path
") 348 # @executable_path references are assumed relative to exepath 350 string(REPLACE "@executable_path
" "${exepath}
" ri "${item}
") 351 get_filename_component(ri "${ri}
" ABSOLUTE) 354 #message(STATUS "info: embedded item exists (${ri})
") 356 set(resolved_item "${ri}
") 358 message(STATUS "warning: embedded item does not exist
'${ri}'") 364 if(item MATCHES "^@loader_path
") 366 # @loader_path references are assumed relative to the 367 # PATH of the given "context
" (presumably another library) 369 get_filename_component(contextpath "${context}
" PATH) 370 string(REPLACE "@loader_path
" "${contextpath}
" ri "${item}
") 371 get_filename_component(ri "${ri}
" ABSOLUTE) 374 #message(STATUS "info: embedded item exists (${ri})
") 376 set(resolved_item "${ri}
") 378 message(STATUS "warning: embedded item does not exist
'${ri}'") 384 if(item MATCHES "^@rpath
") 386 # @rpath references are relative to the paths built into the binaries with -rpath 387 # We handle this case like we do for other Unixes 389 string(REPLACE "@rpath/
" "" norpath_item "${item}
") 391 set(ri "ri-NOTFOUND
") 392 find_file(ri "${norpath_item}
" ${exepath} ${dirs} ${rpaths} NO_DEFAULT_PATH) 394 #message(STATUS "info:
'find_file' in exepath/dirs/rpaths (${ri})
") 396 set(resolved_item "${ri}
") 397 set(ri "ri-NOTFOUND
") 404 set(ri "ri-NOTFOUND
") 405 find_file(ri "${item}
" ${exepath} ${dirs} NO_DEFAULT_PATH) 406 find_file(ri "${item}
" ${exepath} ${dirs} /usr/lib) 408 get_filename_component(basename_item "${item}
" NAME) 409 find_file(ri "${basename_item}
" PATHS ${exepath} ${dirs} NO_DEFAULT_PATH) 410 find_file(ri "${basename_item}
" PATHS /usr/lib) 413 #message(STATUS "info:
'find_file' in exepath/dirs (${ri})
") 415 set(resolved_item "${ri}
") 416 set(ri "ri-NOTFOUND
") 421 if(item MATCHES "[^/]+\\.framework/
") 422 set(fw "fw-NOTFOUND
") 423 find_file(fw "${item}
" 424 "~/Library/Frameworks
" 425 "/Library/Frameworks
" 426 "/System/Library/Frameworks
" 431 set(resolved_item "${fw}
") 432 set(fw "fw-NOTFOUND
") 437 # Using find_program on Windows will find dll files that are in the PATH. 438 # (Converting simple file names into full path names if found.) 440 if(WIN32 AND NOT UNIX) 442 set(ri "ri-NOTFOUND
") 443 find_program(ri "${item}
" PATHS ${exepath} ${dirs} NO_DEFAULT_PATH) 444 find_program(ri "${item}
" PATHS ${exepath} ${dirs}) 446 #message(STATUS "info:
'find_program' in exepath/dirs (${ri})
") 448 set(resolved_item "${ri}
") 449 set(ri "ri-NOTFOUND
") 454 # Provide a hook so that projects can override item resolution 455 # by whatever logic they choose: 457 if(COMMAND gp_resolve_item_override) 458 gp_resolve_item_override("${context}
" "${item}
" "${exepath}
" "${dirs}
" resolved_item resolved) 463 warning: cannot resolve item
'${item}' 466 need more directories?
467 need to use InstallRequiredSystemLibraries?
468 run
in install tree instead of build tree?
471 #****************************************************************************** 472 #warning: cannot resolve item '${item}' 475 # need more directories? 476 # need to use InstallRequiredSystemLibraries? 477 # run in install tree instead of build tree? 479 # context='${context}' 481 # exepath='${exepath}' 483 # resolved_item_var='${resolved_item_var}' 484 #****************************************************************************** 488 set(${resolved_item_var}
"${resolved_item}" PARENT_SCOPE)
494 set(rpaths "${ARGV5}
") 498 #message(STATUS "**
") 500 if(NOT IS_ABSOLUTE "${original_file}
") 501 message(STATUS "warning:
gp_resolved_file_type expects absolute full path
for first arg original_file
") 503 if(IS_ABSOLUTE "${original_file}
") 504 get_filename_component(original_file "${original_file}
" ABSOLUTE) # canonicalize path 511 set(resolved_file "${file}
") 513 if("${file}
" MATCHES "^@(executable|loader)_path
") 518 if(NOT IS_ABSOLUTE "${file}
") 519 gp_resolve_item("${original_file}
" "${file}
" "${exepath}
" "${dirs}
" resolved_file "${rpaths}
") 521 if(IS_ABSOLUTE "${resolved_file}
") 522 get_filename_component(resolved_file "${resolved_file}
" ABSOLUTE) # canonicalize path 525 string(TOLOWER "${original_file}
" original_lower) 526 string(TOLOWER "${resolved_file}
" lower) 529 if(resolved_file MATCHES "^(/lib/|/lib32/|/libx32/|/lib64/|/usr/lib/|/usr/lib32/|/usr/libx32/|/usr/lib64/|/usr/X11R6/|/usr/bin/)
") 535 if(resolved_file MATCHES "^(/System/Library/|/usr/lib/)
") 541 string(TOLOWER "$ENV{SystemRoot}
" sysroot) 542 file(TO_CMAKE_PATH "${sysroot}
" sysroot) 544 string(TOLOWER "$ENV{windir}
" windir) 545 file(TO_CMAKE_PATH "${windir}
" windir) 547 if(lower MATCHES "^(${sysroot}/sys(tem|wow)|${windir}/sys(tem|wow)|(.*/)*(msvc|api-ms-win-)[^/]+dll)
") 552 # if cygwin, we can get the properly formed windows paths from cygpath 553 find_program(CYGPATH_EXECUTABLE cygpath) 555 if(CYGPATH_EXECUTABLE) 556 execute_process(COMMAND ${CYGPATH_EXECUTABLE} -W 557 RESULT_VARIABLE env_rv 558 OUTPUT_VARIABLE env_windir 559 ERROR_VARIABLE env_ev 560 OUTPUT_STRIP_TRAILING_WHITESPACE) 561 if(NOT env_rv STREQUAL "0
") 562 message(FATAL_ERROR "${CYGPATH_EXECUTABLE} -W failed: ${env_rv}\n${env_ev}
") 564 execute_process(COMMAND ${CYGPATH_EXECUTABLE} -S 565 RESULT_VARIABLE env_rv 566 OUTPUT_VARIABLE env_sysdir 567 ERROR_VARIABLE env_ev 568 OUTPUT_STRIP_TRAILING_WHITESPACE) 569 if(NOT env_rv STREQUAL "0
") 570 message(FATAL_ERROR "${CYGPATH_EXECUTABLE} -S failed: ${env_rv}\n${env_ev}
") 572 string(TOLOWER "${env_windir}
" windir) 573 string(TOLOWER "${env_sysdir}
" sysroot) 575 if(lower MATCHES "^(${sysroot}/sys(tem|wow)|${windir}/sys(tem|wow)|(.*/)*(msvc|api-ms-win-)[^/]+dll)
") 583 get_filename_component(original_path "${original_lower}
" PATH) 584 get_filename_component(path "${lower}
" PATH) 585 if(original_path STREQUAL path) 588 string(LENGTH "${original_path}/
" original_length) 589 string(LENGTH "${lower}
" path_length) 590 if(${path_length} GREATER ${original_length}) 591 string(SUBSTRING "${lower}
" 0 ${original_length} path) 592 if("${original_path}/
" STREQUAL path) 600 # Return type string based on computed booleans: 613 #message(STATUS " type:
'${type}'") 616 if(NOT IS_ABSOLUTE "${resolved_file}
") 617 if(lower MATCHES "^(msvc|api-ms-win-)[^/]+dll
" AND is_system) 618 message(STATUS "info: non-absolute msvc file
'${file}' returning type
'${type}'") 620 message(STATUS "warning:
gp_resolved_file_type non-absolute file
'${file}' returning type
'${type}' -- possibly incorrect
") 625 # Provide a hook so that projects can override the decision on whether a 626 # library belongs to the system or not by whatever logic they choose: 628 if(COMMAND gp_resolved_file_type_override) 629 gp_resolved_file_type_override("${resolved_file}
" type) 632 set(${type_var} "${type}
" PARENT_SCOPE) 634 #message(STATUS "**
") 638 function(gp_file_type original_file file type_var) 639 if(NOT IS_ABSOLUTE "${original_file}
") 640 message(STATUS "warning:
gp_file_type expects absolute full path
for first arg original_file
") 643 get_filename_component(exepath "${original_file}
" PATH) 646 gp_resolved_file_type("${original_file}
" "${file}
" "${exepath}
" "" type) 648 set(${type_var} "${type}
" PARENT_SCOPE) 651 function(get_prerequisites_clear_cache) 652 set_property(GLOBAL PROPERTY prerequisites_cachevariables "") 653 endfunction(get_prerequisites_clear_cache) 655 function(get_prerequisites target prerequisites_var exclude_system recurse exepath dirs) 657 # See if we know the answer from our cache. If so, we are done early 659 # incorporate all parameters into cache key 660 string(SHA1 param_hash "${exclude_system}_${recurse}_${exepath}_${dirs}
") 661 set(prerequisites_cache_var_name "prerequisites_cache_${target}_${param_hash}
") 662 string(TOLOWER "${prerequisites_cache_var_name}
" prerequisites_cache_var_name) 663 string(REGEX REPLACE "[:-\\/.]
" "_
" prerequisites_cache_var_name "${prerequisites_cache_var_name}
") 664 get_property(cache_value GLOBAL PROPERTY ${prerequisites_cache_var_name} SET) 666 get_property(cache_value GLOBAL PROPERTY ${prerequisites_cache_var_name}) # if defined, then get value 667 if (cache_value) # already something non-empty -> append 668 set(${prerequisites_var} "${${prerequisites_var}};${cache_value}
" PARENT_SCOPE) 676 set(rpaths "${ARGV6}
") 681 if(NOT IS_ABSOLUTE "${target}
") 682 message("warning: target
'${target}' is not absolute...
") 685 if(NOT EXISTS "${target}
") 686 message("warning: target
'${target}' does not exist...
") 687 set(${prerequisites_var} "" PARENT_SCOPE) 691 set(gp_cmd_paths ${gp_cmd_paths} 692 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\14.0;InstallDir]/../../VC/bin
" 693 "$ENV{VS140COMNTOOLS}/../../VC/bin
" 694 "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin
" 695 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\12.0;InstallDir]/../../VC/bin
" 696 "$ENV{VS120COMNTOOLS}/../../VC/bin
" 697 "C:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/bin
" 698 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\11.0;InstallDir]/../../VC/bin
" 699 "$ENV{VS110COMNTOOLS}/../../VC/bin
" 700 "C:/Program Files (x86)/Microsoft Visual Studio 11.0/VC/bin
" 701 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\10.0;InstallDir]/../../VC/bin
" 702 "$ENV{VS100COMNTOOLS}/../../VC/bin
" 703 "C:/Program Files (x86)/Microsoft Visual Studio 10.0/VC/bin
" 704 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\9.0;InstallDir]/../../VC/bin
" 705 "$ENV{VS90COMNTOOLS}/../../VC/bin
" 706 "C:/Program Files/Microsoft Visual Studio 9.0/VC/bin
" 707 "C:/Program Files (x86)/Microsoft Visual Studio 9.0/VC/bin
" 708 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\8.0;InstallDir]/../../VC/bin
" 709 "$ENV{VS80COMNTOOLS}/../../VC/bin
" 710 "C:/Program Files/Microsoft Visual Studio 8/VC/BIN
" 711 "C:/Program Files (x86)/Microsoft Visual Studio 8/VC/BIN
" 712 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\7.1;InstallDir]/../../VC7/bin
" 713 "$ENV{VS71COMNTOOLS}/../../VC7/bin
" 714 "C:/Program Files/Microsoft Visual Studio .NET 2003/VC7/BIN
" 715 "C:/Program Files (x86)/Microsoft Visual Studio .NET 2003/VC7/BIN
" 720 # <setup-gp_tool-vars> 722 # Try to choose the right tool by default. Caller can set gp_tool prior to 723 # calling this function to force using a different tool. 732 if(WIN32 AND NOT UNIX) # This is how to check for cygwin, har! 733 find_program(gp_dumpbin "dumpbin
" PATHS ${gp_cmd_paths}) 735 set(gp_tool "dumpbin
") 737 set(gp_tool "objdump
") 742 find_program(gp_cmd ${gp_tool} PATHS ${gp_cmd_paths}) 745 message(STATUS "warning: could not find
'${gp_tool}' - cannot analyze prerequisites...
") 749 set(gp_cmd_maybe_filter) # optional command to pre-filter gp_tool results 751 if(gp_tool STREQUAL "ldd
") 753 set(gp_regex "^[\t ]*[^\t ]+ => ([^\t\(]+) .*${eol_char}$
") 754 set(gp_regex_error "not found${eol_char}$
") 755 set(gp_regex_fallback "^[\t ]*([^\t ]+) => ([^\t ]+).*${eol_char}$
") 756 set(gp_regex_cmp_count 1) 757 elseif(gp_tool STREQUAL "otool
") 758 set(gp_cmd_args "-L
") 759 set(gp_regex "^\t([^\t]+) \\(compatibility version ([0-9]+.[0-9]+.[0-9]+), current version ([0-9]+.[0-9]+.[0-9]+)\\)${eol_char}$
") 760 set(gp_regex_error "") 761 set(gp_regex_fallback "") 762 set(gp_regex_cmp_count 3) 763 elseif(gp_tool STREQUAL "dumpbin
") 764 set(gp_cmd_args "/dependents
") 765 set(gp_regex "^ ([^ ].*[Dd][Ll][Ll])${eol_char}$
") 766 set(gp_regex_error "") 767 set(gp_regex_fallback "") 768 set(gp_regex_cmp_count 1) 769 elseif(gp_tool STREQUAL "objdump
") 770 set(gp_cmd_args "-p
") 771 set(gp_regex "^\t*DLL Name: (.*\\.[Dd][Ll][Ll])${eol_char}$
") 772 set(gp_regex_error "") 773 set(gp_regex_fallback "") 774 set(gp_regex_cmp_count 1) 775 # objdump generates copious output so we create a grep filter to pre-filter results 777 find_program(gp_grep_cmd findstr) 779 find_program(gp_grep_cmd grep) 782 set(gp_cmd_maybe_filter COMMAND ${gp_grep_cmd} "-a
" "^[[:blank:]]*DLL Name:
") 785 message(STATUS "warning: gp_tool=
'${gp_tool}' is an
unknown tool...
") 787 message(STATUS "Valid gp_tool values are dumpbin, ldd, objdump and otool.
") 792 if(gp_tool STREQUAL "dumpbin
") 793 # When running dumpbin, it also needs the "Common7/IDE
" directory in the 794 # PATH. It will already be in the PATH if being run from a Visual Studio 795 # command prompt. Add it to the PATH here in case we are running from a 796 # different command prompt. 798 get_filename_component(gp_cmd_dir "${gp_cmd}
" PATH) 799 get_filename_component(gp_cmd_dlls_dir "${gp_cmd_dir}/../../Common7/IDE
" ABSOLUTE) 800 # Use cmake paths as a user may have a PATH element ending with a backslash. 801 # This will escape the list delimiter and create havoc! 802 if(EXISTS "${gp_cmd_dlls_dir}
") 803 # only add to the path if it is not already in the path 804 set(gp_found_cmd_dlls_dir 0) 805 file(TO_CMAKE_PATH "$ENV{PATH}
" env_path) 806 foreach(gp_env_path_element ${env_path}) 807 if(gp_env_path_element STREQUAL gp_cmd_dlls_dir) 808 set(gp_found_cmd_dlls_dir 1) 812 if(NOT gp_found_cmd_dlls_dir) 813 file(TO_NATIVE_PATH "${gp_cmd_dlls_dir}
" gp_cmd_dlls_dir) 814 set(ENV{PATH} "$ENV{PATH};${gp_cmd_dlls_dir}
") 819 # </setup-gp_tool-vars> 821 if(gp_tool STREQUAL "ldd
") 822 set(old_ld_env "$ENV{LD_LIBRARY_PATH}
") 823 set(new_ld_env "${exepath}
") 825 string(APPEND new_ld_env ":${dir}
") 827 set(ENV{LD_LIBRARY_PATH} "${new_ld_env}:$ENV{LD_LIBRARY_PATH}
") 831 # Track new prerequisites at each new level of recursion. Start with an 832 # empty list at each level: 836 # Run gp_cmd on the target: 839 COMMAND ${gp_cmd} ${gp_cmd_args} ${target} 840 ${gp_cmd_maybe_filter} 841 RESULT_VARIABLE gp_rv 842 OUTPUT_VARIABLE gp_cmd_ov 846 if(gp_tool STREQUAL "dumpbin
") 847 # Exclude delay load dependencies under windows (they are listed in dumpbin output after the message below) 848 string(FIND "${gp_cmd_ov}
" "Image has the following delay load dependencies
" gp_delayload_pos) 849 if (${gp_delayload_pos} GREATER -1) 850 string(SUBSTRING "${gp_cmd_ov}
" 0 ${gp_delayload_pos} gp_cmd_ov_no_delayload_deps) 851 string(SUBSTRING "${gp_cmd_ov}
" ${gp_delayload_pos} -1 gp_cmd_ov_delayload_deps) 853 message(STATUS "GetPrequisites(${target}) : ignoring the following delay load dependencies :\n ${gp_cmd_ov_delayload_deps}
") 855 set(gp_cmd_ov ${gp_cmd_ov_no_delayload_deps}) 859 if(NOT gp_rv STREQUAL "0
") 860 if(gp_tool STREQUAL "dumpbin
") 861 # dumpbin error messages seem to go to stdout 862 message(FATAL_ERROR "${gp_cmd} failed: ${gp_rv}\n${gp_ev}\n${gp_cmd_ov}
") 864 message(FATAL_ERROR "${gp_cmd} failed: ${gp_rv}\n${gp_ev}
") 868 if(gp_tool STREQUAL "ldd
") 869 set(ENV{LD_LIBRARY_PATH} "${old_ld_env}
") 873 message(STATUS "<RawOutput cmd=
'${gp_cmd} ${gp_cmd_args} ${target}'>
") 874 message(STATUS "gp_cmd_ov=
'${gp_cmd_ov}'") 875 message(STATUS "</RawOutput>
") 878 get_filename_component(target_dir "${target}
" PATH) 880 # Convert to a list of lines: 882 string(REPLACE ";
" "\\;
" candidates "${gp_cmd_ov}
") 883 string(REPLACE "\n
" "${eol_char};
" candidates "${candidates}
") 885 # check for install id and remove it from list, since otool -L can include a 886 # reference to itself 888 if(gp_tool STREQUAL "otool
") 890 COMMAND otool -D ${target} 891 RESULT_VARIABLE otool_rv 892 OUTPUT_VARIABLE gp_install_id_ov 893 ERROR_VARIABLE otool_ev 895 if(NOT otool_rv STREQUAL "0
") 896 message(FATAL_ERROR "otool -D failed: ${otool_rv}\n${otool_ev}
") 898 # second line is install name 899 string(REGEX REPLACE ".*:\n
" "" gp_install_id "${gp_install_id_ov}
") 902 string(REGEX MATCH "[^\n ].*[^\n ]
" gp_install_id "${gp_install_id}
") 903 #message("INSTALL
ID is \
"${gp_install_id}\"")
907 # Analyze each line for file names that match the regular expression: 909 list(LENGTH ${prerequisites_var} list_length_before_candidates)
910 set(targets_added
"")
911 foreach(candidate ${candidates})
912 if(
"${candidate}" MATCHES
"${gp_regex}")
914 # Extract information from each candidate: 915 if(gp_regex_error AND
"${candidate}" MATCHES
"${gp_regex_error}")
916 string(REGEX REPLACE
"${gp_regex_fallback}" "\\1" raw_item
"${candidate}")
918 string(REGEX REPLACE
"${gp_regex}" "\\1" raw_item
"${candidate}")
921 if(gp_regex_cmp_count GREATER 1)
922 string(REGEX REPLACE "${gp_regex}
" "\\2
" raw_compat_version "${candidate}
") 923 string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$
" "\\1
" compat_major_version "${raw_compat_version}
") 924 string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$
" "\\2
" compat_minor_version "${raw_compat_version}
") 925 string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$
" "\\3
" compat_patch_version "${raw_compat_version}
") 928 if(gp_regex_cmp_count GREATER 2) 929 string(REGEX REPLACE "${gp_regex}
" "\\3
" raw_current_version "${candidate}
") 930 string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$
" "\\1
" current_major_version "${raw_current_version}
") 931 string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$
" "\\2
" current_minor_version "${raw_current_version}
") 932 string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$
" "\\3
" current_patch_version "${raw_current_version}
") 935 # Use the raw_item as the list entries returned by this function. Use the 936 # gp_resolve_item function to resolve it to an actual full path file if 939 set(item "${raw_item}
") 941 # Add each item unless it is excluded: 945 if(item STREQUAL gp_install_id) 949 if(add_item AND ${exclude_system}) 951 gp_resolved_file_type("${target}
" "${item}
" "${exepath}
" "${dirs}
" type "${rpaths}
") 953 if(type STREQUAL "system
") 959 list(LENGTH ${prerequisites_var} list_length_before_append) 960 gp_append_unique(${prerequisites_var} "${item}
") 961 list(LENGTH ${prerequisites_var} list_length_after_append) 964 # If item was really added, this is the first time we have seen it. 965 # Add it to unseen_prereqs so that we can recursively add *its* 968 # But first: resolve its name to an absolute full path name such 969 # that the analysis tools can simply accept it as input. 971 if(NOT list_length_before_append EQUAL list_length_after_append) 972 gp_resolve_item("${target}
" "${item}
" "${exepath}
" "${dirs}
" resolved_item "${rpaths}
") 973 if(EXISTS "${resolved_item}
") 974 # Recurse only if we could resolve the item. 975 # Otherwise the prerequisites_var list will be cleared 976 set(unseen_prereqs ${unseen_prereqs} "${resolved_item}
") 983 message(STATUS "ignoring non-matching
line:
'${candidate}'") 988 list(LENGTH ${prerequisites_var} prerequisites_var_length) 989 if(prerequisites_var_length GREATER 0) 990 list(SORT ${prerequisites_var}) 993 set(more_inputs ${unseen_prereqs}) 994 foreach(input ${more_inputs}) 995 get_prerequisites("${input}
" ${prerequisites_var} ${exclude_system} ${recurse} "${exepath}
" "${dirs}
" "${rpaths}
") 999 # Make result visible to caller 1000 set(${prerequisites_var} ${${prerequisites_var}} PARENT_SCOPE) 1002 # See if we added anything 1003 list(LENGTH ${prerequisites_var} list_length_after_candidates) 1004 if(list_length_after_candidates GREATER ${list_length_before_candidates}) 1005 # Something has been added to prerequisites. Note this in cache 1006 set(targets_added "${${prerequisites_var}}
") 1007 if (list_length_before_candidates GREATER 0) 1008 foreach(i RANGE 1 ${list_length_before_candidates}) # from 1 to old list length, remove first item, i.e. remove all pre-existing items 1009 list(REMOVE_AT targets_added 0) # not the most elegant way of cutting the list start. Simplifications welcome 1015 set_property(GLOBAL PROPERTY ${prerequisites_cache_var_name} "${targets_added}
") 1017 get_property(cache_variables GLOBAL PROPERTY prerequisites_cachevariables) 1018 if (cache_variables) 1019 list(APPEND cache_variables ${prerequisites_cache_var_name}) 1020 list(LENGTH cache_variables len) 1022 set(cache_variables ${prerequisites_cache_var_name}) 1024 set_property(GLOBAL PROPERTY prerequisites_cachevariables ${cache_variables}) 1026 message("Analyzed prerequisites of ${target}
") 1030 function(list_prerequisites target) 1031 if(ARGC GREATER 1 AND NOT "${ARGV1}
" STREQUAL "") 1037 if(ARGC GREATER 2 AND NOT "${ARGV2}
" STREQUAL "") 1038 set(exclude_system "${ARGV2}
") 1040 set(exclude_system 0) 1043 if(ARGC GREATER 3 AND NOT "${ARGV3}
" STREQUAL "") 1044 set(verbose "${ARGV3}
") 1052 set(print_prerequisite_type "${
verbose}
") 1053 set(print_target "${
verbose}
") 1056 get_filename_component(exepath "${target}
" PATH) 1059 get_prerequisites("${target}
" prereqs ${exclude_system} ${all} "${exepath}
" "") 1062 message(STATUS "File '${target}' depends on:
") 1065 foreach(d ${prereqs}) 1066 math(EXPR count "${count} + 1
") 1069 set(count_str "${count}.
") 1072 if(print_prerequisite_type) 1073 gp_file_type("${target}
" "${d}
" type) 1074 set(type_str " (${type})
") 1077 message(STATUS "${count_str}${d}${type_str}
") 1082 function(list_prerequisites_by_glob glob_arg glob_exp) 1083 message(STATUS "=============================================================================
") 1084 message(STATUS "List prerequisites of executables matching ${glob_arg}
'${glob_exp}'") 1086 file(${glob_arg} file_list ${glob_exp}) 1087 foreach(f ${file_list}) 1088 is_file_executable("${f}
" is_f_executable) 1090 message(STATUS "=============================================================================
") 1091 list_prerequisites("${f}
" ${ARGN})
gp_resolved_file_type(original_file, file, exepath, dirs, type_var)
gp_file_type(original_file, file, type_var)
static const unsigned int unknown
Unknown size marker.
use the deprecated old MITK testing style If possible
gp_append_unique(list_var, value)
static void info(const char *fmt,...)
The custom viewer plugin implements simple viewer functionality presented in a customized look and feel It was developed to demonstrate extensibility and customizability of the blueberry application framework As an example for the GUI customization capabilities provided by the BlueBerry application framework
get_prerequisites(target, prerequisites_var, exclude_system, recurse, exepath, dirs)
is_file_executable(file, result_var)
static bool in(Reader::Char c, Reader::Char c1, Reader::Char c2, Reader::Char c3, Reader::Char c4)