1#!/usr/bin/env python3 2 3# Copyright (C) 2014 by Thomas Petazzoni <thomas.petazzoni@free-electrons.com> 4# 5# This program is free software; you can redistribute it and/or modify 6# it under the terms of the GNU General Public License as published by 7# the Free Software Foundation; either version 2 of the License, or 8# (at your option) any later version. 9# 10# This program is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13# General Public License for more details. 14# 15# You should have received a copy of the GNU General Public License 16# along with this program; if not, write to the Free Software 17# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 19# This script generates a random configuration for testing Buildroot. 20 21from binascii import hexlify 22import asyncio 23import csv 24import os 25from random import randint 26import sys 27import traceback 28 29 30class SystemInfo: 31 DEFAULT_NEEDED_PROGS = ["make", "git", "gcc", "timeout"] 32 DEFAULT_OPTIONAL_PROGS = ["bzr", "java", "javac", "jar", "diffoscope"] 33 34 def __init__(self): 35 self.needed_progs = list(self.__class__.DEFAULT_NEEDED_PROGS) 36 self.optional_progs = list(self.__class__.DEFAULT_OPTIONAL_PROGS) 37 self.progs = {} 38 39 def find_prog(self, name, flags=os.X_OK, env=os.environ): 40 if not name or name[0] == os.sep: 41 raise ValueError(name) 42 43 prog_path = env.get("PATH", None) 44 # for windows compatibility, we'd need to take PATHEXT into account 45 46 if prog_path: 47 for prog_dir in filter(None, prog_path.split(os.pathsep)): 48 # os.join() not necessary: non-empty prog_dir 49 # and name[0] != os.sep 50 prog = prog_dir + os.sep + name 51 if os.access(prog, flags): 52 return prog 53 # -- 54 return None 55 56 async def has(self, prog): 57 """Checks whether a program is available. 58 Lazily evaluates missing entries. 59 60 Returns: None if prog not found, else path to the program [evaluates 61 to True] 62 """ 63 try: 64 return self.progs[prog] 65 except KeyError: 66 pass 67 68 have_it = self.find_prog(prog) 69 # java[c] needs special care 70 if have_it and prog in ('java', 'javac'): 71 proc = await asyncio.create_subprocess_shell( 72 "%s -version | grep gcj" % prog, 73 stdout=asyncio.subprocess.DEVNULL, 74 stderr=asyncio.subprocess.DEVNULL) 75 ret = await proc.wait() 76 if ret != 1: 77 have_it = False 78 # -- 79 self.progs[prog] = have_it 80 return have_it 81 82 def check_requirements(self): 83 """Checks program dependencies. 84 85 Returns: True if all mandatory programs are present, else False. 86 """ 87 do_check_has_prog = self.has 88 89 missing_requirements = False 90 for prog in self.needed_progs: 91 if not do_check_has_prog(prog): 92 print("ERROR: your system lacks the '%s' program" % prog) 93 missing_requirements = True 94 95 # check optional programs here, 96 # else they'd get checked by each worker instance 97 for prog in self.optional_progs: 98 do_check_has_prog(prog) 99 100 return not missing_requirements 101 102 103def get_toolchain_configs(toolchains_csv, buildrootdir): 104 """Fetch and return the possible toolchain configurations 105 106 This function returns an array of toolchain configurations. Each 107 toolchain configuration is itself an array of lines of the defconfig. 108 """ 109 110 with open(toolchains_csv) as r: 111 # filter empty lines and comments 112 lines = [t for t in r.readlines() if len(t.strip()) > 0 and t[0] != '#'] 113 toolchains = lines 114 configs = [] 115 116 (_, _, _, _, hostarch) = os.uname() 117 # ~2015 distros report x86 when on a 32bit install 118 if hostarch == 'i686' or hostarch == 'i386' or hostarch == 'x86': 119 hostarch = 'x86' 120 121 for row in csv.reader(toolchains): 122 config = {} 123 configfile = row[0] 124 config_hostarch = row[1] 125 keep = False 126 127 # Keep all toolchain configs that work regardless of the host 128 # architecture 129 if config_hostarch == "any": 130 keep = True 131 132 # Keep all toolchain configs that can work on the current host 133 # architecture 134 if hostarch == config_hostarch: 135 keep = True 136 137 # Assume that x86 32 bits toolchains work on x86_64 build 138 # machines 139 if hostarch == 'x86_64' and config_hostarch == "x86": 140 keep = True 141 142 if not keep: 143 continue 144 145 if not os.path.isabs(configfile): 146 configfile = os.path.join(buildrootdir, configfile) 147 148 with open(configfile) as r: 149 config = r.readlines() 150 configs.append(config) 151 return configs 152 153 154async def is_toolchain_usable(configfile, config): 155 """Check if the toolchain is actually usable.""" 156 157 with open(configfile) as configf: 158 configlines = configf.readlines() 159 160 # Check that the toolchain configuration is still present 161 for toolchainline in config: 162 if toolchainline not in configlines: 163 print("WARN: toolchain can't be used", file=sys.stderr) 164 print(" Missing: %s" % toolchainline.strip(), file=sys.stderr) 165 return False 166 167 return True 168 169 170async def fixup_config(sysinfo, configfile): 171 """Finalize the configuration and reject any problematic combinations 172 173 This function returns 'True' when the configuration has been 174 accepted, and 'False' when the configuration has not been accepted because 175 it is known to fail (in which case another random configuration will be 176 generated). 177 """ 178 179 with open(configfile) as configf: 180 configlines = configf.readlines() 181 182 ROOTFS_SIZE = '5G' 183 184 BR2_TOOLCHAIN_EXTERNAL_URL = 'BR2_TOOLCHAIN_EXTERNAL_URL="http://autobuild.buildroot.org/toolchains/tarballs/' 185 186 if "BR2_NEEDS_HOST_JAVA=y\n" in configlines and not await sysinfo.has("java"): 187 return False 188 # The ctng toolchain is affected by PR58854 189 if 'BR2_PACKAGE_LTTNG_TOOLS=y\n' in configlines and \ 190 BR2_TOOLCHAIN_EXTERNAL_URL + 'armv5-ctng-linux-gnueabi.tar.xz"\n' in configlines: 191 return False 192 # The ctng toolchain tigger an assembler error with guile package when compiled with -Os (same issue as for CS ARM 2014.05-29) 193 if 'BR2_PACKAGE_GUILE=y\n' in configlines and \ 194 'BR2_OPTIMIZE_S=y\n' in configlines and \ 195 BR2_TOOLCHAIN_EXTERNAL_URL + 'armv5-ctng-linux-gnueabi.tar.xz"\n' in configlines: 196 return False 197 # The ctng toolchain is affected by PR58854 198 if 'BR2_PACKAGE_LTTNG_TOOLS=y\n' in configlines and \ 199 BR2_TOOLCHAIN_EXTERNAL_URL + 'armv6-ctng-linux-uclibcgnueabi.tar.xz"\n' in configlines: 200 return False 201 # The ctng toolchain is affected by PR58854 202 if 'BR2_PACKAGE_LTTNG_TOOLS=y\n' in configlines and \ 203 BR2_TOOLCHAIN_EXTERNAL_URL + 'armv7-ctng-linux-gnueabihf.tar.xz"\n' in configlines: 204 return False 205 # The ctng toolchain is affected by PR60155 206 if 'BR2_PACKAGE_SDL=y\n' in configlines and \ 207 BR2_TOOLCHAIN_EXTERNAL_URL + 'powerpc-ctng-linux-uclibc.tar.xz"\n' in configlines: 208 return False 209 # The ctng toolchain is affected by PR60155 210 if 'BR2_PACKAGE_LIBMPEG2=y\n' in configlines and \ 211 BR2_TOOLCHAIN_EXTERNAL_URL + 'powerpc-ctng-linux-uclibc.tar.xz"\n' in configlines: 212 return False 213 # This MIPS toolchain uses eglibc-2.18 which lacks SYS_getdents64 214 if 'BR2_PACKAGE_STRONGSWAN=y\n' in configlines and \ 215 BR2_TOOLCHAIN_EXTERNAL_URL + 'mips64el-ctng_n64-linux-gnu.tar.xz"\n' in configlines: 216 return False 217 # This MIPS toolchain uses eglibc-2.18 which lacks SYS_getdents64 218 if 'BR2_PACKAGE_PYTHON3=y\n' in configlines and \ 219 BR2_TOOLCHAIN_EXTERNAL_URL + 'mips64el-ctng_n64-linux-gnu.tar.xz"\n' in configlines: 220 return False 221 # libffi not available on ARMv7-M, but propagating libffi arch 222 # dependencies in Buildroot is really too much work, so we handle 223 # this here. 224 if 'BR2_ARM_CPU_ARMV7M=y\n' in configlines and \ 225 'BR2_PACKAGE_LIBFFI=y\n' in configlines: 226 return False 227 # libopenssl needs atomic, but propagating this dependency in 228 # Buildroot is really too much work, so we handle this here. 229 if 'BR2_PACKAGE_LIBOPENSSL=y\n' in configlines and \ 230 'BR2_TOOLCHAIN_HAS_ATOMIC=y\n' not in configlines: 231 return False 232 if 'BR2_PACKAGE_SUNXI_BOARDS=y\n' in configlines: 233 configlines.remove('BR2_PACKAGE_SUNXI_BOARDS_FEX_FILE=""\n') 234 configlines.append('BR2_PACKAGE_SUNXI_BOARDS_FEX_FILE="a10/hackberry.fex"\n') 235 # This MIPS uClibc toolchain fails to build the gdb package 236 if 'BR2_PACKAGE_GDB=y\n' in configlines and \ 237 BR2_TOOLCHAIN_EXTERNAL_URL + 'mipsel-ctng-linux-uclibc.tar.xz"\n' in configlines: 238 return False 239 # This MIPS uClibc toolchain fails to build the rt-tests package 240 if 'BR2_PACKAGE_RT_TESTS=y\n' in configlines and \ 241 BR2_TOOLCHAIN_EXTERNAL_URL + 'mipsel-ctng-linux-uclibc.tar.xz"\n' in configlines: 242 return False 243 # This MIPS uClibc toolchain fails to build the civetweb package 244 if 'BR2_PACKAGE_CIVETWEB=y\n' in configlines and \ 245 BR2_TOOLCHAIN_EXTERNAL_URL + 'mipsel-ctng-linux-uclibc.tar.xz"\n' in configlines: 246 return False 247 # This MIPS ctng toolchain fails to build the python3 package 248 if 'BR2_PACKAGE_PYTHON3=y\n' in configlines and \ 249 BR2_TOOLCHAIN_EXTERNAL_URL + 'mips64el-ctng_n64-linux-gnu.tar.xz"\n' in configlines: 250 return False 251 # This MIPS uClibc toolchain fails to build the strace package 252 if 'BR2_PACKAGE_STRACE=y\n' in configlines and \ 253 BR2_TOOLCHAIN_EXTERNAL_URL + 'mipsel-ctng-linux-uclibc.tar.xz"\n' in configlines: 254 return False 255 # This MIPS uClibc toolchain fails to build the cdrkit package 256 if 'BR2_PACKAGE_CDRKIT=y\n' in configlines and \ 257 'BR2_STATIC_LIBS=y\n' in configlines and \ 258 BR2_TOOLCHAIN_EXTERNAL_URL + 'mipsel-ctng-linux-uclibc.tar.xz"\n' in configlines: 259 return False 260 # uClibc vfork static linking issue 261 if 'BR2_PACKAGE_ALSA_LIB=y\n' in configlines and \ 262 'BR2_STATIC_LIBS=y\n' in configlines and \ 263 BR2_TOOLCHAIN_EXTERNAL_URL + 'i486-ctng-linux-uclibc.tar.xz"\n' in configlines: 264 return False 265 # This MIPS uClibc toolchain fails to build the weston package 266 if 'BR2_PACKAGE_WESTON=y\n' in configlines and \ 267 BR2_TOOLCHAIN_EXTERNAL_URL + 'mipsel-ctng-linux-uclibc.tar.xz"\n' in configlines: 268 return False 269 # No C library for internal toolchain 270 if 'BR2_TOOLCHAIN_BUILDROOT_NONE=y\n' in configlines: 271 return False 272 # Xtensa custom cores require an overlay file with internal 273 # toolchains 274 if 'BR2_XTENSA_CUSTOM=y\n' in configlines and \ 275 'BR2_TOOLCHAIN_BUILDROOT=y\n' in configlines: 276 return False 277 278 if 'BR2_TOOLCHAIN_BARE_METAL_BUILDROOT=y\n' in configlines: 279 configlines.remove('BR2_TOOLCHAIN_BARE_METAL_BUILDROOT_ARCH=""\n') 280 configlines.append('BR2_TOOLCHAIN_BARE_METAL_BUILDROOT_ARCH="microblazeel-xilinx-elf"\n') 281 282 if 'BR2_PACKAGE_AUFS_UTIL=y\n' in configlines and \ 283 'BR2_PACKAGE_AUFS_UTIL_VERSION=""\n' in configlines: 284 return False 285 if 'BR2_PACKAGE_A10DISP=y\n' in configlines: 286 return False 287 288 if 'BR2_PACKAGE_HOST_UBOOT_TOOLS_ENVIMAGE=y\n' in configlines and \ 289 'BR2_PACKAGE_HOST_UBOOT_TOOLS_ENVIMAGE_SOURCE=""\n' in configlines and \ 290 'BR2_PACKAGE_HOST_UBOOT_TOOLS_ENVIMAGE_SIZE=""\n' in configlines: 291 bootenv = os.path.join(args.outputdir, "boot_env.txt") 292 with open(bootenv, "w+") as bootenvf: 293 bootenvf.write("prop=value") 294 configlines.remove('BR2_PACKAGE_HOST_UBOOT_TOOLS_ENVIMAGE_SOURCE=""\n') 295 configlines.append('BR2_PACKAGE_HOST_UBOOT_TOOLS_ENVIMAGE_SOURCE="%s"\n' % bootenv) 296 configlines.remove('BR2_PACKAGE_HOST_UBOOT_TOOLS_ENVIMAGE_SIZE=""\n') 297 configlines.append('BR2_PACKAGE_HOST_UBOOT_TOOLS_ENVIMAGE_SIZE="0x1000"\n') 298 299 if 'BR2_PACKAGE_HOST_UBOOT_TOOLS_BOOT_SCRIPT=y\n' in configlines and \ 300 'BR2_PACKAGE_HOST_UBOOT_TOOLS_BOOT_SCRIPT_SOURCE=""\n' in configlines: 301 bootscr = os.path.join(args.outputdir, "boot_script.txt") 302 with open(bootscr, "w+") as bootscrf: 303 bootscrf.write("prop=value") 304 configlines.remove('BR2_PACKAGE_HOST_UBOOT_TOOLS_BOOT_SCRIPT_SOURCE=""\n') 305 configlines.append('BR2_PACKAGE_HOST_UBOOT_TOOLS_BOOT_SCRIPT_SOURCE="%s"\n' % bootscr) 306 307 if 'BR2_ROOTFS_SKELETON_CUSTOM=y\n' in configlines and \ 308 'BR2_ROOTFS_SKELETON_CUSTOM_PATH=""\n' in configlines: 309 configlines.remove('BR2_ROOTFS_SKELETON_CUSTOM=y\n') 310 configlines.remove('BR2_ROOTFS_SKELETON_CUSTOM_PATH=""\n') 311 312 if 'BR2_LINUX_KERNEL=y\n' in configlines and \ 313 'BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y\n' in configlines and \ 314 'BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE=""\n' in configlines: 315 configlines.remove('BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y\n') 316 configlines.append('BR2_LINUX_KERNEL_USE_ARCH_DEFAULT_CONFIG=y\n') 317 configlines.remove('BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE=""\n') 318 319 if 'BR2_LINUX_KERNEL=y\n' in configlines and \ 320 'BR2_LINUX_KERNEL_USE_DEFCONFIG=y\n' in configlines and \ 321 'BR2_LINUX_KERNEL_DEFCONFIG=""\n' in configlines: 322 configlines.remove('BR2_LINUX_KERNEL_USE_DEFCONFIG=y\n') 323 configlines.append('BR2_LINUX_KERNEL_USE_ARCH_DEFAULT_CONFIG=y\n') 324 configlines.remove('BR2_LINUX_KERNEL_DEFCONFIG=""\n') 325 326 if 'BR2_LINUX_KERNEL=y\n' in configlines and \ 327 'BR2_LINUX_KERNEL_CUSTOM_GIT=y\n' in configlines and \ 328 'BR2_LINUX_KERNEL_CUSTOM_REPO_URL=""\n' in configlines: 329 configlines.remove('BR2_LINUX_KERNEL_CUSTOM_GIT=y\n') 330 configlines.append('BR2_LINUX_KERNEL_LATEST_VERSION=y\n') 331 configlines.remove('BR2_LINUX_KERNEL_CUSTOM_REPO_URL=""\n') 332 333 if 'BR2_LINUX_KERNEL=y\n' in configlines and \ 334 'BR2_LINUX_KERNEL_CUSTOM_HG=y\n' in configlines and \ 335 'BR2_LINUX_KERNEL_CUSTOM_REPO_URL=""\n' in configlines: 336 configlines.remove('BR2_LINUX_KERNEL_CUSTOM_HG=y\n') 337 configlines.append('BR2_LINUX_KERNEL_LATEST_VERSION=y\n') 338 configlines.remove('BR2_LINUX_KERNEL_CUSTOM_REPO_URL=""\n') 339 340 if 'BR2_LINUX_KERNEL=y\n' in configlines and \ 341 'BR2_LINUX_KERNEL_CUSTOM_SVN=y\n' in configlines and \ 342 'BR2_LINUX_KERNEL_CUSTOM_REPO_URL=""\n' in configlines: 343 configlines.remove('BR2_LINUX_KERNEL_CUSTOM_SVN=y\n') 344 configlines.append('BR2_LINUX_KERNEL_LATEST_VERSION=y\n') 345 configlines.remove('BR2_LINUX_KERNEL_CUSTOM_REPO_URL=""\n') 346 347 if 'BR2_LINUX_KERNEL=y\n' in configlines and \ 348 'BR2_LINUX_KERNEL_CUSTOM_TARBALL=y\n' in configlines and \ 349 'BR2_LINUX_KERNEL_CUSTOM_TARBALL_LOCATION=""\n' in configlines: 350 configlines.remove('BR2_LINUX_KERNEL_CUSTOM_TARBALL=y\n') 351 configlines.append('BR2_LINUX_KERNEL_LATEST_VERSION=y\n') 352 configlines.remove('BR2_LINUX_KERNEL_CUSTOM_TARBALL_LOCATION=""\n') 353 354 if 'BR2_LINUX_KERNEL=y\n' in configlines and \ 355 'BR2_LINUX_KERNEL_CUSTOM_VERSION=y\n' in configlines and \ 356 'BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE=""\n' in configlines: 357 configlines.remove('BR2_LINUX_KERNEL_CUSTOM_VERSION=y\n') 358 configlines.append('BR2_LINUX_KERNEL_LATEST_VERSION=y\n') 359 configlines.remove('BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE=""\n') 360 361 if 'BR2_LINUX_KERNEL=y\n' in configlines and \ 362 'BR2_LINUX_KERNEL_DTS_SUPPORT=y\n' in configlines and \ 363 'BR2_LINUX_KERNEL_INTREE_DTS_NAME=""\n' in configlines and \ 364 'BR2_LINUX_KERNEL_CUSTOM_DTS_PATH=""\n' in configlines: 365 configlines.remove('BR2_LINUX_KERNEL_DTS_SUPPORT=y\n') 366 configlines.remove('BR2_LINUX_KERNEL_INTREE_DTS_NAME=""\n') 367 configlines.remove('BR2_LINUX_KERNEL_CUSTOM_DTS_PATH=""\n') 368 if 'BR2_LINUX_KERNEL_APPENDED_UIMAGE=y\n' in configlines: 369 configlines.remove('BR2_LINUX_KERNEL_APPENDED_UIMAGE=y\n') 370 configlines.append('BR2_LINUX_KERNEL_UIMAGE=y\n') 371 if 'BR2_LINUX_KERNEL_APPENDED_ZIMAGE=y\n' in configlines: 372 configlines.remove('BR2_LINUX_KERNEL_APPENDED_ZIMAGE=y\n') 373 configlines.append('BR2_LINUX_KERNEL_ZIMAGE=y\n') 374 if 'BR2_LINUX_KERNEL_CUIMAGE=y\n' in configlines: 375 configlines.remove('BR2_LINUX_KERNEL_CUIMAGE=y\n') 376 configlines.append('BR2_LINUX_KERNEL_UIMAGE=y\n') 377 if 'BR2_LINUX_KERNEL_SIMPLEIMAGE=y\n' in configlines: 378 configlines.remove('BR2_LINUX_KERNEL_SIMPLEIMAGE=y\n') 379 configlines.append('BR2_LINUX_KERNEL_VMLINUX=y\n') 380 381 if 'BR2_LINUX_KERNEL_EXT_AUFS=y\n' in configlines and \ 382 'BR2_LINUX_KERNEL_EXT_AUFS_VERSION=""\n' in configlines: 383 configlines.remove('BR2_LINUX_KERNEL_EXT_AUFS=y\n') 384 configlines.remove('BR2_LINUX_KERNEL_EXT_AUFS_VERSION=""\n') 385 386 if 'BR2_PACKAGE_LINUX_BACKPORTS=y\n' in configlines and \ 387 'BR2_PACKAGE_LINUX_BACKPORTS_USE_CUSTOM_CONFIG=y\n' in configlines and \ 388 'BR2_PACKAGE_LINUX_BACKPORTS_CUSTOM_CONFIG_FILE=""\n' in configlines: 389 configlines.remove('BR2_PACKAGE_LINUX_BACKPORTS=y\n') 390 configlines.remove('BR2_PACKAGE_LINUX_BACKPORTS_USE_CUSTOM_CONFIG=y\n') 391 configlines.remove('BR2_PACKAGE_LINUX_BACKPORTS_CUSTOM_CONFIG_FILE=""\n') 392 393 if 'BR2_PACKAGE_LINUX_BACKPORTS=y\n' in configlines and \ 394 'BR2_PACKAGE_LINUX_BACKPORTS_USE_DEFCONFIG=y\n' in configlines and \ 395 'BR2_PACKAGE_LINUX_BACKPORTS_DEFCONFIG=""\n' in configlines: 396 configlines.remove('BR2_PACKAGE_LINUX_BACKPORTS=y\n') 397 configlines.remove('BR2_PACKAGE_LINUX_BACKPORTS_USE_DEFCONFIG=y\n') 398 configlines.remove('BR2_PACKAGE_LINUX_BACKPORTS_DEFCONFIG=""\n') 399 400 if 'BR2_KERNEL_HEADERS_VERSION=y\n' in configlines and \ 401 'BR2_DEFAULT_KERNEL_VERSION=""\n' in configlines: 402 configlines.remove('BR2_KERNEL_HEADERS_VERSION=y\n') 403 configlines.remove('BR2_DEFAULT_KERNEL_VERSION=""\n') 404 405 if 'BR2_KERNEL_HEADERS_CUSTOM_GIT=y\n' in configlines and \ 406 'BR2_KERNEL_HEADERS_CUSTOM_REPO_URL=""\n': 407 configlines.remove('BR2_KERNEL_HEADERS_CUSTOM_GIT=y\n') 408 configlines.remove('BR2_KERNEL_HEADERS_CUSTOM_REPO_URL=""\n') 409 410 if 'BR2_KERNEL_HEADERS_CUSTOM_TARBALL=y\n' in configlines and \ 411 'BR2_KERNEL_HEADERS_CUSTOM_TARBALL_LOCATION=""\n' in configlines: 412 configlines.remove('BR2_KERNEL_HEADERS_CUSTOM_TARBALL=y\n') 413 configlines.remove('BR2_KERNEL_HEADERS_CUSTOM_TARBALL_LOCATION=""\n') 414 415 if 'BR2_TARGET_ARM_TRUSTED_FIRMWARE=y\n' in configlines and \ 416 'BR2_TARGET_ARM_TRUSTED_FIRMWARE_PLATFORM=""\n' in configlines: 417 return False 418 419 if 'BR2_TARGET_ARM_TRUSTED_FIRMWARE=y\n' in configlines and \ 420 'BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_VERSION=y\n' in configlines and \ 421 'BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_VERSION_VALUE=""\n' in configlines: 422 configlines.remove('BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_VERSION=y\n') 423 configlines.append('BR2_TARGET_ARM_TRUSTED_FIRMWARE_LATEST_VERSION=y\n') 424 configlines.remove('BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_VERSION_VALUE=""\n') 425 426 if 'BR2_TARGET_ARM_TRUSTED_FIRMWARE=y\n' in configlines and \ 427 'BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_TARBALL=y\n' in configlines and \ 428 'BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_TARBALL_LOCATION=""\n' in configlines: 429 configlines.remove('BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_TARBALL=y\n') 430 configlines.append('BR2_TARGET_ARM_TRUSTED_FIRMWARE_LATEST_VERSION=y\n') 431 configlines.remove('BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_TARBALL_LOCATION=""\n') 432 433 if 'BR2_TARGET_ARM_TRUSTED_FIRMWARE=y\n' in configlines and \ 434 'BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_GIT=y\n' in configlines and \ 435 'BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_REPO_URL=""\n' in configlines: 436 configlines.remove('BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_GIT=y\n') 437 configlines.append('BR2_TARGET_ARM_TRUSTED_FIRMWARE_LATEST_VERSION=y\n') 438 configlines.remove('BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_REPO_URL=""\n') 439 440 if 'BR2_TARGET_AT91BOOTSTRAP3=y\n' in configlines and \ 441 'BR2_TARGET_AT91BOOTSTRAP3_DEFCONFIG=""\n' in configlines: 442 configlines.remove('BR2_TARGET_AT91BOOTSTRAP3=y\n') 443 configlines.remove('BR2_TARGET_AT91BOOTSTRAP3_DEFCONFIG=""\n') 444 445 if 'BR2_TARGET_BAREBOX=y\n' in configlines and \ 446 'BR2_TARGET_BAREBOX_USE_CUSTOM_CONFIG=y\n' in configlines and \ 447 'BR2_TARGET_BAREBOX_CUSTOM_CONFIG_FILE=""\n' in configlines: 448 configlines.remove('BR2_TARGET_BAREBOX=y\n') 449 configlines.remove('BR2_TARGET_BAREBOX_USE_CUSTOM_CONFIG=y\n') 450 configlines.remove('BR2_TARGET_BAREBOX_CUSTOM_CONFIG_FILE=""\n') 451 452 if 'BR2_TARGET_BAREBOX=y\n' in configlines and \ 453 'BR2_TARGET_BAREBOX_USE_DEFCONFIG=y\n' in configlines and \ 454 'BR2_TARGET_BAREBOX_BOARD_DEFCONFIG=""\n' in configlines: 455 configlines.remove('BR2_TARGET_BAREBOX=y\n') 456 configlines.remove('BR2_TARGET_BAREBOX_USE_DEFCONFIG=y\n') 457 configlines.remove('BR2_TARGET_BAREBOX_BOARD_DEFCONFIG=""\n') 458 459 if 'BR2_TARGET_BOOT_WRAPPER_AARCH64=y\n' in configlines and \ 460 'BR2_TARGET_BOOT_WRAPPER_AARCH64_DTS=""\n' in configlines: 461 return False 462 463 if 'BR2_TARGET_OPTEE_OS=y\n' in configlines and \ 464 'BR2_TARGET_OPTEE_OS_CUSTOM_TARBALL=y\n' in configlines and \ 465 'BR2_TARGET_OPTEE_OS_CUSTOM_TARBALL_LOCATION=""\n' in configlines: 466 configlines.remove('BR2_TARGET_OPTEE_OS_CUSTOM_TARBALL=y\n') 467 configlines.append('BR2_TARGET_OPTEE_OS_LATEST=y\n') 468 configlines.remove('BR2_TARGET_OPTEE_OS_CUSTOM_TARBALL_LOCATION=""\n') 469 470 if 'BR2_TARGET_OPTEE_OS=y\n' in configlines and \ 471 'BR2_TARGET_OPTEE_OS_PLATFORM=""\n' in configlines: 472 configlines.remove('BR2_TARGET_OPTEE_OS=y\n') 473 configlines.remove('BR2_TARGET_OPTEE_OS_PLATFORM=""\n') 474 475 if 'BR2_TARGET_ROOTFS_CRAMFS=y\n' in configlines: 476 configlines.remove('BR2_TARGET_ROOTFS_CRAMFS=y\n') 477 478 if 'BR2_TARGET_ROOTFS_EXT2=y\n' in configlines and \ 479 'BR2_TARGET_ROOTFS_EXT2_SIZE="60M"\n' in configlines: 480 configlines.remove('BR2_TARGET_ROOTFS_EXT2_SIZE="60M"\n') 481 configlines.append('BR2_TARGET_ROOTFS_EXT2_SIZE="%s"\n' % ROOTFS_SIZE) 482 483 if 'BR2_TARGET_ROOTFS_F2FS=y\n' in configlines and \ 484 'BR2_TARGET_ROOTFS_F2FS_SIZE="100M"\n' in configlines: 485 configlines.remove('BR2_TARGET_ROOTFS_F2FS_SIZE="100M"\n') 486 configlines.append('BR2_TARGET_ROOTFS_F2FS_SIZE="%s"\n' % ROOTFS_SIZE) 487 488 if 'BR2_TARGET_ROOTFS_UBIFS=y\n' in configlines and \ 489 'BR2_TARGET_ROOTFS_UBIFS_MAXLEBCNT=2048\n' in configlines: 490 configlines.remove('BR2_TARGET_ROOTFS_UBIFS_MAXLEBCNT=2048\n') 491 configlines.append('BR2_TARGET_ROOTFS_UBIFS_MAXLEBCNT=41610\n') 492 493 if 'BR2_TARGET_ROOTFS_UBI=y\n' in configlines and \ 494 'BR2_TARGET_ROOTFS_UBI_USE_CUSTOM_CONFIG=y\n' in configlines and \ 495 'BR2_TARGET_ROOTFS_UBI_CUSTOM_CONFIG_FILE=""\n' in configlines: 496 configlines.remove('BR2_TARGET_ROOTFS_UBI_USE_CUSTOM_CONFIG=y\n') 497 configlines.remove('BR2_TARGET_ROOTFS_UBI_CUSTOM_CONFIG_FILE=""\n') 498 499 if 'BR2_TARGET_S500_BOOTLOADER=y\n' in configlines and \ 500 'BR2_TARGET_S500_BOOTLOADER_BOARD=""\n' in configlines: 501 configlines.remove('BR2_TARGET_S500_BOOTLOADER=y\n') 502 configlines.remove('BR2_TARGET_S500_BOOTLOADER_BOARD=""\n') 503 504 if 'BR2_TARGET_TI_K3_R5_LOADER=y\n' in configlines and \ 505 'BR2_TARGET_TI_K3_R5_LOADER_USE_DEFCONFIG=y\n' in configlines and \ 506 'BR2_TARGET_TI_K3_R5_LOADER_BOARD_DEFCONFIG=""\n' in configlines: 507 return False 508 509 if 'BR2_TARGET_UBOOT=y\n' in configlines and \ 510 'BR2_TARGET_UBOOT_BUILD_SYSTEM_KCONFIG=y\n' in configlines and \ 511 'BR2_TARGET_UBOOT_USE_CUSTOM_CONFIG=y\n' in configlines and \ 512 'BR2_TARGET_UBOOT_CUSTOM_CONFIG_FILE=""\n' in configlines: 513 configlines.remove('BR2_TARGET_UBOOT=y\n') 514 configlines.remove('BR2_TARGET_UBOOT_BUILD_SYSTEM_KCONFIG=y\n') 515 configlines.remove('BR2_TARGET_UBOOT_USE_CUSTOM_CONFIG=y\n') 516 configlines.remove('BR2_TARGET_UBOOT_CUSTOM_CONFIG_FILE=""\n') 517 518 if 'BR2_TARGET_UBOOT=y\n' in configlines and \ 519 'BR2_TARGET_UBOOT_BUILD_SYSTEM_KCONFIG=y\n' in configlines and \ 520 'BR2_TARGET_UBOOT_USE_DEFCONFIG=y\n' in configlines and \ 521 'BR2_TARGET_UBOOT_BOARD_DEFCONFIG=""\n' in configlines: 522 configlines.remove('BR2_TARGET_UBOOT=y\n') 523 configlines.remove('BR2_TARGET_UBOOT_BUILD_SYSTEM_KCONFIG=y\n') 524 configlines.remove('BR2_TARGET_UBOOT_USE_DEFCONFIG=y\n') 525 configlines.remove('BR2_TARGET_UBOOT_BOARD_DEFCONFIG=""\n') 526 527 if 'BR2_TARGET_UBOOT=y\n' in configlines and \ 528 'BR2_TARGET_UBOOT_BUILD_SYSTEM_LEGACY=y\n' in configlines and \ 529 'BR2_TARGET_UBOOT_BOARDNAME=""\n' in configlines: 530 configlines.remove('BR2_TARGET_UBOOT=y\n') 531 configlines.remove('BR2_TARGET_UBOOT_BUILD_SYSTEM_LEGACY=y\n') 532 configlines.remove('BR2_TARGET_UBOOT_BOARDNAME=""\n') 533 534 if 'BR2_TOOLCHAIN_EXTERNAL=y\n' in configlines and \ 535 'BR2_TOOLCHAIN_EXTERNAL_PREINSTALLED=y\n' in configlines and \ 536 'BR2_TOOLCHAIN_EXTERNAL_PATH=""\n' in configlines: 537 configlines.remove('BR2_TOOLCHAIN_EXTERNAL=y\n') 538 configlines.remove('BR2_TOOLCHAIN_EXTERNAL_PREINSTALLED=y\n') 539 configlines.remove('BR2_TOOLCHAIN_EXTERNAL_PATH=""\n') 540 if 'BR2_ARCH_HAS_NO_TOOLCHAIN_BUILDROOT=y\n' in configlines: 541 return False 542 543 if 'BR2_TOOLCHAIN_EXTERNAL=y\n' in configlines and \ 544 'BR2_TOOLCHAIN_EXTERNAL_CUSTOM=y\n' in configlines and \ 545 'BR2_TOOLCHAIN_EXTERNAL_DOWNLOAD=y\n' in configlines and \ 546 'BR2_TOOLCHAIN_EXTERNAL_URL=""\n' in configlines: 547 configlines.remove('BR2_TOOLCHAIN_EXTERNAL=y\n') 548 configlines.remove('BR2_TOOLCHAIN_EXTERNAL_CUSTOM=y\n') 549 configlines.remove('BR2_TOOLCHAIN_EXTERNAL_DOWNLOAD=y\n') 550 configlines.remove('BR2_TOOLCHAIN_EXTERNAL_URL=""\n') 551 if 'BR2_ARCH_HAS_NO_TOOLCHAIN_BUILDROOT=y\n' in configlines: 552 return False 553 554 if 'BR2_TARGET_MXS_BOOTLETS=y\n' in configlines and \ 555 'BR2_TARGET_MXS_BOOTLETS_CUSTOM_BOARD=y\n' in configlines and \ 556 'BR2_TARGET_MXS_BOOTLETS_CUSTOM_BOARD_NAME=""\n' in configlines: 557 configlines.remove('BR2_TARGET_MXS_BOOTLETS_CUSTOM_BOARD=y\n') 558 configlines.append('BR2_TARGET_MXS_BOOTLETS_STMP37xx=y\n') 559 configlines.remove('BR2_TARGET_MXS_BOOTLETS_CUSTOM_BOARD_NAME=""\n') 560 561 if 'BR2_TARGET_MXS_BOOTLETS=y\n' in configlines and \ 562 'BR2_TARGET_MXS_BOOTLETS_CUSTOM_GIT=y\n' in configlines and \ 563 'BR2_TARGET_MXS_BOOTLETS_CUSTOM_GIT_URL=""\n' in configlines: 564 configlines.remove('BR2_TARGET_MXS_BOOTLETS_CUSTOM_GIT=y\n') 565 configlines.append('BR2_TARGET_MXS_BOOTLETS_FREESCALE=y\n') 566 configlines.remove('BR2_TARGET_MXS_BOOTLETS_CUSTOM_GIT_URL=""\n') 567 568 if 'BR2_TARGET_MXS_BOOTLETS=y\n' in configlines and \ 569 'BR2_TARGET_MXS_BOOTLETS_CUSTOM_TARBALL=y\n' in configlines and \ 570 'BR2_TARGET_MXS_BOOTLETS_CUSTOM_TARBALL_URL=""\n' in configlines: 571 configlines.remove('BR2_TARGET_MXS_BOOTLETS_CUSTOM_TARBALL=y\n') 572 configlines.append('BR2_TARGET_MXS_BOOTLETS_FREESCALE=y\n') 573 configlines.remove('BR2_TARGET_MXS_BOOTLETS_CUSTOM_TARBALL_URL=""\n') 574 575 if 'BR2_TARGET_OPENSBI=y\n' in configlines and \ 576 'BR2_TARGET_OPENSBI_CUSTOM_GIT=y\n' in configlines and \ 577 'BR2_TARGET_OPENSBI_CUSTOM_REPO_URL=""\n' in configlines: 578 configlines.remove('BR2_TARGET_OPENSBI_CUSTOM_GIT=y\n') 579 configlines.append('BR2_TARGET_OPENSBI_LATEST_VERSION=y\n') 580 configlines.remove('BR2_TARGET_OPENSBI_CUSTOM_REPO_URL=""\n') 581 582 if 'BR2_TARGET_OPENSBI=y\n' in configlines and \ 583 'BR2_TARGET_OPENSBI_CUSTOM_TARBALL=y\n' in configlines and \ 584 'BR2_TARGET_OPENSBI_CUSTOM_TARBALL_LOCATION=""\n' in configlines: 585 configlines.remove('BR2_TARGET_OPENSBI_CUSTOM_TARBALL=y\n') 586 configlines.append('BR2_TARGET_OPENSBI_LATEST_VERSION=y\n') 587 configlines.remove('BR2_TARGET_OPENSBI_CUSTOM_TARBALL_LOCATION=""\n') 588 589 if 'BR2_TARGET_OPENSBI=y\n' in configlines and \ 590 'BR2_TARGET_OPENSBI_CUSTOM_VERSION=y\n' in configlines and \ 591 'BR2_TARGET_OPENSBI_CUSTOM_VERSION_VALUE=""\n' in configlines: 592 configlines.remove('BR2_TARGET_OPENSBI_CUSTOM_VERSION=y\n') 593 configlines.append('BR2_TARGET_OPENSBI_LATEST_VERSION=y\n') 594 configlines.remove('BR2_TARGET_OPENSBI_CUSTOM_VERSION_VALUE=""\n') 595 596 if 'BR2_PACKAGE_REFPOLICY=y\n' in configlines and \ 597 'BR2_PACKAGE_REFPOLICY_CUSTOM_GIT=y\n' in configlines and \ 598 'BR2_PACKAGE_REFPOLICY_CUSTOM_REPO_URL=""\n' in configlines: 599 configlines.remove('BR2_PACKAGE_REFPOLICY_CUSTOM_GIT=y\n') 600 configlines.append('BR2_PACKAGE_REFPOLICY_UPSTREAM_VERSION=y\n') 601 configlines.remove('BR2_PACKAGE_REFPOLICY_CUSTOM_REPO_URL=""\n') 602 603 if 'BR2_PACKAGE_XENOMAI=y\n' in configlines and \ 604 'BR2_PACKAGE_XENOMAI_CUSTOM_GIT=y\n' in configlines and \ 605 'BR2_PACKAGE_XENOMAI_REPOSITORY=""\n' in configlines: 606 configlines.remove('BR2_PACKAGE_XENOMAI_CUSTOM_GIT=y\n') 607 configlines.append('BR2_PACKAGE_XENOMAI_LATEST_VERSION=y\n') 608 configlines.remove('BR2_PACKAGE_XENOMAI_REPOSITORY=""\n') 609 610 if 'BR2_PACKAGE_XENOMAI=y\n' in configlines and \ 611 'BR2_PACKAGE_XENOMAI_CUSTOM_TARBALL=y\n' in configlines and \ 612 'BR2_PACKAGE_XENOMAI_CUSTOM_TARBALL_URL=""\n' in configlines: 613 configlines.remove('BR2_PACKAGE_XENOMAI_CUSTOM_TARBALL=y\n') 614 configlines.append('BR2_PACKAGE_XENOMAI_LATEST_VERSION=y\n') 615 configlines.remove('BR2_PACKAGE_XENOMAI_CUSTOM_TARBALL_URL=""\n') 616 617 if 'BR2_PACKAGE_XENOMAI=y\n' in configlines and \ 618 'BR2_PACKAGE_XENOMAI_CUSTOM_VERSION=y\n' in configlines and \ 619 'BR2_PACKAGE_XENOMAI_CUSTOM_VERSION_VALUE=""\n' in configlines: 620 configlines.remove('BR2_PACKAGE_XENOMAI_CUSTOM_VERSION=y\n') 621 configlines.append('BR2_PACKAGE_XENOMAI_LATEST_VERSION=y\n') 622 configlines.remove('BR2_PACKAGE_XENOMAI_CUSTOM_VERSION_VALUE=""\n') 623 624 if 'BR2_PACKAGE_XVISOR=y\n' in configlines and \ 625 'BR2_PACKAGE_XVISOR_USE_CUSTOM_CONFIG=y\n' in configlines and \ 626 'BR2_PACKAGE_XVISOR_CUSTOM_CONFIG_FILE=""\n' in configlines: 627 configlines.remove('BR2_PACKAGE_XVISOR_USE_CUSTOM_CONFIG=y\n') 628 configlines.append('BR2_PACKAGE_XVISOR_USE_DEFCONFIG=y\n') 629 configlines.remove('BR2_PACKAGE_XVISOR_CUSTOM_CONFIG_FILE=""\n') 630 631 # Don't build igh-ethercat driver as they are highly 632 # kernel-version specific 633 for opt in ['8139TOO', 'E100', 'E1000', 'E1000E', 'R8169']: 634 optstr = 'BR2_PACKAGE_IGH_ETHERCAT_%s=y\n' % opt 635 if optstr in configlines: 636 configlines.remove(optstr) 637 638 with open(configfile, "w+") as configf: 639 configf.writelines(configlines) 640 641 return True 642 643 644async def gen_config(args): 645 """Generate a new random configuration 646 647 This function generates the configuration, by choosing a random 648 toolchain configuration and then generating a random selection of 649 packages. 650 """ 651 652 sysinfo = SystemInfo() 653 654 if args.toolchains_csv: 655 # Select a random toolchain configuration 656 configs = get_toolchain_configs(args.toolchains_csv, args.buildrootdir) 657 658 i = randint(0, len(configs) - 1) 659 toolchainconfig = configs[i] 660 else: 661 toolchainconfig = [] 662 663 configlines = list(toolchainconfig) 664 665 # Combine with the minimal configuration 666 minimalconfigfile = os.path.join(args.buildrootdir, 667 'support/config-fragments/minimal.config') 668 with open(minimalconfigfile) as minimalf: 669 configlines += minimalf.readlines() 670 671 # Allow hosts with old certificates to download over https 672 configlines.append("BR2_WGET=\"wget --passive-ftp -nd -t 3 --no-check-certificate\"\n") 673 674 # Per-package folder 675 if randint(0, 15) == 0: 676 configlines.append("BR2_PER_PACKAGE_DIRECTORIES=y\n") 677 678 # Amend the configuration with a few things. 679 if randint(0, 20) == 0: 680 configlines.append("BR2_ENABLE_DEBUG=y\n") 681 if randint(0, 20) == 0: 682 configlines.append("BR2_ENABLE_RUNTIME_DEBUG=y\n") 683 if randint(0, 1) == 0: 684 configlines.append("BR2_INIT_BUSYBOX=y\n") 685 elif randint(0, 15) == 0: 686 configlines.append("BR2_INIT_SYSTEMD=y\n") 687 elif randint(0, 10) == 0: 688 configlines.append("BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_EUDEV=y\n") 689 if randint(0, 20) == 0: 690 configlines.append("BR2_STATIC_LIBS=y\n") 691 if randint(0, 20) == 0: 692 configlines.append("BR2_PACKAGE_PYTHON3_PY_ONLY=y\n") 693 if randint(0, 5) == 0: 694 configlines.append("BR2_OPTIMIZE_2=y\n") 695 if randint(0, 4) == 0: 696 configlines.append("BR2_SYSTEM_ENABLE_NLS=y\n") 697 if randint(0, 4) == 0: 698 configlines.append("BR2_FORTIFY_SOURCE_2=y\n") 699 700 # Randomly enable BR2_REPRODUCIBLE 10% of times 701 # also enable tar filesystem images for testing 702 if await sysinfo.has("diffoscope") and randint(0, 10) == 0: 703 configlines.append("BR2_REPRODUCIBLE=y\n") 704 configlines.append("BR2_TARGET_ROOTFS_TAR=y\n") 705 706 # Write out the configuration file 707 if not os.path.exists(args.outputdir): 708 os.makedirs(args.outputdir) 709 if args.outputdir == os.path.abspath(os.path.join(args.buildrootdir, "output")): 710 configfile = os.path.join(args.buildrootdir, ".config") 711 else: 712 configfile = os.path.join(args.outputdir, ".config") 713 with open(configfile, "w+") as configf: 714 configf.writelines(configlines) 715 716 proc = await asyncio.create_subprocess_exec( 717 "make", "O=%s" % args.outputdir, "-C", args.buildrootdir, "olddefconfig") 718 ret = await proc.wait() 719 if ret: 720 return ret 721 722 if not await is_toolchain_usable(configfile, toolchainconfig): 723 return 2 724 725 # Now, generate the random selection of packages, and fixup 726 # things if needed. 727 # Safe-guard, in case we can not quickly come to a valid 728 # configuration: allow at most 100 (arbitrary) iterations. 729 bounded_loop = 100 730 while True: 731 if bounded_loop == 0: 732 print("ERROR: cannot generate random configuration after 100 iterations", 733 file=sys.stderr) 734 return 1 735 bounded_loop -= 1 736 proc = await asyncio.create_subprocess_exec( 737 "make", "O=%s" % args.outputdir, "-C", args.buildrootdir, 738 "KCONFIG_SEED=0x%s" % hexlify(os.urandom(4)).decode("ascii").upper(), 739 "KCONFIG_PROBABILITY=%d" % randint(1, 20), 740 "randpackageconfig" if args.toolchains_csv else "randconfig") 741 ret = await proc.wait() 742 if ret: 743 return ret 744 745 if await fixup_config(sysinfo, configfile): 746 break 747 748 proc = await asyncio.create_subprocess_exec( 749 "make", "O=%s" % args.outputdir, "-C", args.buildrootdir, "olddefconfig") 750 ret = await proc.wait() 751 if ret: 752 return ret 753 754 proc = await asyncio.create_subprocess_exec( 755 "make", "O=%s" % args.outputdir, "-C", args.buildrootdir, "savedefconfig") 756 ret = await proc.wait() 757 if ret: 758 return ret 759 760 proc = await asyncio.create_subprocess_exec( 761 "make", "O=%s" % args.outputdir, "-C", args.buildrootdir, "dependencies") 762 return await proc.wait() 763 764 765if __name__ == '__main__': 766 import argparse 767 parser = argparse.ArgumentParser(description="Generate a random configuration") 768 parser.add_argument("--outputdir", "-o", 769 help="Output directory (relative to current directory)", 770 type=str, default='output') 771 parser.add_argument("--buildrootdir", "-b", 772 help="Buildroot directory (relative to current directory)", 773 type=str, default='.') 774 775 toolchains_csv = parser.add_mutually_exclusive_group(required=False) 776 toolchains_csv.add_argument("--toolchains-csv", 777 dest="toolchains_csv", 778 help="Path of the toolchain configuration file", 779 type=str) 780 toolchains_csv.add_argument("--no-toolchains-csv", 781 dest="toolchains_csv", 782 help="Generate random toolchain configuration", 783 action='store_false') 784 parser.set_defaults(toolchains_csv="support/config-fragments/autobuild/toolchain-configs.csv") 785 786 args = parser.parse_args() 787 788 # We need the absolute path to use with O=, because the relative 789 # path to the output directory here is not relative to the 790 # Buildroot sources, but to the current directory. 791 args.outputdir = os.path.abspath(args.outputdir) 792 793 try: 794 if sys.version_info < (3, 7): 795 loop = asyncio.get_event_loop() 796 ret = loop.run_until_complete(gen_config(args)) 797 else: 798 ret = asyncio.run(gen_config(args)) 799 except Exception: 800 traceback.print_exc() 801 parser.exit(1) 802 parser.exit(ret) 803