def __parse_project(): """ 解析project,不成功给出提示 :return: """ if not core.data.parse_project(): core.e("work path = " + str(core.data.arguments.work_path())) raise core.TmakeException( 'project parse failed, please ensure work path is right!')
def create_build_vars(self): self.info.build_vars["CMAKE_SYSTEM_NAME"] = "Android" if "CMAKE_SYSTEM_VERSION" not in self.info.build_vars: if self.arch in core.TARGET_ANDROID_CPU_64_ALL: self.info.build_vars["CMAKE_SYSTEM_VERSION"] = "21" else: self.info.build_vars["CMAKE_SYSTEM_VERSION"] = "14" self.check_system_version() self.info.build_vars["CMAKE_ANDROID_NDK"] = '"' + self.ndk_path + '" ' self.info.build_vars["CMAKE_ANDROID_ARCH_ABI"] = self.arch # debug模式下ANDROID_STL和CMAKE_ANDROID_STL_TYPE做特殊处理,并且根据ndk版本使用不同toolchain # release模式下把ANDROID_STL的键值对替换成CMAKE_ANDROID_STL_TYPE has_android_stl = ANDROID_STL_KEY in self.info.build_vars has_cmake_android_stl_type = CMAKE_ANDROID_STL_TYPE_KEY in self.info.build_vars # debug模式并且是build命令才执行 if core.data.build_config == core.CONFIG_DEBUG and core.data.arguments.tmake_cmd() == "build": if has_android_stl or has_cmake_android_stl_type: stl_info = self.info.build_vars[CMAKE_ANDROID_STL_TYPE_KEY] if has_cmake_android_stl_type else \ self.info.build_vars[ANDROID_STL_KEY] if has_android_stl: self.info.build_vars.pop(ANDROID_STL_KEY) if has_cmake_android_stl_type: self.info.build_vars.pop(CMAKE_ANDROID_STL_TYPE_KEY) self.info.build_vars[CMAKE_ANDROID_STL_TYPE_KEY] = stl_info self.info.build_vars[ANDROID_STL_KEY] = stl_info if "CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION" in self.info.build_vars: # ANDROID_TOOLCHAIN_NAME self.info.build_vars["ANDROID_TOOLCHAIN"] = self.info.build_vars["CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION"] else: self.info.build_vars["ANDROID_TOOLCHAIN"] = "gcc" if "CMAKE_SYSTEM_VERSION" in self.info.build_vars: self.info.build_vars["ANDROID_PLATFORM"] = "android-" + self.info.build_vars["CMAKE_SYSTEM_VERSION"] ndk_version = self.__get_android_ndk_version() if ndk_version: self.info.build_vars["ANDROID_ABI"] = self.arch major_version = int(ndk_version[0]) toolchain_path = "" if major_version < 12: core.e('!!!!!!!!ndk version < 12 , cant debug code !!!!!!!! ') # elif major_version == 12: # toolchain_path = os.path.join(comm_utils.get_cmake_download_root(), # 'toolchain/android-cmake/android.toolchain_debug_r12.cmake') # elif major_version == 13: # toolchain_path = os.path.join(comm_utils.get_cmake_download_root(), # 'toolchain/android-cmake/android.toolchain_debug_r13.cmake') else: toolchain_path = os.path.join(self.__get_android_ndk(), 'build/cmake/android.toolchain.cmake') self.info.build_vars[CMAKE_TOOLCHAIN_FILE_KEY] = '"' + toolchain_path + '" ' else: core.e('!!!!!!!!ndk version failed to get !!!!!!!! ') else: if has_android_stl: self.info.build_vars[CMAKE_ANDROID_STL_TYPE_KEY] = self.info.build_vars[ANDROID_STL_KEY] self.info.build_vars.pop(ANDROID_STL_KEY)
def check_system_version(self): if int(self.info.build_vars["CMAKE_SYSTEM_VERSION"]) < 21 \ and self.arch in core.TARGET_ANDROID_CPU_64_ALL: arch = core.data.arguments.get_opt('-a', '--architecture') if arch and arch.lower() == "all": # all的64位,抛指定异常跳过, info = "the target is [all], but the architecture [{}] " \ "is not supported bv android system version [{}]! skip it." raise SkipException(info.format(self.arch, self.info.build_vars["CMAKE_SYSTEM_VERSION"])) else: core.e(TIP_MESSAGE.format(self.info.build_vars["CMAKE_SYSTEM_VERSION"], self.arch)) raise core.TmakeException("CMAKE_SYSTEM_VERSION IS ERROR!")
def get_vs_tool_path(self, arch): """ 获取vs的环境变量文件全路径 :return: """ vs_build_tool = self.__vs_tool_info.get_build_tool_by_arch(arch) if not os.path.exists(vs_build_tool): core.e("{} is not exist!".format(vs_build_tool)) self.__show_help() raise TmakeException( 'in windows platform, tmake need visual studio software, please check!' ) return vs_build_tool
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 run(self): """tmake help entry""" logstr = "Usage:\n tmake command command_paramters [-D[-D][...]] [-opt] [--opt]" cur_dir = os.path.split(os.path.realpath(__file__))[0] cmd_list = os.listdir(cur_dir) logstr += "\n ----command list----" for cmd_file in cmd_list: if cmd_file.startswith("tmake_") and cmd_file.endswith( ".py") and "_base" not in cmd_file: cmd = cmd_file[6:-3] import_cmd = "import core.cmd.tmake_" + cmd call_cmd = "core.cmd.tmake_" + cmd + ".main()" try: exec(import_cmd) except BaseException, e: core.e(e) cmd_executor = eval(call_cmd) info = cmd_executor.help() logstr += "\n " + cmd + " \t : " + info + "\n"
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 run(self): try: arguments = core.data.arguments if not core.data.arguments.tmake_cmd(): import cmd.tmake_help cmd.tmake_help.main().run() return self.check_python_tools() if core.data.arguments.tmake_cmd() != "config": self.check_cmake_tools() core.exec_tmake_command(arguments) # core.s(core.data.arguments.tmake_cmd() + ' success!') except Exception as exception: traceback.print_exc() core.reset_color(log_attributes) if not isinstance(exception, core.TmakeException): core.e(traceback.format_exc()) raise core.TmakeException( 'use `tmake help` to get more information') sys.exit(-1)
def tmake_exit(msg): """exit lib build""" core.e(msg) quit()
def tmake_loge(msg): """log for e""" core.e(msg)
def post_build_cp_lib(self, acg): # IOS平台的symbol_path会根据config添加子目录,将子目录下的文件都拷贝到symbol_path下 if acg.info.build_target == core.PLATFORM_IOS or "wince" in self.arch: symbol_path = acg.path.build_symbol_path if acg.info.build_config == core.CONFIG_DEBUG: subdir_name = "Debug" elif acg.info.build_config == core.CONFIG_RELWITHDEBINFO: subdir_name = "RelWithDebInfo" else: subdir_name = "Release" # move xxx/bin/Debug to xxx/Debug subdir = os.path.join(symbol_path, subdir_name) if os.path.exists(subdir): temp_dir = os.path.join(acg.path.build_path, subdir_name) shutil.move(subdir, temp_dir) # rm xxx/bin shutil.rmtree(symbol_path) # move xxx/Debug to xxx/bin shutil.move(temp_dir, symbol_path) if acg.info.build_target == core.PLATFORM_WINDOWS and "wince" in self.arch: export_path = acg.path.build_installed_path symbol_path = acg.path.build_symbol_path if os.path.exists(export_path): shutil.rmtree(export_path) shutil.copytree(symbol_path, export_path) library_names = [] if core.data.use_cmakelist or (core.data.use_proj_cmakelist and acg.info.external_builds): if abtcoreor.data.arguments.tmake_cmd() == "project": libs_dir = os.path.join(core.data.project.get_build_folder(self.arch), core.BUILD_OUTPUT_NAME) else: libs_dir = os.path.join(core.data.project.get_build_folder(self.arch), core.BUILD_OUTPUT_NAME) libs_info = get_libs_info(libs_dir) library_list = [] for item in libs_info: bfind = False for library in acg.info.libraries: if item.split(":")[0] == library.name: bfind = True break if bfind: continue library_info = LibraryInfo() library_info.name = item.split(":")[0] library_info.link_style = item.split(":")[1] library_info.deps = [] library_info.exported_headers = [] library_list.append(library_info) for library in acg.info.libraries: library_names.append(library.name) acg.info.libraries += library_list for library in acg.info.libraries: # headers if library.name not in library_names and ( core.data.use_cmakelist or (core.data.use_proj_cmakelist and acg.info.external_builds)): src_dir = os.path.join(acg.path.build_path, core.BUILD_INSTALL_PREFIX) # dst_dir = acg.path.get_local_export_include_path(library.name) dst_dir = os.path.join(acg.path.local_export_path, library.name) src_dir = src_dir.replace("\\", "/") dst_dir = dst_dir.replace("\\", "/") move_header_files(src_dir, dst_dir) delete_libs(dst_dir) delete_empty_dir(dst_dir) libs = tmake_utils.get_libname_on_platform(core.data.target, library.name, library.link_style) # lib des_dir = acg.path.get_local_export_lib_path(library.name) if os.path.exists(des_dir): shutil.rmtree(des_dir) if not os.path.exists(des_dir): os.makedirs(des_dir) for lib in libs: lib_path = os.path.join(acg.path.build_installed_path, lib) if os.path.exists(lib_path): # IOS平台编译的export库没有strip(去掉符号), 这里会强制去符号 # mac平台编译的export动态库,调用strip时会失败。这里会再次调用一次 if (core.data.target == core.PLATFORM_IOS or core.data.target == core.PLATFORM_MAC) \ and library.link_style == core.CXX_LIBRARY_LINK_STYLE_SHARED: tmake_utils.stripSymbols(lib_path) tmake_utils.copy(lib_path, os.path.join(des_dir, lib)) else: core.e( '{} is not generate , Make sure that no functions or variables are exported ! '.format( lib_path)) # libsys des_dir = acg.path.get_local_export_libsys_path(library.name) if os.path.exists(des_dir): shutil.rmtree(des_dir) if not os.path.exists(des_dir): os.makedirs(des_dir) for lib in libs: lib_path = os.path.join(acg.path.build_symbol_path, lib) if os.path.exists(lib_path): tmake_utils.copy(lib_path, os.path.join(des_dir, lib)) else: core.e( '{} is not generate , Make sure that no functions or variables are exported ! '.format( lib_path))
def __update_deps(self, library): """ 编译完一个项目后,把项目里的library更新到全局依赖里 :param library: :return: """ library_dir = self.path_info.build_installed_path library_dirs = [library_dir] library_dirs.extend(tmake_utils.fix_path_to_abs(self.global_lib_dirs)) if library["lib_dirs"]: library_dirs.extend(tmake_utils.fix_path_to_abs(library["lib_dirs"])) include_dirs = [] # exported_headers 也放入include_headers里,有的项目只配置了exported_headers # 过滤下不是文件夹的,不然如果是文件类型的编译会报警告 # 只有导出的头文件其他项目才可以使用,如果导出头文件配置了文件类型的话,设置local_export文件夹 des_dir = self.path_info.get_local_export_include_path(library["name"]) if library["exported_headers"]: headers_folder = tmake_utils.fix_path_to_abs(library["exported_headers"]) # 清空一下,使用中发现不清可能出现不对的头文件 tmake_utils.clean(des_dir) # 如果是project直接添加,如果是build要复制到local_export里,用那里面的路径 if self.is_project_cmd: for path in headers_folder: if os.path.isdir(path): include_dirs.append(path) else: include_dirs.append(os.path.dirname(path)) else: if not os.path.exists(des_dir): os.makedirs(des_dir) include_dirs.append(des_dir) for path in headers_folder: if not os.path.exists(path): continue # 因外部输入参数错误,可能导致拷贝根目录,这是不允许的 if path == '/': core.e("Cannot copy the root directory, please check exported_headers!") continue if os.path.isdir(path): tmake_utils.copytree(path, des_dir, ignore_hide=True) sub_folder = os.listdir(path) for item in sub_folder: full_path = os.path.join(des_dir, item) if os.path.isdir(full_path): include_dirs.append(full_path) else: import shutil shutil.copy(path, os.path.join(des_dir, os.path.basename(path))) if library["exported_headers_by_folder"]: tmake_utils.move_files_to_target(des_dir, library["exported_headers_by_folder"]) # 把导出的c及cpp文件删除一下 from core.info.tmake_builtin import tmake_glob exclude_list = tmake_glob(des_dir, "*.c", True) exclude_list += tmake_glob(des_dir, "*.cpp", True) print exclude_list for item in exclude_list: tmake_utils.clean(item) core.data.deps_mgr.update_dep_module_lib_dir(library["name"], library_dirs, include_dirs)
def __init__(self, message): core.e(' TmakeException --> {0}'.format(message))
def __init__(self, message): core.i('skip info: {0}'.format(message)) core.e(' SkipException --> {0}'.format(message))