You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

GenerateDocumentation.cmake 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. # Author Yann Renard / INRIA; Laurent Bonnet / Mensia Technologies
  2. # Date 2008-10-15
  3. # Modified 2013-06-26
  4. #
  5. # this CMake script iterates over several source documentation directories in
  6. # order to compile it with doxygen. It has the ability to configure the
  7. # doxyfile depending on some variables and to build documentation sources from
  8. # computer generated templates (.dox-skeleton) and hand written documentation
  9. # parts (.dox-part)
  10. IF(MENSIA_BUILD_DOC)
  11. # look for doxygen, if not present, no need to generate documentation
  12. FIND_PROGRAM(doxygen_bin "doxygen" PATHS $ENV{OpenViBE_dependencies}/bin NO_DEFAULT_PATH)
  13. FIND_PROGRAM(doxygen_bin "doxygen" PATHS $ENV{OpenViBE_dependencies}/bin "C:/Program Files/doxygen/bin" "C:/Program Files (x86)/doxygen/bin")
  14. IF(doxygen_bin)
  15. debug_message( " Found doxygen...")
  16. #Set the project on which the documentation commands will be attached
  17. SET(PROJECT_NAME_DOC ${PROJECT_NAME}-doc)
  18. ADD_CUSTOM_TARGET(${PROJECT_NAME_DOC} ALL)
  19. ADD_DEPENDENCIES(${PROJECT_NAME_DOC} ${PROJECT_NAME})
  20. # intializes the variable that will be used in the doxyfile for input
  21. # directories
  22. # STRING(REPLACE "\\" "/" ov_doxy_input "\"$ENV{OpenViBE_base}/cmake-modules\"")
  23. STRING(REPLACE "\\" "/" ov_doxy_input "\"${PROJECT_SOURCE_DIR}/src\"")
  24. # intializes the variable that will contain the list of resource files to
  25. # copy to the target directory
  26. SET(RESOURCE_FILES "")
  27. SET(scenario_files "")
  28. # for each project, we look at its resources and store them in a list
  29. # for each project, we look at partial documentation files (.dox-part) and
  30. # parse them to get |ov[a-zA-Z0-9_]*_begin| or |ov[a-zA-Z0-9_]*_end|
  31. # tokens. This tokens will later be included in the skeleton doxumentation
  32. # files (.dox-skeleton)
  33. SET(current_project_src "${PROJECT_SOURCE_DIR}/src")
  34. # updates the doxyfile variable for input directories
  35. SET(ov_doxy_input "${ov_doxy_input} \"${current_project_src}\"")
  36. debug_message( " [ OK ] Candidate directory found ${current_project_src}")
  37. # looks for resources and stores thm in a list
  38. FILE(GLOB_RECURSE resource_files_tmp "${current_project_src}/*.png" "${current_project_src}/*.svg" "${current_project_src}/*.css" "${current_project_src}/*.php")
  39. SET(RESOURCE_FILES ${RESOURCE_FILES} ${resource_files_tmp})
  40. # looks for scenario files
  41. FILE(GLOB_RECURSE scenario_files_tmp "${current_project_src}/*.xml")
  42. SET(scenario_files ${scenario_files} ${scenario_files_tmp})
  43. # looks for partial hand written documentation
  44. FILE(GLOB_RECURSE doxs "${current_project_src}/*.dox-part")
  45. FOREACH(dox ${doxs})
  46. GET_FILENAME_COMPONENT(dox_filename ${dox} NAME_WE)
  47. debug_message( " Documentation part found ${dox}")
  48. SET(dox_tag_name NOTFOUND)
  49. # iterates on each line of the file to look after begin/end tags
  50. # "dox_tag_name" stores the name of the variable
  51. # to use to configure the skeleton file. It is computed from the
  52. # begin tag.
  53. FILE(READ ${dox} dox_lines)
  54. # replaces empty cariage returns with semi colons to be compliant
  55. # with CMake lists. note the space before and after the semi
  56. # colon, this is for CMake not to skip empty lines
  57. STRING(REPLACE "\n" " ; " dox_lines " ${dox_lines} ")
  58. FOREACH(dox_line ${dox_lines})
  59. # this regex removes the spaces we added before the loop
  60. STRING(REGEX REPLACE "^ (.*) $" "\\1" dox_line ${dox_line})
  61. # we initialize several variables that will be used in
  62. # this loop
  63. SET(dox_line_processed FALSE)
  64. SET(dox_tag_begin NOTFOUND)
  65. SET(dox_tag_end NOTFOUND)
  66. SET(dox_tag NOTFOUND)
  67. # and look for a new tag in this line
  68. STRING(REGEX MATCH "\\|[a-zA-Z0-9_]*\\|" dox_tag "${dox_line}")
  69. IF(dox_tag)
  70. # a tag is found, so we want to know if it is a
  71. # OVP_DocBegin* or OVP_DocEnd* tag
  72. STRING(REGEX MATCH "\\|OVP_DocBegin_[a-zA-Z0-9_]*\\|" dox_tag_begin "${dox_line}")
  73. STRING(REGEX MATCH "\\|OVP_DocEnd_[a-zA-Z0-9_]*\\|" dox_tag_end "${dox_line}")
  74. # in case we already have something in
  75. # dox_tag_name, it means that begin tag has
  76. # already been processed, so either we terminate with end
  77. # tag, either we continue with come content to add in the
  78. # variable
  79. IF(dox_tag_name AND dox_tag_end)
  80. # in case we find end tag, we just terminate cleaning
  81. # the tag and what follows. We then terminate and
  82. # create a new CMake variable with the content of this
  83. # begin/end tagged things.
  84. STRING(REGEX REPLACE ".*\\|OVP_DocEnd_([a-zA-Z0-9_]*)\\|.*" "\\1" dox_tag_name_check ${dox_line})
  85. STRING(REGEX REPLACE "\\|OVP_DocEnd_([a-zA-Z0-9_]*)\\|.*" "" dox_line "${dox_line}")
  86. debug_message( " - Completed tag pair |${dox_tag_name}|")
  87. SET(dox_tag_name_value "${dox_tag_name_value}\n${dox_line}")
  88. SET("Doc_${dox_tag_name}_Content" ${dox_tag_name_value})
  89. SET(dox_tag_name NOTFOUND)
  90. SET(dox_line_processed TRUE)
  91. ENDIF(dox_tag_name AND dox_tag_end)
  92. # in case dox_tag_name is empty, it means
  93. # that begin tag has not yet been found, so we just look at it
  94. # or skip to next line
  95. IF(NOT dox_tag_name AND dox_tag_begin)
  96. # in case we find begin tag, we just start saving the
  97. # CMake variable name, and clean the tag and what
  98. # comes before. We then intialize the content of the
  99. # begin/end tagged thing with what comes after begin
  100. # tag.
  101. STRING(REGEX REPLACE ".*\\|OVP_DocBegin_([a-zA-Z0-9_]*)\\|.*" "\\1" dox_tag_name ${dox_line})
  102. STRING(REGEX REPLACE ".*\\|OVP_DocBegin_([a-zA-Z0-9_]*)\\|" "" dox_line "${dox_line}")
  103. SET(dox_tag_name_value "${dox_line}")
  104. SET(dox_line_processed TRUE)
  105. ENDIF(NOT dox_tag_name AND dox_tag_begin)
  106. # in case dox tag is not OVP_DocBegin* or OVP_DocEnd*
  107. # just print a warning and continue
  108. IF(NOT dox_line_processed)
  109. MESSAGE(STATUS " - Unexpected tag ${dox_tag} will be ignored")
  110. ENDIF(NOT dox_line_processed)
  111. ENDIF(dox_tag)
  112. # in case this line was not processed, either because it does
  113. # not have any tag, either because the tag was unexpected, we
  114. # just append the whole line to the content of the current
  115. # variable
  116. IF(dox_tag_name AND NOT dox_line_processed)
  117. # in case we don't find the end tag, just append this
  118. # new line to the current content
  119. SET(dox_tag_name_value "${dox_tag_name_value}\n${dox_line}")
  120. ENDIF(dox_tag_name AND NOT dox_line_processed)
  121. ENDFOREACH(dox_line)
  122. ENDFOREACH(dox)
  123. # now we have stored all the begin/end tagged things in variable, we just
  124. # have to configure the skeleton configuration files with those variables.
  125. # note that the skeleon files should be prepared to receive the CMake
  126. # variables with @CMakeVariableName@ anywhere it is needed.
  127. #
  128. # in order to do so, we look after all the (.dox-skeleton) files and call
  129. # the configure command to build the final documentation (.dox) file.
  130. FILE(GLOB_RECURSE dox_skeletons "${PROJECT_SOURCE_DIR}/src/*.dox-skeleton")
  131. FOREACH(dox_skeleton ${dox_skeletons})
  132. GET_FILENAME_COMPONENT(dox_skeleton_filename ${dox_skeleton} NAME_WE)
  133. GET_FILENAME_COMPONENT(dox_skeleton_path ${dox_skeleton} PATH)
  134. CONFIGURE_FILE(
  135. "${dox_skeleton}"
  136. "${dox_skeleton_path}/${dox_skeleton_filename}.dox"
  137. @ONLY)
  138. debug_message( " [ OK ] Configured skeleton ${dox_skeleton}")
  139. ENDFOREACH(dox_skeleton)
  140. # now add post-build commands to copy resources in the target directory
  141. IF(RESOURCE_FILES)
  142. debug_message( " Found resources...")
  143. FOREACH(current_resource ${RESOURCE_FILES})
  144. GET_FILENAME_COMPONENT(current_resource_stripped ${current_resource} NAME)
  145. debug_message( " [ OK ] Resource file ${current_resource}")
  146. ADD_CUSTOM_COMMAND(
  147. TARGET ${PROJECT_NAME_DOC}
  148. POST_BUILD
  149. COMMAND ${CMAKE_COMMAND}
  150. ARGS -E copy_if_different "${current_resource}" "${PROJECT_SOURCE_DIR}/doc/${PROJECT_NAME}/html/${current_resource_stripped}"
  151. COMMAND ${CMAKE_COMMAND}
  152. ARGS -E copy_if_different "${current_resource}" "${PROJECT_SOURCE_DIR}/doc/${PROJECT_NAME}/latex/${current_resource_stripped}"
  153. COMMENT " ---> [html/latex] Copying resource file ${current_resource_stripped}..."
  154. VERBATIM)
  155. ENDFOREACH(current_resource)
  156. ENDIF(RESOURCE_FILES)
  157. # now add post-build commands to copy scenario files in the target directory
  158. IF(scenario_files)
  159. debug_message( " Found scenario files...")
  160. FOREACH(current_scenario ${scenario_files})
  161. GET_FILENAME_COMPONENT(current_scenario_stripped ${current_scenario} NAME)
  162. debug_message( " [ OK ] scenario file ${current_scenario}")
  163. ADD_CUSTOM_COMMAND(
  164. TARGET ${PROJECT_NAME_DOC}
  165. POST_BUILD
  166. COMMAND ${CMAKE_COMMAND}
  167. ARGS -E copy_if_different "${current_scenario}" "${PROJECT_SOURCE_DIR}/doc/${PROJECT_NAME}/html/scenarios/${current_scenario_stripped}"
  168. COMMAND ${CMAKE_COMMAND}
  169. ARGS -E copy_if_different "${current_scenario}" "${PROJECT_SOURCE_DIR}/doc/${PROJECT_NAME}/latex/scenarios/${current_scenario_stripped}"
  170. COMMENT " ---> [html/latex] Copying scenario file ${current_scenario_stripped}..."
  171. VERBATIM)
  172. ENDFOREACH(current_scenario)
  173. # Saving all scenarios in a dedicated package
  174. ADD_CUSTOM_COMMAND(
  175. TARGET ${PROJECT_NAME_DOC}
  176. POST_BUILD
  177. COMMAND ${CMAKE_COMMAND} ARGS -E tar cfz ${PROJECT_NAME_DOC}-scenarios.tar.gz scenarios
  178. COMMAND ${CMAKE_COMMAND} ARGS -E copy ${PROJECT_NAME_DOC}-scenarios.tar.gz ${PROJECT_SOURCE_DIR}/doc/${PROJECT_NAME}/
  179. COMMAND ${CMAKE_COMMAND} ARGS -E remove ${PROJECT_NAME_DOC}-scenarios.tar.gz
  180. WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/doc/${PROJECT_NAME}/html"
  181. COMMENT " ---> Packaging scenario files..."
  182. VERBATIM)
  183. ENDIF(scenario_files)
  184. # the final doxyfile filename is generated, platform compliantly
  185. SET(ov_doxy_final "${PROJECT_SOURCE_DIR}/src/doc/doxyfile")
  186. IF(WIN32)
  187. STRING(REPLACE "/" "\\" ov_doxy_final ${ov_doxy_final})
  188. ENDIF(WIN32)
  189. # these lines configure the variables used to configure the doxyfile
  190. SET(ov_doxy_strip_from_path ${ov_doxy_input})
  191. SET(ov_doxy_version ${PROJECT_VERSION})
  192. SET(ov_doxy_output_directory ../doc/${PROJECT_NAME})
  193. SET(ov_doxy_project_name ${PROJECT_NAME}-documentation)
  194. SET(ov_doxy_header_project_name ${PROJECT_NAME}-documentation)
  195. SET(ov_doxy_header_version ${PROJECT_VERSION})
  196. SET(ov_doxy_header_branch ${PROJECT_BRANCH})
  197. SET(ov_doxy_header_hash ${PROJECT_COMMITHASH})
  198. IF(PROJECT_PRODUCT_NAME)
  199. SET(ov_doxy_header_product_name ${PROJECT_PRODUCT_NAME})
  200. ELSE(PROJECT_PRODUCT_NAME)
  201. SET(ov_doxy_header_product_name ${PROJECT_NAME})
  202. ENDIF(PROJECT_PRODUCT_NAME)
  203. debug_message( " Looking for additional documentation supports...")
  204. # configure doxyfile to generate a chm if available
  205. FIND_PROGRAM(HHC_BIN "hhc" PATHS "C:\Program Files\HTML Help Workshop" "C:\Program Files (x86)\HTML Help Workshop" NO_DEFAULT_PATH)
  206. IF(HHC_BIN)
  207. debug_message( " [ OK ] Found HHC, Windows help (.chm) file will be produced.")
  208. SET(ov_doxy_generate_chm YES)
  209. SET(ov_doxy_hhc_location "\"${HHC_BIN}\"")
  210. SET(ov_doxy_chm_file "\"..\\${PROJECT_NAME}-doc.chm\"")
  211. ELSE(HHC_BIN)
  212. MESSAGE(WARNING " [FAILED] HHC not found, Windows help (.chm) file will not be produced.")
  213. SET(ov_doxy_generate_chm NO)
  214. ENDIF(HHC_BIN)
  215. # configure doxyfile to generate a latex->PDF file if available
  216. FIND_PROGRAM(LATEX_BIN "latex")
  217. IF(LATEX_BIN)
  218. debug_message( " [ OK ] Found latex, a PDF file will be produced.")
  219. SET(ov_doxy_generate_latex YES)
  220. ELSE(LATEX_BIN)
  221. MESSAGE(WARNING " [FAILED] Latex not found, PDF file will not be produced.")
  222. SET(ov_doxy_generate_latex NO)
  223. ENDIF(LATEX_BIN)
  224. # then the doxyfile is configured
  225. CONFIGURE_FILE(
  226. src/doc/doxyfile-skeleton
  227. ${ov_doxy_final}
  228. @ONLY)
  229. # the latex header
  230. CONFIGURE_FILE(
  231. src/doc/header.tex-skeleton
  232. ${PROJECT_SOURCE_DIR}/src/doc/header.tex
  233. @ONLY)
  234. # and the html header
  235. CONFIGURE_FILE(
  236. src/doc/header.html-skeleton
  237. ${PROJECT_SOURCE_DIR}/src/doc/header.html
  238. @ONLY)
  239. # and a post-build command is added in order to run doxygen
  240. ADD_CUSTOM_COMMAND(
  241. TARGET ${PROJECT_NAME_DOC}
  242. POST_BUILD
  243. # COMMAND ${CMAKE_COMMAND} ARGS -E make_directory ${PROJECT_NAME}/chm
  244. COMMAND "${doxygen_bin}" -u "${ov_doxy_final}" && "${doxygen_bin}" "${ov_doxy_final}"
  245. COMMAND ${CMAKE_COMMAND} ARGS -E tar cfz ${PROJECT_NAME}/${PROJECT_NAME_DOC}.tar.gz ${PROJECT_NAME}/html
  246. WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/doc"
  247. COMMENT " ---> Running doxygen in [${PROJECT_SOURCE_DIR}/doc]..."
  248. VERBATIM)
  249. # make the pdf from latex output
  250. # latex2pdf.log will be actually removed only if make.bat returns successfully
  251. # therefore any error will be readable in the log file.
  252. IF(LATEX_BIN)
  253. IF(WIN32)
  254. ADD_CUSTOM_COMMAND(
  255. TARGET ${PROJECT_NAME_DOC}
  256. POST_BUILD
  257. COMMAND "${PROJECT_SOURCE_DIR}/doc/${PROJECT_NAME}/latex/make.bat > ../latex2pdf.log"
  258. COMMAND ${CMAKE_COMMAND} ARGS -E copy refman.pdf ../${PROJECT_NAME_DOC}.pdf
  259. COMMAND ${CMAKE_COMMAND} ARGS -E remove ../latex2pdf.log
  260. WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/doc/${PROJECT_NAME}/latex"
  261. COMMENT " ---> Latex 2 PDF..."
  262. VERBATIM)
  263. ELSE(WIN32)
  264. ADD_CUSTOM_COMMAND(
  265. TARGET ${PROJECT_NAME_DOC}
  266. POST_BUILD
  267. COMMAND make -C "${PROJECT_SOURCE_DIR}/doc/${PROJECT_NAME}/latex" > ../latex2pdf.log
  268. COMMAND ${CMAKE_COMMAND} ARGS -E copy refman.pdf ../${PROJECT_NAME_DOC}.pdf
  269. COMMAND ${CMAKE_COMMAND} ARGS -E remove ../latex2pdf.log
  270. WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/doc/${PROJECT_NAME}/latex"
  271. COMMENT " ---> Latex 2 PDF..."
  272. VERBATIM)
  273. ENDIF(WIN32)
  274. ENDIF(LATEX_BIN)
  275. # CLEANUP
  276. ADD_CUSTOM_COMMAND(
  277. TARGET ${PROJECT_NAME_DOC}
  278. POST_BUILD
  279. COMMAND ${CMAKE_COMMAND} ARGS -E remove_directory latex
  280. COMMAND ${CMAKE_COMMAND} ARGS -E remove_directory html
  281. COMMAND ${CMAKE_COMMAND} ARGS -E remove ../doxygen.log
  282. WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/doc/${PROJECT_NAME}"
  283. COMMENT " ---> Cleaning up..."
  284. VERBATIM)
  285. ELSE(doxygen_bin)
  286. MESSAGE(WARNING " FAILED to find doxygen...")
  287. ENDIF(doxygen_bin)
  288. ENDIF(MENSIA_BUILD_DOC)