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}")