220 lines
5.6 KiB
Python
220 lines
5.6 KiB
Python
import os
|
||
import sys
|
||
import json
|
||
|
||
|
||
|
||
|
||
'''
|
||
更新日志:
|
||
|
||
2024.8.9
|
||
添加对 -imacros 选项中宏定义的读取
|
||
2024.8.19
|
||
读取到的宏定义删除多余的 $ 符号
|
||
|
||
'''
|
||
|
||
|
||
|
||
def get_out_path(sub:str):
|
||
with open('ohos_config.json') as f:
|
||
j=json.loads(f.read())
|
||
return os.path.join(j["out_path"],sub)
|
||
|
||
|
||
# 找到指定后缀的文件
|
||
def find_type(path:str,fix:str):
|
||
dlist=os.listdir(path)
|
||
file_list=[]
|
||
for i in dlist:
|
||
ps=os.path.join(path, i)
|
||
if os.path.isdir(ps):
|
||
file_list+=find_type(ps,fix)
|
||
else:
|
||
if(ps[-len(fix):]==fix):
|
||
file_list.append(ps)
|
||
return file_list
|
||
|
||
|
||
|
||
# 输出目录列表
|
||
def list_dirs(path:str,file=None):
|
||
dlist=os.listdir(path)
|
||
file_list=[]
|
||
for i in dlist:
|
||
ps=os.path.join(path, i)
|
||
if os.path.isdir(ps) and not os.path.islink(ps):
|
||
if(file is None):
|
||
file_list.append(ps)
|
||
else:
|
||
print(ps,file=file)
|
||
file_list+=list_dirs(ps,file)
|
||
file_list.sort()
|
||
return file_list
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
# 从配置文件中读取宏定义
|
||
def read_defines(values:list):
|
||
flage=False
|
||
def_list=[]
|
||
for item in values:
|
||
if(item=='-imacros'):
|
||
flage=True
|
||
continue
|
||
if(flage==True):
|
||
flage=False
|
||
# print(item)
|
||
if(os.path.exists(item)):
|
||
with open(item) as f:
|
||
data=f.readlines()
|
||
for defs in data:
|
||
split=defs.split()
|
||
if(split[0]=="#define"):
|
||
def_list.append(split[1]+'='+split[2])
|
||
return def_list
|
||
|
||
|
||
|
||
|
||
def unescape(line:str):
|
||
table=[("\\\"","\""),("\\<","<"),("\\>",">"),("\\$","$"),("\\(","("),("\\)",")")]
|
||
for item in table:
|
||
line=line.replace(item[0],item[1])
|
||
# 删除多余的 $ 符号
|
||
line=line.replace('$','')
|
||
return line
|
||
|
||
# 找到include和define
|
||
def find_inc_def(file_list:list):
|
||
defines=[]
|
||
include_dirs=[]
|
||
ldflags=[]
|
||
current_path=os.path.abspath('.')
|
||
for item in file_list:
|
||
with open(item) as f:
|
||
for line in f.readlines():
|
||
index=line.find("=")
|
||
if(index>0):
|
||
line_sp=[line[:index],line[index+1:]]
|
||
else:
|
||
line_sp=[line]
|
||
if(len(line_sp)>=2):
|
||
head=line_sp[0].strip()
|
||
# defines 中可能含有空格 这里单独处理
|
||
if(head=="defines"):
|
||
values=line_sp[-1].strip().replace('-D','\n').split('\n')
|
||
for d in values:
|
||
defines.append(unescape(d.strip()))
|
||
if(head=="cflags") or head=="include_dirs":
|
||
# print(f"head:{head}")
|
||
values=line_sp[-1].strip().split()
|
||
# 读取宏文件里定义的 define
|
||
_def_list=read_defines(values)
|
||
defines+=_def_list
|
||
for d in values:
|
||
# cflags 中也可能包含define
|
||
if(d[:2]=='-D'):
|
||
defines.append(unescape(d[2:]))
|
||
elif(d[0:2]=="-I"):
|
||
if(d[0:4]=="-I.."):
|
||
dir=os.path.normpath(d[9:])
|
||
dir=os.path.join(current_path,dir)
|
||
else:
|
||
dir=os.path.join(get_out_path(''),d[2:])
|
||
if(os.path.exists(dir)):
|
||
include_dirs.append(dir)
|
||
# else:
|
||
# print(d)
|
||
elif(head=='ldflags'):
|
||
values=line_sp[-1].strip().split()
|
||
values_dict={"file:":item,"values":values}
|
||
ldflags.append(values_dict)
|
||
# else:
|
||
# print(f"unknow:{head}")
|
||
defines=list(set(defines))
|
||
include_dirs=list(set(include_dirs))
|
||
# ldflags=list(set(ldflags))
|
||
defines.sort()
|
||
# inc的先后顺序很重要,排序之后可能造成语法解析有问题
|
||
# include_dirs.sort()
|
||
return defines,include_dirs,ldflags
|
||
|
||
|
||
|
||
|
||
# 更新配置文件
|
||
def flush_cpp_setting(defines:list,include_dirs:list):
|
||
set_file=".vscode/c_cpp_properties.json"
|
||
with open(set_file,encoding="utf-8") as f:
|
||
j=json.loads(f.read())
|
||
j["configurations"][0]["includePath"]=include_dirs
|
||
j["configurations"][0]["defines"]=defines
|
||
d=json.dumps(j,sort_keys=True, indent=2, separators=(',', ': '))
|
||
with open(set_file,mode='w+',encoding="utf-8") as f:
|
||
f.write(d)
|
||
|
||
|
||
|
||
|
||
# 输出编译的文件
|
||
def find_build_files():
|
||
_tmp_file="ninja_commands.txt"
|
||
_cmd=f"{get_out_path('')}../../../prebuilts/build-tools/linux-x86/bin/ninja -C {get_out_path('')} -t commands > {_tmp_file}"
|
||
with os.popen(_cmd) as f:
|
||
ret=f.readlines()
|
||
for item in ret:
|
||
print(item)
|
||
|
||
c_file_list=[]
|
||
with open(_tmp_file) as f:
|
||
for item in f.readlines():
|
||
item_sp=item.split()
|
||
for item_x in item_sp:
|
||
item_x_fix=item_x.split('.')[-1]
|
||
if(item_x_fix in ['c','cpp','C','CPP','S','s']):
|
||
f_path=item_x[9:]
|
||
if f_path not in c_file_list:
|
||
c_file_list.append(f_path)
|
||
os.remove(_tmp_file)
|
||
c_file_list.sort()
|
||
return c_file_list
|
||
|
||
|
||
|
||
if __name__ == "__main__":
|
||
|
||
# 读取 .ninja 文件来设置define和include
|
||
file_list=find_type(get_out_path("obj"),".ninja")
|
||
defines,include_dirs,ldflags=find_inc_def(file_list)
|
||
flush_cpp_setting(defines,include_dirs)
|
||
|
||
with open("ldflags_list"+".json",mode="w+",encoding="utf-8") as g:
|
||
g.write(json.dumps(ldflags,sort_keys=True, indent=2, separators=(',', ': ')))
|
||
|
||
|
||
# 打印编译的源文件
|
||
# for item in find_build_files():
|
||
# print(item)
|
||
|
||
# with open("dirs_list.txt",mode='w+') as f:
|
||
# dirs_list=list_dirs('.',file=f)
|
||
# for item in dirs_list:
|
||
# print(item,file=f)
|
||
|
||
|
||
# print("defines:")
|
||
# for item in defines:
|
||
# print(f"\t{item}")
|
||
# print("include_dirs:")
|
||
# for item in include_dirs:
|
||
# print(f"\t{item}")
|
||
# print("ldflags:")
|
||
# for item in ldflags:
|
||
# print(f"\t{item}")
|