Minos Galanakis | d19a19f | 2020-06-03 15:38:03 +0100 | [diff] [blame] | 1 | # ----------------------------------------------------------------------------- |
Minos Galanakis | 7bd5b91 | 2021-01-12 13:08:21 +0000 | [diff] [blame] | 2 | # Copyright (c) 2020-2021, Arm Limited. All rights reserved. |
Minos Galanakis | d19a19f | 2020-06-03 15:38:03 +0100 | [diff] [blame] | 3 | # |
| 4 | # SPDX-License-Identifier: BSD-3-Clause |
| 5 | # |
| 6 | # ----------------------------------------------------------------------------- |
| 7 | |
| 8 | # This module is providing the default parameters for manual Documentation |
| 9 | # building. ( Without relying on CMake to determine the enviroment ) |
| 10 | # |
| 11 | # It will however be able to communicate parameters when populated |
| 12 | # by CMake (using the tfm_env.py file), and use a best-effort approach |
| 13 | # to determine them when the interface file is not preset. |
| 14 | |
| 15 | import os |
| 16 | import re |
| 17 | import json |
| 18 | from subprocess import check_output |
| 19 | from platform import system |
| 20 | |
| 21 | # When called after cmake an evniroment variables file will be present |
| 22 | try: |
| 23 | from tfm_env import cmake_env |
| 24 | except Exception as E: |
| 25 | print("ERROR: Configuration Exception:", E) |
| 26 | cmake_env = None |
| 27 | |
| 28 | tfm_def_render_cmake = True |
| 29 | tfm_def_copy_files = True |
| 30 | tfm_def_build_doxygen = True |
| 31 | |
| 32 | |
| 33 | def find_tfm_root(start_dir=os.path.dirname(os.path.abspath(__file__)), |
| 34 | target_files=["license.rst", |
| 35 | "dco.txt", |
Minos Galanakis | b863864 | 2021-01-15 13:40:14 +0000 | [diff] [blame] | 36 | "toolchain_GNUARM.cmake"], |
Minos Galanakis | d19a19f | 2020-06-03 15:38:03 +0100 | [diff] [blame] | 37 | max_depth=5): |
| 38 | """ Method which attempts to find the root of the project |
| 39 | by traversing parent directoried and attempts to located each of the |
| 40 | files included in target_files list""" |
| 41 | |
| 42 | tfm_root = start_dir |
| 43 | |
| 44 | for i in range(max_depth): |
| 45 | tfm_root = os.path.dirname(tfm_root) |
| 46 | if set(target_files).issubset(set(os.listdir(tfm_root))): |
| 47 | return tfm_root |
| 48 | return None |
| 49 | |
| 50 | |
| 51 | def find_package(binary_name): |
| 52 | """ Attempts to resolve the abolute path for a given application or return |
| 53 | empty string is nothing is found""" |
| 54 | |
| 55 | sys_det = system() |
| 56 | |
| 57 | if sys_det == "Windows": |
| 58 | cmd = "where" |
| 59 | # Window's where requires the extension |
| 60 | binary_name = binary_name + ".exe" |
| 61 | elif sys_det in ["Darwin", "Linux"]: |
| 62 | cmd = "which" |
| 63 | try: |
| 64 | return check_output([cmd, binary_name]).decode('UTF-8').strip() |
| 65 | except Exception as E: |
| 66 | return "" |
| 67 | |
| 68 | |
| 69 | def render_cmake_file(config_map, in_file, out_file): |
| 70 | """ Read an input file containing CMAKE variables and try to |
| 71 | render them based on a configuration map. Variables not listed |
| 72 | on the map will be cleared """ |
| 73 | |
| 74 | # Read the input file |
| 75 | with open(in_file, "r", encoding='utf-8') as F: |
| 76 | _data = F.read() |
| 77 | |
| 78 | # Render all config entires included in the map |
| 79 | for k, v in config_map.items(): |
| 80 | v = v.replace("\\", "\\\\") |
| 81 | _data = re.sub(r'@%s@' % k, r'%s' % v, _data) |
| 82 | |
| 83 | # Set all remaining entries to blank |
| 84 | _data = re.sub(r'@[A-Z\_]+@', "", _data) |
| 85 | |
| 86 | # Create output file |
| 87 | with open(out_file, "w", encoding='utf-8') as F: |
| 88 | F.write(_data) |
| 89 | |
| 90 | |
| 91 | # Default output director for reference_manual. It should not be empty |
| 92 | tfm_def_doxy_output_dir = "reference_manual" |
| 93 | |
| 94 | |
| 95 | if cmake_env is None: |
| 96 | # #################### Automatic Defaults ( Standalone )################# # |
| 97 | |
| 98 | # Resolve ../../ |
| 99 | tfm_def_root_dir = find_tfm_root() |
| 100 | |
| 101 | # Set the copy files directory to whatever will be passed to sphynx-build |
| 102 | tfm_def_copy_dir = os.path.abspath(os.getcwd()) |
| 103 | |
| 104 | # Documentation base path |
| 105 | tfm_def_doc_root = os.path.join(tfm_def_root_dir, "docs") |
| 106 | tfm_def_copy_doc_root = os.path.join(tfm_def_copy_dir, "docs") |
| 107 | |
Anton Komlev | 4c436bf | 2021-10-18 21:59:55 +0100 | [diff] [blame] | 108 | tfm_def_doxy_root = os.path.join(tfm_def_doc_root, "doxygen") |
Minos Galanakis | d19a19f | 2020-06-03 15:38:03 +0100 | [diff] [blame] | 109 | |
| 110 | tfm_def_doxy_output_dir = os.path.join(tfm_def_copy_dir, |
| 111 | tfm_def_doxy_output_dir) |
| 112 | |
| 113 | # Input files ( Files containing CMAKE variables ) |
| 114 | tfm_def_conf_in_file = os.path.join(tfm_def_doc_root, "conf.py.in") |
| 115 | tfm_def_doxygen_in_file = os.path.join(tfm_def_doxy_root, "Doxyfile.in") |
| 116 | |
| 117 | # Attempt to detect plantUML |
| 118 | _ubuntu_plantum_loc = "/usr/share/plantuml/plantuml.jar" |
| 119 | if "PLANTUML_JAR_PATH" in os.environ.keys(): |
| 120 | tfm_def_plantum_loc = os.environ["PLANTUML_JAR_PATH"] |
| 121 | elif os.path.isfile(_ubuntu_plantum_loc): |
| 122 | tfm_def_plantum_loc = _ubuntu_plantum_loc |
| 123 | else: |
| 124 | tfm_def_plantum_loc = "" |
| 125 | |
| 126 | # Attempt to detect the java interpreter location |
| 127 | tfm_def_java_binary = find_package("java") |
| 128 | tfm_def_doxygen_loc = find_package("doxygen") |
| 129 | tfm_def_doxygen_dot_loc = find_package("dot") |
| 130 | |
| 131 | else: |
| 132 | # #################### Cmake Defaults ################################## # |
| 133 | tfm_def_root_dir = os.path.abspath(cmake_env["TFM_ROOT_DIR"]) |
| 134 | tfm_def_copy_dir = os.path.abspath(cmake_env["SPHINX_TMP_DOC_DIR"]) |
| 135 | tfm_def_plantum_loc = os.path.abspath(cmake_env["PLANTUML_JAR_PATH"]) |
| 136 | tfm_def_java_binary = os.path.abspath(cmake_env["Java_JAVA_EXECUTABLE"]) |
Anton Komlev | f7836d1 | 2021-12-23 16:27:46 +0000 | [diff] [blame] | 137 | tfm_def_tfm_version = cmake_env["SPHINXCFG_TFM_VERSION"] |
Minos Galanakis | d19a19f | 2020-06-03 15:38:03 +0100 | [diff] [blame] | 138 | tfm_def_conf_in_file = cmake_env["SPHINXCFG_TEMPLATE_FILE"] |
| 139 | |
| 140 | tfm_def_copy_files = True if cmake_env["SPHINXCFG_COPY_FILES"] == "True" \ |
| 141 | else False |
| 142 | tfm_def_render_cmake = True \ |
| 143 | if cmake_env["SPHINXCFG_RENDER_CONF"] == "True" else False |
| 144 | |
| 145 | tfm_def_build_doxygen = True \ |
| 146 | if cmake_env["DOXYCFG_DOXYGEN_BUILD"] == "True" else False |
| 147 | |
| 148 | if tfm_def_build_doxygen: |
| 149 | tfm_def_doxy_root = cmake_env["DOXYCFG_DOXYGEN_CFG_DIR"] |
| 150 | tfm_def_doxygen_in_file = os.path.join(tfm_def_doxy_root, |
| 151 | "Doxyfile.in") |
| 152 | |
| 153 | # Documentation base path |
| 154 | tfm_def_doc_root = os.path.join(tfm_def_root_dir, "docs") |
| 155 | tfm_def_copy_doc_root = os.path.join(tfm_def_copy_dir, "docs") |
| 156 | |
| 157 | # Disable copyfiles for next invocation |
| 158 | cmake_env["SPHINXCFG_COPY_FILES"] = "False" |
| 159 | with open("tfm_env.py", "w", encoding='utf-8') as F: |
| 160 | F.write("cmake_env =" + json.dumps(cmake_env)) |
| 161 | |
| 162 | |
| 163 | # Version will be retrieved in that order Git -> Cmake -> Boilerplate |
| 164 | try: |
Anton Komlev | eb5433d | 2021-12-02 21:11:03 +0000 | [diff] [blame] | 165 | vrex = re.compile(r'(?P<GIT_HASH>[a-f0-9]{40})' |
| 166 | r'+\s+tag\s+refs\/tags\/TF-Mv(?P<VER_MAJ>\d+).' |
| 167 | r'(?P<VER_MIN>\d+).?(?P<VER_HOT>\d+)(?P<RC>-RC\d+)?') |
Minos Galanakis | 3568bea | 2020-11-16 20:15:48 +0000 | [diff] [blame] | 168 | |
Anton Komlev | f7836d1 | 2021-12-23 16:27:46 +0000 | [diff] [blame] | 169 | tfm_def_tfm_version = check_output("git for-each-ref refs/tags --sort=-taggerdate --count=1", |
| 170 | shell = True, encoding = 'UTF-8') |
| 171 | |
| 172 | _v = vrex.search(tfm_def_tfm_version) |
Minos Galanakis | 3568bea | 2020-11-16 20:15:48 +0000 | [diff] [blame] | 173 | version = [ _v.group("VER_MAJ"), |
| 174 | _v.group("VER_MIN"), |
| 175 | _v.group("VER_HOT"), |
| 176 | _v.group("RC")] |
Minos Galanakis | 3568bea | 2020-11-16 20:15:48 +0000 | [diff] [blame] | 177 | git_hash = _v.group("GIT_HASH") |
| 178 | |
| 179 | # Sanitize the verison and remove empty entries |
| 180 | version = [i.replace("-","") for i in version if i] |
Anton Komlev | f7836d1 | 2021-12-23 16:27:46 +0000 | [diff] [blame] | 181 | tfm_def_tfm_version = "v"+".".join(version) |
Minos Galanakis | d19a19f | 2020-06-03 15:38:03 +0100 | [diff] [blame] | 182 | |
Anton Komlev | eb5433d | 2021-12-02 21:11:03 +0000 | [diff] [blame] | 183 | vlrex = re.compile(r'^(?P<GIT_HASH_LATEST>[a-f0-9]{40})') |
| 184 | |
Anton Komlev | f7836d1 | 2021-12-23 16:27:46 +0000 | [diff] [blame] | 185 | git_hash_latest = check_output("git rev-parse HEAD", |
| 186 | shell = True, encoding = 'UTF-8') |
Anton Komlev | eb5433d | 2021-12-02 21:11:03 +0000 | [diff] [blame] | 187 | |
| 188 | git_hash_latest = vlrex.search(git_hash_latest).group('GIT_HASH_LATEST') |
| 189 | |
| 190 | if git_hash != git_hash_latest: |
| 191 | git_hash_latest = git_hash_latest[:7] |
Anton Komlev | f7836d1 | 2021-12-23 16:27:46 +0000 | [diff] [blame] | 192 | tfm_def_tfm_version += "+ ({})".format(git_hash_latest) |
Minos Galanakis | 3568bea | 2020-11-16 20:15:48 +0000 | [diff] [blame] | 193 | |
Minos Galanakis | d19a19f | 2020-06-03 15:38:03 +0100 | [diff] [blame] | 194 | except Exception as E: |
| 195 | try: |
Anton Komlev | f7836d1 | 2021-12-23 16:27:46 +0000 | [diff] [blame] | 196 | tfm_def_tfm_version |
Minos Galanakis | d19a19f | 2020-06-03 15:38:03 +0100 | [diff] [blame] | 197 | except NameError: |
Anton Komlev | f7836d1 | 2021-12-23 16:27:46 +0000 | [diff] [blame] | 198 | tfm_def_tfm_version = "Unknown" |
Minos Galanakis | d19a19f | 2020-06-03 15:38:03 +0100 | [diff] [blame] | 199 | |
| 200 | # #################### User Defaults ######################################## # |
| 201 | |
| 202 | # Directories, referenced by TF-M root, which may contain releval documents |
| 203 | # which need to be broughtt over |
| 204 | document_scan_dirs = ["tools", "platform"] |
| 205 | |
| 206 | document_scan_ext = [".rst", ".md", ".jpg", ".png"] |
| 207 | |
| 208 | # Other documents that should be added to the root documentation folder |
| 209 | documents_extra = ["license.rst", "dco.txt"] |
| 210 | |
| 211 | # Output files ( After CMAKE variables have been evaluated ) |
| 212 | tfm_def_conf_out_file = os.path.join(tfm_def_copy_dir, "conf_rendered.py") |
| 213 | if tfm_def_build_doxygen: |
| 214 | tfm_def_doxygen_out_file = os.path.join(tfm_def_doxy_root, |
| 215 | "DoxyfileCfg.in") |
| 216 | |
| 217 | # If env is none, the script is running as standalone. Generate it with the |
| 218 | # auto-detected values set above |
| 219 | if cmake_env is None: |
| 220 | cmake_env = {"TFM_ROOT_DIR": tfm_def_root_dir, |
| 221 | "DOXYGEN_EXECUTABLE": tfm_def_doxygen_loc, |
| 222 | "DOXYGEN_DOT_EXECUTABLE": tfm_def_doxygen_dot_loc, |
| 223 | "PLANTUML_JAR_PATH": tfm_def_plantum_loc, |
Anton Komlev | f7836d1 | 2021-12-23 16:27:46 +0000 | [diff] [blame] | 224 | "SPHINXCFG_TFM_VERSION": tfm_def_tfm_version, |
Minos Galanakis | d19a19f | 2020-06-03 15:38:03 +0100 | [diff] [blame] | 225 | "Java_JAVA_EXECUTABLE": tfm_def_java_binary, |
| 226 | "DOXYCFG_OUTPUT_PATH": tfm_def_doxy_output_dir, |
Anton Komlev | f7836d1 | 2021-12-23 16:27:46 +0000 | [diff] [blame] | 227 | "DOXYCFG_TFM_VERSION": tfm_def_tfm_version, |
Minos Galanakis | d19a19f | 2020-06-03 15:38:03 +0100 | [diff] [blame] | 228 | } |
| 229 | # Only Override the version |
| 230 | else: |
Anton Komlev | f7836d1 | 2021-12-23 16:27:46 +0000 | [diff] [blame] | 231 | cmake_env["SPHINXCFG_TFM_VERSION"] = tfm_def_tfm_version |