kicad文件解析器c++移植
首先需要感谢trae和https://github.com/Steffen-W/KiCadFiles,没有你们就没有开始和本文。
这个是自有项目开发中重要的一个环节是实现kicad文件的解析器,使用的是trae工具。
最初的时候是直接使用kicad的源码进行移植,主要是想移植pcbnew和essschematic模块,由于源代码复杂,涉及多个库和太多的文件,失败了。
在加上设计的时候提出了不切实际的想法,比如想转化为proto buffer,这个就比较花时间了。
还有个问题就是移植的过程无法调试,主要的原因是kicad源码太大,太多,极限的情况下c++有个文件有57kB,导致中间遇到错误时,调试的时间不可控;而且AI有时候有作弊的习惯,经常会提出所谓的简化版本,其实都是浪费时间。而且trae写代码飞快,天马行孔,很快洋洋洒洒就是几千行。
后来感觉移植kicad源码的方式走不通,后来就找到了一个kicadfiles的pyhon库,觉得以这个为基础进行移植。汲取以前的教训,这次移植的过程中是边移植边测试。
这次了先让trae进行了代码的分析,觉得采取分步骤进行,边移植边测试的进行。
首先移植了基础的base_type,sexp_data等模块,然后要求trae进行c++和python交叉测试,每次都要求进行交叉测试和验证。
然后移植primitive_graphics和advanced_graphics等模块,同样要求trae进行c++和python交叉测试,每次都要求进行交叉测试和验证和进行回归测试。这里在移植的时候发现trae实现的代码糅合太紧,要求trae进行了解析的分层处理,然后是同样的进行C++和python交叉测试和回归测试。
接着把PCB部分pad_and_drill进行移植,同样要求trae进行c++和python交叉测试,每次都要求进行交叉测试和验证和进行回归测试。
下面是当时给TRAE的记录:
footprint_library
详细梳理primitive_graphics.py 的所有字段,然后逐字段对比 Python 和 C++ 的 to_sexpr/from_sexpr 行为,C++ 输出纯文本,Python 逐行读取解析。并编写测试验证,解决bug.
Rect(token=“rect”) 无 C++无对应类
Rectangle(token=“rectangle”) 无 C++无对应类
Bezier(token=“bezier”) 无 C++无对应类
Polygon(token=“polygon”) 无 C++无对应类把这些补全,然后详细梳理primitive_graphics.py 的所有字段,然后逐字段对比 Python 和 C++ 的 to_sexpr/from_sexpr 行为,并编写测试验证,解决bug.
详细梳理pad_and_drill.py 的所有字段,然后逐字段对比 Python 和 C++ 的 to_sexpr/from_sexpr 行为,并编写测试验证,解决bug.
详细梳理zone_system.py 的所有字段,然后逐字段对比 Python 和 C++ 的 to_sexpr/from_sexpr 行为,并编写测试验证,解决bug.
The section order is not critical other than the header must be the first token.
详细梳理advanced_graphics.py 的所有字段,然后逐字段对比 Python 和 C++ 的 to_sexpr/from_sexpr 行为,并编写测试验证,解决bug.
详细梳理footprint_library.py 的所有字段,然后逐字段对比 Python 和 C++ 的 to_sexpr/from_sexpr 行为,并编写测试验证
详细梳理symbol_library.py 的所有字段,补全缺失字段,然后逐字段对比 Python 和 C++ 的 to_sexpr/from_sexpr 行为,并编写测试验证,解决bug.
实现symbol_library.py 的对应的C++移植到symbol_library.h和symbol_library.cpp中,然后逐字段对比 Python 和 C++ 的 to_sexpr/from_sexpr 行为,并编写测试验证,解决bug.
基础模块和辅助模块移植和测试完后。进行比较核心的board_layout的移植,这个因为包含很多模块,同样也是要求进行c++和python的交叉测试,中间有回到footprint_library模块进行修正和测试。测试和验证通过后就把源PCB文件加进来进行测试,测试通过了,这时人的信心大增,非常高兴。
接下来就把原理图相关的基础模块也进行了移植,同样进行了c++和pyhon的交叉对比测试和回归测试,因为开始觉得可能形成可工作的版本,同时模块代码量也起来了,把基础代码include和src开始做版本管理,每个版本入库前都要求做所有的测试和回归测试。原理图模块也慢慢顺利开发出来了。
幸运的事情终于慢慢发生了,原理图,pcb和元器件的封装等慢慢都成型并进行了测试,实际的文件都能被KICAD打开。当时的心情非常激动,因为前面失败了好多次,模块变大后调试困难失败了好几次了。
后面是效率提升,优化版本
现在的任务是重新E:\aicode\kicad-bindings\pcb10\jetson-agx-thor-baseboard.kicad_pcb为测试对象,使用test_board_layout.cpp分析parse和to_sexpr的时间,给出优化方案提升速度。
这个时候AI会给出几个方案,这些方案有改动大的,有改动小的,我一般选择重要的,修改范围小的进行实施,每次实施前都做好版本备份。AI实施代码优化会很快,天马行空的很快就能完成,这时候一定要做现成的所有测试和回归测试,也可以考虑增加新的测试样本和测试用例,
这是顺利实施后的效果。人生不如意,十之八九,AI也会换错。这时候入库保存的代码就派上用处了。
优化阶段我总体的原则是选重要的,容易实施的进行,当然也要对AI产生的代码进行分析。
当然我也提出了些其他的方法:比如使用fast_float库,

优化是个漫长和有趣的事情。中间还是发生了很多次回归测试失败的事情。
这时候就需要把入库的文件重新提取出来,进行回归测试和所有能想到的测试。
优化工程和代码改动的过程中有时我会把trae退出了,删除build目录下的文件,然后要求重新编译,避免有时可能使用旧的lib文件的问题。
优化前的耗时:
优化后的
被AI拒绝的方案:
最后那个激进的方案我一直没有实施。Token 使用 string_view(之前的激进方案,风险较高但收益 15-25%)
从优化项来看我基本选择的都是改动小,波及范围不大的改进方案,基本上拒绝了伤筋动骨那种的优化方案。


• SExprList 是 序列化(to_sexpr)和反序列化(from_sexpr)的核心桥梁
• 热路径(Board/Footprint/Pad/Zone/Track/Via)已通过 parse_skip_name 绕过 AST
• 但仍有 120+ 个 from_sexpr 函数 和 80+ 个 to_sexpr 构造 依赖 SExprList
• 这些主要服务于:SCH 文件解析、SYM 文件解析、图形元素、尺寸标注等非 PCB 热路径
最后的结果肯定不是最优,优化性能提升了四倍,我觉得够用了。
仓库:https://github.com/zlyadvocate/kicadfileparse-
更多推荐
所有评论(0)