Commit 97cfe161 authored by wanli's avatar wanli

🌈 style: 新增qmake工程构建工具

parent 3cb3d82a
import os
import json
import platform
from pathlib import Path
project = {
"name": "evue-awtk", # xxx.pro,
"modules": {
"crane_lvgl_W31/external/zlib": "",
"crane_lvgl_W31/external/libpng": "",
"crane_lvgl_W31/external/libjpeg-turbo": "",
"crane_lvgl_W31/external/libqrencode": "",
"crane_lvgl_W31/gui/lv_watch": "",
"crane_lvgl_W31/gui/lv_drivers": "",
"ecma/src": "ecma"
}
}
def get_module_name(path):
for key in project.get("modules"):
if Path(path).as_posix().find(key) >= 0:
result = key.split("/")[-1]
if len(project.get("modules").get(key)) > 0:
result = project.get("modules").get(key)
return result
return Path(path).as_posix().split("/")[-1]
def gen_pro_from_build_log(projectname, root_dir, filename, output_dir):
source_path = Path(filename)
target_path = Path(output_dir)
with open(source_path.as_posix(), "r", encoding="utf-8") as f:
lines = f.readlines()
gccLines = [l for l in lines if l.find("-o") >= 0]
pris = {}
defs = "" # define
incs = "" # include
lnks = "" # link
pri_files = []
srcs = "SOURCES += \\\n"
ss = "$$PWD/../" # 相对路径的问题
tmp = ""
pro_relative_path = "$$PWD/"
parent_path = Path(output_dir)
while Path(root_dir).absolute().as_posix() != parent_path.absolute().as_posix():
tmp += "../"
pro_relative_path += "../"
parent_path = parent_path.parent
# print("tmp ========>", tmp)
ss += tmp
for l in gccLines:
options = l.split(' ')
name = options[-1].split("\\")[-1]
path = options[-1][:-len(name)]
defines = []
includes = []
links = []
for d in options:
if d.startswith("-D"):
defines.append(d[2:])
if d.startswith("-I"):
includes.append(d[2:])
if d.startswith("-l") or d.startswith("-L"):
links.append(d)
if path not in pris:
pris[path] = []
pris[path].append({
'name': name,
'fullpath': Path(options[-1].replace("\n", "")).as_posix()
})
if defs == "":
for d in defines:
defs += "DEFINES += " + d + " \n"
if incs == "":
for i in includes:
incs += "INCLUDEPATH += " + pro_relative_path + i + "\n"
if lnks == "":
for i in links:
lnks += "LIBS += " + i + "\n"
with open("a.json", "w+") as f:
f.write(json.dumps(pris))
for key in pris:
if len(key) <= 0:
continue
for d in pris[key]:
fn = get_module_name(key) + ".pri"
print(d["fullpath"], " <=====> ", fn)
if fn not in pri_files:
pri_files.append(fn)
if not target_path.joinpath("pris").exists():
os.makedirs(target_path.joinpath("pris").absolute().as_posix())
if not target_path.joinpath("pris").joinpath(fn).exists():
with open(target_path.joinpath("pris").joinpath(fn).absolute().as_posix(), "w+") as f:
f.write(srcs + " " * (len(srcs) - 4) + ss + d["fullpath"] + " \\\n")
else:
with open(target_path.joinpath("pris").joinpath(fn).absolute().as_posix(), "a+") as f:
f.write(" " * (len(srcs) - 4) + ss + d["fullpath"] + " \\\n")
target_name = projectname.split("\\")[-1].replace(".log", "").replace(".exe", "")
pro_file = target_path.joinpath("{}.pro".format(target_name)).absolute().as_posix()
with open(pro_file, "w+") as f:
f.write('''
TEMPLATE = app
TARGET = {}
CONFIG -= app_bundle
CONFIG -= qt\n
'''.format(target_name))
f.write("\n{}\n\n{}\n\n{}\n\n".format(lnks, defs, incs))
for aa in pri_files:
f.write("include(pris/{})".format(aa) + "\n")
return pro_file
if __name__ == "__main__":
# root_dir = "./"
# output_dir = "build_log"
# tmp = "$$PWD/"
# parent_path = Path(output_dir)
# while Path(root_dir).absolute().as_posix() != parent_path.absolute().as_posix():
# tmp += "../"
# parent_path = parent_path.parent
# print(parent_path.absolute().as_posix())
# print("tmp ========>", tmp)
gen_pro_from_build_log("evue-awtk", ".", "./build.log", "project")
\ No newline at end of file
import os
import json
import platform
import shutil
from pathlib import Path
# https://github.com/project-generator/project_generator
# 嵌入式项目生成工具
# 判断是否是编译语句
def is_compiler_cmd(cmd):
return cmd.startswith("gcc") or cmd.startswith("g++")
# 判断是否是链接语句
def is_link_cmd(cmd):
return cmd.startswith("ar")
# 判断是否是源文件
def is_source_file(cmd):
return cmd.enddwith(".c") or cmd.endswith(".cpp") or cmd.endswith(".cc") or cmd.endswith(".cxx")
# 判断是否是object文件
def is_object_file(filename):
return filename.endswith(".o")
def del_files(path):
if not os.listdir(path):
print('sorry, it is nothing')
return
for i in os.listdir(path):
path_file = os.path.join(path,i)
print(path_file)
if os.path.isfile(path_file):
os.remove(path_file)
else:
del_files(path_file)
shutil.rmtree(path_file)
project = {
"name": "awtk", # xxx.pro,
"modules": {
# "crane_lvgl_W31/external/zlib": "",
# "crane_lvgl_W31/external/libpng": "",
# "crane_lvgl_W31/external/libjpeg-turbo": "",
# "crane_lvgl_W31/external/libqrencode": "",
# "crane_lvgl_W31/gui/lv_watch": "",
# "crane_lvgl_W31/gui/lv_drivers": "",
# "ecma/src": "ecma",
# "3rd/SDL": "SDL",
# "src/ext_widgets": "ext_widgets",
}
}
def get_module_name(path):
for key in project.get("modules"):
if Path(path).as_posix().find(key) >= 0:
print("============>", key)
result = key.split("/")[-1]
if len(project.get("modules").get(key)) > 0:
result = project.get("modules").get(key)
return result
return Path(os.path.abspath(path)).as_posix().split("/")[-1]
def gen_pro_from_build_log(project_name, root_dir, filename, output_dir):
source_path = Path(root_dir)
target_path = Path(output_dir)
# 如果输入路径不包含输出路径,则直接报错
if target_path.absolute().as_posix().find(source_path.absolute().as_posix()) < 0:
print("source directory must include target directory")
return
project_name = project_name.split("\\")[-1].replace(".log", "").replace(".exe", "")
target_path = target_path.joinpath(project_name)
if target_path.exists():
shutil.rmtree(target_path.absolute().as_posix())
if not target_path.joinpath("pris").exists():
os.makedirs(target_path.joinpath("pris").absolute().as_posix())
with open(filename, "r", encoding="utf-8") as f:
lines = f.readlines()
gccLines = [l for l in lines if l.find("-o") >= 0]
pris = {}
defs = "" # define
incs = "" # include
lnks = "" # link
pri_files = []
srcs = "SOURCES += \\\n"
relative_path = "" # 相对路径的问题
# pro_relative_path = "$$PWD/"
pri_relative_path = "$$PWD/../"
parent_path = target_path
# 这里会有死循环的问题
while source_path.absolute().as_posix() != parent_path.absolute().as_posix():
relative_path += "../"
parent_path = parent_path.parent
# pro_relative_path += relative_path
# pri_relative_path += relative_path
for l in gccLines:
options = l.split(' ')
name = options[-1].split("\\")[-1]
path = options[-1][:-len(name)]
defines = []
includes = []
links = []
# 按模块加载不同的宏、头文件路径、库
for d in options:
if d.startswith("-D") and d[2:] not in defines:
defines.append(d[2:])
if d.startswith("-I") and d[2:] not in includes:
includes.append(d[2:])
if d.startswith("-l") or d.startswith("-L") and d not in links:
links.append(d)
if path not in pris:
pris[path] = []
pris[path].append({
'name': name,
'fullpath': Path(options[-1].replace("\n", "")).as_posix()
})
# with open("inca.log", "a+") as f:
# f.write("************************\n".join(includes) + "\n\n")
if defs == "":
for d in defines:
defs += "DEFINES += " + d + " \n"
if incs == "":
for i in includes:
# incs += "INCLUDEPATH += $$PWD/" + Path(i).as_posix() + "\n"
incs += "INCLUDEPATH += " + i + "\n"
if lnks == "":
for i in links:
lnks += "LIBS += " + i + "\n"
with open("a.json", "w+") as f:
f.write(json.dumps(pris))
# sources = []
for key in pris:
if len(key) <= 0:
continue
fn = get_module_name(key) + ".pri" # 考虑..问题
if fn not in pri_files:
pri_files.append(fn)
if target_path.joinpath("pris").joinpath(fn).exists():
target_file = target_path.joinpath("pris").joinpath(fn).absolute().as_posix()
with open(target_file, "a+") as f:
for d in pris[key]:
print(d["fullpath"], " <=====> ", fn)
p = len(srcs) * " " + pri_relative_path + d["fullpath"] + " \\\n"
f.write(p)
else:
target_file = target_path.joinpath("pris").joinpath(fn).absolute().as_posix()
with open(target_file, "w+") as f:
f.write(srcs)
for d in pris[key]:
print(d["fullpath"], " <=====> ", fn)
p = len(srcs) * " " + pri_relative_path + d["fullpath"] + " \\\n"
f.write(p)
pro_file = target_path.joinpath("{}.pro".format(project_name)).absolute().as_posix()
with open(pro_file, "w+") as f:
f.write('''
TEMPLATE = app
TARGET = {}
CONFIG -= app_bundle
CONFIG -= qt\n
'''.format(project_name))
f.write("\n{}\n\n{}\n\n{}\n\n".format(lnks, defs, incs))
for aa in pri_files:
f.write("include(pris/{})".format(aa) + "\n")
with open("incs.log", "a+") as f:
f.write(incs)
return pro_file
def find_clines_by_olist(o_list, lines):
c_lines = []
for line in lines:
if is_compiler_cmd(line):
t = [item.strip() for item in line.split(" ")]
for i in t:
if i.endswith(".o") and i in o_list:
c_lines.append(line)
break
return c_lines
def find_deps_from_a(name, lines):
o_list = []
a_line = ""
for line in lines:
if is_link_cmd(line) and name in line:
t = [item.strip() for item in line.split(" ")]
for i in t:
if i.endswith(name):
a_line = line
if a_line != "":
t = [item.strip() for item in a_line.split(" ")]
for i in t:
if i.endswith(".o"):
o_list.append(i)
c_lines = find_clines_by_olist(o_list, lines)
return {
'o': o_list,
'name': name,
'c_lines': c_lines
}
def find_deps_from_exe(name, lines):
o_list = []
a_list = []
L_list = []
exe_line = ""
for line in lines:
if is_compiler_cmd(line):
t = [item.strip() for item in line.split(" ")]
for i in t:
if i.endswith(name):
exe_line = line
if exe_line != "":
t = [item.strip() for item in exe_line.split(" ")]
for i in t:
if i.endswith(".o"):
o_list.append(i)
if i.startswith("-l"):
a_list.append(i[2:] + ".a")
if i.startswith("-L"):
L_list.append(i[2:])
c_lines = find_clines_by_olist(o_list, lines)
return {
'name': name,
'exe_line': exe_line,
'o': o_list,
'a': a_list,
'L': L_list,
'c_lines': c_lines,
}
def gen_build_log(name, lines):
c_lines = []
result = find_deps_from_exe(name, lines)
for a in result["a"]:
ret = find_deps_from_a(a, lines)
c_lines.extend(ret["c_lines"])
c_lines.extend(result["c_lines"])
return c_lines
def find_all_exe(filename):
with open(filename, "r", encoding="utf-8") as f:
lines = f.readlines()
exe_path_names = {}
for line in lines:
if is_compiler_cmd(line) and ".exe" in line:
t = [item.strip() for item in line.split(" ")]
for i in t:
if i.endswith(".exe"):
exe_path_names[i.split("\\")[-1]] = i
return exe_path_names, lines
if __name__ == "__main__":
# root_dir = "./"
# output_dir = "build_log"
# tmp = "$$PWD/"
# parent_path = Path(output_dir)
# while Path(root_dir).absolute().as_posix() != parent_path.absolute().as_posix():
# tmp += "../"
# parent_path = parent_path.parent
# print(parent_path.absolute().as_posix())
# print("tmp ========>", tmp)
# name = "build.log"
# exes, lines = find_all_exe(name)
# with open("exes.log", "w+") as f:
# f.write(" \n".join(exes))
# for item in exes:
# # print(len(find_all_exe(name).keys()))
# ret = gen_build_log(item, lines)
# build_log = "build_log/"+ item + ".log"
# with open(build_log, "w+") as f:
# f.write("\n".join(ret))
# gen_pro_from_build_log(item, "./", build_log, "build_log")
# gen_pro_from_build_log("action_thread", ".", "action_thread_test.exe.log", "build_log")
gen_pro_from_build_log("evue-auto", ".", "./build.log", "./")
# tp = Path("./")
# sp = Path("./project/evue-awtk")
# tmp = ""
# pro_relative_path = "$$PWD/"
# parent_path = sp
# # 这里会有死循环的问题
# while tp.absolute().as_posix() != parent_path.absolute().as_posix():
# tmp += "../"
# pro_relative_path += "../"
# parent_path = parent_path.parent
# print(tmp, pro_relative_path)
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment