linuxOS_D21X/tools/scripts/del_board.py
2024-11-29 16:33:21 +08:00

328 lines
9.9 KiB
Python
Executable File

#!/usr/bin/env python3
# SPDX-License-Identifier: Apache-2.0
# Copyright (C) 2023-2024 ArtInChip
import os
import sys
import argparse
import subprocess
UBOOT_DIR = 'source/uboot-2021.10/'
LINUX_DIR = ''
def GetLinuxDir(args):
global LINUX_DIR
dirs = os.listdir(args.topdir + '/source')
for sub_dir in dirs:
if 'linux' in sub_dir:
LINUX_DIR = 'source/' + sub_dir + '/'
def RunCommand(cmd, dumpmsg=False, verbose=False):
"""Execute command
Args:
cmd: cmd line content
dumpmsg: display message during cmd execute
Return:
0 if success, -1 if failure.
"""
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=-1)
ret = p.wait()
if ret != 0:
print('Run commmand error:')
print(' ' + cmd)
print('stdout: {}\nstderr: {}'.format(p.stdout.read(), p.stderr.read()))
return -1
if verbose:
print(cmd)
if dumpmsg or verbose:
print(p.stdout.read())
if verbose:
print(p.stderr.read())
return 0
def RunShellCommand(cmd):
ret = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if ret.returncode:
print(indent_str('Failed to run shell command:' + cmd, 1))
sys.exit(1)
return str(ret.stdout, encoding='utf-8')
def indent_str(text, indent):
itext = text
while indent > 0:
itext = '\t' + itext
indent -= 1
return itext
def GetReferenceBoardDefconfig(targetcfg):
cmd = 'find {} -maxdepth 1 -type f -name "*_defconfig"'.format(targetcfg)
defconfigs = RunShellCommand(cmd)
return defconfigs.split()
def GetChipNameOfDefconfig(dotcfg):
f = open(dotcfg, 'r')
lines = f.readlines()
f.close()
name = None
for ln in lines:
if 'LUBAN_CHIP_NAME' in ln:
name = ln.replace('LUBAN_CHIP_NAME=', '').replace('"', '').strip()
break
return name
def GetChipOptionOfDefconfig(dotcfg, chip):
f = open(dotcfg, 'r')
lines = f.readlines()
f.close()
name = None
for ln in lines:
if 'LUBAN_CHIP_{}'.format(chip.upper()) in ln and '=y' in ln:
name = ln.replace('=y', '').strip()
break
return name
def GetBoardNameOfDefconfig(dotcfg):
f = open(dotcfg, 'r')
lines = f.readlines()
f.close()
name = None
for ln in lines:
if 'LUBAN_BOARD_NAME' in ln:
name = ln.replace('LUBAN_BOARD_NAME=', '').replace('"', '').strip()
break
return name
def GetBoardOptionNameOfDefconfig(dotcfg, board_name):
f = open(dotcfg, 'r')
lines = f.readlines()
f.close()
opt_name = None
for ln in lines:
if 'LUBAN_BOARD_' in ln and board_name.upper() in ln and '=y' in ln:
opt_name = ln.replace('=y', '').strip()
break
return opt_name
def GetArchOfRefDefconfig(dotcfg):
f = open(dotcfg, 'r')
lines = f.readlines()
f.close()
name = None
for ln in lines:
if 'BR2_ARCH=' in ln:
name = ln.replace('BR2_ARCH=', '').replace('"', '').strip()
break
return name
def SelectReferenceDefconfig(defconfigs, dotconfigs):
reflist = []
for cfg in defconfigs:
for dotcfg in dotconfigs:
if os.path.basename(cfg) in dotcfg:
break
reflist.append(os.path.basename(cfg))
if len(reflist) == 0:
print(indent_str('Error, cannot find reference defconfig', 1))
sys.exit(1)
print(indent_str('Reference defconfig:(Delete one board base on selected defconfig)', 1))
num = 1
for ref in reflist:
print(indent_str('{}: {}'.format(num, ref), 2))
num += 1
inputstr = input(indent_str('Select reference defconfig for detele board(number): ', 1)).strip()
if inputstr.isdigit() == False:
print(indent_str('Error, please input number'), 1)
sys.exit(1)
num = int(inputstr)
if num not in range(1, len(reflist) + 1):
print(indent_str('Error, input number not in list', 1))
sys.exit(1)
selected = reflist[num - 1]
print(indent_str(selected + '\n', 2))
return selected
def GetBoardNameForConfig(name):
return name.replace('\t', '_').replace(' ', '_')
def GenDotConfig(args, cfg_list):
root_cfg = args.topdir + 'package/Config.in'
dotconfigs = []
tmpdir = os.path.dirname(args.conf) + '/tmp/'
cmd = 'rm -rf {} && mkdir -p {}'.format(tmpdir, tmpdir)
RunShellCommand(cmd)
for cfg in cfg_list:
dotcfg = tmpdir + os.path.basename(cfg) + '.config'
dotconfigs.append(dotcfg)
cmd = 'HOSTARCH={} BR2_CONFIG={} BASE_DIR={} BR2_DEFCONFIG={} {} --defconfig={} {}'.format(args.arch, dotcfg, args.outdir, cfg, args.conf, cfg, root_cfg)
RunShellCommand(cmd)
return dotconfigs
def DeleteOneBoardDirectory(topdir, refcfg, dotconfigs):
for ref_dotcfg in dotconfigs:
if refcfg in ref_dotcfg:
break
refboardname = GetBoardNameOfDefconfig(ref_dotcfg)
refchipname = GetChipNameOfDefconfig(ref_dotcfg)
refboard_dir = topdir + 'target/{}/{}'.format(refchipname, refboardname)
# copy new board directory
cmd = 'rm -rdf {}'.format(refboard_dir)
RunShellCommand(cmd)
print(indent_str('Deleted: ' + refboard_dir.replace(topdir, ''), 1))
def DeleteOneDefconfig(topdir, refcfg, dotconfigs):
global UBOOT_DIR
global LINUX_DIR
for ref_dotcfg in dotconfigs:
if refcfg in ref_dotcfg:
break
arch = GetArchOfRefDefconfig(ref_dotcfg)
refboardname = GetBoardNameOfDefconfig(ref_dotcfg)
refboard_opt = GetBoardOptionNameOfDefconfig(ref_dotcfg, refboardname)
refchipname = GetChipNameOfDefconfig(ref_dotcfg)
target_cfgdir = topdir + 'target/configs/'
f = open(target_cfgdir + refcfg, 'r')
lines = f.readlines()
f.close()
# Create U-Boot/Kernel/Busybox defconfig for new board
ref_uboot_cfg = ''
ref_linux_cfg = ''
ref_busybox_cfg = ''
for ln in lines:
if 'BR2_TARGET_UBOOT_BOARD_DEFCONFIG' in ln:
ref_uboot_cfg = ln.replace('BR2_TARGET_UBOOT_BOARD_DEFCONFIG', '').replace('=', '').replace('"', '').strip() + '_defconfig'
if 'BR2_LINUX_KERNEL_DEFCONFIG' in ln:
ref_linux_cfg = ln.replace('BR2_LINUX_KERNEL_DEFCONFIG', '').replace('=', '').replace('"', '').strip() + '_defconfig'
if 'BR2_PACKAGE_BUSYBOX_CONFIG' in ln:
ref_busybox_cfg = ln.replace('BR2_PACKAGE_BUSYBOX_CONFIG', '').replace('=', '').replace('"', '').strip()
# Delete defconfig for u-boot
refcfg_path = '{}{}configs/{}'.format(topdir, UBOOT_DIR, ref_uboot_cfg)
cmd = 'rm {}'.format(refcfg_path)
RunShellCommand(cmd)
print(indent_str('deleted: ' + refcfg_path.replace(topdir, ''), 1))
# Delete defconfig for linux kernel
if arch == 'riscv64':
arch = 'riscv'
refcfg_path = '{}{}arch/{}/configs/{}'.format(topdir, LINUX_DIR, arch, ref_linux_cfg)
cmd = 'rm {}'.format(refcfg_path)
RunShellCommand(cmd)
print(indent_str('Deleted: ' + refcfg_path.replace(topdir, ''), 1))
# Delete config for busybox
refcfg_path = '{}{}'.format(topdir, ref_busybox_cfg)
cmd = 'rm {}'.format(refcfg_path)
RunShellCommand(cmd)
print(indent_str('Deleted: ' + refcfg_path.replace(topdir, ''), 1))
# Delete SDK defconfig
refcfg_path = '{}{}'.format(target_cfgdir, refcfg)
cmd = 'rm {}'.format(refcfg_path)
RunShellCommand(cmd)
print(indent_str('Deleted: ' + refcfg_path.replace(topdir, ''), 1))
# Add new board to Config.in
cfg_in = '{}target/{}/Config.in'.format(topdir, refchipname)
f = open(cfg_in, 'r')
lines = f.readlines()
f.close()
board_option = 'LUBAN_BOARD_{}_{}'.format(refchipname.upper(), refboardname.upper())
f = open(cfg_in, 'w')
chip_option = GetChipOptionOfDefconfig(ref_dotcfg, refchipname)
delete_depends = False
for ln in lines:
if 'config' in ln and board_option in ln:
delete_depends = True
continue
if 'bool' in ln and refboardname in ln:
continue
if delete_depends and 'depends on' in ln and chip_option in ln:
delete_depends = False
continue
if 'default' in ln and board_option in ln:
continue
f.write(ln)
f.close()
print(indent_str('Updated: ' + cfg_in.replace(topdir, ''), 1))
def DeleteOneBoard(args):
GetLinuxDir(args)
target_cfgdir = args.topdir + 'target/configs/'
defconfigs = GetReferenceBoardDefconfig(target_cfgdir)
defconfigs.sort()
if len(defconfigs) == 0:
print(indent_str("Error: no defconfig is found.", 1));
sys.exit(1)
dotconfigs = GenDotConfig(args, defconfigs)
refcfg = SelectReferenceDefconfig(defconfigs, dotconfigs)
DeleteOneBoardDirectory(args.topdir, refcfg, dotconfigs)
DeleteOneDefconfig(args.topdir, refcfg, dotconfigs)
return 0
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-c", "--conf", type=str, help="conf executable")
parser.add_argument("-t", "--topdir", type=str, help="Top root directory")
parser.add_argument("-o", "--outdir", type=str, help="Output root directory")
args = parser.parse_args()
if args.conf == None:
print(indent_str('Error, please provide path of application "conf"', 1))
sys.exit(1)
if os.path.exists(args.conf) == False:
print(indent_str('Error, "conf" is not exist', 1))
sys.exit(1)
if args.topdir == None:
print(indent_str('Error, please provide path of top directory', 1))
sys.exit(1)
args.topdir = os.path.abspath(args.topdir)
if args.topdir.endswith('/') == False:
args.topdir = args.topdir + '/'
if args.outdir == None:
args.outdir = args.topdir
else:
args.outdir = os.path.abspath(args.outdir)
if args.outdir.endswith('/') == False:
args.outdir = args.outdir + '/'
cmd = 'arch'
args.arch = RunShellCommand(cmd)
DeleteOneBoard(args)