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