quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

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())