# -*- coding: utf-8 -*- """ 脚本作用: A)指定分区img转化格式 B)制作pac C)拷贝营运商信息、img、bin、xml等到out指定目录,不压缩 调用方法 python makepac.py """ import os import sys try: # python2 reload(sys) sys.setdefaultencoding('utf-8') except: # Python3 import importlib importlib.reload(sys) import filecmp import shutil import time import subprocess from csv import reader #import ConfigParser from symbols import BMConfigDir from bt_version import BT_VERSION import optparse try: # Python3 from configparser import ConfigParser except ImportError: # Python2 from ConfigParser import ConfigParser CONFIG_FILE = "pac.ini" PAC_TAR = "archive_images" partition = "partition" SIMG2IMG = "out/host/linux-x86/bin/simg2img" RENAME_IMG_LIST = [] CARRIER_LIST = [] PAC_LIST = [] NOT_PAC_LIST = [] SCRIPT_PATH = os.path.dirname(os.path.realpath(__file__)) def main(board_path): if not board_path: board_path = 'out/target/product' BOARD_PATHS = os.environ.get("OUT") if BOARD_PATHS: BOARD_target = BOARD_PATHS.split("/")[-1] board_path = board_path + "/" + BOARD_target cmd = 'find {} -maxdepth 1 -name "*.xml"'.format(board_path) output = exec_cmd(cmd) print(output) target_board_file = output.strip().split('\n') target_board_path,target_board = os.path.split(target_board_file[0]) if not target_board_path: target_board_path = board_path print("[TARGET_BOARD]:"+str(target_board_path)) restore_product(target_board_path) ##判断是否编译过ota########## is_check_ota = False native_folder = os.path.join(target_board_path, "native_backup") if os.path.exists(os.path.join(target_board_path,"make_ota_flag")): if os.path.exists(native_folder): print("copy backup img from native_backup") is_check_ota = True for img in os.listdir(native_folder): img_path = os.path.join(native_folder, img) if os.path.isfile(img_path) and os.path.splitext(img_path)[1] == ".img": if os.path.exists(os.path.join(target_board_path, img)): os.remove(os.path.join(target_board_path, img)) shutil.copy(img_path, target_board_path) else: print("not find native_backup folder") ##判断cp_sign是否存在,如果cp_sign 目录不存在也会打包### cp_sign = os.path.join(target_board_path, "cp_sign") if os.path.exists(cp_sign): carrier_product_list = [] native_product_list = [] product_list = os.listdir(cp_sign) for product in product_list: product_path = os.path.join(cp_sign, product) if os.path.isfile(product_path): continue pac_ini_path = os.path.join(product_path, "pac.ini") carrier = read_carrier(pac_ini_path) if carrier.strip(): carrier_product_list.append(product) else: native_product_list.append(product) print("=============== perl mkpac start =======================") for product in native_product_list: product_path = os.path.join(cp_sign, product) if os.path.isdir(product_path): print("*******[ap product:"+product+"]*************") backup_product(product_path) get_ap_product(product_path,target_board_path,is_check_ota) get_pac(product_path, target_board_path) for product in carrier_product_list: product_path = os.path.join(cp_sign, product) if os.path.isdir(product_path): print("*******[ap product:"+product+"]*************") get_ap_product(product_path,target_board_path,is_check_ota) get_pac(product_path, target_board_path) print("pac list:[") if len(PAC_LIST): for pac in PAC_LIST: print(pac+" [PASS]") if len(NOT_PAC_LIST): for pac_fail in NOT_PAC_LIST: print(pac_fail+" [FAIL]") print("]") print("=============== perl mkpac end =========================") else: print("not find cp_sign") ###########copy tar############# restore_product(target_board_path) print("tart copy *img *bin etc") copy_tar(target_board_path) ###########rename spase image####### print("unsparse list:") print(RENAME_IMG_LIST) if len(RENAME_IMG_LIST): for rename_img in RENAME_IMG_LIST: print("rename_img:"+rename_img) if not os.path.exists(rename_img): print("not find "+rename_img) continue image_path,image_name = os.path.split(rename_img) new_img_name = image_name[5:] new_img_path = os.path.join(image_path, new_img_name) if os.path.exists(new_img_path): os.remove(new_img_path) os.rename(rename_img, new_img_path) else: print("not unsparse image") restore_product(target_board_path) def backup_product(product_path): pac_ini_path = os.path.join(product_path, "pac.ini") product_value = get_carrier_partition(pac_ini_path) if not product_value.strip(): print("not find product partition") return product_img_name = product_value.split('/')[-1] product_img_path_tmp ='/'.join(product_value.split('/')[:-1]) filename_new = "MAKEPAC-" + product_img_name if not os.path.exists(os.path.join(product_img_path_tmp, filename_new)): print("=====backup_product=====:"+str(product_path)) shutil.copy(product_value, os.path.join(product_img_path_tmp, filename_new)) def restore_product(target_board_path): print("rename TEMP- and MAKEPAC-") file_list = os.listdir(target_board_path) for file in file_list: file_path = os.path.join(target_board_path, file) if os.path.isfile(file_path): if file.startswith("MAKEPAC-"): print("rename MAKEPAC- file:"+file) new_file_name = file[8:] if os.path.exists(os.path.join(target_board_path, new_file_name)): os.remove(os.path.join(target_board_path, new_file_name)) os.rename(os.path.join(target_board_path, file), os.path.join(target_board_path, new_file_name)) elif file.startswith("TEMP-"): print("rename TEMP- file:"+file) new_file_name = file[5:] if os.path.exists(os.path.join(target_board_path, new_file_name)): os.remove(os.path.join(target_board_path, new_file_name)) os.rename(os.path.join(target_board_path, file), os.path.join(target_board_path, new_file_name)) def copy_tar(target_board_path): if os.path.exists(os.path.join(target_board_path, "repac")): print("repac,no need create archive_images") return imges_folder = os.path.join(target_board_path, PAC_TAR) if os.path.exists(imges_folder): shutil.rmtree(imges_folder,True) os.mkdir(imges_folder) current_pwd = os.getcwd() os.chdir(target_board_path) tar_cmd = 'find . -maxdepth 1 -name "*.img" -o -name "*.bin" -o -name "*.xml" -o -name "installed-files.txt" -o -name "PRODUCT_SECURE_BOOT_SPRD" | awk -F "/" \'{print$2}\'' output = os.popen(tar_cmd) image_list = output.read().strip().replace('\n',',').split(',') os.chdir(current_pwd) if len(image_list): for img in image_list: if not img.startswith("TEMP-"): img_old_path = os.path.join(target_board_path, img) shutil.copy(img_old_path, imges_folder) native_folder = os.path.join(target_board_path, "native_backup") if os.path.exists(native_folder): for img in os.listdir(native_folder): img_path = os.path.join(native_folder, img) if os.path.isfile(img_path) and os.path.splitext(img_path)[1] == ".img": if os.path.exists(os.path.join(imges_folder, img)): os.remove(os.path.join(imges_folder, img)) shutil.copy(img_path, imges_folder) print("carrier list:") global CARRIER_LIST CARRIER_LIST = list(set(CARRIER_LIST)) print(CARRIER_LIST) if len(CARRIER_LIST): for carrier in CARRIER_LIST: carrier_folder = os.path.join(imges_folder, carrier) if os.path.exists(carrier_folder): shutil.rmtree(carrier_folder,True) os.mkdir(carrier_folder) carrier_path = os.path.join(target_board_path, carrier) carrier_folder_list = os.listdir(carrier_path) for carrier_file in carrier_folder_list: carrier_file_path = os.path.join(carrier_path, carrier_file) if os.path.isfile(carrier_file_path) and not carrier_file.startswith('TEMP-'): shutil.copy(carrier_file_path, carrier_folder) #删除modem bin文件 if os.path.exists(os.path.join(target_board_path, "make_ota_flag")): f = open(os.path.join(target_board_path, "make_ota_flag"), 'r') bin_list = f.read().strip() f.close() bin_list = bin_list.split(',') print(bin_list) for bin in bin_list: if os.path.exists(os.path.join(imges_folder, bin)): os.remove(os.path.join(imges_folder, bin)) def get_pac(product_path, target_board_path): conf = BMConfigParser() conf.read(os.path.join(product_path, "pac.ini")) pac_name = conf.get("Attr", "PAC_NAME") if pac_name.strip(): pac_path = os.path.join(product_path, pac_name) if os.path.exists(pac_path): PAC_LIST.append(pac_name) make_bt_version(product_path, target_board_path) else: NOT_PAC_LIST.append(pac_name) def get_ap_product(product_path, target_board_path, is_check_ota): ############查询carrier########### carrier = '' carrier_flag = os.path.join(product_path, "pac.ini") if os.path.exists(carrier_flag): carrier = read_carrier(carrier_flag) if carrier.strip(): CARRIER_LIST.append(carrier) #######转换格式######## pac_ini_path = os.path.join(product_path, "pac.ini") sparse_list = parser_pac_ini(pac_ini_path) if len(sparse_list): for img in sparse_list: img = '/'.join(img.split('/')[1:]) image_path,image_name = os.path.split(img) ##判断之前是否已转换过 check_sparse = os.path.join(image_path, "TEMP-"+image_name) if os.path.exists(check_sparse): print("has unsparse %s"%image_name) else: sparse_check(img, image_path, "unsparse-"+image_name) else: print("not transfer sparse img ") #########打pac包################## mkpac_pl = os.path.join(SCRIPT_PATH, "mkpac.pl") current_pwd = os.getcwd() os.chdir(product_path) print("current path:"+os.getcwd()) cmd = "perl %s"%(mkpac_pl) exec_cmd(cmd) os.chdir(current_pwd) def read_carrier(carrier_flag): carrier_value = '' conf = BMConfigParser() conf.read(carrier_flag) options_list = conf.options("Attr") if "carrier" not in options_list: print("not configured carrier") return carrier_value carrier_value = conf.get("Attr", "carrier") return carrier_value def get_carrier_partition(carrier_flag): carrier_partition = '' conf = BMConfigParser() conf.read(carrier_flag) options_list = conf.options("partition") if "carrier_partition" not in options_list: print("not configured carrier_partition") return carrier_partition carrier_product = conf.get("partition", "carrier_partition") pac_list = conf.options("pac_list") if carrier_product not in pac_list: print("not carrier_partition in pac_list") return carrier_partition product_value = conf.get("pac_list", carrier_product) if not product_value.strip(): print("find product_value in empty") return carrier_partition product_value = '/'.join(product_value.split('/')[1:]) print("get_carrier_partition--product_value:" + str(product_value)) return product_value def sparse_check(installed_systeimage, product_out, upsparse_image): print("installed_systeimage:"+str(installed_systeimage)) #需要转换的image print("product_out:"+str(product_out)) #image路径 print("SIMG2IMG:"+str(SIMG2IMG))#转换工具· #upsparse_image 转换后的img 名称 system_header = os.path.join(product_out, "system_header.img") sparse_magic = os.path.join(product_out, "sparse_magic.img") if os.path.exists(system_header): cmd = "dd if=%s of=%s bs=1 skip=0 count=4"%(installed_systeimage, system_header) exec_cmd(cmd) with open(sparse_magic, 'w') as out_in: out_in.write("\x3a\xff\x26\xed") result = filecmp.cmp(system_header, sparse_magic, False) print("cmp result:"+str(result)) if result: print("[%s]transfer sparse img to unsparse img"%installed_systeimage) sparse_cmd = "%s %s %s"%(SIMG2IMG, installed_systeimage, os.path.join(product_out, upsparse_image)) exec_cmd(sparse_cmd) else: print("[%s]not transfer sparse img"%installed_systeimage) os.remove(sparse_magic) os.remove(system_header) #####对已转换格式的img重命名########## upsparse_image_path = os.path.join(product_out, upsparse_image) if os.path.exists(upsparse_image_path): image_path,image_name = os.path.split(installed_systeimage) new_img_name = os.path.join(image_path, "TEMP-"+image_name) os.rename(installed_systeimage, new_img_name) RENAME_IMG_LIST.append(new_img_name) os.rename(upsparse_image_path, installed_systeimage) def parser_pac_ini(pac_ini_path): #解析ini数据 print("pac_ini_path:"+str(pac_ini_path)) params = [] if not os.path.exists(pac_ini_path): print("not find: %s"%pac_ini_path) return params conf = BMConfigParser() conf.read(pac_ini_path) options_list = conf.options("partition") if "sparse" not in options_list: print("%s not configured sparse"%pac_ini_path) return params sparse_config = conf.get("partition", "sparse") sparse_list = [] if sparse_config.strip(): if ',' in sparse_config: sparse_list.extend(sparse_config.strip().split(',')) else: sparse_list.append(sparse_config.strip()) else: print("%s not configured sparse value"%pac_ini_path) return params image_list = conf.options("pac_list") for sp in sparse_list: if sp not in image_list: continue sparse_path = conf.get("pac_list", sp).strip() params.append(sparse_path) return params def exec_cmd(cmd, use_shell=False): print("exec command: " + cmd) cmd_list = split(cmd) proc = subprocess.Popen(cmd_list, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=use_shell) (output, error) = proc.communicate() print("command output: " + output.decode()) # exit_code = proc.wait() return output.decode() def split(s): for row in reader([s], delimiter=" "): return row def make_bt_version(product_type, target_board_path): time_tup = time.localtime(time.time()) format_time = '%Y-%m-%d-%a:%H:%M' cur_time = time.strftime(format_time, time_tup) bt = BT_VERSION(product_type, cur_time, target_board_path) bt.out_version(target_board_path) class BMConfigParser(ConfigParser): def __init__(self, defaults=None): ConfigParser.__init__(self, defaults=defaults) def optionxform(self, option_str): return option_str def help(): init_optparse = optparse.OptionParser( usage="usage: %prog [options] args", description="show help" ) init_optparse.add_option( '-o', '--out', help='output path', dest='output', type="string") init_optparse.add_option( '-p', '--tool-path', help='tool path', type="string") (options, args) = init_optparse.parse_args() #if not options.output: # print init_optparse.error('Insufficient number of arguments') # sys.exit(1) return options if __name__ == "__main__": options = help() print("=============== makepac.py start =======================") config = BMConfigDir(SCRIPT_PATH) dir = config.get_dir() print("dir:" + dir) print("SCRIPT_PATH path:"+SCRIPT_PATH) code_path = SCRIPT_PATH.split(dir)[0] os.chdir(code_path) print("pwd:" + os.getcwd()) if options.tool_path: SIMG2IMG = os.path.join(options.tool_path, 'simg2img') main(options.output) print("=============== makepac.py end =========================")