def __init_vs_tools(self): """ 查找vs的路径 :return: """ if not PlatformInfo.is_windows_system(): return self.__find_2017_tools() for version in VSToolInfo.VS_VERSION_LIST: env_key = 'VS{}0COMNTOOLS'.format( VSToolInfo.VS_VERSION_MAP[version]) common_path = os.getenv(env_key) if common_path: if "Common7" in common_path: install_folder = common_path[:common_path.find("Common7")] else: install_folder = common_path core.v("found vs tool in the environment :{}={} ".format( env_key, common_path)) self.__wrap_vs_info(install_folder, version) self.__filter_custom_vs() if self.custom_vs and not self.__vs_tool_info.install_root: self.__show_help() raise TmakeException( "can not find Virsual Studio path with custom version: {}". format(self.custom_vs)) self.__show_vs_version_info()
def set_global_flag_by_cmd(self): # 命令行中-M形式传递的宏参数也设置上 cmd_defines = core.data.arguments.get_opts_by_prefix("-M") if cmd_defines: self.global_defines += cmd_defines core.v("defines in cmd:{}".format(self.global_defines)) settings = core.data.arguments.get_opts_by_prefix("-F") c_flags = "" cxx_flags = "" linker_flags = "" for setting in settings: if "=" not in setting: continue type = setting[:setting.find("=")] value = setting[setting.find("=") + 1:] if type == "c_flags": c_flags += " {} ".format(value) if type == "cxx_flags": cxx_flags += " {} ".format(value) if type == "linker_flags": linker_flags += " {} ".format(value) core.v("flag in cmd:{} {} {}".format(c_flags, cxx_flags, linker_flags)) if c_flags: self.global_c_flags += c_flags if cxx_flags: self.global_cxx_flags += cxx_flags if linker_flags: self.global_linker_flags += linker_flags
def execute_build_command(self, command_text): """ execute build command """ command = tmake_utils.get_cd_command() + " \"" + self.path.build_path + "\" && " + command_text core.v(command) self.__do_rm_build_bin_dir() # shell=xx,windows的线上构建报错,不要修改为false #ret = core.subprocess.call(command, shell=True) ret = subprocess.call(command, shell=True) if ret != 0: raise core.TmakeException('build failed! return code is {}'.format(ret)) if core.data.use_cmakelist or core.data.use_proj_cmakelist: if core.data.use_cmakelist: recover_cmakelists(self.path.project_folder) if core.data.arguments.tmake_cmd() == "project": src_dir = os.path.join(self.path.project_path, core.BUILD_OUTPUT_NAME) else: src_dir = os.path.join(self.path.build_path, core.BUILD_OUTPUT_NAME) # build folder arrange_dir(src_dir, src_dir) delete_empty_dir(src_dir) # export folder dst_dir = os.path.join(self.path.build_path, core.BUILD_INSTALL_PREFIX, core.BUILD_OUTPUT_NAME) copy_libs_to_export(src_dir, dst_dir) src_dir = os.path.join(self.path.build_path, core.BUILD_INSTALL_PREFIX) arrange_dir(src_dir, dst_dir) delete_empty_dir(src_dir) if core.data.use_proj_cmakelist: for external_build in self.info.external_builds: if external_build.path: path = external_build.path recover_cmakelists(path)
def __do_rm_build_bin_dir(self): """ 清空输出路径 :return: """ rm_dirs = [os.path.join(self.path.build_path, "bin"), os.path.join(self.path.build_path, "export")] for dir in rm_dirs: core.v("do_rm_build_bin_dir: " + dir) if os.path.exists(dir): tmake_utils.rmtree(dir, True)
def execute_with_msg(cmd): """ 返回命令执行的文本输出 :param cmd: :return: """ core.v("execute_with_msg: " + str(cmd)) import os r = os.popen(cmd) text = r.read() r.close() return text
def execute(self): exec_string = 'self.function(' arguments_length = len(self.arguments) for i in range(arguments_length): exec_string += 'self.arguments[' + str(i) if i == (arguments_length - 1): # if last item exec_string += ']' else: exec_string += '], ' exec_string += ')' # invoke exec exec_string core.v('function is {} , args is {} , invoke success'.format(self.function.__name__, self.arguments))
def execute_prog_with_sysstdout(command, pram_cwd=None): code = -1 ret = '' core.v("execute_prog_with_sysstdout: " + str(command)) try: process = subprocess.Popen(command, shell=False, stdout=sys.stdout, stderr=sys.stderr, cwd=pram_cwd) process.wait() code = process.returncode except BaseException as e: core.e(' Exception : %s ' % e) return code, ret
def save_success_build_info(self, acg): alllibs = [] for library in acg.info.libraries: core.v("save success build info of :" + library.name) a = {'m': library.name, 'deps': library.deps, 'eh': library.exported_headers, 'ls': library.link_style} alllibs.append(a) config = { 't': core.data.target, 'c': core.data.build_config, 'a': self.arch, 'l': alllibs } jsonc = json.dumps(config) json.dump(jsonc, open(acg.path.success_build_status_file_path, 'w'))
def print_info(self): """trace log""" core.v('---->abs xml path : %s ' % os.path.join(self.__xmlpath)) core.i(">>>>>>>>> the project info:") core.i("name : " + str(self.name)) core.i("link_name : " + str(self.link_name)) core.i("version : " + str(self.version)) core.i("author : " + str(self.author)) core.i("git_url : " + str(self.git_url)) core.i("git_branch : " + str(self.git_branch)) core.i("git_commit : " + str(self.git_commit)) core.i("include_dir : " + str(self.include_dir)) core.i("lib_dir : " + str(self.lib_dir)) core.i("sym_lib_dir : " + str(self.sym_lib_dir)) core.i("package : " + str("{}.zip".format(self.package_name)))
def __run_test(self, task_list): """ 对 tmake_host_tester_task 的支持 :param task_list: :return: """ task_name_list = [] for task in task_list: # 配置了并且跟当前编译的config不一致的情况下就跳过 if task.config and task.config != core.data.build_config: core.v("skip task {}.".format(task.name)) continue task_name_list.append(task.name) if task_name_list: argus = self.arguments.clone(["run", core.GLOBAL_SEPARATED.join(task_name_list)]) core.exec_tmake_command(argus)
def __find_2017_tools(self): """ 针对2017的特殊处理 :return: """ env_key = 'VS{}0COMNTOOLS'.format(VSToolInfo.VS_VERSION_MAP["vs2017"]) real_path = os.getenv(env_key) if real_path and os.path.exists(real_path): dir_list = os.listdir(real_path) for dir_name in dir_list: var_path = os.path.join(real_path, dir_name, "VC/Auxiliary/Build/vcvars32.bat") if os.path.isfile(var_path): core.v("found vs tool in the specified path:{} ".format( var_path)) self.__wrap_vs_info(os.path.join(real_path, dir_name), "vs2017") break
def execute_prog_with_output(command, pram_cwd=None): code = -1 ret = '' core.v("execute_prog_with_output: " + str(command)) try: process = subprocess.Popen(command, shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=pram_cwd) while True: line = process.stdout.readline() if not line: break ret += line process.wait() code = process.returncode except BaseException as e: core.e(' Exception : %s ' % e) return code, ret
def parse_project(self): """parse tmake.proj""" # load WORK_PATH from core.utils import tmake_project_parser script = os.path.join(core.data.arguments.work_path(), "tmake.proj") if os.path.exists(script): core.v("project path=" + script) core.data.project = tmake_project_parser.parse(script) self.__parse_project_deps(core.data.project, True) # 依赖关系处理完毕逻辑 core.data.deps_mgr.parse_finish() return True # 处理只有CMakeLists.txt的场景 script = os.path.join(core.data.arguments.work_path(), "CMakeLists.txt") if os.path.exists(script): core.data.use_cmakelist = True core.v("project path=" + script) core.data.project = tmake_project_parser.parse(script) if core.data.arguments.tmake_cmd() == "project": path_info = PathInfo(self.arch, core.data.arguments.work_path()) base_path = path_info.project_path else: base_path = core.data.project.get_build_folder(self.arch) export_path = os.path.join(base_path, core.BUILD_INSTALL_PREFIX) exectable_output_path = os.path.join(base_path, core.BUILD_OUTPUT_NAME) library_output_path = os.path.join(base_path, core.BUILD_OUTPUT_NAME) export_path = export_path.replace("\\", "/") exectable_output_path = exectable_output_path.replace("\\", "/") library_output_path = library_output_path.replace("\\", "/") recover_cmakelists(core.data.arguments.work_path()) change_cmakelists_output(core.data.arguments.work_path(), export_path, exectable_output_path, library_output_path) return True return False
def run(self): """plugin main entry""" self.param_check() arch_list = core.get_archs() for arch in arch_list: self.arch = arch try: self.acg_list = general_cmake_info(arch, True) except core.SkipException: continue self.build() acg = self.acg_list[-1] if not self.no_test: if not acg.info.tasks: core.v("There is no task to run.") elif core.data.target != core.data.platform.host: info = "" for item in acg.info.tasks: info += " " + item.name core.v("There have task[{}] to run, but host and target is not same, skip!".format(info)) else: self.__run_test(acg.info.tasks)
def execute_task(self, task): if core.data.target == core.data.platform.host: core.v('curr run name : %s' % task) args = [] command = string.strip(task.command) cwd = task.work_directory args += task.args core.v('command : {} , cwd : {} , args : {}'.format( command, cwd, args)) if len(command) <= 0: raise core.TmakeException( '[Possible error] tmake_host_tester_task : {} command property configuration error !!!' .format(task)) cmd_check = re.split(' *', command) core.v('pre cmd_check : {}'.format(cmd_check)) cmd_check[0] = os.path.join(self.acg.path.build_symbol_path, cmd_check[0]) if core.data.platform.host == core.PLATFORM_WINDOWS: cmd_check[0] += '.exe' core.v('post cmd_check : {}'.format(cmd_check)) if not os.path.exists(cmd_check[0]): raise core.TmakeException( '%s is not exist %s , please first build !' % (cmd_check[0], self.__common_log_info())) if len(cwd) <= 0: cwd = None elif not os.path.isabs(cwd): cwd = os.path.abspath( os.path.join(self.acg.path.project_folder, cwd)) cmd_check += args core.i('\n----> exec {} ......'.format(cmd_check)) self.env_set() ret, msg = process_utils.execute_prog_with_sysstdout( cmd_check, cwd) if ret == 0: core.s('{} test success!\n'.format(task.name)) else: raise core.TmakeException( '{} test error! {} message : {}\n'.format( task.name, ret, msg)) else: raise core.TmakeException( '%s and %s do not match , please do not add -t parameter' % (core.data.target, core.data.platform.host))
def tmake_logv(msg): """log for v""" core.v(msg)
def execute_prog(command): core.v("execute_prog: " + str(command)) return subprocess.call(command, shell=True)
def __show_vs_version_info(self): for item in self.__all_vs_tools: core.v("all vs tools info:\n" + str(item)) core.v("using vs tool info:\n" + str(self.__vs_tool_info))
def make_project(self, cmake_list_path, name): """ call cmake project """ if self.get_cmake_generator_name(name) == '': return target = core.data.target project_folder = self.path.project_path command_text = "" use_nmake = "" if PlatformInfo.is_windows_system(): vs_tools = core.data.environment.get_vs_tool_path(self.arch) if target != core.PLATFORM_ANDROID and target != core.PLATFORM_WINDOWS: raise core.TmakeException('unsupported target : ' + target) command_text += '"' + vs_tools + '" ' command_text += "&&" command_text += '"' + self.cmake_home + '" ' command_text += '-H"' + cmake_list_path + '" ' command_text += '-B"' + project_folder + '" ' command_text += '-G"' + self.get_cmake_generator_name(name) + '" ' command_text += use_nmake + self.__build_params() core.v(command_text) # tmake_utils.do_rm_build_bin_dir(tmake_utils.get_build_path(self.arch)) # windows用false,其余的用true if core.data.use_cmakelist: if core.data.arguments.tmake_cmd() == "project": path_info = PathInfo(self.arch, core.data.arguments.work_path()) base_path = path_info.project_path else: base_path = core.data.project.get_build_folder(self.arch) export_path = os.path.join(base_path, core.BUILD_INSTALL_PREFIX) exectable_output_path = os.path.join(base_path, core.BUILD_OUTPUT_NAME) library_output_path = os.path.join(base_path, core.BUILD_OUTPUT_NAME) # pre_command_text = '"' + self.cmake_home + '" ../../../../ ' + " -DCMAKE_INSTALL_PREFIX={}".format(export_path) + \ # " -DEXECUTABLE_OUTPUT_PATH={}".format(exectable_output_path) + \ # " -DLIBRARY_OUTPUT_PATH={}".format(library_output_path) # # pre_command_text = tmake_utils.get_cd_command() + " \"" + self.path.project_path + "\" && " + pre_command_text # # ret = core.subprocess.call(pre_command_text, shell=not PlatformInfo.is_windows_system()) # if ret != 0: # raise core.TmakeException('Set CMAKE_INSTALL_PREFIX failed! return code is {}'.format(ret)) ret = subprocess.call(command_text, shell=not PlatformInfo.is_windows_system()) if core.data.use_cmakelist: recover_cmakelists(self.path.project_folder) if core.data.use_proj_cmakelist: for external_build in self.info.external_builds: if external_build.path: path = external_build.path recover_cmakelists(path) if ret != 0: raise core.TmakeException('build failed! return code is {}'.format(ret))