1#!/usr/bin/env python3 2# coding=utf-8 3# The build entrance of UniProton. 4# Copyright © Huawei Technologies Co., Ltd. 2010-2020. All rights reserved. 5 6import os 7import sys 8import time 9import shutil 10import subprocess 11import platform 12from sys import argv 13UniProton_home = os.path.dirname(os.path.abspath(__file__)) 14sys.path.insert(0, "%s/cmake/common/build_auxiliary_script"%UniProton_home) 15from make_buildef import make_buildef 16sys.path.insert(0, "%s/build/uniproton_ci_lib"%UniProton_home) 17import globle 18from logs import BuilderNolog, log_msg 19from get_config_info import * 20 21 22class Compile: 23 24 # 根据makechoice获取config的配置的环境,compile_mode, lib_type, 25 def get_config(self, cpu_type, cpu_plat): 26 self.compile_mode = get_compile_mode() 27 self.lib_type, self.plam_type, self.hcc_path, self.kconf_dir, self.system, self.core = get_cpu_info(cpu_type, cpu_plat, self.build_machine_platform) 28 if not self.compile_mode and self.lib_type and self.plam_type and self.hcc_path and self.kconf_dir: 29 log_msg('error', 'load config.xml env error') 30 sys.exit(0) 31 self.config_file_path = '%s/build/uniproton_config/config_%s'%(self.home_path, self.kconf_dir) 32 33 self.objcopy_path = self.hcc_path 34 35 def setCmdEnv(self): 36 self.build_time_tag = time.strftime('%Y-%m-%d_%H:%M:00') 37 self.log_dir = '%s/logs/%s' % (self.build_dir, self.cpu_type) 38 self.log_file = '%s.log' % self.kconf_dir 39 40 def SetCMakeEnviron(self): 41 os.environ["CPU_TYPE"] = self.cpu_type 42 os.environ["PLAM_TYPE"] = self.plam_type 43 os.environ["LIB_TYPE"] = self.lib_type 44 os.environ["COMPILE_OPTION"] = self.compile_option 45 os.environ["HCC_PATH"] = self.hcc_path 46 os.environ["UNIPROTON_PACKING_PATH"] = self.UniProton_packing_path 47 os.environ["CONFIG_FILE_PATH"] = self.config_file_path 48 os.environ["LIB_RUN_TYPE"] = self.lib_run_type 49 os.environ["HOME_PATH"] = self.home_path 50 os.environ["COMPILE_MODE"] = self.compile_mode 51 os.environ["BUILD_MACHINE_PLATFORM"] = self.build_machine_platform 52 os.environ["SYSTEM"] = self.system 53 os.environ["CORE"] = self.core 54 os.environ["OBJCOPY_PATH"] = self.objcopy_path 55 os.environ['PATH'] = '%s:%s' % (self.hcc_path, os.getenv('PATH')) 56 57 # 环境准备,准备执行cmake,make,makebuildfile,CmakeList需要的环境 58 # 每次compile之前请调用该函数 59 def prepare_env(self, cpu_type, choice): 60 # makebuildfile需要的环境kconf_dir 61 # cmake需要的环境cmake_env_path,home_path(cmakelist所在的路径),home_path, 62 # make cmd拼接需要的环境:home_path,UniProton_make_jx,log_dir,log_file,build_time_tag, UniProton_make_jx 63 64 #根据cpu_type, choice从config文件中获取并初始化初始化hcc_path, plam_type, kconf_dir 65 #根据输入分支获取 66 #从编译镜像环境获取 67 self.get_config(cpu_type, choice) 68 self.setCmdEnv() 69 self.SetCMakeEnviron() 70 71 #获取编译环境是arm64还是x86,用户不感知,并将其写入环境变量。 72 def getOsPlatform(self): 73 self.cmake_env_path = get_tool_info('cmake', 'tool_path') 74 75 if platform.uname()[-1] == 'aarch64': 76 self.build_machine_platform = 'arm64' 77 else: 78 self.build_machine_platform = 'x86' 79 80 # 获取当前编译的路径信息,配置文件信息,编译选项信息 81 def __init__(self, cpu_type: str, make_option="normal", lib_run_type="FPGA", choice="ALL", make_phase="ALL", 82 UniProton_packing_path=""): 83 # 当前路径信息 84 self.system = "" 85 self.objcopy_path = "" 86 self.builder = None 87 self.compile_mode = "" 88 self.core = "" 89 self.plam_type = "" 90 self.kconf_dir = "" 91 self.build_tmp_dir = "" 92 self.log_dir = "" 93 self.lib_type = "" 94 self.hcc_path = "" 95 self.log_file = "" 96 self.config_file_path = "" 97 self.build_time_tag = "" 98 self.build_dir = globle.build_dir 99 self.home_path = globle.home_path 100 self.kbuild_path = globle.kbuild_path 101 # 当前选项信息 102 self.cpu_type = cpu_type 103 self.compile_option = make_option 104 self.lib_run_type = lib_run_type 105 self.make_choice = choice.lower() 106 self.make_phase = make_phase 107 self.UniProton_packing_path = UniProton_packing_path if make_phase == "CREATE_CMAKE_FILE" else '%s/output'%self.home_path 108 self.UniProton_binary_dir = os.getenv('RPROTON_BINARY_DIR') 109 self.UniProton_install_file_option = os.getenv('RPROTON_INSTALL_FILE_OPTION') 110 self.UniProton_make_jx = 'VERBOSE=1' if self.UniProton_install_file_option == 'SUPER_BUILD' else 'VERBOSE=1 -j$(nproc)' 111 # 当前编译平台信息 112 self.getOsPlatform() 113 114 #调用cmake生成Makefile文件,需要 115 def CMake(self): 116 if self.UniProton_binary_dir: 117 self.build_tmp_dir = '%s/output/tmp/%s' % (self.UniProton_binary_dir, self.kconf_dir) 118 else: 119 self.build_tmp_dir = '%s/output/tmp/%s' % (self.build_dir, self.kconf_dir) 120 os.environ['BUILD_TMP_DIR'] = self.build_tmp_dir 121 122 if not os.path.exists(self.build_tmp_dir): 123 os.makedirs(self.build_tmp_dir) 124 if not os.path.exists(self.log_dir): 125 os.makedirs(self.log_dir) 126 127 log_msg('info', 'BUILD_TIME_TAG %s' % self.build_time_tag) 128 self.builder = BuilderNolog(os.path.join(self.log_dir, self.log_file)) 129 if self.make_phase in ['CREATE_CMAKE_FILE', 'ALL']: 130 real_path = os.path.realpath(self.build_tmp_dir) 131 if os.path.exists(real_path): 132 shutil.rmtree(real_path) 133 os.makedirs(self.build_tmp_dir) 134 #拼接cmake命令 135 if self.compile_option == 'fortify': 136 cmd = '%s/cmake %s -DCMAKE_TOOLCHAIN_FILE=%s/cmake/tool_chain/uniproton_tool_chain.cmake ' \ 137 '-DCMAKE_C_COMPILER_LAUNCHER="sourceanalyzer;-b;%sproject" ' \ 138 '-DCMAKE_INSTALL_PREFIX=%s &> %s/%s' % ( 139 self.cmake_env_path, self.home_path, self.home_path, self.cpu_type, 140 self.UniProton_packing_path, self.log_dir, self.log_file) 141 elif self.compile_option == 'hllt': 142 cmd = '%s/cmake %s -DCMAKE_TOOLCHAIN_FILE=%s/cmake/tool_chain/uniproton_tool_chain.cmake ' \ 143 '-DCMAKE_C_COMPILER_LAUNCHER="lltwrapper" -DCMAKE_INSTALL_PREFIX=%s &> %s/%s' % ( 144 self.cmake_env_path, self.home_path, self.home_path, self.UniProton_packing_path, self.log_dir, self.log_file) 145 else: 146 cmd = '%s/cmake %s -DCMAKE_TOOLCHAIN_FILE=%s/cmake/tool_chain/uniproton_tool_chain.cmake ' \ 147 '-DCMAKE_INSTALL_PREFIX=%s &> %s/%s' % ( 148 self.cmake_env_path, self.home_path, self.home_path, self.UniProton_packing_path, self.log_dir, self.log_file) 149 #执行cmake命令 150 if self.builder.run(cmd, cwd=self.build_tmp_dir, env=None): 151 log_msg('error', 'generate makefile failed!') 152 return False 153 154 log_msg('info', 'generate makefile succeed.') 155 return True 156 157 def UniProton_clean(self): 158 for foldername,subfoldernames,filenames in os.walk(self.build_dir): 159 for subfoldername in subfoldernames: 160 if subfoldername in ['logs','output','__pycache__']: 161 folder_path = os.path.join(foldername,subfoldername) 162 shutil.rmtree(os.path.relpath(folder_path)) 163 for filename in filenames: 164 if filename == 'prt_buildef.h': 165 file_dir = os.path.join(foldername,filename) 166 os.remove(os.path.relpath(file_dir)) 167 if os.path.exists('%s/cmake/common/build_auxiliary_script/__pycache__'%self.home_path): 168 shutil.rmtree('%s/cmake/common/build_auxiliary_script/__pycache__'%self.home_path) 169 if os.path.exists('%s/output'%self.home_path): 170 shutil.rmtree('%s/output'%self.home_path) 171 if os.path.exists('%s/tools/SRE/x86-win32/sp_makepatch/makepatch'%self.home_path): 172 os.remove('%s/tools/SRE/x86-win32/sp_makepatch/makepatch'%self.home_path) 173 if os.path.exists('%s/build/prepare/__pycache__'%self.home_path): 174 shutil.rmtree('%s/build/prepare/__pycache__'%self.home_path) 175 return True 176 177 178 def make(self): 179 if self.make_phase in ['EXECUTING_MAKE', 'ALL']: 180 self.builder.run('make clean', cwd=self.build_tmp_dir, env=None) 181 tmp = sys.argv 182 if self.builder.run( 183 'make all %s &>> %s/%s' % ( 184 self.UniProton_make_jx, self.log_dir, self.log_file), cwd=self.build_tmp_dir, env=None): 185 log_msg('error', 'make %s %s failed!' % (self.cpu_type, self.plam_type)) 186 return False 187 sys.argv = tmp 188 if self.compile_option in ['normal', 'coverity', 'single']: 189 if self.builder.run('make install %s &>> %s/%s' % (self.UniProton_make_jx, self.log_dir, self.log_file), cwd=self.build_tmp_dir, env=None): 190 log_msg('error', 'make install failed!') 191 return False 192 if os.path.exists('%s/%s' % (self.log_dir, self.log_file)): 193 self.builder.log_format() 194 195 log_msg('info', 'make %s %s succeed.' % (self.cpu_type, self.plam_type)) 196 return True 197 198 def SdkCompaile(self)->bool: 199 # 判断该环境中是否需要编译 200 if self.hcc_path == 'None': 201 return True 202 203 self.MakeBuildef() 204 if self.CMake() and self.make(): 205 log_msg('info', 'make %s %s lib succeed!' % (self.cpu_type, self.make_choice)) 206 return True 207 else: 208 log_msg('info', 'make %s %s lib failed!' % (self.cpu_type, self.make_choice)) 209 return False 210 211 # 对外函数,调用后根据类初始化时的值进行编译 212 def UniProtonCompile(self): 213 #清除UniProton缓存 214 if self.cpu_type == 'clean': 215 log_msg('info', 'UniProton clean') 216 return self.UniProton_clean() 217 # 根据cpu的编译平台配置相应的编译环境。 218 if self.make_choice == "all": 219 for make_choice in globle.cpu_plat[self.cpu_type]: 220 self.prepare_env(self.cpu_type, make_choice) 221 if not self.SdkCompaile(): 222 return False 223 else: 224 self.prepare_env(self.cpu_type, self.make_choice) 225 if not self.SdkCompaile(): 226 return False 227 return True 228 229 def MakeBuildef(self): 230 231 if not make_buildef(globle.home_path,self.kconf_dir,"CREATE"): 232 sys.exit(1) 233 log_msg('info', 'make_buildef_file.sh %s successfully.' % self.kconf_dir) 234 235# argv[1]: cpu_plat 表示要编译的平台: 236# argv[2]: compile_option 控制编译选项,调用不同的cmake参数,目前只有normal coverity hllt fortify single(是否编译安全c,组件化独立构建需求) 237# argv[3]: lib_run_type lib库要跑的平台 faga sim等 238# argv[4]: make_choice 239# argv[5]: make_phase 全量构建选项 240# argv[6]: UniProton_packing_path lib库的安装位置 241if __name__ == "__main__": 242 default_para = ("all", "normal", "FPGA", "ALL", "ALL", "") 243 if len(argv) == 1: 244 para = [default_para[i] for i in range(0, len(default_para))] 245 else: 246 para = [argv[i+1] if i < len(argv) - 1 else default_para[i] for i in range(0,len(default_para))] 247 248 cur_cpu_type = para[0].lower() 249 cur_compile_option = para[1].lower() 250 cur_lib_run_type = para[2] 251 cur_make_choice = para[3] 252 cur_make_phase = para[4] 253 cur_UniProton_packing_path = para[5] 254 for plat in globle.cpus_[cur_cpu_type]: 255 UniProton_build = Compile(plat, cur_compile_option, cur_lib_run_type, cur_make_choice, cur_make_phase, cur_UniProton_packing_path) 256 if not UniProton_build.UniProtonCompile(): 257 sys.exit(1) 258 sys.exit(0) 259 260