软件需求

在开发嵌入式项目的时候,经常要添加文件到项目中进行管理,特别是开发LVGL等UI项目的时候 要手工添加很多c文件到项目中,如果没有添加完整很容易报错.

这时候就需要有个脚本来对比项目文件(.uprojx和.uproj)和项目根目录中的文件,那些文件已经添加了 那些没有添加,做一下对比.

软件功能

  1. 选择一个Keil5的项目文件(.uprojx,.uproj)
  2. 选择一个Keil5的项目根目录
  3. 自动根据项目文件内容,来对比已经导入的文件和未导入文件
  4. 输出结果,未导入的文件 output.log

Python环境

  1. 下载 Python3.8
  2. 安装依赖库 图形界面库tkinter
1
pip install tkinter

main.py 程序代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import os
import tkinter as tk
from tkinter import filedialog
import xml.etree.ElementTree as ET


def parse_keil_project(project_file_path):
    project_files = set()

    try:
        tree = ET.parse(project_file_path)
        root = tree.getroot()

        # 获取项目根目录
        project_root = os.path.dirname(project_file_path)

        for file_elem in root.iter("File"):
            file_path = file_elem.find("FilePath").text
            _, file_extension = os.path.splitext(file_path)
            if file_extension.lower() in (".c", ".cpp", ".s"):
                # 将相对路径解析为绝对路径
                absolute_path = os.path.abspath(os.path.join(project_root, file_path))
                project_files.add(absolute_path)

    except Exception as e:
        print(f"Error parsing project file: {e}")

    return project_files


def compare_files(project_files, compare_dir):
    missing_files = set()

    for root, _, files in os.walk(compare_dir):
        for file in files:
            file_path = os.path.abspath(os.path.join(root, file))  # 获取绝对路径
            _, file_extension = os.path.splitext(file_path)
            if file_extension.lower() in (".c", ".cpp", ".s"):
                if file_path not in project_files:
                    missing_files.add(file_path)

    return missing_files


def main():
    root = tk.Tk()
    root.withdraw()  # 隐藏主窗口

    # 选择项目文件
    project_file_path = filedialog.askopenfilename(title="选择Keil项目文件",
                                                   filetypes=[("Keil Project Files", "*.uvprojx *.uvproj")])
    if not project_file_path:
        print("未选择项目文件。")
        return

    # 选择对比目录
    compare_dir = filedialog.askdirectory(title="选择需要对比的目录")
    if not compare_dir:
        print("未选择对比目录。")
        return

    # 解析项目文件
    project_files = parse_keil_project(project_file_path)

    # 比较文件并记录结果
    missing_files = compare_files(project_files, compare_dir)

    # 记录比较结果到日志文件,按路径排序
    log_file = "output.log"
    added_file = "added.log"

    with open(log_file, "w") as f:
        f.write("以下文件在项目中不存在:\n")
        for missing_file in sorted(missing_files):  # 按路径排序
            f.write(missing_file + "\n")

    print(f"比较完成,结果已记录到 {log_file}。")


if __name__ == "__main__":
    main()

运行

1
python main.py

输出结果

output.log

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
以下文件在项目中不存在:
E:\demo_lvgl\LCDRGB565\app\lvgl\src\draw\sdl\lv_draw_sdl_arc.c
E:\demo_lvgl\LCDRGB565\app\lvgl\src\draw\sdl\lv_draw_sdl_bg.c
E:\demo_lvgl\LCDRGB565\app\lvgl\src\draw\sdl\lv_draw_sdl_composite.c
E:\demo_lvgl\LCDRGB565\app\lvgl\src\draw\sdl\lv_draw_sdl_img.c
E:\demo_lvgl\LCDRGB565\app\lvgl\src\draw\sdl\lv_draw_sdl_label.c
E:\demo_lvgl\LCDRGB565\app\lvgl\src\draw\sdl\lv_draw_sdl_layer.c
E:\demo_lvgl\LCDRGB565\app\lvgl\src\draw\sdl\lv_draw_sdl_line.c
E:\demo_lvgl\LCDRGB565\app\lvgl\src\draw\sdl\lv_draw_sdl_mask.c
E:\demo_lvgl\LCDRGB565\app\lvgl\src\draw\sdl\lv_draw_sdl_polygon.c
E:\demo_lvgl\LCDRGB565\app\lvgl\src\draw\sdl\lv_draw_sdl_rect.c
E:\demo_lvgl\LCDRGB565\app\lvgl\src\draw\sdl\lv_draw_sdl_stack_blur.c
E:\demo_lvgl\LCDRGB565\app\lvgl\src\draw\sdl\lv_draw_sdl_texture_cache.c
E:\demo_lvgl\LCDRGB565\app\lvgl\src\draw\sdl\lv_draw_sdl_utils.c
E:\demo_lvgl\LCDRGB565\app\lvgl\src\draw\stm32_dma2d\lv_gpu_stm32_dma2d.c
E:\demo_lvgl\LCDRGB565\app\lvgl\src\draw\swm341_dma2d\lv_gpu_swm341_dma2d.c
E:\demo_lvgl\LCDRGB565\app\lvgl\src\extra\lv_extra.c