alder_lake_bios/Board/Oem/L05AlderLakePMultiBoardPkg/LfcBpr/Lib/action_build.py

423 lines
20 KiB
Python

"""
BSD 2-Clause License
Copyright (c) 2020, Hefei LCFC Information Technology Co.Ltd.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
"""
from Lib.lcfc_lib import *
from Lib.action_base import ActionBase
import shutil
import os
import subprocess
class ActionBuild(ActionBase):
# bios_smt Insyde: for SMT and for sign (Windows); Phoenix: for SMT
# crisis Insyde only: for sign (crisis)
# bios_cap Phoenix only: for sign (Windows and crisis)
BUILD_TYPE_NORMAL = ''
BUILD_TYPE_DEBUG = '1'
BUILD_TYPE_DDT = '2'
BUILD_TYPE_DDT_DEBUG = '3'
BUILD_TYPE_POST_TIME_PERFORMANCE = '4'
BUILD_TYPE_SPECIFIC_DRIVER = '5'
BUILD_TYPE_CLEAN = 'C'
cmd_list_insyde = {
BUILD_TYPE_NORMAL: 'nmake uefi64',
BUILD_TYPE_DEBUG: 'nmake efidebug',
BUILD_TYPE_DDT: 'nmake uefi64ddt',
BUILD_TYPE_DDT_DEBUG: 'nmake debugddt',
BUILD_TYPE_POST_TIME_PERFORMANCE: 'nmake uefi64perf',
BUILD_TYPE_SPECIFIC_DRIVER: 'nmake uefi64',
BUILD_TYPE_CLEAN: 'nmake clean',
}
cmd_list_phoenix = {
BUILD_TYPE_NORMAL: 'PhMake.bat',
BUILD_TYPE_DEBUG: 'PhMake.bat TARGET=DEBUG',
BUILD_TYPE_SPECIFIC_DRIVER: 'PhMake.bat',
BUILD_TYPE_CLEAN: 'PhMake.bat clean',
}
__psw_crisis_modify_dict = {}
__content_orig = ''
def __init__(self, build_type, build_id, psw_crisis=False):
super().__init__()
self.build_type = build_type
self.build_id = build_id
self.psw_crisis = psw_crisis
def pre_work(self, count, action_str):
super().pre_work(count, action_str)
if self.build_type == ActionBuild.BUILD_TYPE_CLEAN:
return
# str_start = '##############################LCFC START##############################\n'
# str_end = '##############################LCFC END################################\n'
#
# insyde_file_dict = {
# 'Project.env': [
# '[Defines]\n',
# str_start,
# """# This code is auto generated by tool, please DO NOT modify
# EDK_GLOBAL LCFC_ENABLE = YES
# EDK_GLOBAL %s= YES
# DEFINE LCFC_CC_FLAGS =
# DEFINE LCFC_CC_FLAGS = $(LCFC_CC_FLAGS) /D LCFC_ENABLE
# DEFINE LCFC_CC_FLAGS = $(LCFC_CC_FLAGS) /D %s\n"""
# % (g.project_config['projectflag'] +
# ' ' * (26 - len(g.project_config['projectflag']) + len('LCFC_ENABLE')),
# g.project_config['projectflag']),
# str_end
# ],
# 'Project.dsc': [
# '[BuildOptions.common.EDKII]\n',
# str_start,
# """# This code is auto generated by tool, please DO NOT modify
# !if $(LCFC_ENABLE) == YES
# MSFT:*_*_*_CC_FLAGS = $(LCFC_CC_FLAGS)
# MSFT:*_*_*_VFRPP_FLAGS = $(LCFC_CC_FLAGS)
# MSFT:*_*_*_ASLPP_FLAGS = $(LCFC_CC_FLAGS)
# MSFT:*_*_*_ASLCC_FLAGS = $(LCFC_CC_FLAGS)
# MSFT:*_*_*_VFCFPP_FLAGS = $(LCFC_CC_FLAGS)
# !endif\n""",
# str_end
# ],
# 'ProjectSetup.bat': [
# '@echo off\n',
# '@REM ' + str_start,
# """@REM This code is auto generated by tool, please DO NOT modify
# set %s=YES\n""" % g.project_config['projectflag'],
# '@REM ' + str_end
# ]
# }
#
# phoenix_file_dict = {
# 'PhMake.bat': [
# '@ECHO OFF\n',
# '@REM ' + str_start,
# """@REM This code is auto generated by tool, please DO NOT modify
# set %s=YES\n""" % g.project_config['projectflag'],
# '@REM ' + str_end
# ]
# }
#
# file_dict = {}
# if g.insyde:
# file_dict = insyde_file_dict.items()
# process_bios_ver(2)
# shutil.copyfile('Project_%s.uni' % g.build_id, 'Project.uni')
# elif g.phoenix:
# file_dict = phoenix_file_dict.items()
# process_bios_ver(2)
# shutil.copyfile('project_%s.def' % g.build_id, 'project.def')
# for keys, values in file_dict:
# try:
# with open(keys) as f:
# content = f.readlines()
# except FileNotFoundError:
# error_handle(1, 'Can not find %s' % keys)
# self.status = STATUS_ERROR
# return
# try:
# start = content.index(values[1])
# end = content.index(values[3])
# for _ in range(start, end + 1):
# content.pop(start)
# except ValueError:
# pass
# insert = False
# for _i, _data in enumerate(content):
# if _data == values[0]:
# content.insert(_i + 1, values[1])
# content.insert(_i + 2, values[2])
# content.insert(_i + 3, values[3])
# insert = True
# break
# if insert is False:
# error_handle(1, 'Can not modify %s, maybe file format updated, please contact tool owner' % keys)
# self.status = STATUS_ERROR
# return
# with open(keys, 'w') as f:
# f.writelines(content)
psw_crisis_modify_dict = {
'Insyde': [
'OemConfig.env',
'DEFINE L05_PASSWORD_RESET_CRISIS_BIOS_ENABLE = NO',
r'\n\s*DEFINE\s+L05_PASSWORD_RESET_CRISIS_BIOS_ENABLE\s+=\s+NO',
r'\n\s*DEFINE\s+L05_PASSWORD_RESET_CRISIS_BIOS_ENABLE\s+=\s+YES',
'NO',
'YES'
],
'Phoenix': [
'project_%s.def' % g.build_id,
'Option LENOVOOIL_CRISIS_CLEAR_PASSWORD, 0',
r'\n\s*Option\s+LENOVOOIL_CRISIS_CLEAR_PASSWORD,\s+0',
r'\n\s*Option\s+LENOVOOIL_CRISIS_CLEAR_PASSWORD,\s+1',
'0',
'1'
]
}
if self.psw_crisis:
self.__psw_crisis_modify_dict = psw_crisis_modify_dict
try:
with open(psw_crisis_modify_dict[g.project_config['ibv']][0]) as f:
self.__content_orig = content = f.read()
except FileNotFoundError:
self.status = STATUS_ERROR
error_handle(1, 'Cannot find ' + psw_crisis_modify_dict[g.project_config['ibv']][0])
return
string1 = psw_crisis_modify_dict[g.project_config['ibv']][2]
try:
string2 = re.search(string1, content).group(0)
except AttributeError:
self.status = STATUS_ERROR
error_handle(1, 'Cannot modify file for password crisis, please make sure %s contain %s'
% (psw_crisis_modify_dict[g.project_config['ibv']][0],
psw_crisis_modify_dict[g.project_config['ibv']][1]))
return
string3 = string2.replace(psw_crisis_modify_dict[g.project_config['ibv']][4],
psw_crisis_modify_dict[g.project_config['ibv']][5])
content = content.replace(string2, string3)
with open(psw_crisis_modify_dict[g.project_config['ibv']][0], 'w') as f:
f.write(content)
else:
try:
with open(psw_crisis_modify_dict[g.project_config['ibv']][0]) as f:
self.__content_orig = content = f.read()
except FileNotFoundError:
self.status = STATUS_ERROR
error_handle(1, 'Cannot find ' + psw_crisis_modify_dict[g.project_config['ibv']][0])
return
string1 = psw_crisis_modify_dict[g.project_config['ibv']][3]
if re.search(string1, content):
self.status = STATUS_ERROR
error_handle(1, 'Error: this is not psw crisis build, but seems your code set to build psw crisis. '
'Most likely your previous build is psw crisis build and it failed, so tool '
'was not able to change the code back. Please check the %s'
% psw_crisis_modify_dict[g.project_config['ibv']][0])
return
if not process_bios_ver(2):
error_handle(1, 'Cannot find BIOS version in project folder, maybe you should set the Project Folder?')
if g.gui:
g.gui_b_1['state'] = tk.NORMAL
self.status = STATUS_ERROR
return
#set ec full version
process_ec_ver(2)
for _i in os.listdir(os.getcwd()):
if os.path.isfile(_i) and '.' in _i:
if _i.split('.')[-2][-3:] == '_' + g.build_id:
shutil.copyfile(_i, _i.replace('_' + g.build_id, ''))
# self.action_output['crisis'] = shutil.copy(r'Tool\Temp\CrisisPsw_Phoenix.cap',
# os.path.join(self.output_folder, 'crisis.bin'))
def action(self, count, action_str):
super().action(count, action_str)
if self.status != STATUS_SUCCESS:
return self.status
if g.insyde:
#try to remove bios_smt.bin
try_fun_bypass_error(fun = os.remove, passby_error = (FileNotFoundError),arg = r'bios_smt.bin')
# try to remove crisis.bin
try_fun_bypass_error(fun = os.remove,passby_error = (FileNotFoundError),arg = r'crisis.bin')
# try to remove bios_smtxx.bin
for path in search(path=g.working_path_abs, name=r"bios_smt\d{1,}.bin"):
try_fun_bypass_error(fun = os.remove,passby_error = (FileNotFoundError),arg = path)
if ActionBuild.cmd_list_insyde.get(self.build_type) is None:
error_handle(1, 'Did not support %s command' % g.argv['BuildId'])
self.status = STATUS_ERROR
return
if DEBUG_MODE:
self.action_output['bios_smt'] = shutil.copy(os.path.join(g.tool_path_abs,
r'Tool\Temp\BiosMe_Insyde.bin'),
os.path.join(self.output_folder, 'bios_smt.bin'))
self.action_output['crisis'] = shutil.copy(os.path.join(g.tool_path_abs,
r'Tool\Temp\Crisis_Insyde.fd'),
os.path.join(self.output_folder, 'crisis.bin'))
shutil.copy(os.path.join(g.tool_path_abs,
r'Tool\Temp\bios_smt1.bin'),
os.path.join(g.working_path_abs, 'bios_smt1.bin'))
shutil.copy(os.path.join(g.tool_path_abs,
r'Tool\Temp\bios_smt2.bin'),
os.path.join(g.working_path_abs, 'bios_smt2.bin'))
match_bios_bin = []
for path in search(path = g.working_path_abs,name=r"bios_smt\d{1,}.bin"):
print('weiled path =%s'%path)
match_bios_bin.append(path)
for bios in match_bios_bin:
(path,bios_full_name) = os.path.split(bios)
(bios_name, extension) = os.path.splitext(bios_full_name)
self.action_output[bios_name] = shutil.copy(bios,
os.path.join(self.output_folder,bios_full_name))
else:
if self.build_type == ActionBuild.BUILD_TYPE_CLEAN:
build_cmd = r'ProjectSetup.bat && %s' % ActionBuild.cmd_list_insyde[self.build_type]
else:
build_cmd = r'ProjectSetup.bat && BuildFsp.cmd /r && %s' \
% ActionBuild.cmd_list_insyde[self.build_type]
print(' Build command:', build_cmd)
proc = subprocess.Popen(build_cmd, shell=True)
g.build_proc = proc
proc.communicate()
if proc.stdin:
proc.stdin.close()
if proc.stdout:
proc.stdout.close()
if proc.stderr:
proc.stderr.close()
status = proc.returncode
if status:
self.status = STATUS_ERROR
return
if self.build_type == ActionBuild.BUILD_TYPE_CLEAN:
return
try:
self.action_output['bios_smt'] = shutil.copy(r'bios_smt.bin',
os.path.join(self.output_folder, 'bios_smt.bin'))
self.action_output['crisis'] = shutil.copy(r'crisis.bin',
os.path.join(self.output_folder, 'crisis.bin'))
except FileNotFoundError:
error_handle(1, 'Can not find bios_smt.bin or crisis.bin in project folder, maybe you forgot'
' to modify ProjectPostBuild.bat?')
self.status = STATUS_ERROR
return
match_bios_bin = []
for path in search(path = g.working_path_abs,name=r"bios_smt\d{1,}.bin"):
match_bios_bin.append(path)
for bios in match_bios_bin:
(path,bios_full_name) = os.path.split(bios)
(bios_name, extension) = os.path.splitext(bios_full_name)
self.action_output[bios_name] = shutil.copy(bios,
os.path.join(self.output_folder,bios_full_name))
elif g.phoenix:
# try to remove bios_smt.bin
try_fun_bypass_error(fun = os.remove, passby_error = (FileNotFoundError),arg = r'bios_smt.bin')
# try to remove bios_cap.cap
try_fun_bypass_error(fun = os.remove,passby_error = (FileNotFoundError),arg = r'bios_cap.cap')
#try to remove bios_smtxx.bin
for path in search(path=g.working_path_abs, name=r"bios_smt\d{1,}.bin"):
try_fun_bypass_error(fun = os.remove,passby_error = (FileNotFoundError),arg = path)
if ActionBuild.cmd_list_phoenix.get(self.build_type) is None:
error_handle(1, 'Did not support %s command' % g.argv['BuildId'])
self.status = STATUS_ERROR
return
if DEBUG_MODE:
print('g.tool_path_abs ='+g.tool_path_abs)
self.action_output['bios_smt'] = shutil.copy(os.path.join(g.tool_path_abs,
'Tool','Temp','BiosMe_Phoenix.bin'),
os.path.join(self.output_folder, 'bios_smt.bin'))
self.action_output['bios_cap'] = shutil.copy(os.path.join(g.tool_path_abs,
'Tool','Temp','BiosMe_Phoenix.cap'),
os.path.join(self.output_folder, 'bios_cap.cap'))
shutil.copy(os.path.join(g.tool_path_abs,
r'Tool\Temp\bios_smt1.bin'),
os.path.join(g.working_path_abs, 'bios_smt1.bin'))
shutil.copy(os.path.join(g.tool_path_abs,
r'Tool\Temp\bios_smt2.bin'),
os.path.join(g.working_path_abs, 'bios_smt2.bin'))
match_bios_bin = []
for path in search(path = g.working_path_abs,name=r"bios_smt\d{1,}.bin"):
match_bios_bin.append(path)
for bios in match_bios_bin:
(path,bios_full_name) = os.path.split(bios)
(bios_name, extension) = os.path.splitext(bios_full_name)
self.action_output[bios_name] = shutil.copy(bios,
os.path.join(self.output_folder,bios_full_name))
else:
build_tool = ''
for _i in range(10):
build_tool = g.project_config['buildtool' + str(_i)]
if os.path.isfile(build_tool):
break
if _i == 9:
error_handle(1,
'Can not find the Visual Studio bat file path for Phoenix code, '
'please config the ini correctly')
self.status = STATUS_ERROR
return
build_cmd = r'"%s" && %s'\
% (build_tool, ActionBuild.cmd_list_phoenix[self.build_type])
print(' Build command:', build_cmd)
#build_cmd = 'subst w:' + build_cmd
proc = subprocess.Popen(build_cmd, shell=True)
g.build_proc = proc
proc.communicate()
if proc.stdin:
proc.stdin.close()
if proc.stdout:
proc.stdout.close()
if proc.stderr:
proc.stderr.close()
status = proc.returncode
if status:
self.status = STATUS_ERROR
return
if self.build_type == ActionBuild.BUILD_TYPE_CLEAN:
return
try:
self.action_output['bios_smt'] = shutil.copy(r'bios_smt.bin',
os.path.join(self.output_folder, 'bios_smt.bin'))
self.action_output['bios_cap'] = shutil.copy(r'bios_cap.cap',
os.path.join(self.output_folder, 'bios_cap.bin'))
except FileNotFoundError:
error_handle(1, 'Can not find bios_smt.bin or crisis.bin in project folder, maybe you forgot '
'to modify Project.mak?')
self.status = STATUS_ERROR
return
match_bios_bin = []
for path in search(path = g.working_path_abs,name=r"bios_smt\d{1,}.bin"):
match_bios_bin.append(path)
for bios in match_bios_bin:
(path,bios_full_name) = os.path.split(bios)
(bios_name, extension) = os.path.splitext(bios_full_name)
self.action_output[bios_name] = shutil.copy(bios,
os.path.join(self.output_folder,bios_full_name))
return
def post_work(self, count, action_str):
super().post_work(count, action_str)
if self.psw_crisis:
with open(self.__psw_crisis_modify_dict[g.project_config['ibv']][0], 'w') as f:
f.write(self.__content_orig)