Files
rtt_tools/sharelib.py
2021-09-06 20:08:35 +08:00

243 lines
7.7 KiB
Python

#
# 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')
'''
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):
if self._lib_name != "rt-thread":
return False
import json
init_c_path = os.path.join(os.getcwd(), "gen_ports/gen_ports.c")
init_cpp_path = init_c_path + "pp"
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/cpp\n',
' * \n',
' * @warn: auto generated init ports file; DO NOT EDIT.',
' */\n\n',
'#include <rtthread.h>\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 export(self, share_lib_path):
dist_path = share_lib_path + '/' + self._lib_name
if os.path.exists(dist_path):
shutil.rmtree(dist_path)
print("dist_path: " + dist_path)
os.makedirs(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=(',', ': '))
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))