1#!/usr/bin/env python3 2 3import os.path 4import re 5import requests 6import textwrap 7import sys 8 9BASE_URL = "https://toolchains.bootlin.com/downloads/releases/toolchains" 10 11AUTOGENERATED_COMMENT = """# This file was auto-generated by support/scripts/gen-bootlin-toolchains 12# Do not edit 13""" 14 15# In the below dict: 16 17# - 'conditions' indicate the cumulative conditions under which the 18# toolchain will be made available. In several situations, a given 19# toolchain is usable on several architectures variants (for 20# example, an ARMv6 toolchain can be used on ARMv7) 21# - 'test_options' indicate one specific configuration where the 22# toolchain can be used. It is used to create the runtime test 23# cases. If 'test_options' does not exist, the code assumes it can 24# be made equal to 'conditions' 25# - 'prefix' is the prefix of the cross-compilation toolchain tools 26 27arches = { 28 'aarch64': { 29 'conditions': ['BR2_aarch64'], 30 'prefix': 'aarch64', 31 }, 32 'aarch64be': { 33 'conditions': ['BR2_aarch64_be'], 34 'prefix': 'aarch64_be', 35 }, 36 'arcle-750d': { 37 'conditions': ['BR2_arcle', 'BR2_arc750d'], 38 'prefix': 'arc', 39 }, 40 'arcle-hs38': { 41 'conditions': ['BR2_arcle', 'BR2_archs38'], 42 'prefix': 'arc', 43 }, 44 'armv5-eabi': { 45 'conditions': ['BR2_arm', 'BR2_ARM_CPU_ARMV5', 'BR2_ARM_EABI'], 46 'test_options': ['BR2_arm', 'BR2_arm926t', 'BR2_ARM_EABI'], 47 'prefix': 'arm', 48 }, 49 'armv6-eabihf': { 50 'conditions': ['BR2_arm', 'BR2_ARM_CPU_ARMV6', 'BR2_ARM_EABIHF'], 51 'test_options': ['BR2_arm', 'BR2_arm1176jzf_s', 'BR2_ARM_EABIHF'], 52 'prefix': 'arm', 53 }, 54 'armv7-eabihf': { 55 'conditions': ['BR2_arm', 'BR2_ARM_CPU_ARMV7A', 'BR2_ARM_EABIHF'], 56 'test_options': ['BR2_arm', 'BR2_cortex_a8', 'BR2_ARM_EABIHF'], 57 'prefix': 'arm', 58 }, 59 'armebv7-eabihf': { 60 'conditions': ['BR2_armeb', 'BR2_ARM_CPU_ARMV7A', 'BR2_ARM_EABIHF'], 61 'test_options': ['BR2_armeb', 'BR2_cortex_a8', 'BR2_ARM_EABIHF'], 62 'prefix': 'armeb', 63 }, 64 'armv7m': { 65 'conditions': ['BR2_arm', 'BR2_ARM_CPU_ARMV7M'], 66 'test_options': ['BR2_arm', 'BR2_cortex_m4'], 67 'prefix': 'arm', 68 }, 69 'm68k-68xxx': { 70 'conditions': ['BR2_m68k_m68k'], 71 'test_options': ['BR2_m68k', 'BR2_m68k_68040'], 72 'prefix': 'm68k', 73 }, 74 'm68k-coldfire': { 75 'conditions': ['BR2_m68k_cf'], 76 'test_options': ['BR2_m68k', 'BR2_m68k_cf5208'], 77 'prefix': 'm68k', 78 }, 79 'microblazebe': { 80 'conditions': ['BR2_microblazebe'], 81 'prefix': 'microblaze', 82 'gdbserver': False 83 }, 84 'microblazeel': { 85 'conditions': ['BR2_microblazeel'], 86 'prefix': 'microblazeel', 87 'gdbserver': False 88 }, 89 'mips32': { 90 # Not sure it could be used by other mips32 variants? 91 'conditions': ['BR2_mips', 'BR2_mips_32', '!BR2_MIPS_SOFT_FLOAT'], 92 'prefix': 'mips', 93 }, 94 'mips32el': { 95 # Not sure it could be used by other mips32el variants? 96 'conditions': ['BR2_mipsel', 'BR2_mips_32', '!BR2_MIPS_SOFT_FLOAT'], 97 'prefix': 'mipsel', 98 }, 99 'mips32r5el': { 100 'conditions': ['BR2_mipsel', 'BR2_mips_32r5', '!BR2_MIPS_SOFT_FLOAT'], 101 'prefix': 'mipsel', 102 }, 103 'mips32r6el': { 104 'conditions': ['BR2_mipsel', 'BR2_mips_32r6', '!BR2_MIPS_SOFT_FLOAT'], 105 'prefix': 'mipsel', 106 }, 107 'mips64-n32': { 108 # Not sure it could be used by other mips64 variants? 109 'conditions': ['BR2_mips64', 'BR2_mips_64', 'BR2_MIPS_NABI32', '!BR2_MIPS_SOFT_FLOAT'], 110 'prefix': 'mips64', 111 }, 112 'mips64el-n32': { 113 # Not sure it could be used by other mips64el variants? 114 'conditions': ['BR2_mips64el', 'BR2_mips_64', 'BR2_MIPS_NABI32', '!BR2_MIPS_SOFT_FLOAT'], 115 'prefix': 'mips64el', 116 }, 117 'mips64r6el-n32': { 118 'conditions': ['BR2_mips64el', 'BR2_mips_64r6', 'BR2_MIPS_NABI32', '!BR2_MIPS_SOFT_FLOAT'], 119 'prefix': 'mips64el', 120 }, 121 'nios2': { 122 'conditions': ['BR2_nios2'], 123 'prefix': 'nios2', 124 }, 125 'openrisc': { 126 'conditions': ['BR2_or1k'], 127 'prefix': 'or1k', 128 'gdbserver': False, 129 }, 130 'powerpc-440fp': { 131 # Not sure it could be used by other powerpc variants? 132 'conditions': ['BR2_powerpc', 'BR2_powerpc_440fp'], 133 'prefix': 'powerpc', 134 }, 135 'powerpc-e300c3': { 136 # Not sure it could be used by other powerpc variants? 137 'conditions': ['BR2_powerpc', 'BR2_powerpc_e300c3'], 138 'prefix': 'powerpc', 139 }, 140 'powerpc-e500mc': { 141 # Not sure it could be used by other powerpc variants? 142 'conditions': ['BR2_powerpc', 'BR2_powerpc_e500mc'], 143 'prefix': 'powerpc', 144 }, 145 'powerpc64-e5500': { 146 'conditions': ['BR2_powerpc64', 'BR2_powerpc_e5500'], 147 'prefix': 'powerpc64', 148 }, 149 'powerpc64-e6500': { 150 'conditions': ['BR2_powerpc64', 'BR2_powerpc_e6500'], 151 'prefix': 'powerpc64', 152 }, 153 'powerpc64-power8': { 154 'conditions': ['BR2_powerpc64', 'BR2_powerpc_power8'], 155 'prefix': 'powerpc64', 156 }, 157 'powerpc64le-power8': { 158 'conditions': ['BR2_powerpc64le', 'BR2_powerpc_power8'], 159 'prefix': 'powerpc64le', 160 }, 161 'riscv32-ilp32d': { 162 'conditions': ['BR2_riscv', 'BR2_riscv_g', 'BR2_RISCV_32', 'BR2_RISCV_ABI_ILP32D'], 163 'prefix': 'riscv32', 164 }, 165 'riscv64-lp64d': { 166 'conditions': ['BR2_riscv', 'BR2_riscv_g', 'BR2_RISCV_64', 'BR2_RISCV_ABI_LP64D', 'BR2_USE_MMU'], 167 'prefix': 'riscv64', 168 }, 169 's390x-z13': { 170 'conditions': ['BR2_s390x', 'BR2_s390x_z13'], 171 'prefix': 's390x', 172 }, 173 'sh-sh4': { 174 'conditions': ['BR2_sh', 'BR2_sh4'], 175 'prefix': 'sh4', 176 }, 177 'sh-sh4aeb': { 178 'conditions': ['BR2_sh', 'BR2_sh4aeb'], 179 'prefix': 'sh4aeb', 180 }, 181 'sparc64': { 182 'conditions': ['BR2_sparc64', 'BR2_sparc_v9'], 183 'prefix': 'sparc64', 184 }, 185 'sparcv8': { 186 'conditions': ['BR2_sparc', 'BR2_sparc_v8'], 187 'prefix': 'sparc', 188 }, 189 'x86-64': { 190 'conditions': ['BR2_x86_64', 191 'BR2_X86_CPU_HAS_MMX', 192 'BR2_X86_CPU_HAS_SSE', 193 'BR2_X86_CPU_HAS_SSE2'], 194 'test_options': ['BR2_x86_64', 'BR2_x86_x86_64'], 195 'prefix': 'x86_64', 196 }, 197 'x86-64-v2': { 198 'conditions': ['BR2_x86_64', 199 'BR2_X86_CPU_HAS_MMX', 200 'BR2_X86_CPU_HAS_SSE', 201 'BR2_X86_CPU_HAS_SSE2', 202 'BR2_X86_CPU_HAS_SSE3', 203 'BR2_X86_CPU_HAS_SSSE3', 204 'BR2_X86_CPU_HAS_SSE4', 205 'BR2_X86_CPU_HAS_SSE42'], 206 'test_options': ['BR2_x86_64', 'BR2_x86_x86_64_v2'], 207 'prefix': 'x86_64', 208 }, 209 'x86-64-v3': { 210 'conditions': ['BR2_x86_64', 211 'BR2_X86_CPU_HAS_MMX', 212 'BR2_X86_CPU_HAS_SSE', 213 'BR2_X86_CPU_HAS_SSE2', 214 'BR2_X86_CPU_HAS_SSE3', 215 'BR2_X86_CPU_HAS_SSSE3', 216 'BR2_X86_CPU_HAS_SSE4', 217 'BR2_X86_CPU_HAS_SSE42', 218 'BR2_X86_CPU_HAS_AVX', 219 'BR2_X86_CPU_HAS_AVX2'], 220 'test_options': ['BR2_x86_64', 'BR2_x86_x86_64_v3'], 221 'prefix': 'x86_64', 222 }, 223 'x86-64-v4': { 224 'conditions': ['BR2_x86_64', 225 'BR2_X86_CPU_HAS_MMX', 226 'BR2_X86_CPU_HAS_SSE', 227 'BR2_X86_CPU_HAS_SSE2', 228 'BR2_X86_CPU_HAS_SSE3', 229 'BR2_X86_CPU_HAS_SSSE3', 230 'BR2_X86_CPU_HAS_SSE4', 231 'BR2_X86_CPU_HAS_SSE42', 232 'BR2_X86_CPU_HAS_AVX', 233 'BR2_X86_CPU_HAS_AVX2', 234 'BR2_X86_CPU_HAS_AVX512'], 235 'test_options': ['BR2_x86_64', 'BR2_x86_x86_64_v4'], 236 'prefix': 'x86_64', 237 }, 238 'x86-64-core-i7': { 239 'conditions': ['BR2_x86_64', 240 'BR2_X86_CPU_HAS_MMX', 241 'BR2_X86_CPU_HAS_SSE', 242 'BR2_X86_CPU_HAS_SSE2', 243 'BR2_X86_CPU_HAS_SSE3', 244 'BR2_X86_CPU_HAS_SSSE3', 245 'BR2_X86_CPU_HAS_SSE4', 246 'BR2_X86_CPU_HAS_SSE42'], 247 'test_options': ['BR2_x86_64', 'BR2_x86_corei7'], 248 'prefix': 'x86_64', 249 }, 250 'x86-core2': { 251 'conditions': ['BR2_i386', 252 'BR2_X86_CPU_HAS_MMX', 253 'BR2_X86_CPU_HAS_SSE', 254 'BR2_X86_CPU_HAS_SSE2', 255 'BR2_X86_CPU_HAS_SSE3', 256 'BR2_X86_CPU_HAS_SSSE3'], 257 'test_options': ['BR2_i386', 'BR2_x86_core2'], 258 'prefix': 'i686', 259 }, 260 'x86-i686': { 261 'conditions': ['BR2_i386', 262 '!BR2_x86_i486', 263 '!BR2_x86_i586', 264 '!BR2_x86_x1000', 265 '!BR2_x86_pentium_mmx', 266 '!BR2_x86_geode', 267 '!BR2_x86_c3', 268 '!BR2_x86_winchip_c6', 269 '!BR2_x86_winchip2'], 270 'test_options': ['BR2_i386', 271 'BR2_x86_i686'], 272 'prefix': 'i686', 273 }, 274 'xtensa-lx60': { 275 'conditions': ['BR2_xtensa', 'BR2_XTENSA_CUSTOM', 'BR2_XTENSA_LITTLE_ENDIAN'], 276 'prefix': 'xtensa', 277 }, 278} 279 280 281class Toolchain: 282 def __init__(self, arch, libc, variant, version): 283 self.arch = arch 284 self.libc = libc 285 self.variant = variant 286 self.version = version 287 self.fname_prefix = "%s--%s--%s-%s" % (self.arch, self.libc, self.variant, self.version) 288 self.option_name = "BR2_TOOLCHAIN_EXTERNAL_BOOTLIN_%s_%s_%s" % \ 289 (self.arch.replace("-", "_").upper(), self.libc.upper(), self.variant.replace("-", "_").upper()) 290 self.fragment = requests.get(self.fragment_url).text.split("\n") 291 self.sha256 = requests.get(self.hash_url).text.split(" ")[0] 292 293 @property 294 def tarball_url(self): 295 return os.path.join(BASE_URL, self.arch, "tarballs", 296 self.fname_prefix + ".tar.bz2") 297 298 @property 299 def hash_url(self): 300 return os.path.join(BASE_URL, self.arch, "tarballs", 301 self.fname_prefix + ".sha256") 302 303 @property 304 def fragment_url(self): 305 return os.path.join(BASE_URL, self.arch, "fragments", 306 self.fname_prefix + ".frag") 307 308 def gen_config_in_options(self, f): 309 f.write("config %s\n" % self.option_name) 310 f.write("\tbool \"%s %s %s %s\"\n" % 311 (self.arch, self.libc, self.variant, self.version)) 312 depends = [] 313 selects = [] 314 315 for c in arches[self.arch]['conditions']: 316 depends.append(c) 317 318 if not arches[self.arch].get('gdbserver', True): 319 selects.append("BR2_TOOLCHAIN_EXTERNAL_HAS_NO_GDBSERVER") 320 321 for frag in self.fragment: 322 # libc type 323 if frag.startswith("BR2_TOOLCHAIN_EXTERNAL_CUSTOM_UCLIBC"): 324 selects.append("BR2_TOOLCHAIN_EXTERNAL_UCLIBC") 325 elif frag.startswith("BR2_TOOLCHAIN_EXTERNAL_CUSTOM_GLIBC"): 326 # glibc needs mmu support 327 if "BR2_USE_MMU" not in depends: 328 depends.append("BR2_USE_MMU") 329 selects.append("BR2_TOOLCHAIN_EXTERNAL_GLIBC") 330 elif frag.startswith("BR2_TOOLCHAIN_EXTERNAL_CUSTOM_MUSL"): 331 # musl needs mmu support 332 if "BR2_USE_MMU" not in depends: 333 depends.append("BR2_USE_MMU") 334 selects.append("BR2_TOOLCHAIN_EXTERNAL_MUSL") 335 336 # gcc version 337 if frag.startswith("BR2_TOOLCHAIN_EXTERNAL_GCC_"): 338 m = re.match("^BR2_TOOLCHAIN_EXTERNAL_GCC_([0-9_]*)=y$", frag) 339 assert m, "Cannot get gcc version for toolchain %s" % self.fname_prefix 340 selects.append("BR2_TOOLCHAIN_GCC_AT_LEAST_%s" % m[1]) 341 # respect the GCC requirement for the selected CPU/arch tuning 342 depends.append("!BR2_ARCH_NEEDS_GCC_AT_LEAST_%s" % str(int(m[1]) + 1)) 343 344 # kernel headers version 345 if frag.startswith("BR2_TOOLCHAIN_EXTERNAL_HEADERS_"): 346 m = re.match("^BR2_TOOLCHAIN_EXTERNAL_HEADERS_([0-9_]*)=y$", frag) 347 assert m, "Cannot get kernel headers version for toolchain %s" % self.fname_prefix 348 selects.append("BR2_TOOLCHAIN_HEADERS_AT_LEAST_%s" % m[1]) 349 350 # C++ 351 if frag.startswith("BR2_TOOLCHAIN_EXTERNAL_CXX"): 352 selects.append("BR2_INSTALL_LIBSTDCPP") 353 354 # SSP 355 if frag.startswith("BR2_TOOLCHAIN_EXTERNAL_HAS_SSP"): 356 selects.append("BR2_TOOLCHAIN_HAS_SSP") 357 358 # wchar 359 if frag.startswith("BR2_TOOLCHAIN_EXTERNAL_WCHAR"): 360 selects.append("BR2_USE_WCHAR") 361 362 # locale 363 if frag.startswith("BR2_TOOLCHAIN_EXTERNAL_LOCALE"): 364 # locale implies the availability of wchar 365 selects.append("BR2_USE_WCHAR") 366 selects.append("BR2_ENABLE_LOCALE") 367 368 # thread support 369 if frag.startswith("BR2_TOOLCHAIN_EXTERNAL_HAS_THREADS"): 370 selects.append("BR2_TOOLCHAIN_HAS_THREADS") 371 372 if frag.startswith("BR2_TOOLCHAIN_EXTERNAL_HAS_THREADS_DEBUG"): 373 selects.append("BR2_TOOLCHAIN_HAS_THREADS_DEBUG") 374 375 if frag.startswith("BR2_TOOLCHAIN_EXTERNAL_HAS_THREADS_NPTL"): 376 selects.append("BR2_TOOLCHAIN_HAS_THREADS_NPTL") 377 378 # RPC 379 if frag.startswith("BR2_TOOLCHAIN_EXTERNAL_INET_RPC"): 380 selects.append("BR2_TOOLCHAIN_HAS_NATIVE_RPC") 381 382 # D language 383 if frag.startswith("BR2_TOOLCHAIN_EXTERNAL_DLANG"): 384 selects.append("BR2_TOOLCHAIN_HAS_DLANG") 385 386 # fortran 387 if frag.startswith("BR2_TOOLCHAIN_EXTERNAL_FORTRAN"): 388 selects.append("BR2_TOOLCHAIN_HAS_FORTRAN") 389 390 # OpenMP 391 if frag.startswith("BR2_TOOLCHAIN_EXTERNAL_OPENMP"): 392 selects.append("BR2_TOOLCHAIN_HAS_OPENMP") 393 394 for depend in depends: 395 f.write("\tdepends on %s\n" % depend) 396 397 for select in selects: 398 f.write("\tselect %s\n" % select) 399 400 f.write("\thelp\n") 401 402 desc = "Bootlin toolchain for the %s architecture, using the %s C library. " % \ 403 (self.arch, self.libc) 404 405 if self.variant == "stable": 406 desc += "This is a stable version, which means it is using stable and proven versions of gcc, gdb and binutils." 407 else: 408 desc += "This is a bleeding-edge version, which means it is using the latest versions of gcc, gdb and binutils." 409 410 f.write(textwrap.fill(desc, width=62, initial_indent="\t ", subsequent_indent="\t ") + "\n") 411 f.write("\n") 412 f.write("\t https://toolchains.bootlin.com/\n") 413 414 f.write("\n") 415 416 def gen_mk(self, f): 417 f.write("ifeq ($(%s),y)\n" % self.option_name) 418 f.write("TOOLCHAIN_EXTERNAL_BOOTLIN_VERSION = %s\n" % self.version) 419 f.write("TOOLCHAIN_EXTERNAL_BOOTLIN_SOURCE = %s--%s--%s-$(TOOLCHAIN_EXTERNAL_BOOTLIN_VERSION).tar.bz2\n" % 420 (self.arch, self.libc, self.variant)) 421 f.write("TOOLCHAIN_EXTERNAL_BOOTLIN_SITE = %s\n" % 422 os.path.join(BASE_URL, self.arch, "tarballs")) 423 f.write("endif\n\n") 424 pass 425 426 def gen_hash(self, f): 427 f.write("# From %s\n" % self.hash_url) 428 f.write("sha256 %s %s\n" % (self.sha256, os.path.basename(self.tarball_url))) 429 430 def gen_test(self, f): 431 if self.variant == "stable": 432 variant = "Stable" 433 else: 434 variant = "BleedingEdge" 435 testname = "TestExternalToolchainBootlin" + \ 436 self.arch.replace("-", "").capitalize() + \ 437 self.libc.capitalize() + variant 438 f.write("\n\n") 439 f.write("class %s(TestExternalToolchain):\n" % testname) 440 f.write(" config = \"\"\"\n") 441 if 'test_options' in arches[self.arch]: 442 test_options = arches[self.arch]['test_options'] 443 else: 444 test_options = arches[self.arch]['conditions'] 445 for opt in test_options: 446 if opt.startswith("!"): 447 f.write(" # %s is not set\n" % opt[1:]) 448 else: 449 f.write(" %s=y\n" % opt) 450 f.write(" BR2_TOOLCHAIN_EXTERNAL=y\n") 451 f.write(" BR2_TOOLCHAIN_EXTERNAL_BOOTLIN=y\n") 452 f.write(" %s=y\n" % self.option_name) 453 f.write(" # BR2_TARGET_ROOTFS_TAR is not set\n") 454 f.write(" \"\"\"\n") 455 f.write(" toolchain_prefix = \"%s-linux\"\n" % arches[self.arch]['prefix']) 456 f.write("\n") 457 f.write(" def test_run(self):\n") 458 f.write(" TestExternalToolchain.common_check(self)\n") 459 460 def __repr__(self): 461 return "Toolchain(arch=%s libc=%s variant=%s version=%s, option=%s)" % \ 462 (self.arch, self.libc, self.variant, self.version, self.option_name) 463 464 465def get_toolchains(): 466 toolchains = list() 467 for arch, details in arches.items(): 468 print(arch) 469 url = os.path.join(BASE_URL, arch, "available_toolchains") 470 page = requests.get(url).text 471 fnames = sorted(re.findall(r'<td><a href="(\w[^"]+)"', page)) 472 # This dict will allow us to keep only the latest version for 473 # each toolchain. 474 tmp = dict() 475 for fname in fnames: 476 parts = fname.split('--') 477 assert parts[0] == arch, "Arch does not match: %s vs. %s" % (parts[0], arch) 478 libc = parts[1] 479 if parts[2].startswith("stable-"): 480 variant = "stable" 481 version = parts[2][len("stable-"):] 482 elif parts[2].startswith("bleeding-edge-"): 483 variant = "bleeding-edge" 484 version = parts[2][len("bleeding-edge-"):] 485 tmp[(arch, libc, variant)] = version 486 487 if len(tmp) == 0: 488 print("ERROR: no toolchains found for architecture %s" % arch) 489 sys.exit(1) 490 491 toolchains += [Toolchain(k[0], k[1], k[2], v) for k, v in tmp.items()] 492 493 return toolchains 494 495 496def gen_config_in_options(toolchains, fpath): 497 with open(fpath, "w") as f: 498 f.write(AUTOGENERATED_COMMENT) 499 500 f.write("config BR2_TOOLCHAIN_EXTERNAL_BOOTLIN_ARCH_SUPPORTS\n") 501 f.write("\tbool\n") 502 for arch, details in arches.items(): 503 conditions = details['conditions'].copy() 504 f.write("\tdefault y if %s\n" % " && ".join(conditions)) 505 f.write("\n") 506 507 f.write("if BR2_TOOLCHAIN_EXTERNAL_BOOTLIN\n\n") 508 509 f.write("config BR2_TOOLCHAIN_EXTERNAL_PREFIX\n") 510 f.write("\tdefault \"$(ARCH)-linux\"\n") 511 512 f.write("\n") 513 514 f.write("config BR2_PACKAGE_PROVIDES_TOOLCHAIN_EXTERNAL\n") 515 f.write("\tdefault \"toolchain-external-bootlin\"\n") 516 517 f.write("\n") 518 519 f.write("choice\n") 520 f.write("\tprompt \"Bootlin toolchain variant\"\n") 521 522 for toolchain in toolchains: 523 toolchain.gen_config_in_options(f) 524 525 f.write("endchoice\n") 526 f.write("endif\n") 527 528 529def gen_mk(toolchains, fpath): 530 with open(fpath, "w") as f: 531 f.write("#" * 80 + "\n") 532 f.write("#\n") 533 f.write("# toolchain-external-bootlin\n") 534 f.write("#\n") 535 f.write("#" * 80 + "\n") 536 f.write("\n") 537 f.write(AUTOGENERATED_COMMENT) 538 for toolchain in toolchains: 539 toolchain.gen_mk(f) 540 f.write("$(eval $(toolchain-external-package))\n") 541 542 543def gen_hash(toolchains, fpath): 544 with open(fpath, "w") as f: 545 f.write(AUTOGENERATED_COMMENT) 546 for toolchain in toolchains: 547 toolchain.gen_hash(f) 548 549 550def gen_runtime_test(toolchains, fpath): 551 with open(fpath, "w") as f: 552 f.write(AUTOGENERATED_COMMENT) 553 f.write("from tests.toolchain.test_external import TestExternalToolchain\n") 554 for toolchain in toolchains: 555 toolchain.gen_test(f) 556 557 558def gen_toolchains(toolchains): 559 maindir = "toolchain/toolchain-external/toolchain-external-bootlin" 560 gen_config_in_options(toolchains, os.path.join(maindir, "Config.in.options")) 561 gen_mk(toolchains, os.path.join(maindir, "toolchain-external-bootlin.mk")) 562 gen_hash(toolchains, os.path.join(maindir, "toolchain-external-bootlin.hash")) 563 gen_runtime_test(toolchains, 564 os.path.join("support", "testing", "tests", "toolchain", "test_external_bootlin.py")) 565 566 567toolchains = get_toolchains() 568gen_toolchains(toolchains) 569