make_generated_files.py (9549B)
1 #!/usr/bin/env python3 2 3 # make_generated_files.py 4 # 5 # Copyright The Mbed TLS Contributors 6 # SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 7 8 """ 9 Generate the TF-PSA-Crypto generated files 10 """ 11 import argparse 12 import filecmp 13 import shutil 14 import subprocess 15 import sys 16 17 from pathlib import Path 18 from typing import List, Optional 19 20 from mbedtls_framework import build_tree 21 22 class GenerationScript: 23 """ 24 Representation of a script generating a configuration independent file. 25 """ 26 # pylint: disable=too-few-public-methods 27 def __init__(self, script: Path, files: List[Path], 28 output_dir_option: Optional[str] = None, 29 output_file_option: Optional[str] = None): 30 # Path from the root of Mbed TLS or TF-PSA-Crypto of the generation script 31 self.script = script 32 33 # Executable to run the script, needed for Windows 34 if script.suffix == ".py": 35 self.exe = "python" 36 elif script.suffix == ".pl": 37 self.exe = "perl" 38 39 # List of the default paths from the Mbed TLS or TF-PSA-Crypto root of the 40 # files the script generates. 41 self.files = files 42 43 # Output directory script argument. Can be an empty string in case it is a 44 # positional argument. 45 self.output_dir_option = output_dir_option 46 47 # Output file script argument. Can be an empty string in case it is a 48 # positional argument. 49 self.output_file_option = output_file_option 50 51 def get_generation_script_files(generation_script: str): 52 """ 53 Get the list of the default paths of the files that a given script 54 generates. It is assumed that the script supports the "--list" option. 55 """ 56 files = [] 57 if generation_script.endswith(".py"): 58 cmd = ["python"] 59 elif generation_script.endswith(".pl"): 60 cmd = ["perl"] 61 cmd += [generation_script, "--list"] 62 63 output = subprocess.check_output(cmd, universal_newlines=True) 64 for line in output.splitlines(): 65 files.append(Path(line)) 66 67 return files 68 69 if build_tree.looks_like_tf_psa_crypto_root("."): 70 TF_PSA_CRYPTO_GENERATION_SCRIPTS = [ 71 GenerationScript( 72 Path("scripts/generate_driver_wrappers.py"), 73 [Path("core/psa_crypto_driver_wrappers.h"), 74 Path("core/psa_crypto_driver_wrappers_no_static.c")], 75 "", None 76 ), 77 GenerationScript( 78 Path("framework/scripts/generate_test_keys.py"), 79 [Path("tests/include/test/test_keys.h")], 80 None, "--output" 81 ), 82 GenerationScript( 83 Path("scripts/generate_psa_constants.py"), 84 [Path("programs/psa/psa_constant_names_generated.c")], 85 "", None 86 ), 87 GenerationScript( 88 Path("framework/scripts/generate_bignum_tests.py"), 89 get_generation_script_files("framework/scripts/generate_bignum_tests.py"), 90 "--directory", None 91 ), 92 GenerationScript( 93 Path("framework/scripts/generate_config_tests.py"), 94 get_generation_script_files("framework/scripts/generate_config_tests.py"), 95 "--directory", None 96 ), 97 GenerationScript( 98 Path("framework/scripts/generate_ecp_tests.py"), 99 get_generation_script_files("framework/scripts/generate_ecp_tests.py"), 100 "--directory", None 101 ), 102 GenerationScript( 103 Path("framework/scripts/generate_psa_tests.py"), 104 get_generation_script_files("framework/scripts/generate_psa_tests.py"), 105 "--directory", None 106 ), 107 ] 108 109 110 if build_tree.looks_like_mbedtls_root(".") and not build_tree.is_mbedtls_3_6(): 111 MBEDTLS_GENERATION_SCRIPTS = [ 112 GenerationScript( 113 Path("scripts/generate_errors.pl"), 114 [Path("library/error.c")], 115 None, "tf-psa-crypto/drivers/builtin/include/mbedtls \ 116 include/mbedtls/ \ 117 scripts/data_files" 118 ), 119 GenerationScript( 120 Path("scripts/generate_features.pl"), 121 [Path("library/version_features.c")], 122 None, "include/mbedtls/ scripts/data_files" 123 ), 124 GenerationScript( 125 Path("framework/scripts/generate_ssl_debug_helpers.py"), 126 [Path("library/ssl_debug_helpers_generated.c")], 127 "", None 128 ), 129 GenerationScript( 130 Path("framework/scripts/generate_test_keys.py"), 131 [Path("tests/include/test/test_keys.h")], 132 None, "--output" 133 ), 134 GenerationScript( 135 Path("framework/scripts/generate_test_cert_macros.py"), 136 [Path("tests/include/test/test_certs.h")], 137 None, "--output" 138 ), 139 GenerationScript( 140 Path("scripts/generate_query_config.pl"), 141 [Path("programs/test/query_config.c")], 142 None, "include/mbedtls/mbedtls_config.h \ 143 tf-psa-crypto/include/psa/crypto_config.h \ 144 scripts/data_files/query_config.fmt" 145 ), 146 GenerationScript( 147 Path("framework/scripts/generate_config_tests.py"), 148 get_generation_script_files("framework/scripts/generate_config_tests.py"), 149 "--directory", None 150 ), 151 GenerationScript( 152 Path("framework/scripts/generate_tls13_compat_tests.py"), 153 [Path("tests/opt-testcases/tls13-compat.sh")], 154 None, "--output" 155 ), 156 GenerationScript( 157 Path("framework/scripts/generate_tls_handshake_tests.py"), 158 [Path("tests/opt-testcases/handshake-generated.sh")], 159 None, "--output" 160 ), 161 GenerationScript( 162 Path("scripts/generate_visualc_files.pl"), 163 get_generation_script_files("scripts/generate_visualc_files.pl"), 164 "--directory", None 165 ), 166 ] 167 168 def get_generated_files(generation_scripts: List[GenerationScript]): 169 """ 170 List the generated files in Mbed TLS or TF-PSA-Crypto. The path from root 171 is returned for each generated files. 172 """ 173 files = [] 174 for generation_script in generation_scripts: 175 files += generation_script.files 176 177 return files 178 179 def make_generated_files(generation_scripts: List[GenerationScript]): 180 """ 181 Generate the configuration independent files in their default location in 182 the Mbed TLS or TF-PSA-Crypto tree. 183 """ 184 for generation_script in generation_scripts: 185 subprocess.run([generation_script.exe, str(generation_script.script)], check=True) 186 187 def check_generated_files(generation_scripts: List[GenerationScript], root: Path): 188 """ 189 Check that the given root directory contains the generated files as expected/ 190 generated by this script. 191 """ 192 for generation_script in generation_scripts: 193 for file in generation_script.files: 194 file = root / file 195 bak_file = file.with_name(file.name + ".bak") 196 if bak_file.exists(): 197 bak_file.unlink() 198 file.rename(bak_file) 199 200 command = [generation_script.exe, str(generation_script.script)] 201 if generation_script.output_dir_option is not None: 202 command += [generation_script.output_dir_option, 203 str(root / Path(generation_script.files[0].parent))] 204 elif generation_script.output_file_option is not None: 205 command += generation_script.output_file_option.split() 206 command += [str(root / Path(generation_script.files[0]))] 207 subprocess.run([item for item in command if item.strip()], check=True) 208 209 for file in generation_script.files: 210 file = root / file 211 bak_file = file.with_name(file.name + ".bak") 212 if not filecmp.cmp(file, bak_file): 213 ref_file = file.with_name(file.name + ".ref") 214 ref_file = root / ref_file 215 if ref_file.exists(): 216 ref_file.unlink() 217 shutil.copy(file, ref_file) 218 print(f"Generated file {file} not identical to the reference one {ref_file}.") 219 file.unlink() 220 bak_file.rename(file) 221 222 def main(): 223 """ 224 Main function of this program 225 """ 226 parser = argparse.ArgumentParser() 227 228 parser.add_argument('--list', action='store_true', 229 default=False, help='List generated files.') 230 parser.add_argument('--root', metavar='DIR', 231 help='Root of the tree containing the generated files \ 232 to check (default: Mbed TLS or TF-PSA-Cryto root.)') 233 parser.add_argument('--check', action='store_true', 234 default=False, help='Check the generated files in root') 235 236 args = parser.parse_args() 237 238 if not build_tree.looks_like_root("."): 239 raise RuntimeError("This script must be run from Mbed TLS or TF-PSA-Crypto root.") 240 241 if build_tree.looks_like_tf_psa_crypto_root("."): 242 generation_scripts = TF_PSA_CRYPTO_GENERATION_SCRIPTS 243 elif not build_tree.is_mbedtls_3_6(): 244 generation_scripts = MBEDTLS_GENERATION_SCRIPTS 245 else: 246 raise Exception("No support for Mbed TLS 3.6") 247 248 if args.list: 249 files = get_generated_files(generation_scripts) 250 for file in files: 251 print(str(file)) 252 elif args.check: 253 check_generated_files(generation_scripts, Path(args.root or ".")) 254 else: 255 make_generated_files(generation_scripts) 256 257 if __name__ == "__main__": 258 sys.exit(main())