8cba5463de
The logic in gen-bootlin-toolchains was assuming all glibc toolchains have RPC support, which is no longer true since glibc 2.32 has dropped RPC support. It turns out that gen-bootlin-toolchains already had some proper logic that selects BR2_TOOLCHAIN_HAS_NATIVE_RPC depending on the presence of BR2_TOOLCHAIN_EXTERNAL_INET_RPC in the toolchain fragment. As such toolchain fragments have been fixed in https://toolchains.bootlin.com, we can now rely on this to properly decide if the toolchain has RPC support or not. Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
497 lines
18 KiB
Python
Executable File
497 lines
18 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import os.path
|
|
import re
|
|
import requests
|
|
import textwrap
|
|
|
|
BASE_URL = "https://toolchains.bootlin.com/downloads/releases/toolchains"
|
|
|
|
AUTOGENERATED_COMMENT = """# This file was auto-generated by support/scripts/gen-bootlin-toolchains
|
|
# Do not edit
|
|
"""
|
|
|
|
# In the below dict:
|
|
|
|
# - 'conditions' indicate the cumulative conditions under which the
|
|
# toolchain will be made available. In several situations, a given
|
|
# toolchain is usable on several architectures variants (for
|
|
# example, an ARMv6 toolchain can be used on ARMv7)
|
|
# - 'test_options' indicate one specific configuration where the
|
|
# toolchain can be used. It is used to create the runtime test
|
|
# cases. If 'test_options' does not exist, the code assumes it can
|
|
# be made equal to 'conditions'
|
|
# - 'prefix' is the prefix of the cross-compilation toolchain tools
|
|
|
|
arches = {
|
|
'aarch64': {
|
|
'conditions': ['BR2_aarch64'],
|
|
'prefix': 'aarch64',
|
|
},
|
|
'aarch64be': {
|
|
'conditions': ['BR2_aarch64_be'],
|
|
'prefix': 'aarch64_be',
|
|
},
|
|
'arcle-750d': {
|
|
'conditions': ['BR2_arcle', 'BR2_arc750d'],
|
|
'prefix': 'arc',
|
|
},
|
|
'arcle-hs38': {
|
|
'conditions': ['BR2_arcle', 'BR2_archs38'],
|
|
'prefix': 'arc',
|
|
},
|
|
'armv5-eabi': {
|
|
'conditions': ['BR2_ARM_CPU_ARMV5', 'BR2_ARM_EABI'],
|
|
'test_options': ['BR2_arm', 'BR2_arm926t', 'BR2_ARM_EABI'],
|
|
'prefix': 'arm',
|
|
},
|
|
'armv6-eabihf': {
|
|
'conditions': ['BR2_ARM_CPU_ARMV6', 'BR2_ARM_EABIHF'],
|
|
'test_options': ['BR2_arm', 'BR2_arm1176jzf_s', 'BR2_ARM_EABIHF'],
|
|
'prefix': 'arm',
|
|
},
|
|
'armv7-eabihf': {
|
|
'conditions': ['BR2_ARM_CPU_ARMV7A', 'BR2_ARM_EABIHF'],
|
|
'test_options': ['BR2_arm', 'BR2_cortex_a8', 'BR2_ARM_EABIHF'],
|
|
'prefix': 'arm',
|
|
},
|
|
'armv7m': {
|
|
'conditions': ['BR2_ARM_CPU_ARMV7M'],
|
|
'test_options': ['BR2_arm', 'BR2_cortex_m4'],
|
|
'prefix': 'arm',
|
|
},
|
|
'm68k-68xxx': {
|
|
'conditions': ['BR2_m68k_m68k'],
|
|
'test_options': ['BR2_m68k', 'BR2_m68k_68040'],
|
|
'prefix': 'm68k',
|
|
},
|
|
'm68k-coldfire': {
|
|
'conditions': ['BR2_m68k_cf'],
|
|
'test_options': ['BR2_m68k', 'BR2_m68k_cf5208'],
|
|
'prefix': 'm68k',
|
|
},
|
|
'microblazebe': {
|
|
'conditions': ['BR2_microblazebe'],
|
|
'prefix': 'microblaze',
|
|
},
|
|
'microblazeel': {
|
|
'conditions': ['BR2_microblazeel'],
|
|
'prefix': 'microblazeel',
|
|
},
|
|
'mips32': {
|
|
# Not sure it could be used by other mips32 variants?
|
|
'conditions': ['BR2_mips', 'BR2_mips_32', '!BR2_MIPS_SOFT_FLOAT'],
|
|
'prefix': 'mips',
|
|
},
|
|
'mips32el': {
|
|
# Not sure it could be used by other mips32el variants?
|
|
'conditions': ['BR2_mipsel', 'BR2_mips_32', '!BR2_MIPS_SOFT_FLOAT'],
|
|
'prefix': 'mipsel',
|
|
},
|
|
'mips32r5el': {
|
|
'conditions': ['BR2_mipsel', 'BR2_mips_32r5', '!BR2_MIPS_SOFT_FLOAT'],
|
|
'prefix': 'mipsel',
|
|
},
|
|
'mips32r6el': {
|
|
'conditions': ['BR2_mipsel', 'BR2_mips_32r6', '!BR2_MIPS_SOFT_FLOAT'],
|
|
'prefix': 'mipsel',
|
|
},
|
|
'mips64': {
|
|
# Not sure it could be used by other mips64 variants?
|
|
'conditions': ['BR2_mips64', 'BR2_mips_64', '!BR2_MIPS_SOFT_FLOAT'],
|
|
'prefix': 'mips64',
|
|
},
|
|
'mips64-n32': {
|
|
# Not sure it could be used by other mips64 variants?
|
|
'conditions': ['BR2_mips64', 'BR2_mips_64', 'BR2_MIPS_NABI32', '!BR2_MIPS_SOFT_FLOAT'],
|
|
'prefix': 'mips64',
|
|
},
|
|
'mips64el-n32': {
|
|
# Not sure it could be used by other mips64el variants?
|
|
'conditions': ['BR2_mips64el', 'BR2_mips_64', 'BR2_MIPS_NABI32', '!BR2_MIPS_SOFT_FLOAT'],
|
|
'prefix': 'mips64el',
|
|
},
|
|
'mips64r6el-n32': {
|
|
'conditions': ['BR2_mips64el', 'BR2_mips_64r6', 'BR2_MIPS_NABI32', '!BR2_MIPS_SOFT_FLOAT'],
|
|
'prefix': 'mips64el',
|
|
},
|
|
'nios2': {
|
|
'conditions': ['BR2_nios2'],
|
|
'prefix': 'nios2',
|
|
},
|
|
'openrisc': {
|
|
'conditions': ['BR2_or1k'],
|
|
'prefix': 'or1k',
|
|
},
|
|
'powerpc-440fp': {
|
|
# Not sure it could be used by other powerpc variants?
|
|
'conditions': ['BR2_powerpc', 'BR2_powerpc_440fp'],
|
|
'prefix': 'powerpc',
|
|
},
|
|
'powerpc-e300c3': {
|
|
# Not sure it could be used by other powerpc variants?
|
|
'conditions': ['BR2_powerpc', 'BR2_powerpc_e300c3'],
|
|
'prefix': 'powerpc',
|
|
},
|
|
'powerpc-e500mc': {
|
|
# Not sure it could be used by other powerpc variants?
|
|
'conditions': ['BR2_powerpc', 'BR2_powerpc_e500mc'],
|
|
'prefix': 'powerpc',
|
|
},
|
|
'powerpc64-e5500': {
|
|
'conditions': ['BR2_powerpc64', 'BR2_powerpc_e5500'],
|
|
'prefix': 'powerpc64',
|
|
},
|
|
'powerpc64-e6500': {
|
|
'conditions': ['BR2_powerpc64', 'BR2_powerpc_e6500'],
|
|
'prefix': 'powerpc64',
|
|
},
|
|
'powerpc64-power8': {
|
|
'conditions': ['BR2_powerpc64', 'BR2_powerpc_power8'],
|
|
'prefix': 'powerpc64',
|
|
},
|
|
'powerpc64le-power8': {
|
|
'conditions': ['BR2_powerpc64le', 'BR2_powerpc_power8'],
|
|
'prefix': 'powerpc64le',
|
|
},
|
|
'riscv32-ilp32d': {
|
|
'conditions': ['BR2_riscv', 'BR2_riscv_g', 'BR2_RISCV_32', 'BR2_RISCV_ABI_ILP32D'],
|
|
'prefix': 'riscv32',
|
|
},
|
|
'riscv64': {
|
|
'conditions': ['BR2_riscv', 'BR2_riscv_g', 'BR2_RISCV_64', 'BR2_RISCV_ABI_LP64'],
|
|
'prefix': 'riscv64',
|
|
},
|
|
'sh-sh4': {
|
|
'conditions': ['BR2_sh', 'BR2_sh4'],
|
|
'prefix': 'sh4',
|
|
},
|
|
'sh-sh4aeb': {
|
|
'conditions': ['BR2_sh', 'BR2_sh4aeb'],
|
|
'prefix': 'sh4aeb',
|
|
},
|
|
'sparc64': {
|
|
'conditions': ['BR2_sparc64', 'BR2_sparc_v9'],
|
|
'prefix': 'sparc64',
|
|
},
|
|
'sparcv8': {
|
|
'conditions': ['BR2_sparc', 'BR2_sparc_v8'],
|
|
'prefix': 'sparc',
|
|
},
|
|
'x86-64-core-i7': {
|
|
'conditions': ['BR2_x86_64',
|
|
'BR2_X86_CPU_HAS_MMX',
|
|
'BR2_X86_CPU_HAS_SSE',
|
|
'BR2_X86_CPU_HAS_SSE2',
|
|
'BR2_X86_CPU_HAS_SSE3',
|
|
'BR2_X86_CPU_HAS_SSSE3',
|
|
'BR2_X86_CPU_HAS_SSE4',
|
|
'BR2_X86_CPU_HAS_SSE42'],
|
|
'test_options': ['BR2_x86_64', 'BR2_x86_corei7'],
|
|
'prefix': 'x86_64',
|
|
},
|
|
'x86-core2': {
|
|
'conditions': ['BR2_i386',
|
|
'BR2_X86_CPU_HAS_MMX',
|
|
'BR2_X86_CPU_HAS_SSE',
|
|
'BR2_X86_CPU_HAS_SSE2',
|
|
'BR2_X86_CPU_HAS_SSE3',
|
|
'BR2_X86_CPU_HAS_SSSE3'],
|
|
'test_options': ['BR2_i386', 'BR2_x86_core2'],
|
|
'prefix': 'i686',
|
|
},
|
|
'x86-i686': {
|
|
'conditions': ['BR2_i386',
|
|
'!BR2_x86_i486',
|
|
'!BR2_x86_i586',
|
|
'!BR2_x86_x1000'],
|
|
'test_options': ['BR2_i386',
|
|
'BR2_x86_i686'],
|
|
'prefix': 'i686',
|
|
},
|
|
'xtensa-lx60': {
|
|
'conditions': ['BR2_xtensa', 'BR2_xtensa_fsf'],
|
|
'prefix': 'xtensa',
|
|
},
|
|
}
|
|
|
|
|
|
class Toolchain:
|
|
def __init__(self, arch, libc, variant, version):
|
|
self.arch = arch
|
|
self.libc = libc
|
|
self.variant = variant
|
|
self.version = version
|
|
self.fname_prefix = "%s--%s--%s-%s" % (self.arch, self.libc, self.variant, self.version)
|
|
self.option_name = "BR2_TOOLCHAIN_EXTERNAL_BOOTLIN_%s_%s_%s" % \
|
|
(self.arch.replace("-", "_").upper(), self.libc.upper(), self.variant.replace("-", "_").upper())
|
|
self.fragment = requests.get(self.fragment_url).text.split("\n")
|
|
self.sha256 = requests.get(self.hash_url).text.split(" ")[0]
|
|
|
|
@property
|
|
def tarball_url(self):
|
|
return os.path.join(BASE_URL, self.arch, "tarballs",
|
|
self.fname_prefix + ".tar.bz2")
|
|
|
|
@property
|
|
def hash_url(self):
|
|
return os.path.join(BASE_URL, self.arch, "tarballs",
|
|
self.fname_prefix + ".sha256")
|
|
|
|
@property
|
|
def fragment_url(self):
|
|
return os.path.join(BASE_URL, self.arch, "fragments",
|
|
self.fname_prefix + ".frag")
|
|
|
|
def gen_config_in_options(self, f):
|
|
f.write("config %s\n" % self.option_name)
|
|
f.write("\tbool \"%s %s %s %s\"\n" %
|
|
(self.arch, self.libc, self.variant, self.version))
|
|
depends = []
|
|
selects = []
|
|
|
|
for c in arches[self.arch]['conditions']:
|
|
depends.append(c)
|
|
|
|
for frag in self.fragment:
|
|
# libc type
|
|
if frag.startswith("BR2_TOOLCHAIN_EXTERNAL_CUSTOM_UCLIBC"):
|
|
selects.append("BR2_TOOLCHAIN_EXTERNAL_UCLIBC")
|
|
elif frag.startswith("BR2_TOOLCHAIN_EXTERNAL_CUSTOM_GLIBC"):
|
|
# glibc needs mmu support
|
|
depends.append("BR2_USE_MMU")
|
|
# glibc doesn't support static only configuration
|
|
depends.append("!BR2_STATIC_LIBS")
|
|
selects.append("BR2_TOOLCHAIN_EXTERNAL_GLIBC")
|
|
elif frag.startswith("BR2_TOOLCHAIN_EXTERNAL_CUSTOM_MUSL"):
|
|
# musl needs mmu support
|
|
depends.append("BR2_USE_MMU")
|
|
selects.append("BR2_TOOLCHAIN_EXTERNAL_MUSL")
|
|
|
|
# gcc version
|
|
if frag.startswith("BR2_TOOLCHAIN_EXTERNAL_GCC_"):
|
|
m = re.match("^BR2_TOOLCHAIN_EXTERNAL_GCC_([0-9_]*)=y$", frag)
|
|
assert m, "Cannot get gcc version for toolchain %s" % self.fname_prefix
|
|
selects.append("BR2_TOOLCHAIN_GCC_AT_LEAST_%s" % m[1])
|
|
|
|
# kernel headers version
|
|
if frag.startswith("BR2_TOOLCHAIN_EXTERNAL_HEADERS_"):
|
|
m = re.match("^BR2_TOOLCHAIN_EXTERNAL_HEADERS_([0-9_]*)=y$", frag)
|
|
assert m, "Cannot get kernel headers version for toolchain %s" % self.fname_prefix
|
|
selects.append("BR2_TOOLCHAIN_HEADERS_AT_LEAST_%s" % m[1])
|
|
|
|
# C++
|
|
if frag.startswith("BR2_TOOLCHAIN_EXTERNAL_CXX"):
|
|
selects.append("BR2_INSTALL_LIBSTDCPP")
|
|
|
|
# SSP
|
|
if frag.startswith("BR2_TOOLCHAIN_EXTERNAL_HAS_SSP"):
|
|
selects.append("BR2_TOOLCHAIN_HAS_SSP")
|
|
|
|
# wchar
|
|
if frag.startswith("BR2_TOOLCHAIN_EXTERNAL_WCHAR"):
|
|
selects.append("BR2_USE_WCHAR")
|
|
|
|
# locale
|
|
if frag.startswith("BR2_TOOLCHAIN_EXTERNAL_LOCALE"):
|
|
# locale implies the availability of wchar
|
|
selects.append("BR2_USE_WCHAR")
|
|
selects.append("BR2_ENABLE_LOCALE")
|
|
|
|
# thread support
|
|
if frag.startswith("BR2_TOOLCHAIN_EXTERNAL_HAS_THREADS"):
|
|
selects.append("BR2_TOOLCHAIN_HAS_THREADS")
|
|
|
|
if frag.startswith("BR2_TOOLCHAIN_EXTERNAL_HAS_THREADS_DEBUG"):
|
|
selects.append("BR2_TOOLCHAIN_HAS_THREADS_DEBUG")
|
|
|
|
if frag.startswith("BR2_TOOLCHAIN_EXTERNAL_HAS_THREADS_NPTL"):
|
|
selects.append("BR2_TOOLCHAIN_HAS_THREADS_NPTL")
|
|
|
|
# RPC
|
|
if frag.startswith("BR2_TOOLCHAIN_EXTERNAL_INET_RPC"):
|
|
selects.append("BR2_TOOLCHAIN_HAS_NATIVE_RPC")
|
|
|
|
# D language
|
|
if frag.startswith("BR2_TOOLCHAIN_EXTERNAL_DLANG"):
|
|
selects.append("BR2_TOOLCHAIN_HAS_DLANG")
|
|
|
|
# fortran
|
|
if frag.startswith("BR2_TOOLCHAIN_EXTERNAL_FORTRAN"):
|
|
selects.append("BR2_TOOLCHAIN_HAS_FORTRAN")
|
|
|
|
# OpenMP
|
|
if frag.startswith("BR2_TOOLCHAIN_EXTERNAL_OPENMP"):
|
|
selects.append("BR2_TOOLCHAIN_HAS_OPENMP")
|
|
|
|
for depend in depends:
|
|
f.write("\tdepends on %s\n" % depend)
|
|
|
|
for select in selects:
|
|
f.write("\tselect %s\n" % select)
|
|
|
|
f.write("\thelp\n")
|
|
|
|
desc = "Bootlin toolchain for the %s architecture, using the %s C library. " % \
|
|
(self.arch, self.libc)
|
|
|
|
if self.variant == "stable":
|
|
desc += "This is a stable version, which means it is using stable and proven versions of gcc, gdb and binutils."
|
|
else:
|
|
desc += "This is a bleeding-edge version, which means it is using the latest versions of gcc, gdb and binutils."
|
|
|
|
f.write(textwrap.fill(desc, width=62, initial_indent="\t ", subsequent_indent="\t ") + "\n")
|
|
f.write("\n")
|
|
f.write("\t https://toolchains.bootlin.com/\n")
|
|
|
|
f.write("\n")
|
|
|
|
def gen_mk(self, f):
|
|
f.write("ifeq ($(%s),y)\n" % self.option_name)
|
|
f.write("TOOLCHAIN_EXTERNAL_BOOTLIN_VERSION = %s\n" % self.version)
|
|
f.write("TOOLCHAIN_EXTERNAL_BOOTLIN_SOURCE = %s--%s--%s-$(TOOLCHAIN_EXTERNAL_BOOTLIN_VERSION).tar.bz2\n" %
|
|
(self.arch, self.libc, self.variant))
|
|
f.write("TOOLCHAIN_EXTERNAL_BOOTLIN_SITE = %s\n" %
|
|
os.path.join(BASE_URL, self.arch, "tarballs"))
|
|
f.write("endif\n\n")
|
|
pass
|
|
|
|
def gen_hash(self, f):
|
|
f.write("# From %s\n" % self.hash_url)
|
|
f.write("sha256 %s %s\n" % (self.sha256, os.path.basename(self.tarball_url)))
|
|
|
|
def gen_test(self, f):
|
|
if self.variant == "stable":
|
|
variant = "Stable"
|
|
else:
|
|
variant = "BleedingEdge"
|
|
testname = "TestExternalToolchainBootlin" + \
|
|
self.arch.replace("-", "").capitalize() + \
|
|
self.libc.capitalize() + variant
|
|
f.write("\n\n")
|
|
f.write("class %s(TestExternalToolchain):\n" % testname)
|
|
f.write(" config = \"\"\"\n")
|
|
if 'test_options' in arches[self.arch]:
|
|
test_options = arches[self.arch]['test_options']
|
|
else:
|
|
test_options = arches[self.arch]['conditions']
|
|
for opt in test_options:
|
|
if opt.startswith("!"):
|
|
f.write(" # %s is not set\n" % opt[1:])
|
|
else:
|
|
f.write(" %s=y\n" % opt)
|
|
f.write(" BR2_TOOLCHAIN_EXTERNAL=y\n")
|
|
f.write(" BR2_TOOLCHAIN_EXTERNAL_BOOTLIN=y\n")
|
|
f.write(" %s=y\n" % self.option_name)
|
|
f.write(" # BR2_TARGET_ROOTFS_TAR is not set\n")
|
|
f.write(" \"\"\"\n")
|
|
f.write(" toolchain_prefix = \"%s-linux\"\n" % arches[self.arch]['prefix'])
|
|
f.write("\n")
|
|
f.write(" def test_run(self):\n")
|
|
f.write(" TestExternalToolchain.common_check(self)\n")
|
|
|
|
def __repr__(self):
|
|
return "Toolchain(arch=%s libc=%s variant=%s version=%s, option=%s)" % \
|
|
(self.arch, self.libc, self.variant, self.version, self.option_name)
|
|
|
|
|
|
def get_toolchains():
|
|
toolchains = list()
|
|
for arch, details in arches.items():
|
|
print(arch)
|
|
url = os.path.join(BASE_URL, arch, "available_toolchains")
|
|
page = requests.get(url).text
|
|
fnames = sorted(re.findall(r'<td><a href="(\w[^"]+)"', page))
|
|
# This dict will allow us to keep only the latest version for
|
|
# each toolchain.
|
|
tmp = dict()
|
|
for fname in fnames:
|
|
parts = fname.split('--')
|
|
assert parts[0] == arch, "Arch does not match: %s vs. %s" % (parts[0], arch)
|
|
libc = parts[1]
|
|
if parts[2].startswith("stable-"):
|
|
variant = "stable"
|
|
version = parts[2][len("stable-"):]
|
|
elif parts[2].startswith("bleeding-edge-"):
|
|
variant = "bleeding-edge"
|
|
version = parts[2][len("bleeding-edge-"):]
|
|
tmp[(arch, libc, variant)] = version
|
|
|
|
toolchains += [Toolchain(k[0], k[1], k[2], v) for k, v in tmp.items()]
|
|
|
|
return toolchains
|
|
|
|
|
|
def gen_config_in_options(toolchains, fpath):
|
|
with open(fpath, "w") as f:
|
|
f.write(AUTOGENERATED_COMMENT)
|
|
|
|
f.write("config BR2_TOOLCHAIN_EXTERNAL_BOOTLIN_ARCH_SUPPORTS\n")
|
|
f.write("\tbool\n")
|
|
for arch, details in arches.items():
|
|
f.write("\tdefault y if %s\n" % " && ".join(details['conditions']))
|
|
f.write("\n")
|
|
|
|
f.write("if BR2_TOOLCHAIN_EXTERNAL_BOOTLIN\n\n")
|
|
|
|
f.write("config BR2_TOOLCHAIN_EXTERNAL_PREFIX\n")
|
|
f.write("\tdefault \"$(ARCH)-linux\"\n")
|
|
|
|
f.write("\n")
|
|
|
|
f.write("config BR2_PACKAGE_PROVIDES_TOOLCHAIN_EXTERNAL\n")
|
|
f.write("\tdefault \"toolchain-external-bootlin\"\n")
|
|
|
|
f.write("\n")
|
|
|
|
f.write("choice\n")
|
|
f.write("\tprompt \"Bootlin toolchain variant\"\n")
|
|
|
|
for toolchain in toolchains:
|
|
toolchain.gen_config_in_options(f)
|
|
|
|
f.write("endchoice\n")
|
|
f.write("endif\n")
|
|
|
|
|
|
def gen_mk(toolchains, fpath):
|
|
with open(fpath, "w") as f:
|
|
f.write("#" * 80 + "\n")
|
|
f.write("#\n")
|
|
f.write("# toolchain-external-bootlin\n")
|
|
f.write("#\n")
|
|
f.write("#" * 80 + "\n")
|
|
f.write("\n")
|
|
f.write(AUTOGENERATED_COMMENT)
|
|
for toolchain in toolchains:
|
|
toolchain.gen_mk(f)
|
|
f.write("$(eval $(toolchain-external-package))\n")
|
|
|
|
|
|
def gen_hash(toolchains, fpath):
|
|
with open(fpath, "w") as f:
|
|
f.write(AUTOGENERATED_COMMENT)
|
|
for toolchain in toolchains:
|
|
toolchain.gen_hash(f)
|
|
|
|
|
|
def gen_runtime_test(toolchains, fpath):
|
|
with open(fpath, "w") as f:
|
|
f.write(AUTOGENERATED_COMMENT)
|
|
f.write("from tests.toolchain.test_external import TestExternalToolchain\n")
|
|
for toolchain in toolchains:
|
|
toolchain.gen_test(f)
|
|
|
|
|
|
def gen_toolchains(toolchains):
|
|
maindir = "toolchain/toolchain-external/toolchain-external-bootlin"
|
|
gen_config_in_options(toolchains, os.path.join(maindir, "Config.in.options"))
|
|
gen_mk(toolchains, os.path.join(maindir, "toolchain-external-bootlin.mk"))
|
|
gen_hash(toolchains, os.path.join(maindir, "toolchain-external-bootlin.hash"))
|
|
gen_runtime_test(toolchains,
|
|
os.path.join("support", "testing", "tests", "toolchain", "test_external_bootlin.py"))
|
|
|
|
|
|
toolchains = get_toolchains()
|
|
gen_toolchains(toolchains)
|