PageRenderTime 71ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/cmake/GetPrerequisites_2_8.cmake

https://bitbucket.org/lindenlab/viewer-beta/
CMake | 786 lines | 417 code | 107 blank | 262 comment | 84 complexity | 4974bf0c4612322976c1e3c522ecf7e2 MD5 | raw file
Possible License(s): LGPL-2.1
  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)