xref: /OK3568_Linux_fs/buildroot/support/scripts/gen-bootlin-toolchains (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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