release.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. import sys
  2. import os
  3. import json
  4. import zipfile
  5. # 切换到项目根目录
  6. os.chdir(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
  7. def get_board_type():
  8. with open("build/compile_commands.json") as f:
  9. data = json.load(f)
  10. for item in data:
  11. if not item["file"].endswith("main.cc"):
  12. continue
  13. command = item["command"]
  14. # extract -DBOARD_TYPE=xxx
  15. board_type = command.split("-DBOARD_TYPE=\\\"")[1].split("\\\"")[0].strip()
  16. return board_type
  17. return None
  18. def get_project_version():
  19. with open("CMakeLists.txt") as f:
  20. for line in f:
  21. if line.startswith("set(PROJECT_VER"):
  22. return line.split("\"")[1].split("\"")[0].strip()
  23. return None
  24. def merge_bin():
  25. if os.system("idf.py merge-bin") != 0:
  26. print("merge bin failed")
  27. sys.exit(1)
  28. def zip_bin(board_type, project_version):
  29. if not os.path.exists("releases"):
  30. os.makedirs("releases")
  31. output_path = f"releases/v{project_version}_{board_type}.zip"
  32. if os.path.exists(output_path):
  33. os.remove(output_path)
  34. with zipfile.ZipFile(output_path, 'w', compression=zipfile.ZIP_DEFLATED) as zipf:
  35. zipf.write("build/merged-binary.bin", arcname="merged-binary.bin")
  36. print(f"zip bin to {output_path} done")
  37. def release_current():
  38. merge_bin()
  39. board_type = get_board_type()
  40. print("board type:", board_type)
  41. project_version = get_project_version()
  42. print("project version:", project_version)
  43. zip_bin(board_type, project_version)
  44. def get_all_board_types():
  45. board_configs = {}
  46. with open("main/CMakeLists.txt") as f:
  47. lines = f.readlines()
  48. for i, line in enumerate(lines):
  49. # 查找 if(CONFIG_BOARD_TYPE_*) 行
  50. if "if(CONFIG_BOARD_TYPE_" in line:
  51. config_name = line.strip().split("if(")[1].split(")")[0]
  52. # 查找下一行的 set(BOARD_TYPE "xxx")
  53. next_line = lines[i + 1].strip()
  54. if next_line.startswith("set(BOARD_TYPE"):
  55. board_type = next_line.split('"')[1]
  56. board_configs[config_name] = board_type
  57. return board_configs
  58. def release(board_type, board_config):
  59. config_path = f"main/boards/{board_type}/config.json"
  60. if not os.path.exists(config_path):
  61. print(f"跳过 {board_type} 因为 config.json 不存在")
  62. return
  63. # Print Project Version
  64. project_version = get_project_version()
  65. print(f"Project Version: {project_version}", config_path)
  66. release_path = f"releases/v{project_version}_{board_type}.zip"
  67. if os.path.exists(release_path):
  68. print(f"跳过 {board_type} 因为 {release_path} 已存在")
  69. return
  70. with open(config_path, "r") as f:
  71. config = json.load(f)
  72. target = config["target"]
  73. builds = config["builds"]
  74. for build in builds:
  75. name = build["name"]
  76. if not name.startswith(board_type):
  77. raise ValueError(f"name {name} 必须 {board_type} 开头")
  78. sdkconfig_append = [f"{board_config}=y"]
  79. for append in build.get("sdkconfig_append", []):
  80. sdkconfig_append.append(append)
  81. print(f"name: {name}")
  82. print(f"target: {target}")
  83. for append in sdkconfig_append:
  84. print(f"sdkconfig_append: {append}")
  85. # unset IDF_TARGET
  86. os.environ.pop("IDF_TARGET", None)
  87. # Call set-target
  88. if os.system(f"idf.py set-target {target}") != 0:
  89. print("set-target failed")
  90. sys.exit(1)
  91. # Append sdkconfig
  92. with open("sdkconfig", "a") as f:
  93. f.write("\n")
  94. for append in sdkconfig_append:
  95. f.write(f"{append}\n")
  96. # Build with macro BOARD_NAME defined to name
  97. if os.system(f"idf.py -DBOARD_NAME={name} build") != 0:
  98. print("build failed")
  99. sys.exit(1)
  100. # Call merge-bin
  101. if os.system("idf.py merge-bin") != 0:
  102. print("merge-bin failed")
  103. sys.exit(1)
  104. # Zip bin
  105. zip_bin(name, project_version)
  106. print("-" * 80)
  107. if __name__ == "__main__":
  108. if len(sys.argv) > 1:
  109. board_configs = get_all_board_types()
  110. found = False
  111. for board_config, board_type in board_configs.items():
  112. if sys.argv[1] == 'all' or board_type == sys.argv[1]:
  113. release(board_type, board_config)
  114. found = True
  115. if not found:
  116. print(f"未找到板子类型: {sys.argv[1]}")
  117. print("可用的板子类型:")
  118. for board_type in board_configs.values():
  119. print(f" {board_type}")
  120. else:
  121. release_current()