GetPrerequisites_2_8.cmake
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:25k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. # GetPrerequisites.cmake
  2. #
  3. # This script provides functions to list the .dll, .dylib or .so files that an
  4. # executable or shared library file depends on. (Its prerequisites.)
  5. #
  6. # It uses various tools to obtain the list of required shared library files:
  7. #   dumpbin (Windows)
  8. #   ldd (Linux/Unix)
  9. #   otool (Mac OSX)
  10. #
  11. # The following functions are provided by this script:
  12. #   gp_append_unique
  13. #   is_file_executable
  14. #   gp_item_default_embedded_path
  15. #     (projects can override with gp_item_default_embedded_path_override)
  16. #   gp_resolve_item
  17. #     (projects can override with gp_resolve_item_override)
  18. #   gp_resolved_file_type
  19. #   gp_file_type
  20. #   get_prerequisites
  21. #   list_prerequisites
  22. #   list_prerequisites_by_glob
  23. #
  24. # Requires CMake 2.6 or greater because it uses function, break, return and
  25. # PARENT_SCOPE.
  26. #=============================================================================
  27. # Copyright 2008-2009 Kitware, Inc.
  28. #
  29. # Distributed under the OSI-approved BSD License (the "License");
  30. # see accompanying file Copyright.txt for details.
  31. #
  32. # This software is distributed WITHOUT ANY WARRANTY; without even the
  33. # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  34. # See the License for more information.
  35. #=============================================================================
  36. # (To distributed this file outside of CMake, substitute the full
  37. #  License text for the above reference.)
  38. # gp_append_unique list_var value
  39. #
  40. # Append value to the list variable ${list_var} only if the value is not
  41. # already in the list.
  42. #
  43. function(gp_append_unique list_var value)
  44.   set(contains 0)
  45.   foreach(item ${${list_var}})
  46.     if("${item}" STREQUAL "${value}")
  47.       set(contains 1)
  48.       break()
  49.     endif("${item}" STREQUAL "${value}")
  50.   endforeach(item)
  51.   if(NOT contains)
  52.     set(${list_var} ${${list_var}} "${value}" PARENT_SCOPE)
  53.   endif(NOT contains)
  54. endfunction(gp_append_unique)
  55. # is_file_executable file result_var
  56. #
  57. # Return 1 in ${result_var} if ${file} is a binary executable.
  58. #
  59. # Return 0 in ${result_var} otherwise.
  60. #
  61. function(is_file_executable file result_var)
  62.   #
  63.   # A file is not executable until proven otherwise:
  64.   #
  65.   set(${result_var} 0 PARENT_SCOPE)
  66.   get_filename_component(file_full "${file}" ABSOLUTE)
  67.   string(TOLOWER "${file_full}" file_full_lower)
  68.   # If file name ends in .exe on Windows, *assume* executable:
  69.   #
  70.   if(WIN32)
  71.     if("${file_full_lower}" MATCHES "\.exe$")
  72.       set(${result_var} 1 PARENT_SCOPE)
  73.       return()
  74.     endif("${file_full_lower}" MATCHES "\.exe$")
  75.     # A clause could be added here that uses output or return value of dumpbin
  76.     # to determine ${result_var}. In 99%+? practical cases, the exe name
  77.     # match will be sufficient...
  78.     #
  79.   endif(WIN32)
  80.   # Use the information returned from the Unix shell command "file" to
  81.   # determine if ${file_full} should be considered an executable file...
  82.   #
  83.   # If the file command's output contains "executable" and does *not* contain
  84.   # "text" then it is likely an executable suitable for prerequisite analysis
  85.   # via the get_prerequisites macro.
  86.   #
  87.   if(UNIX)
  88.     if(NOT file_cmd)
  89.       find_program(file_cmd "file")
  90.     endif(NOT file_cmd)
  91.     if(file_cmd)
  92.       execute_process(COMMAND "${file_cmd}" "${file_full}"
  93.         OUTPUT_VARIABLE file_ov
  94.         OUTPUT_STRIP_TRAILING_WHITESPACE
  95.         )
  96.       # Replace the name of the file in the output with a placeholder token
  97.       # (the string " _file_full_ ") so that just in case the path name of
  98.       # the file contains the word "text" or "executable" we are not fooled
  99.       # into thinking "the wrong thing" because the file name matches the
  100.       # other 'file' command output we are looking for...
  101.       #
  102.       string(REPLACE "${file_full}" " _file_full_ " file_ov "${file_ov}")
  103.       string(TOLOWER "${file_ov}" file_ov)
  104.       #message(STATUS "file_ov='${file_ov}'")
  105.       if("${file_ov}" MATCHES "executable")
  106.         #message(STATUS "executable!")
  107.         if("${file_ov}" MATCHES "text")
  108.           #message(STATUS "but text, so *not* a binary executable!")
  109.         else("${file_ov}" MATCHES "text")
  110.           set(${result_var} 1 PARENT_SCOPE)
  111.           return()
  112.         endif("${file_ov}" MATCHES "text")
  113.       endif("${file_ov}" MATCHES "executable")
  114.     else(file_cmd)
  115.       message(STATUS "warning: No 'file' command, skipping execute_process...")
  116.     endif(file_cmd)
  117.   endif(UNIX)
  118. endfunction(is_file_executable)
  119. # gp_item_default_embedded_path item default_embedded_path_var
  120. #
  121. # Return the path that others should refer to the item by when the item
  122. # is embedded inside a bundle.
  123. #
  124. # Override on a per-project basis by providing a project-specific
  125. # gp_item_default_embedded_path_override function.
  126. #
  127. function(gp_item_default_embedded_path item default_embedded_path_var)
  128.   # On Windows and Linux, "embed" prerequisites in the same directory
  129.   # as the executable by default:
  130.   #
  131.   set(path "@executable_path")
  132.   set(overridden 0)
  133.   # On the Mac, relative to the executable depending on the type
  134.   # of the thing we are embedding:
  135.   #
  136.   if(APPLE)
  137.     #
  138.     # The assumption here is that all executables in the bundle will be
  139.     # in same-level-directories inside the bundle. The parent directory
  140.     # of an executable inside the bundle should be MacOS or a sibling of
  141.     # MacOS and all embedded paths returned from here will begin with
  142.     # "@executable_path/../" and will work from all executables in all
  143.     # such same-level-directories inside the bundle.
  144.     #
  145.     # By default, embed things right next to the main bundle executable:
  146.     #
  147.     set(path "@executable_path/../../Contents/MacOS")
  148.     # Embed .dylibs right next to the main bundle executable:
  149.     #
  150.     if(item MATCHES "\.dylib$")
  151.       set(path "@executable_path/../MacOS")
  152.       set(overridden 1)
  153.     endif(item MATCHES "\.dylib$")
  154.     # Embed frameworks in the embedded "Frameworks" directory (sibling of MacOS):
  155.     #
  156.     if(NOT overridden)
  157.       if(item MATCHES "[^/]+\.framework/")
  158.         set(path "@executable_path/../Frameworks")
  159.         set(overridden 1)
  160.       endif(item MATCHES "[^/]+\.framework/")
  161.     endif(NOT overridden)
  162.   endif()
  163.   # Provide a hook so that projects can override the default embedded location
  164.   # of any given library by whatever logic they choose:
  165.   #
  166.   if(COMMAND gp_item_default_embedded_path_override)
  167.     gp_item_default_embedded_path_override("${item}" path)
  168.   endif(COMMAND gp_item_default_embedded_path_override)
  169.   set(${default_embedded_path_var} "${path}" PARENT_SCOPE)
  170. endfunction(gp_item_default_embedded_path)
  171. # gp_resolve_item context item exepath dirs resolved_item_var
  172. #
  173. # Resolve an item into an existing full path file.
  174. #
  175. # Override on a per-project basis by providing a project-specific
  176. # gp_resolve_item_override function.
  177. #
  178. function(gp_resolve_item context item exepath dirs resolved_item_var)
  179.   set(resolved 0)
  180.   set(resolved_item "${item}")
  181.   # Is it already resolved?
  182.   #
  183.   if(EXISTS "${resolved_item}")
  184.     set(resolved 1)
  185.   endif(EXISTS "${resolved_item}")
  186.   if(NOT resolved)
  187.     if(item MATCHES "@executable_path")
  188.       #
  189.       # @executable_path references are assumed relative to exepath
  190.       #
  191.       string(REPLACE "@executable_path" "${exepath}" ri "${item}")
  192.       get_filename_component(ri "${ri}" ABSOLUTE)
  193.       if(EXISTS "${ri}")
  194.         #message(STATUS "info: embedded item exists (${ri})")
  195.         set(resolved 1)
  196.         set(resolved_item "${ri}")
  197.       else(EXISTS "${ri}")
  198.         message(STATUS "warning: embedded item does not exist '${ri}'")
  199.       endif(EXISTS "${ri}")
  200.     endif(item MATCHES "@executable_path")
  201.   endif(NOT resolved)
  202.   if(NOT resolved)
  203.     if(item MATCHES "@loader_path")
  204.       #
  205.       # @loader_path references are assumed relative to the
  206.       # PATH of the given "context" (presumably another library)
  207.       #
  208.       get_filename_component(contextpath "${context}" PATH)
  209.       string(REPLACE "@loader_path" "${contextpath}" ri "${item}")
  210.       get_filename_component(ri "${ri}" ABSOLUTE)
  211.       if(EXISTS "${ri}")
  212.         #message(STATUS "info: embedded item exists (${ri})")
  213.         set(resolved 1)
  214.         set(resolved_item "${ri}")
  215.       else(EXISTS "${ri}")
  216.         message(STATUS "warning: embedded item does not exist '${ri}'")
  217.       endif(EXISTS "${ri}")
  218.     endif(item MATCHES "@loader_path")
  219.   endif(NOT resolved)
  220.   if(NOT resolved)
  221.     set(ri "ri-NOTFOUND")
  222.     find_file(ri "${item}" ${exepath} ${dirs} NO_DEFAULT_PATH)
  223.     find_file(ri "${item}" ${exepath} ${dirs} /usr/lib)
  224.     if(ri)
  225.       #message(STATUS "info: 'find_file' in exepath/dirs (${ri})")
  226.       set(resolved 1)
  227.       set(resolved_item "${ri}")
  228.       set(ri "ri-NOTFOUND")
  229.     endif(ri)
  230.   endif(NOT resolved)
  231.   if(NOT resolved)
  232.     if(item MATCHES "[^/]+\.framework/")
  233.       set(fw "fw-NOTFOUND")
  234.       find_file(fw "${item}"
  235.         "~/Library/Frameworks"
  236.         "/Library/Frameworks"
  237.         "/System/Library/Frameworks"
  238.       )
  239.       if(fw)
  240.         #message(STATUS "info: 'find_file' found framework (${fw})")
  241.         set(resolved 1)
  242.         set(resolved_item "${fw}")
  243.         set(fw "fw-NOTFOUND")
  244.       endif(fw)
  245.     endif(item MATCHES "[^/]+\.framework/")
  246.   endif(NOT resolved)
  247.   # Using find_program on Windows will find dll files that are in the PATH.
  248.   # (Converting simple file names into full path names if found.)
  249.   #
  250.   if(WIN32)
  251.   if(NOT resolved)
  252.     set(ri "ri-NOTFOUND")
  253.     find_program(ri "${item}" PATHS "${exepath};${dirs}" NO_DEFAULT_PATH)
  254.     find_program(ri "${item}" PATHS "${exepath};${dirs}")
  255.     if(ri)
  256.       #message(STATUS "info: 'find_program' in exepath/dirs (${ri})")
  257.       set(resolved 1)
  258.       set(resolved_item "${ri}")
  259.       set(ri "ri-NOTFOUND")
  260.     endif(ri)
  261.   endif(NOT resolved)
  262.   endif(WIN32)
  263.   # Provide a hook so that projects can override item resolution
  264.   # by whatever logic they choose:
  265.   #
  266.   if(COMMAND gp_resolve_item_override)
  267.     gp_resolve_item_override("${context}" "${item}" "${exepath}" "${dirs}" resolved_item resolved)
  268.   endif(COMMAND gp_resolve_item_override)
  269.   if(NOT resolved)
  270.     message(STATUS "
  271. warning: cannot resolve item '${item}'
  272.   possible problems:
  273.     need more directories?
  274.     need to use InstallRequiredSystemLibraries?
  275.     run in install tree instead of build tree?
  276. ")
  277. #    message(STATUS "
  278. #******************************************************************************
  279. #warning: cannot resolve item '${item}'
  280. #
  281. #  possible problems:
  282. #    need more directories?
  283. #    need to use InstallRequiredSystemLibraries?
  284. #    run in install tree instead of build tree?
  285. #
  286. #    context='${context}'
  287. #    item='${item}'
  288. #    exepath='${exepath}'
  289. #    dirs='${dirs}'
  290. #    resolved_item_var='${resolved_item_var}'
  291. #******************************************************************************
  292. #")
  293.   endif(NOT resolved)
  294.   set(${resolved_item_var} "${resolved_item}" PARENT_SCOPE)
  295. endfunction(gp_resolve_item)
  296. # gp_resolved_file_type original_file file exepath dirs type_var
  297. #
  298. # Return the type of ${file} with respect to ${original_file}. String
  299. # describing type of prerequisite is returned in variable named ${type_var}.
  300. #
  301. # Use ${exepath} and ${dirs} if necessary to resolve non-absolute ${file}
  302. # values -- but only for non-embedded items.
  303. #
  304. # Possible types are:
  305. #   system
  306. #   local
  307. #   embedded
  308. #   other
  309. #
  310. function(gp_resolved_file_type original_file file exepath dirs type_var)
  311.   #message(STATUS "**")
  312.   if(NOT IS_ABSOLUTE "${original_file}")
  313.     message(STATUS "warning: gp_resolved_file_type expects absolute full path for first arg original_file")
  314.   endif()
  315.   set(is_embedded 0)
  316.   set(is_local 0)
  317.   set(is_system 0)
  318.   set(resolved_file "${file}")
  319.   if("${file}" MATCHES "^@(executable|loader)_path")
  320.     set(is_embedded 1)
  321.   endif()
  322.   if(NOT is_embedded)
  323.     if(NOT IS_ABSOLUTE "${file}")
  324.       gp_resolve_item("${original_file}" "${file}" "${exepath}" "${dirs}" resolved_file)
  325.     endif()
  326.     string(TOLOWER "${original_file}" original_lower)
  327.     string(TOLOWER "${resolved_file}" lower)
  328.     if(UNIX)
  329.       if(resolved_file MATCHES "^(/lib/|/lib32/|/lib64/|/usr/lib/|/usr/lib32/|/usr/lib64/|/usr/X11R6/)")
  330.         set(is_system 1)
  331.       endif()
  332.     endif()
  333.     if(APPLE)
  334.       if(resolved_file MATCHES "^(/System/Library/|/usr/lib/)")
  335.         set(is_system 1)
  336.       endif()
  337.     endif()
  338.     if(WIN32)
  339.       string(TOLOWER "$ENV{SystemRoot}" sysroot)
  340.       string(REGEX REPLACE "\\" "/" sysroot "${sysroot}")
  341.       string(TOLOWER "$ENV{windir}" windir)
  342.       string(REGEX REPLACE "\\" "/" windir "${windir}")
  343.       if(lower MATCHES "^(${sysroot}/system|${windir}/system|${sysroot}/syswow|${windir}/syswow|(.*/)*msvc[^/]+dll)")
  344.         set(is_system 1)
  345.       endif()
  346.     endif()
  347.     if(NOT is_system)
  348.       get_filename_component(original_path "${original_lower}" PATH)
  349.       get_filename_component(path "${lower}" PATH)
  350.       if("${original_path}" STREQUAL "${path}")
  351.         set(is_local 1)
  352.       endif()
  353.     endif()
  354.   endif()
  355.   # Return type string based on computed booleans:
  356.   #
  357.   set(type "other")
  358.   if(is_system)
  359.     set(type "system")
  360.   elseif(is_embedded)
  361.     set(type "embedded")
  362.   elseif(is_local)
  363.     set(type "local")
  364.   endif()
  365.   #message(STATUS "gp_resolved_file_type: '${file}' '${resolved_file}'")
  366.   #message(STATUS "                type: '${type}'")
  367.   if(NOT is_embedded)
  368.     if(NOT IS_ABSOLUTE "${resolved_file}")
  369.       if(lower MATCHES "^msvc[^/]+dll" AND is_system)
  370.         message(STATUS "info: non-absolute msvc file '${file}' returning type '${type}'")
  371.       else()
  372.         message(STATUS "warning: gp_resolved_file_type non-absolute file '${file}' returning type '${type}' -- possibly incorrect")
  373.       endif()
  374.     endif()
  375.   endif()
  376.   set(${type_var} "${type}" PARENT_SCOPE)
  377.   #message(STATUS "**")
  378. endfunction()
  379. # gp_file_type original_file file type_var
  380. #
  381. # Return the type of ${file} with respect to ${original_file}. String
  382. # describing type of prerequisite is returned in variable named ${type_var}.
  383. #
  384. # Possible types are:
  385. #   system
  386. #   local
  387. #   embedded
  388. #   other
  389. #
  390. function(gp_file_type original_file file type_var)
  391.   if(NOT IS_ABSOLUTE "${original_file}")
  392.     message(STATUS "warning: gp_file_type expects absolute full path for first arg original_file")
  393.   endif()
  394.   get_filename_component(exepath "${original_file}" PATH)
  395.   set(type "")
  396.   gp_resolved_file_type("${original_file}" "${file}" "${exepath}" "" type)
  397.   set(${type_var} "${type}" PARENT_SCOPE)
  398. endfunction(gp_file_type)
  399. # get_prerequisites target prerequisites_var exclude_system recurse dirs
  400. #
  401. # Get the list of shared library files required by ${target}. The list in
  402. # the variable named ${prerequisites_var} should be empty on first entry to
  403. # this function. On exit, ${prerequisites_var} will contain the list of
  404. # required shared library files.
  405. #
  406. #  target is the full path to an executable file
  407. #
  408. #  prerequisites_var is the name of a CMake variable to contain the results
  409. #
  410. #  exclude_system is 0 or 1: 0 to include "system" prerequisites , 1 to
  411. #   exclude them
  412. #
  413. #  recurse is 0 or 1: 0 for direct prerequisites only, 1 for all prerequisites
  414. #   recursively
  415. #
  416. #  exepath is the path to the top level executable used for @executable_path
  417. #   replacment on the Mac
  418. #
  419. #  dirs is a list of paths where libraries might be found: these paths are
  420. #   searched first when a target without any path info is given. Then standard
  421. #   system locations are also searched: PATH, Framework locations, /usr/lib...
  422. #
  423. function(get_prerequisites target prerequisites_var exclude_system recurse exepath dirs)
  424.   set(verbose 0)
  425.   set(eol_char "E")
  426.   if(NOT IS_ABSOLUTE "${target}")
  427.     message("warning: target '${target}' is not absolute...")
  428.   endif(NOT IS_ABSOLUTE "${target}")
  429.   if(NOT EXISTS "${target}")
  430.     message("warning: target '${target}' does not exist...")
  431.   endif(NOT EXISTS "${target}")
  432.   # <setup-gp_tool-vars>
  433.   #
  434.   # Try to choose the right tool by default. Caller can set gp_tool prior to
  435.   # calling this function to force using a different tool.
  436.   #
  437.   if("${gp_tool}" STREQUAL "")
  438.     set(gp_tool "ldd")
  439.     if(APPLE)
  440.       set(gp_tool "otool")
  441.     endif(APPLE)
  442.     if(WIN32)
  443.       set(gp_tool "dumpbin")
  444.     endif(WIN32)
  445.   endif("${gp_tool}" STREQUAL "")
  446.   set(gp_tool_known 0)
  447.   if("${gp_tool}" STREQUAL "ldd")
  448.     set(gp_cmd_args "")
  449.     set(gp_regex "^[t ]*[^t ]+ => ([^t ]+).*${eol_char}$")
  450.     set(gp_regex_cmp_count 1)
  451.     set(gp_tool_known 1)
  452.   endif("${gp_tool}" STREQUAL "ldd")
  453.   if("${gp_tool}" STREQUAL "otool")
  454.     set(gp_cmd_args "-L")
  455.     set(gp_regex "^t([^t]+) \(compatibility version ([0-9]+.[0-9]+.[0-9]+), current version ([0-9]+.[0-9]+.[0-9]+)\)${eol_char}$")
  456.     set(gp_regex_cmp_count 3)
  457.     set(gp_tool_known 1)
  458.   endif("${gp_tool}" STREQUAL "otool")
  459.   if("${gp_tool}" STREQUAL "dumpbin")
  460.     set(gp_cmd_args "/dependents")
  461.     set(gp_regex "^    ([^ ].*[Dd][Ll][Ll])${eol_char}$")
  462.     set(gp_regex_cmp_count 1)
  463.     set(gp_tool_known 1)
  464.     set(ENV{VS_UNICODE_OUTPUT} "") # Block extra output from inside VS IDE.
  465.   endif("${gp_tool}" STREQUAL "dumpbin")
  466.   if(NOT gp_tool_known)
  467.     message(STATUS "warning: gp_tool='${gp_tool}' is an unknown tool...")
  468.     message(STATUS "CMake function get_prerequisites needs more code to handle '${gp_tool}'")
  469.     message(STATUS "Valid gp_tool values are dumpbin, ldd and otool.")
  470.     return()
  471.   endif(NOT gp_tool_known)
  472.   set(gp_cmd_paths ${gp_cmd_paths}
  473.     "C:/Program Files/Microsoft Visual Studio 9.0/VC/bin"
  474.     "C:/Program Files (x86)/Microsoft Visual Studio 9.0/VC/bin"
  475.     "C:/Program Files/Microsoft Visual Studio 8/VC/BIN"
  476.     "C:/Program Files (x86)/Microsoft Visual Studio 8/VC/BIN"
  477.     "C:/Program Files/Microsoft Visual Studio .NET 2003/VC7/BIN"
  478.     "C:/Program Files (x86)/Microsoft Visual Studio .NET 2003/VC7/BIN"
  479.     "/usr/local/bin"
  480.     "/usr/bin"
  481.     )
  482.   find_program(gp_cmd ${gp_tool} PATHS ${gp_cmd_paths})
  483.   if(NOT gp_cmd)
  484.     message(STATUS "warning: could not find '${gp_tool}' - cannot analyze prerequisites...")
  485.     return()
  486.   endif(NOT gp_cmd)
  487.   if("${gp_tool}" STREQUAL "dumpbin")
  488.     # When running dumpbin, it also needs the "Common7/IDE" directory in the
  489.     # PATH. It will already be in the PATH if being run from a Visual Studio
  490.     # command prompt. Add it to the PATH here in case we are running from a
  491.     # different command prompt.
  492.     #
  493.     get_filename_component(gp_cmd_dir "${gp_cmd}" PATH)
  494.     get_filename_component(gp_cmd_dlls_dir "${gp_cmd_dir}/../../Common7/IDE" ABSOLUTE)
  495.     if(EXISTS "${gp_cmd_dlls_dir}")
  496.       # only add to the path if it is not already in the path
  497.       if(NOT "$ENV{PATH}" MATCHES "${gp_cmd_dlls_dir}")
  498.         set(ENV{PATH} "$ENV{PATH};${gp_cmd_dlls_dir}")
  499.       endif(NOT "$ENV{PATH}" MATCHES "${gp_cmd_dlls_dir}")
  500.     endif(EXISTS "${gp_cmd_dlls_dir}")
  501.   endif("${gp_tool}" STREQUAL "dumpbin")
  502.   #
  503.   # </setup-gp_tool-vars>
  504.   if("${gp_tool}" STREQUAL "ldd")
  505.     set(old_ld_env "$ENV{LD_LIBRARY_PATH}")
  506.     foreach(dir ${exepath} ${dirs})
  507.       set(ENV{LD_LIBRARY_PATH} "${dir}:$ENV{LD_LIBRARY_PATH}")
  508.     endforeach(dir)
  509.   endif("${gp_tool}" STREQUAL "ldd")
  510.   # Track new prerequisites at each new level of recursion. Start with an
  511.   # empty list at each level:
  512.   #
  513.   set(unseen_prereqs)
  514.   # Run gp_cmd on the target:
  515.   #
  516.   execute_process(
  517.     COMMAND ${gp_cmd} ${gp_cmd_args} ${target}
  518.     OUTPUT_VARIABLE gp_cmd_ov
  519.     )
  520.   if("${gp_tool}" STREQUAL "ldd")
  521.     set(ENV{LD_LIBRARY_PATH} "${old_ld_env}")
  522.   endif("${gp_tool}" STREQUAL "ldd")
  523.   if(verbose)
  524.     message(STATUS "<RawOutput cmd='${gp_cmd} ${gp_cmd_args} ${target}'>")
  525.     message(STATUS "gp_cmd_ov='${gp_cmd_ov}'")
  526.     message(STATUS "</RawOutput>")
  527.   endif(verbose)
  528.   get_filename_component(target_dir "${target}" PATH)
  529.   # Convert to a list of lines:
  530.   #
  531.   string(REGEX REPLACE ";" "\\;" candidates "${gp_cmd_ov}")
  532.   string(REGEX REPLACE "n" "${eol_char};" candidates "${candidates}")
  533.   # Analyze each line for file names that match the regular expression:
  534.   #
  535.   foreach(candidate ${candidates})
  536.   if("${candidate}" MATCHES "${gp_regex}")
  537.     # Extract information from each candidate:
  538.     string(REGEX REPLACE "${gp_regex}" "\1" raw_item "${candidate}")
  539.     if(gp_regex_cmp_count GREATER 1)
  540.       string(REGEX REPLACE "${gp_regex}" "\2" raw_compat_version "${candidate}")
  541.       string(REGEX REPLACE "^([0-9]+)\.([0-9]+)\.([0-9]+)$" "\1" compat_major_version "${raw_compat_version}")
  542.       string(REGEX REPLACE "^([0-9]+)\.([0-9]+)\.([0-9]+)$" "\2" compat_minor_version "${raw_compat_version}")
  543.       string(REGEX REPLACE "^([0-9]+)\.([0-9]+)\.([0-9]+)$" "\3" compat_patch_version "${raw_compat_version}")
  544.     endif(gp_regex_cmp_count GREATER 1)
  545.     if(gp_regex_cmp_count GREATER 2)
  546.       string(REGEX REPLACE "${gp_regex}" "\3" raw_current_version "${candidate}")
  547.       string(REGEX REPLACE "^([0-9]+)\.([0-9]+)\.([0-9]+)$" "\1" current_major_version "${raw_current_version}")
  548.       string(REGEX REPLACE "^([0-9]+)\.([0-9]+)\.([0-9]+)$" "\2" current_minor_version "${raw_current_version}")
  549.       string(REGEX REPLACE "^([0-9]+)\.([0-9]+)\.([0-9]+)$" "\3" current_patch_version "${raw_current_version}")
  550.     endif(gp_regex_cmp_count GREATER 2)
  551.     # Use the raw_item as the list entries returned by this function. Use the
  552.     # gp_resolve_item function to resolve it to an actual full path file if
  553.     # necessary.
  554.     #
  555.     set(item "${raw_item}")
  556.     # Add each item unless it is excluded:
  557.     #
  558.     set(add_item 1)
  559.     if(${exclude_system})
  560.       set(type "")
  561.       gp_resolved_file_type("${target}" "${item}" "${exepath}" "${dirs}" type)
  562.       if("${type}" STREQUAL "system")
  563.         set(add_item 0)
  564.       endif("${type}" STREQUAL "system")
  565.     endif(${exclude_system})
  566.     if(add_item)
  567.       list(LENGTH ${prerequisites_var} list_length_before_append)
  568.       gp_append_unique(${prerequisites_var} "${item}")
  569.       list(LENGTH ${prerequisites_var} list_length_after_append)
  570.       if(${recurse})
  571.         # If item was really added, this is the first time we have seen it.
  572.         # Add it to unseen_prereqs so that we can recursively add *its*
  573.         # prerequisites...
  574.         #
  575.         # But first: resolve its name to an absolute full path name such
  576.         # that the analysis tools can simply accept it as input.
  577.         #
  578.         if(NOT list_length_before_append EQUAL list_length_after_append)
  579.           gp_resolve_item("${target}" "${item}" "${exepath}" "${dirs}" resolved_item)
  580.           set(unseen_prereqs ${unseen_prereqs} "${resolved_item}")
  581.         endif(NOT list_length_before_append EQUAL list_length_after_append)
  582.       endif(${recurse})
  583.     endif(add_item)
  584.   else("${candidate}" MATCHES "${gp_regex}")
  585.     if(verbose)
  586.       message(STATUS "ignoring non-matching line: '${candidate}'")
  587.     endif(verbose)
  588.   endif("${candidate}" MATCHES "${gp_regex}")
  589.   endforeach(candidate)
  590.   list(LENGTH ${prerequisites_var} prerequisites_var_length)
  591.   if(prerequisites_var_length GREATER 0)
  592.     list(SORT ${prerequisites_var})
  593.   endif(prerequisites_var_length GREATER 0)
  594.   if(${recurse})
  595.     set(more_inputs ${unseen_prereqs})
  596.     foreach(input ${more_inputs})
  597.       get_prerequisites("${input}" ${prerequisites_var} ${exclude_system} ${recurse} "${exepath}" "${dirs}")
  598.     endforeach(input)
  599.   endif(${recurse})
  600.   set(${prerequisites_var} ${${prerequisites_var}} PARENT_SCOPE)
  601. endfunction(get_prerequisites)
  602. # list_prerequisites target all exclude_system verbose
  603. #
  604. #  ARGV0 (target) is the full path to an executable file
  605. #
  606. #  optional ARGV1 (all) is 0 or 1: 0 for direct prerequisites only,
  607. #   1 for all prerequisites recursively
  608. #
  609. #  optional ARGV2 (exclude_system) is 0 or 1: 0 to include "system"
  610. #   prerequisites , 1 to exclude them
  611. #
  612. #  optional ARGV3 (verbose) is 0 or 1: 0 to print only full path
  613. #   names of prerequisites, 1 to print extra information
  614. #
  615. function(list_prerequisites target)
  616.   if("${ARGV1}" STREQUAL "")
  617.     set(all 1)
  618.   else("${ARGV1}" STREQUAL "")
  619.     set(all "${ARGV1}")
  620.   endif("${ARGV1}" STREQUAL "")
  621.   if("${ARGV2}" STREQUAL "")
  622.     set(exclude_system 0)
  623.   else("${ARGV2}" STREQUAL "")
  624.     set(exclude_system "${ARGV2}")
  625.   endif("${ARGV2}" STREQUAL "")
  626.   if("${ARGV3}" STREQUAL "")
  627.     set(verbose 0)
  628.   else("${ARGV3}" STREQUAL "")
  629.     set(verbose "${ARGV3}")
  630.   endif("${ARGV3}" STREQUAL "")
  631.   set(count 0)
  632.   set(count_str "")
  633.   set(print_count "${verbose}")
  634.   set(print_prerequisite_type "${verbose}")
  635.   set(print_target "${verbose}")
  636.   set(type_str "")
  637.   get_filename_component(exepath "${target}" PATH)
  638.   set(prereqs "")
  639.   get_prerequisites("${target}" prereqs ${exclude_system} ${all} "${exepath}" "")
  640.   if(print_target)
  641.     message(STATUS "File '${target}' depends on:")
  642.   endif(print_target)
  643.   foreach(d ${prereqs})
  644.     math(EXPR count "${count} + 1")
  645.     if(print_count)
  646.       set(count_str "${count}. ")
  647.     endif(print_count)
  648.     if(print_prerequisite_type)
  649.       gp_file_type("${target}" "${d}" type)
  650.       set(type_str " (${type})")
  651.     endif(print_prerequisite_type)
  652.     message(STATUS "${count_str}${d}${type_str}")
  653.   endforeach(d)
  654. endfunction(list_prerequisites)
  655. # list_prerequisites_by_glob glob_arg glob_exp
  656. #
  657. #  glob_arg is GLOB or GLOB_RECURSE
  658. #
  659. #  glob_exp is a globbing expression used with "file(GLOB" to retrieve a list
  660. #   of matching files. If a matching file is executable, its prerequisites are
  661. #   listed.
  662. #
  663. # Any additional (optional) arguments provided are passed along as the
  664. # optional arguments to the list_prerequisites calls.
  665. #
  666. function(list_prerequisites_by_glob glob_arg glob_exp)
  667.   message(STATUS "=============================================================================")
  668.   message(STATUS "List prerequisites of executables matching ${glob_arg} '${glob_exp}'")
  669.   message(STATUS "")
  670.   file(${glob_arg} file_list ${glob_exp})
  671.   foreach(f ${file_list})
  672.     is_file_executable("${f}" is_f_executable)
  673.     if(is_f_executable)
  674.       message(STATUS "=============================================================================")
  675.       list_prerequisites("${f}" ${ARGN})
  676.       message(STATUS "")
  677.     endif(is_f_executable)
  678.   endforeach(f)
  679. endfunction(list_prerequisites_by_glob)