vtkModuleGraphviz.cmake 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. #[==[
  2. @ingroup module-impl
  3. @brief Output a node in the graph
  4. Queries the properties for modules and generates the node for it in the graph
  5. and its outgoing dependency edges.
  6. #]==]
  7. function (_vtk_module_graphviz_module_node var module)
  8. get_property(_vtk_graphviz_file GLOBAL
  9. PROPERTY "_vtk_module_${module}_file")
  10. if (_vtk_graphviz_file)
  11. get_property(_vtk_graphviz_module_third_party GLOBAL
  12. PROPERTY "_vtk_module_${module}_third_party")
  13. get_property(_vtk_graphviz_module_exclude_wrap GLOBAL
  14. PROPERTY "_vtk_module_${module}_exclude_wrap")
  15. get_property(_vtk_graphviz_module_depends GLOBAL
  16. PROPERTY "_vtk_module_${module}_depends")
  17. get_property(_vtk_graphviz_module_private_depends GLOBAL
  18. PROPERTY "_vtk_module_${module}_private_depends")
  19. get_property(_vtk_graphviz_module_optional_depends GLOBAL
  20. PROPERTY "_vtk_module_${module}_optional_depends")
  21. get_property(_vtk_graphviz_module_implements GLOBAL
  22. PROPERTY "_vtk_module_${module}_implements")
  23. get_property(_vtk_graphviz_module_implementable GLOBAL
  24. PROPERTY "_vtk_module_${module}_implementable")
  25. else ()
  26. get_property(_vtk_graphviz_module_third_party
  27. TARGET "${module}"
  28. PROPERTY "INTERFACE_vtk_module_third_party")
  29. get_property(_vtk_graphviz_module_exclude_wrap
  30. TARGET "${module}"
  31. PROPERTY "INTERFACE_vtk_module_exclude_wrap")
  32. get_property(_vtk_graphviz_module_depends
  33. TARGET "${module}"
  34. PROPERTY "INTERFACE_vtk_module_depends")
  35. set(_vtk_graphviz_module_private_depends)
  36. set(_vtk_graphviz_module_optional_depends)
  37. get_property(_vtk_graphviz_module_implements
  38. TARGET "${module}"
  39. PROPERTY "INTERFACE_vtk_module_implements")
  40. get_property(_vtk_graphviz_module_implementable
  41. TARGET "${module}"
  42. PROPERTY "INTERFACE_vtk_module_implementable")
  43. endif ()
  44. if (_vtk_graphviz_module_third_party)
  45. set(_vtk_graphviz_shape "${_vtk_graphviz_third_party}")
  46. else ()
  47. set(_vtk_graphviz_shape "${_vtk_graphviz_first_party}")
  48. endif ()
  49. if (_vtk_graphviz_file)
  50. if (DEFINED "VTK_MODULE_USE_EXTERNAL_${module}" AND VTK_MODULE_USE_EXTERNAL_${module})
  51. set(_vtk_graphviz_fillcolor "${_vtk_graphviz_external}")
  52. else ()
  53. set(_vtk_graphviz_fillcolor "${_vtk_graphviz_internal}")
  54. endif ()
  55. else ()
  56. set(_vtk_graphviz_fillcolor "${_vtk_graphviz_external}")
  57. endif ()
  58. if (_vtk_graphviz_module_exclude_wrap)
  59. set(_vtk_graphviz_penwidth "${_vtk_graphviz_exclude_wrap}")
  60. else ()
  61. set(_vtk_graphviz_penwidth "${_vtk_graphviz_include_wrap}")
  62. endif ()
  63. if (_vtk_graphviz_module_implementable)
  64. set(_vtk_graphviz_color "${_vtk_graphviz_implementable}")
  65. else ()
  66. set(_vtk_graphviz_color "${_vtk_graphviz_not_implementable}")
  67. endif ()
  68. set(_vtk_graphviz_node_block "\"${module}\" [
  69. label=\"${module}\"
  70. shape=${_vtk_graphviz_shape}
  71. style=filled
  72. color=${_vtk_graphviz_color}
  73. fillcolor=${_vtk_graphviz_fillcolor}
  74. penwidth=${_vtk_graphviz_penwidth}
  75. ];\n")
  76. foreach (_vtk_graphviz_module_implement IN LISTS _vtk_graphviz_module_implements)
  77. string(APPEND _vtk_graphviz_node_block
  78. "\"${module}\" -> \"${_vtk_graphviz_module_implement}\" [style=${_vtk_graphviz_implements}, arrowhead=${_vtk_graphviz_required_depends}];\n")
  79. endforeach ()
  80. foreach (_vtk_graphviz_module_depend IN LISTS _vtk_graphviz_module_depends)
  81. string(APPEND _vtk_graphviz_node_block
  82. "\"${module}\" -> \"${_vtk_graphviz_module_depend}\" [style=${_vtk_graphviz_public_depends}, arrowhead=${_vtk_graphviz_required_depends}];\n")
  83. endforeach ()
  84. if (_vtk_graphviz_PRIVATE_DEPENDENCIES)
  85. foreach (_vtk_graphviz_module_private_depend IN LISTS _vtk_graphviz_module_private_depends)
  86. string(APPEND _vtk_graphviz_node_block
  87. "\"${module}\" -> \"${_vtk_graphviz_module_private_depend}\" [style=${_vtk_graphviz_private_depends}, arrowhead=${_vtk_graphviz_required_depends}];\n")
  88. endforeach ()
  89. foreach (_vtk_graphviz_module_optional_depend IN LISTS _vtk_graphviz_module_optional_depends)
  90. string(APPEND _vtk_graphviz_node_block
  91. "\"${module}\" -> \"${_vtk_graphviz_module_optional_depend}\" [style=${_vtk_graphviz_optional_depends}, arrowhead=${_vtk_graphviz_optional_depends}];\n")
  92. endforeach ()
  93. endif ()
  94. set("${var}" "${_vtk_graphviz_node_block}" PARENT_SCOPE)
  95. endfunction ()
  96. #[==[
  97. @ingroup module-support
  98. @brief Generate graphviz output for a module dependency graph
  99. Information about the modules built and/or available may be dumped to a
  100. Graphviz `.dot` file.
  101. ~~~
  102. vtk_module_graphviz(
  103. MODULES <module>...
  104. OUTPUT <path>
  105. [PRIVATE_DEPENDENCIES <ON|OFF>]
  106. [KIT_CLUSTERS <ON|OFF>])
  107. ~~~
  108. * `MODULES`: (Required) The modules to output information for.
  109. * `OUTPUT`: (Required) A Graphviz file describing the modules built will
  110. be output to this path. Relative paths are rooted to `CMAKE_BINARY_DIR`.
  111. * `PRIVATE_DEPENDENCIES`: (Default `ON`) Whether to draw private dependency
  112. edges or not..
  113. * `KIT_CLUSTERS`: (Default `OFF`) Whether to draw modules as part of a kit as
  114. a cluster or not.
  115. #]==]
  116. function (vtk_module_graphviz)
  117. cmake_parse_arguments(_vtk_graphviz
  118. ""
  119. "PRIVATE_DEPENDENCIES;KIT_CLUSTERS;OUTPUT"
  120. "MODULES"
  121. ${ARGN})
  122. if (_vtk_graphviz_UNPARSED_ARGUMENTS)
  123. message(FATAL_ERROR
  124. "Unparsed arguments for vtk_module_graphviz: "
  125. "${_vtk_graphviz_UNPARSED_ARGUMENTS}")
  126. endif ()
  127. if (NOT DEFINED _vtk_graphviz_OUTPUT)
  128. message(FATAL_ERROR
  129. "The `OUTPUT` argument is required.")
  130. endif ()
  131. if (NOT _vtk_graphviz_MODULES)
  132. message(FATAL_ERROR "No modules given to output.")
  133. endif ()
  134. if (NOT DEFINED _vtk_graphviz_PRIVATE_DEPENDENCIES)
  135. set(_vtk_graphviz_PRIVATE_DEPENDENCIES ON)
  136. endif ()
  137. if (NOT DEFINED _vtk_graphviz_KIT_CLUSTERS)
  138. set(_vtk_graphviz_KIT_CLUSTERS OFF)
  139. endif ()
  140. if (NOT IS_ABSOLUTE "${_vtk_graphviz_OUTPUT}")
  141. set(_vtk_graphviz_OUTPUT "${CMAKE_BINARY_DIR}/${_vtk_graphviz_OUTPUT}")
  142. endif ()
  143. set(_vtk_graphviz_kits)
  144. set(_vtk_graphviz_no_kit_modules)
  145. if (_vtk_graphviz_KIT_CLUSTERS)
  146. # Get a list of all kits.
  147. foreach (_vtk_graphviz_module IN LISTS _vtk_graphviz_MODULES)
  148. get_property(_vtk_graphviz_kit GLOBAL
  149. PROPERTY "_vtk_module_${_vtk_graphviz_module}_kit")
  150. if (_vtk_graphviz_kit)
  151. list(APPEND _vtk_graphviz_kits
  152. "${_vtk_graphviz_kit}")
  153. else ()
  154. list(APPEND _vtk_graphviz_no_kit_modules
  155. "${_vtk_graphviz_module}")
  156. endif ()
  157. endforeach ()
  158. if (_vtk_graphviz_kits)
  159. list(REMOVE_DUPLICATES _vtk_graphviz_kits)
  160. endif ()
  161. else ()
  162. set(_vtk_graphviz_no_kit_modules "${_vtk_graphviz_MODULES}")
  163. endif ()
  164. # Shapes
  165. set(_vtk_graphviz_first_party "rectangle")
  166. set(_vtk_graphviz_third_party "cds")
  167. set(_vtk_graphviz_internal "\"/svg/white\"")
  168. set(_vtk_graphviz_external "\"/svg/cyan\"")
  169. # Border style
  170. set(_vtk_graphviz_include_wrap "5")
  171. set(_vtk_graphviz_exclude_wrap "1")
  172. set(_vtk_graphviz_implementable "\"/svg/darkorchid\"")
  173. set(_vtk_graphviz_not_implementable "\"/svg/coral\"")
  174. # Dependencies
  175. set(_vtk_graphviz_public_depends "solid")
  176. set(_vtk_graphviz_private_depends "dotted")
  177. set(_vtk_graphviz_implements "bold")
  178. set(_vtk_graphviz_required_depends "normal")
  179. set(_vtk_graphviz_optional_depends "empty")
  180. set(_vtk_graphviz_contents "strict digraph modules {\nclusterrank=local;\nrankdir=TB;\n")
  181. # Output modules not part of a kit.
  182. string(APPEND _vtk_graphviz_contents
  183. "subgraph \"modules_without_kits\" {\n")
  184. foreach (_vtk_graphviz_module IN LISTS _vtk_graphviz_no_kit_modules)
  185. _vtk_module_graphviz_module_node(_vtk_graphviz_node "${_vtk_graphviz_module}")
  186. string(APPEND _vtk_graphviz_contents
  187. "${_vtk_graphviz_node}\n")
  188. endforeach ()
  189. string(APPEND _vtk_graphviz_contents
  190. "}\n")
  191. # Output kits as clusters.
  192. foreach (_vtk_graphviz_kit IN LISTS _vtk_graphviz_kits)
  193. string(APPEND _vtk_graphviz_contents
  194. "subgraph \"cluster_${_vtk_graphviz_kit}\" {\nlabel=\"${_vtk_graphviz_kit}\"\n")
  195. get_property(_vtk_graphviz_kit_modules GLOBAL
  196. PROPERTY "_vtk_kit_${_vtk_graphviz_kit}_kit_modules")
  197. foreach (_vtk_graphviz_kit_module IN LISTS _vtk_graphviz_kit_modules)
  198. if (NOT _vtk_graphviz_kit_module IN_LIST _vtk_graphviz_MODULES)
  199. continue ()
  200. endif ()
  201. _vtk_module_graphviz_module_node(_vtk_graphviz_node "${_vtk_graphviz_kit_module}")
  202. string(APPEND _vtk_graphviz_contents
  203. "${_vtk_graphviz_node}\n")
  204. endforeach ()
  205. string(APPEND _vtk_graphviz_contents
  206. "}\n")
  207. endforeach ()
  208. # Write the key cluster.
  209. string(APPEND _vtk_graphviz_contents "
  210. subgraph cluster_key {
  211. label=Key;
  212. subgraph cluster_party {
  213. first_party [
  214. label=\"First party\"
  215. shape=${_vtk_graphviz_first_party}
  216. style=filled
  217. color=${_vtk_graphviz_not_implementable}
  218. fillcolor=${_vtk_graphviz_internal}
  219. penwidth=${_vtk_graphviz_include_wrap}
  220. ];
  221. third_party [
  222. label=\"Third party\"
  223. shape=${_vtk_graphviz_third_party}
  224. style=filled
  225. color=${_vtk_graphviz_not_implementable}
  226. fillcolor=${_vtk_graphviz_internal}
  227. penwidth=${_vtk_graphviz_include_wrap}
  228. ];
  229. }
  230. subgraph cluster_whence {
  231. internal [
  232. label=\"Internal module\"
  233. shape=${_vtk_graphviz_first_party}
  234. style=filled
  235. color=${_vtk_graphviz_not_implementable}
  236. fillcolor=${_vtk_graphviz_internal}
  237. penwidth=${_vtk_graphviz_include_wrap}
  238. ];
  239. external [
  240. label=\"External module\"
  241. shape=${_vtk_graphviz_first_party}
  242. style=filled
  243. color=${_vtk_graphviz_not_implementable}
  244. fillcolor=${_vtk_graphviz_external}
  245. penwidth=${_vtk_graphviz_include_wrap}
  246. ];
  247. }
  248. subgraph cluster_wrapping {
  249. include_wrap [
  250. label=\"Wrappable\"
  251. shape=${_vtk_graphviz_first_party}
  252. style=filled
  253. color=${_vtk_graphviz_not_implementable}
  254. fillcolor=${_vtk_graphviz_internal}
  255. penwidth=${_vtk_graphviz_include_wrap}
  256. ];
  257. exclude_wrap [
  258. label=\"Not wrappable\"
  259. shape=${_vtk_graphviz_first_party}
  260. style=filled
  261. color=${_vtk_graphviz_not_implementable}
  262. fillcolor=${_vtk_graphviz_internal}
  263. penwidth=${_vtk_graphviz_exclude_wrap}
  264. ];
  265. }
  266. subgraph cluster_implementable {
  267. implementable [
  268. label=\"Implementable\"
  269. shape=${_vtk_graphviz_first_party}
  270. style=filled
  271. color=${_vtk_graphviz_implementable}
  272. fillcolor=${_vtk_graphviz_internal}
  273. penwidth=${_vtk_graphviz_include_wrap}
  274. ];
  275. not_implementable [
  276. label=\"Not implementable\"
  277. shape=${_vtk_graphviz_first_party}
  278. style=filled
  279. color=${_vtk_graphviz_not_implementable}
  280. fillcolor=${_vtk_graphviz_internal}
  281. penwidth=${_vtk_graphviz_include_wrap}
  282. ];
  283. }
  284. subgraph cluster_dependencies {
  285. dependent [
  286. label=\"Dependent\"
  287. shape=${_vtk_graphviz_first_party}
  288. style=filled
  289. color=${_vtk_graphviz_not_implementable}
  290. fillcolor=${_vtk_graphviz_internal}
  291. penwidth=${_vtk_graphviz_include_wrap}
  292. ];
  293. private_dependee [
  294. label=\"Private Dependee\"
  295. shape=${_vtk_graphviz_first_party}
  296. style=filled
  297. color=${_vtk_graphviz_not_implementable}
  298. fillcolor=${_vtk_graphviz_internal}
  299. penwidth=${_vtk_graphviz_include_wrap}
  300. ];
  301. optional_dependee [
  302. label=\"Optional Dependee\"
  303. shape=${_vtk_graphviz_first_party}
  304. style=filled
  305. color=${_vtk_graphviz_not_implementable}
  306. fillcolor=${_vtk_graphviz_internal}
  307. penwidth=${_vtk_graphviz_include_wrap}
  308. ];
  309. public_dependee [
  310. label=\"Public Dependee\"
  311. shape=${_vtk_graphviz_first_party}
  312. style=filled
  313. color=${_vtk_graphviz_not_implementable}
  314. fillcolor=${_vtk_graphviz_internal}
  315. penwidth=${_vtk_graphviz_include_wrap}
  316. ];
  317. implemented [
  318. label=\"Implemented\"
  319. shape=${_vtk_graphviz_first_party}
  320. style=filled
  321. color=${_vtk_graphviz_implementable}
  322. fillcolor=${_vtk_graphviz_internal}
  323. penwidth=${_vtk_graphviz_include_wrap}
  324. ];
  325. dependent -> private_dependee [style=${_vtk_graphviz_private_depends}, arrowhead=${_vtk_graphviz_required_depends}];
  326. dependent -> optional_dependee [style=${_vtk_graphviz_private_depends}, arrowhead=${_vtk_graphviz_optional_depends}];
  327. dependent -> public_dependee [style=${_vtk_graphviz_public_depends}, arrowhead=${_vtk_graphviz_required_depends}];
  328. dependent -> implemented [style=${_vtk_graphviz_implements}, arrowhead=${_vtk_graphviz_required_depends}];
  329. }
  330. }
  331. ")
  332. string(APPEND _vtk_graphviz_contents "}\n")
  333. #file(GENERATE
  334. # OUTPUT "${_vtk_graphviz_OUTPUT}"
  335. # CONTENT "${_vtk_graphviz_contents}")
  336. file(WRITE "${_vtk_graphviz_OUTPUT}" "${_vtk_graphviz_contents}")
  337. endfunction ()