gen-bootlin-toolchains 21 KB

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