加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
project.py 17.99 KB
一键复制 编辑 原始数据 按行查看 历史
xiao 提交于 2024-01-25 17:47 . Dev (#49)
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571
#!/usr/bin/env python3
import random
import sys
import os
import shutil
import time
sys.path.insert(0, "./utils/python")
sys.path.insert(0, "../utils/python")
import tool
tools = tool.ProjectTools()
welcome_str = "XRobot 2023\n感谢使用本项目,使用./project.py help获取使用方法"
project_path_str = "工程目录:"
cfg_dir = tools.project_path + "/config"
bsp_dir = tools.project_path + "/hw/bsp"
src_dir = tools.project_path + "/src"
dev_dir = tools.project_path + "/src/device"
mod_dir = tools.project_path + "/src/module"
sys_dir = tools.project_path + "/src/system"
rbt_dir = tools.project_path + "/src/robot"
fm_dir = tools.project_path + "/firmware"
build_dir = tools.project_path + "/build"
report_dir = build_dir + "/report"
report_ans_dir = build_dir + "/report_ans"
user_dir = tools.project_path + "/user"
user_bsp_dir = user_dir + "/bsp"
user_cmp_dir = user_dir + "/component"
user_dev_dir = user_dir + "/device"
user_mod_dir = user_dir + "/module"
user_sys_dir = user_dir + "/system"
user_rbt_dir = user_dir + "/robot"
def list_target():
print("Offical:")
for dirname in tools.list_dir(bsp_dir):
print(" Board[" + dirname + "]")
config_dir = bsp_dir + "/" + dirname + "/config"
for filename in tools.list_file(config_dir):
if filename.endswith(".config"):
print(" Robot[" + filename[0:-7] + "]")
print("User:")
for dirname in tools.list_dir(user_bsp_dir):
print(" Board[" + dirname + "]")
config_dir = user_bsp_dir + "/" + dirname + "/config"
for filename in tools.list_file(config_dir):
if filename.endswith(".config"):
print(" Robot[" + filename[0:-7] + "]")
def select_config(config_path, type):
if not os.path.exists(config_path):
print("Error:Robot not found.")
exit(-1)
shutil.copyfile(config_path, cfg_dir + "/.config")
print("Copy " + config_path + " to config/.config")
# The above code is calling a function `generate_cmake` and passing `tools.project_path` as an
# argument.
generate_cmake(cfg_dir)
tools.clean_cache()
tools.config_cmake(type)
print("Load config success from", config_path)
def select_config_idf(config_path, type):
if not os.path.exists(config_path):
print("Error:Robot not found.")
exit(-1)
shutil.copyfile(config_path, cfg_dir + "/.config")
print("Copy " + config_path + " to config/.config")
generate_cmake(cfg_dir)
tools.clean_cache()
tools.config_cmake_idf(type)
print("Load config success from", config_path)
def build(board, robot, type="Debug", code_check=False):
target = []
time_count = 0.0
if os.path.exists(fm_dir):
shutil.rmtree(fm_dir)
os.makedirs(fm_dir, exist_ok=True)
if board == "all":
for dirname in tools.list_dir(bsp_dir):
target.append([bsp_dir + "/" + dirname, []])
for dirname in tools.list_dir(user_bsp_dir):
target.append([user_bsp_dir + "/" + dirname, []])
else:
for dirname in tools.list_dir(bsp_dir):
if dirname == board:
target.append([bsp_dir + "/" + dirname, []])
for dirname in tools.list_dir(user_bsp_dir):
if dirname == board:
target.append([user_bsp_dir + "/" + dirname, []])
random.shuffle(target)
if len(target) == 0:
print("ERROR:No target select.")
return
for i in range(len(target)):
config_dir = target[i][0] + "/config"
for filename in tools.list_file(config_dir):
if filename.endswith(".config") and (
robot == "all" or robot == filename[:-7]
):
target[i][1].append([filename[:-7], 0.0])
print("Select config " + target[i][0] + " " + filename)
if len(target[i][1]) == 0:
print("ERROR:No target select.")
return
for item in target:
bsp = item[0]
for rbt_data in item[1]:
rbt = rbt_data[0]
rbt_data[1] = time.time()
config_file = bsp + "/config/" + rbt + ".config"
fm_board_dir = fm_dir + "/" + bsp.split("/")[-1]
fm_robot_dir = fm_board_dir + "/" + rbt
if os.path.exists(bsp + "/sdkconfig"):
select_config_idf(config_file, type)
os.system(
'bash -c "source ~/.idf_profile && cd ' + build_dir + ' && ninja"'
)
else:
select_config(config_file, type)
os.system("cd " + build_dir + " && ninja")
if not os.path.exists(build_dir + "/" + "xrobot.elf"):
print("\033[0;31;40mBuild " + bsp + " [" + rbt + "] failed.\033[0m")
exit(-1)
rbt_data[1] = time.time() - rbt_data[1]
time_count += rbt_data[1]
os.makedirs(fm_board_dir, exist_ok=True)
os.makedirs(fm_robot_dir, exist_ok=True)
if code_check:
os.makedirs(report_dir, exist_ok=True)
os.makedirs(report_ans_dir, exist_ok=True)
os.system(
"CodeChecker analyze " + build_dir + "/compile_commands.json"
" --enable sensitive --output " + report_dir
)
os.system(
"CodeChecker parse --export html --output "
+ report_ans_dir
+ " "
+ report_dir
)
os.system("cp -r " + report_ans_dir + " " + fm_robot_dir)
dirlist = os.walk(
build_dir,
)
for root, dirs, files in dirlist:
for file in files:
tmp_path = root[len(build_dir) :]
if tmp_path.count("/") > 1:
continue
if len(tmp_path) == 0:
tmp_path = "/"
else:
tmp_path = tmp_path + "/"
if (
file.endswith(".hex")
or file.endswith(".bin")
or file.endswith(".elf")
):
print("Found object", file)
os.makedirs(fm_robot_dir + "/" + tmp_path, exist_ok=True)
shutil.copyfile(
root + "/" + file,
fm_robot_dir + tmp_path + file.split("/")[-1],
)
os.system(
"md5sum "
+ fm_robot_dir
+ tmp_path
+ file.split("/")[-1]
+ " > "
+ fm_robot_dir
+ tmp_path
+ file.split("/")[-1]
+ ".md5"
)
for item in target:
bsp = item[0]
for rbt_data in item[1]:
rbt = rbt_data[0]
if bsp.startswith(bsp_dir):
print(
"\033[0;32;40mRobot["
+ rbt
+ "]"
+ " for board "
+ bsp[len(bsp_dir) + 1 :]
+ " build done in %.2f seconds.\033[0m" % rbt_data[1]
)
else:
print(
"\033[0;32;40mRobot["
+ rbt
+ "]"
+ " for custom board "
+ bsp[len(user_bsp_dir) + 1 :]
+ " build done in %.2f seconds.\033[0m" % rbt_data[1]
)
print("\033[0;32;40mAll target build done in %.2f seconds.\033[0m" % time_count)
def select(board, robot):
config_file = ""
for dirname in tools.list_dir(bsp_dir):
if dirname == board:
config_file = bsp_dir + "/" + dirname + "/config/" + robot + ".config"
for dirname in tools.list_dir(user_bsp_dir):
if dirname == board:
config_file = user_bsp_dir + "/" + dirname + "/config/" + robot + ".config"
if len(config_file) == 0:
print("No config file found")
exit(-1)
select_config(config_file, "Debug")
def generate_kconfig():
print("Start generate Kconfig.")
kconfig_file = open(
tools.project_path + "/config/auto.Kconfig", "w", encoding="utf8"
)
kconfig_file.write("# XRobot\n")
kconfig_file.write("# Auto generated file. Do not edit.\n")
kconfig_file.write("# -----------------------------------------------")
tools.kconfig_add_choice(
"board-",
"开发板",
kconfig_file,
[tools.list_dir(bsp_dir), tools.list_dir(user_bsp_dir)],
[bsp_dir, user_bsp_dir],
)
tools.kconfig_add_choice(
"system-",
"系统",
kconfig_file,
[tools.list_dir(sys_dir), tools.list_dir(user_sys_dir)],
[sys_dir, user_sys_dir],
)
tools.kconfig_add_choice(
"robot-",
"机器人",
kconfig_file,
[tools.list_dir(rbt_dir), tools.list_dir(user_rbt_dir)],
[rbt_dir, user_rbt_dir],
)
tools.kconfig_add_menu(
"component-", "组件", kconfig_file, [tools.list_dir(user_cmp_dir)], [user_cmp_dir]
)
tools.kconfig_add_menu(
"device-",
"设备",
kconfig_file,
[tools.list_dir(dev_dir), tools.list_dir(user_dev_dir)],
[dev_dir, user_dev_dir],
)
tools.kconfig_add_menu(
"module-",
"模块",
kconfig_file,
[tools.list_dir(mod_dir), tools.list_dir(user_mod_dir)],
[mod_dir, user_mod_dir],
)
kconfig_file.close()
print("Generate Kconfig done.")
def generate_cmake(path):
print("Start generate config.cmake.")
if os.path.exists(path + "/.config"):
print("Found config file.")
else:
tools.menuconfig(path)
config_file = open(path + "/.config", "r", encoding="utf8")
cmake_file = open(path + "/config.cmake", "w", encoding="utf8")
cmake_file.write("# XRobot\n")
cmake_file.write("# Auto generated file. Do not edit.\n")
cmake_file.write("set(CONFIG_PREFIX " + tools.config_prefix + ")\n")
for lines in config_file.readlines():
line = lines.rstrip("\n")
if not line:
continue
if line.startswith("#") and line.endswith(" is not set"):
tools.cmake_add_detail(cmake_file, line[2:-11], "0")
continue
if line.endswith("=y"):
tools.cmake_add_detail(cmake_file, line[:-2], "1")
continue
if line.startswith("#"):
continue
temp = line.split("=")
tools.cmake_add_detail(cmake_file, temp[0], temp[1])
config_file.close()
cmake_file.close()
print("Generate done.")
def new_component(name: str):
cppfile = open(
tools.project_path + "/src/component/comp_" + name + ".cpp",
mode="w+",
encoding="utf8",
)
cppfile.write('#include "comp_' + name + '.hpp"\n\nusing namespace Component;\n')
cppfile.close()
hppfile = open(
tools.project_path + "/src/component/comp_" + name + ".hpp",
mode="w+",
encoding="utf8",
)
hppfile.write(
"#include <component.hpp>\n\nnamespace Component {\n"
+ "class YourComponentName {\n"
+ " public:\n};\n"
+ "} // namespace Component"
)
hppfile.close()
print("Create new component [" + name + "] done.")
def new_device(name: str):
os.mkdir(tools.project_path + "/src/device/" + name)
cppfile = open(
tools.project_path + "/src/device/" + name + "/dev_" + name + ".cpp",
mode="w+",
encoding="utf8",
)
cppfile.write('#include "dev_' + name + '.hpp"\n\nusing namespace Device;\n')
cppfile.close()
hppfile = open(
tools.project_path + "/src/device/" + name + "/dev_" + name + ".hpp",
mode="w+",
encoding="utf8",
)
hppfile.write(
'#include "device.hpp"\n\nnamespace Device {\n'
+ "class YourDeviceName {\n"
+ " public:\n};\n"
+ "} // namespace Device"
)
hppfile.close()
configfile = open(
tools.project_path + "/src/device/" + name + "/Kconfig",
mode="w+",
encoding="utf8",
)
configfile.close()
infofile = open(
tools.project_path + "/src/device/" + name + "/info.cmake",
mode="w+",
encoding="utf8",
)
infofile.write(
"CHECK_SUB_ENABLE(MODULE_ENABLE device)\nif(${MODULE_ENABLE})\n "
'file(GLOB CUR_SOURCES "${SUB_DIR}/*.cpp")\n SUB_ADD_SRC(CUR_SOURCES)\n SUB_ADD_INC(SUB_DIR)\nendif()'
)
infofile.close()
print("Create new device [" + name + "] done.")
def new_module(name: str):
os.mkdir(tools.project_path + "/src/module/" + name)
cppfile = open(
tools.project_path + "/src/module/" + name + "/mod_" + name + ".cpp",
mode="w+",
encoding="utf8",
)
cppfile.write('#include "mod_' + name + '.hpp"\n\nusing namespace Module;\n')
cppfile.close()
hppfile = open(
tools.project_path + "/src/module/" + name + "/mod_" + name + ".hpp",
mode="w+",
encoding="utf8",
)
hppfile.write(
'#include "module.hpp"\n\nnamespace Module {\n'
+ "class YourModuleName {\n"
+ " public:\n};\n"
+ "} // namespace Module"
)
hppfile.close()
configfile = open(
tools.project_path + "/src/module/" + name + "/Kconfig",
mode="w+",
encoding="utf8",
)
configfile.close()
infofile = open(
tools.project_path + "/src/module/" + name + "/info.cmake",
mode="w+",
encoding="utf8",
)
infofile.write(
"CHECK_SUB_ENABLE(MODULE_ENABLE module)\nif(${MODULE_ENABLE})\n "
'file(GLOB CUR_SOURCES "${SUB_DIR}/*.cpp")\n'
" SUB_ADD_SRC(CUR_SOURCES)\n "
"SUB_ADD_INC(SUB_DIR)\nendif()"
)
infofile.close()
print("Create new module [" + name + "] done.")
def new_robot(name: str):
os.mkdir(tools.project_path + "/src/robot/" + name)
cppfile = open(
tools.project_path + "/src/robot/" + name + "/robot.cpp",
mode="w+",
encoding="utf8",
)
cppfile.write(
'#include "robot.hpp"\n\n#include <system.hpp>\n#include <thread.hpp>\n\nusing namespace Robot;\n\n'
)
cppfile.write(
"/* clang-format off */\n//TODO: write your param\n/* clang-format on */\n\n"
)
cppfile.write(
"void robot_init() {\n System::Start<Robot::YourRobotName, Robot::YourRobotName::Param>(param);\n}\n"
)
cppfile.close()
hppfile = open(
tools.project_path + "/src/robot/" + name + "/robot.hpp",
mode="w+",
encoding="utf8",
)
hppfile.write(
'/* #include "dev_xxx.hpp" */\n\nvoid robot_init();\n\nnamespace Robot {\n'
+ "class YourRobotName {\n"
+ " public:\n};\n"
+ "} // namespace Robot"
)
hppfile.close()
configfile = open(
tools.project_path + "/src/robot/" + name + "/Kconfig",
mode="w+",
encoding="utf8",
)
configfile.close()
print("Create new Robot [" + name + "] done.")
cmd = sys.argv
cmd_len = len(cmd)
if cmd_len < 2:
print("参数错误,请输入./project.py help")
exit()
if cmd[1] == "config":
tools.clean_cache()
generate_kconfig()
tools.guiconfig(cfg_dir)
generate_cmake(cfg_dir)
tools.config_cmake()
elif cmd[1] == "menuconfig":
tools.clean_cache()
generate_kconfig()
tools.menuconfig(cfg_dir)
generate_cmake(cfg_dir)
tools.config_cmake()
elif cmd[1] == "help":
print(welcome_str)
print(project_path_str + tools.project_path)
print("帮助页面/help")
print("#命令 - #功能")
print("help - 显示本页面")
print("config - 生成新配置(GUI)")
print("menuconfig - 生成新配置(Terminal)")
print("refresh - 重新生成cmake缓存")
print("clean - 清除编译产物")
print("build [BOARD] [ROBOT] - 构建目标")
print("list - 列出可构建目标")
print("init - 初始化submodule")
print("init-cn - 使用gitee镜像初始化submodule")
print("select [BOARD] [ROBOT] - 选择构建目标")
print("new [TYPE] [NAME] - 新建模块")
elif cmd[1] == "generate":
generate_cmake(cmd[2] + "/config")
elif cmd[1] == "refresh":
tools.clean_cache()
tools.config_cmake()
elif cmd[1] == "clean":
tools.clean_cache()
print("clean done.")
elif cmd[1] == "build":
if cmd_len < 4:
print("参数错误")
exit(-1)
build(cmd[2], cmd[3])
elif cmd[1] == "build-debug":
if cmd_len < 4:
print("参数错误")
exit(-1)
build(cmd[2], cmd[3], "Debug")
elif cmd[1] == "build-release":
if cmd_len < 4:
print("参数错误")
exit(-1)
build(cmd[2], cmd[3], "Release")
elif cmd[1] == "build-debug-check":
if cmd_len < 4:
print("参数错误")
exit(-1)
build(cmd[2], cmd[3], "Debug", True)
elif cmd[1] == "build-release-check":
if cmd_len < 4:
print("参数错误")
exit(-1)
build(cmd[2], cmd[3], "Release", True)
elif cmd[1] == "list":
list_target()
elif cmd[1] == "init":
os.system("git submodule init && git submodule update")
elif cmd[1] == "init-cn":
if os.path.exists(".gitmodules_cn"):
os.system("mv .gitmodules .gitmodules_en && mv .gitmodules_cn .gitmodules && git submodule init && git submodule update")
else:
os.system("git submodule init && git submodule update")
os.system("mv .gitmodules .gitmodules_cn && mv .gitmodules_en .gitmodules")
elif cmd[1] == "select":
if cmd_len < 4:
print("参数错误")
exit(-1)
select(cmd[2], cmd[3])
elif cmd[1] == "new":
if cmd_len < 4:
print("参数错误")
try:
eval("new_" + cmd[2] + "(cmd[3])")
except:
print("命令错误")
else:
print("参数错误,请输入./project.py help")
exit(0)
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化