# # used to generate share lib # import os import shutil from SCons.Script import * SharelibRootSconscript = ''' import rtconfig from building import * cwd = GetCurrentDir() CPPPATH = [${CPPPATH}] LIBS = [${LIB_LIST}] LIBPATH = [${LIBPATH}] group = DefineGroup('${LIB_NAME}', [], depend = ${LIB_DEPENDS}, CPPPATH = CPPPATH, LIBS = LIBS, LIBPATH = LIBPATH) Return('group') ''' SharelibMainSconscript = ''' # for package compiling import os from building import * cwd = GetCurrentDir() objs = [] list = os.listdir(cwd) CPPPATH = [cwd] Import('SHARE_LIB_HANDLE') for d in list: if SHARE_LIB_HANDLE.is_this_lib(d): continue path = os.path.join(cwd, d) if os.path.isfile(os.path.join(path, 'SConscript')): objs = objs + SConscript(os.path.join(d, 'SConscript')) Return('objs') ''' class SharelibItem: ''' share lib handler ''' def __init__(self, path, group, header_files = [], all_header = False, libs = [], need_path = True): self._path = path self._group = group self._header_files = header_files self._libs = libs self._all_header = all_header self._need_path = need_path class SharelibHandler: def __init__(self, lib_name, lib_deps): self._items = [] self._lib_name = lib_name self._lib_deps = lib_deps self._LIB_LIST = [] self._HEADER_PATH_LIST = [] def __export_lib(self, dist_path, path, libs): for lib in libs: self._LIB_LIST.append(lib) def __export_headers(self, dist_path, group, path, headers, all, need_path = True): dst = os.path.join(dist_path, group) if need_path and (group not in self._HEADER_PATH_LIST): self._HEADER_PATH_LIST.append(group) if not os.path.exists(dst): os.makedirs(dst) if all: from glob import glob for file in glob(path+'/*.h'): shutil.copy(file, dst) else: for file in headers: shutil.copy(os.path.join(path, file), dst) def is_this_lib(self, lib_name): return self._lib_name == lib_name def __load_pkg(self, share_lib_path, pkg): import json pkg_desc = os.path.join(share_lib_path, pkg, "package.json") if not os.path.isfile(pkg_desc): return None fp = open(pkg_desc, 'r') if not fp: return None _pkg = json.load(fp) fp.close() return _pkg def update_sharelib(self, share_lib_path): kcfg = open(os.path.join(share_lib_path, 'kconfig'), 'w+') if not kcfg: print("create root kconfig failed") exit(1) kcfg.writelines(['menu "Share lib pkgs enable control"\n', '\n']) for pkg in os.listdir(share_lib_path): if pkg == self._lib_name: continue _pkg = self.__load_pkg(share_lib_path, pkg) if not _pkg: continue if len(_pkg['depends']) < 1: continue kcfg.writelines(['config ' + _pkg['depends'][0] + '\n']) kcfg.writelines([' bool "Using ' + _pkg['lib_name' ] + '"\n']) if len(_pkg['depends']) < 2: kcfg.writelines([' default n\n', '\n']) continue for item in _pkg['depends'][1,:]: kcfg.writelines([' select ' + item + '\n']) kcfg.writelines([' default n\n', '\n']) kcfg.writelines(['endmenu\n']) kcfg.close() def gen_ports(self, share_lib_path): import json init_c_path = os.path.join(os.getcwd(), "gen_ports", "gen_ports_c.c") init_cpp_path = os.path.join(os.getcwd(), "gen_ports", "gen_ports_cpp.cpp") finit_c = open(init_c_path, 'w+') finit_cpp = open(init_cpp_path, 'w+') if (not finit_c) or (not finit_cpp): print("create root kconfig failed") exit(1) file_head = ['/**\n', ' * @file: gen_ports_c.c/_cpp.cpp\n', ' * \n', ' * @warn: auto generated init ports file; DO NOT EDIT.', ' */\n\n', '#include \n\n'] finit_c.writelines(file_head) finit_cpp.writelines(file_head) for pkg in os.listdir(share_lib_path): if pkg == self._lib_name: continue _pkg = self.__load_pkg(share_lib_path, pkg) has_def = (_pkg != None) and (len(_pkg['depends']) > 0) port_file = os.path.join(share_lib_path, pkg, "ports.json") if not os.path.isfile(port_file): continue with open(port_file, 'r') as pf: _ports = json.load(pf) _ports_list = _ports['ports'] if has_def: finit_c.writelines(['#ifdef ' + _pkg['depends'][0] + '\n']) finit_cpp.writelines(['#ifdef ' + _pkg['depends'][0] + '\n']) for item in _ports_list: pw = finit_c if item['is_cpp']: pw = finit_cpp pw.writelines(['extern ' + item['function'] + ';\n']) pw.writelines([item['export'] + ';\n\n']) if has_def: print("write end") finit_c.writelines(['#endif /** ' + _pkg['depends'][0] + ' end */\n']) finit_cpp.writelines(['#endif /** ' + _pkg['depends'][0] + ' end */\n']) finit_c.close() finit_cpp.close() def __init_sconscipt(self, share_lib_path): port_file = os.path.join(share_lib_path, "SConscript") if os.path.isfile(port_file): return False with open(port_file, 'w+') as pf: pf.write(SharelibMainSconscript) def export(self, share_lib_path, gen_ports = False): reserved_subdir = ['.git', 'README.md', '.gitignore', '.gitmodules', '.gitattributes', '.drone.yml'] self.__init_sconscipt(share_lib_path) dist_path = share_lib_path + '/' + self._lib_name if os.path.exists(dist_path): for d in os.listdir(dist_path): if d in reserved_subdir: continue if d.endswith('.a') or d.endswith('.lib'): continue pth = os.path.join(dist_path, d) if os.path.isfile(pth): os.remove(pth) continue shutil.rmtree(pth) print("dist_path: " + dist_path) for item in self._items: if item._group == '': self.__export_lib(dist_path, item._path, item._libs) else: self.__export_headers(dist_path, item._group, item._path, item._header_files, item._all_header, item._need_path) root_sc = open(dist_path + '/SConscript', 'w') if not root_sc: print("create root SConscript failed") exit(1) from string import Template t = Template(SharelibRootSconscript) LIBPATH = '' if len(self._LIB_LIST) == 0 else 'cwd' CPPPATH = '' for h in self._HEADER_PATH_LIST: CPPPATH = CPPPATH + "cwd + '/" + h + "'," LIB_LIST = '' for l in self._LIB_LIST: LIB_LIST = LIB_LIST + "'" + l + "'," data = {'CPPPATH': CPPPATH, 'LIB_LIST': LIB_LIST, 'LIBPATH': LIBPATH, 'LIB_NAME': self._lib_name, 'LIB_DEPENDS': self._lib_deps} root_sc.write(t.substitute(data)) root_sc.close() # generate package.json data = {'depends': self._lib_deps, 'format_version': 1, 'lib_name': self._lib_name} import json with open(dist_path + '/package.json','w+') as f: json.dump(data,f, sort_keys=True, indent=4, separators=(',', ': ')) if gen_ports: self.gen_ports(share_lib_path) self.update_sharelib(share_lib_path) def test(self): print('hello word ', self._lib_name) for item in self._items: print(item._path, item._all_header, item._header_files) def add_headers(self, group, path, include_all = False, headers = [], need_path = True): self._items.append(SharelibItem(path, group, headers, include_all, [], need_path)) def add_special_file(self, group, path, files): self._items.append(SharelibItem(path, group, files, False, [], False)) def add_lib(self, path, libs): self._items.append(SharelibItem(path, '', [], False, libs))