Files
phs_v1.0.1.0/vscode_cpp_setting.py

220 lines
5.6 KiB
Python
Raw Permalink Normal View History

2024-09-27 19:21:56 +08:00
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}")