|
| 1 | +# This script takes the stm32f407 runtimes generated by build-rts.py and |
| 2 | +# patches them to turn them into an Alire crate. |
| 3 | +# |
| 4 | +# In particular it: |
| 5 | +# - adds an alire.toml |
| 6 | +# - overwrites runtime_build.gpr and ravenscar_build.gpr with our own versions |
| 7 | +# to take advantage of crate configuration variables. |
| 8 | +# - patches target_options.gpr to add a prefix to the BUILD and LIBRARY_TYPE |
| 9 | +# GPR scenario variables. |
| 10 | +# - adds stm32f407_runtime_config.ads which renames the crate config package |
| 11 | +# generated by Alire so that the common runtime sources can access the |
| 12 | +# config via one common package name. |
| 13 | +# - installs extra linker scripts with the directory hierarchy intact |
| 14 | +# (bb-runtimes flattens the directory structure when installing sources). |
| 15 | + |
| 16 | +import argparse |
| 17 | +import pathlib |
| 18 | +import shutil |
| 19 | +from typing import Dict |
| 20 | + |
| 21 | + |
| 22 | +def patch_ravenscar_build_gpr(gpr_file: pathlib.Path, profile: str, target: str): |
| 23 | + """Patch the ravenscar_build.gpr file to add some style switches""" |
| 24 | + |
| 25 | + # Change "light-tasking" to "light_tasking" |
| 26 | + profile = profile.replace("-", "_") |
| 27 | + |
| 28 | + with open(gpr_file, "r") as f: |
| 29 | + content = f.read() |
| 30 | + |
| 31 | + # Add -gnaty-d to the switches used to build the runtime. This fixes style |
| 32 | + # warnings about line endings for packages which "with" the crate |
| 33 | + # configuration package generated by Alire, which uses CRLF line endings on |
| 34 | + # Windows. |
| 35 | + content = content.replace( |
| 36 | + f'for Default_Switches ("Ada") use Target_Options.GNARL_ADAFLAGS', |
| 37 | + f'for Default_Switches ("Ada") use Target_Options.GNARL_ADAFLAGS & ("-gnaty-d")', |
| 38 | + ) |
| 39 | + |
| 40 | + with open(gpr_file, "w") as f: |
| 41 | + f.write(content) |
| 42 | + |
| 43 | + |
| 44 | +def patch_target_options(gpr_file: pathlib.Path, profile: str, target: str): |
| 45 | + """Patch the target_options.gpr file to add the crate name as a prefix |
| 46 | + to GPR variables. |
| 47 | +
|
| 48 | + E.g. for light-tasking-stm32f407: |
| 49 | + BUILD becomes LIGHT_TASKING_STM32F407_BUILD |
| 50 | + LIBRARY_TYPE becomes LIGHT_TASKING_STM32F407_LIBRARY_TYPE |
| 51 | +
|
| 52 | + This follows the Alire best practices and allows the build mode to be |
| 53 | + set for just the runtime crate if need be. |
| 54 | + """ |
| 55 | + |
| 56 | + # Change "light-tasking" to "light_tasking" |
| 57 | + profile = profile.replace("-", "_") |
| 58 | + |
| 59 | + with open(gpr_file, "r") as f: |
| 60 | + content = f.read() |
| 61 | + |
| 62 | + content = content.replace( |
| 63 | + f'"BUILD"', |
| 64 | + f'"{profile.upper()}_{target.upper()}_BUILD"', |
| 65 | + ) |
| 66 | + content = content.replace( |
| 67 | + f'"LIBRARY_TYPE"', |
| 68 | + f'"{profile.upper()}_{target.upper()}_LIBRARY_TYPE"', |
| 69 | + ) |
| 70 | + |
| 71 | + with open(gpr_file, "w") as f: |
| 72 | + f.write(content) |
| 73 | + |
| 74 | + |
| 75 | +def gen_from_template( |
| 76 | + template_file: pathlib.Path, |
| 77 | + out_file: pathlib.Path, |
| 78 | + template_values: Dict[str, str], |
| 79 | +): |
| 80 | + with open(template_file, "r") as f: |
| 81 | + content = f.read() |
| 82 | + |
| 83 | + for key, value in template_values.items(): |
| 84 | + content = content.replace(f"$({key})", value) |
| 85 | + |
| 86 | + with open(out_file, "w", newline="\n") as f: |
| 87 | + f.write(content) |
| 88 | + |
| 89 | + |
| 90 | +def capitalize_underscored(s: str): |
| 91 | + return "_".join(x.capitalize() for x in s.split("_")) |
| 92 | + |
| 93 | + |
| 94 | +def main(): |
| 95 | + parser = argparse.ArgumentParser() |
| 96 | + parser.add_argument( |
| 97 | + "--runtime-dir", type=str, help="Path to the runtime directory to patch" |
| 98 | + ) |
| 99 | + parser.add_argument( |
| 100 | + "--profile", |
| 101 | + type=str, |
| 102 | + choices=["light", "light-tasking", "embedded"], |
| 103 | + help="The runtime profile", |
| 104 | + ) |
| 105 | + parser.add_argument( |
| 106 | + "--version", |
| 107 | + type=str, |
| 108 | + default="15.0.0-dev", |
| 109 | + help="Version string to put in the alire.toml file", |
| 110 | + ) |
| 111 | + |
| 112 | + args = parser.parse_args() |
| 113 | + |
| 114 | + runtime_dir = pathlib.Path(args.runtime_dir) |
| 115 | + profile = args.profile |
| 116 | + pretty_target = "STM32F407" |
| 117 | + target = "stm32f407" |
| 118 | + |
| 119 | + has_libgnarl = (runtime_dir / "ravenscar_build.gpr").exists() |
| 120 | + |
| 121 | + project_files = ["runtime_build.gpr"] |
| 122 | + if has_libgnarl: |
| 123 | + project_files.append("ravenscar_build.gpr") |
| 124 | + |
| 125 | + patch_target_options( |
| 126 | + gpr_file=runtime_dir / "target_options.gpr", profile=profile, target=target |
| 127 | + ) |
| 128 | + |
| 129 | + if has_libgnarl: |
| 130 | + patch_ravenscar_build_gpr( |
| 131 | + gpr_file=runtime_dir / "ravenscar_build.gpr", profile=profile, target=target |
| 132 | + ) |
| 133 | + |
| 134 | + profile_underscored = profile.replace("-", "_") |
| 135 | + |
| 136 | + # light and light-tasking require "Ada" and "Asm_Cpp". |
| 137 | + # embedded also requires "C". |
| 138 | + languages_list = ["Ada", "Asm_Cpp"] |
| 139 | + if profile == "embedded": |
| 140 | + languages_list.append("C") |
| 141 | + |
| 142 | + template_values = { |
| 143 | + "profile": profile, |
| 144 | + "profile_underscored": profile_underscored, |
| 145 | + "target": target, |
| 146 | + "pretty_target": pretty_target, |
| 147 | + "project_files_list": str(project_files), |
| 148 | + "version": args.version, |
| 149 | + "languages_list": ", ".join(f'"{lang}"' for lang in languages_list) |
| 150 | + } |
| 151 | + |
| 152 | + templates_dir = pathlib.Path(__file__).parent / "templates" |
| 153 | + |
| 154 | + gen_from_template( |
| 155 | + template_file=templates_dir / "alire.toml.in", |
| 156 | + out_file=runtime_dir / "alire.toml", |
| 157 | + template_values=template_values, |
| 158 | + ) |
| 159 | + |
| 160 | + gen_from_template( |
| 161 | + template_file=templates_dir / "runtime_build.gpr.in", |
| 162 | + out_file=runtime_dir / "runtime_build.gpr", |
| 163 | + template_values=template_values, |
| 164 | + ) |
| 165 | + |
| 166 | + if has_libgnarl: |
| 167 | + gen_from_template( |
| 168 | + template_file=templates_dir / "ravenscar_build.gpr.in", |
| 169 | + out_file=runtime_dir / "ravenscar_build.gpr", |
| 170 | + template_values=template_values, |
| 171 | + ) |
| 172 | + |
| 173 | + gen_from_template( |
| 174 | + template_file=templates_dir / "stm32f407_runtime_config.ads.in", |
| 175 | + out_file=runtime_dir / "gnat_user" / "stm32f407_runtime_config.ads", |
| 176 | + template_values=template_values, |
| 177 | + ) |
| 178 | + |
| 179 | + shutil.copytree( |
| 180 | + src=pathlib.Path(__file__).parent / "stm32f407_src" / "ld", |
| 181 | + dst=runtime_dir / "ld", |
| 182 | + dirs_exist_ok=True, |
| 183 | + ) |
| 184 | + |
| 185 | + |
| 186 | +if __name__ == "__main__": |
| 187 | + main() |
0 commit comments