Calibre 编码乱码速查:BOM、CRLF、GBK 与中文路径
更新时间:2026-10-22。FAQ 速查页,属于 EDA 工具排错系列,总入口见 开源 EDA 报错排错中心。Calibre(Siemens EDA 的物理验证工具,DRC/LVS/PEX 三件套)解析 SVRF deck 与 runset 时按字节读文件,对文件编码的容忍度比现代脚本语言低得多:文件头三个不可见的 BOM 字节能让
LAYOUT PRIMARY变成「不认识的命令」,Windows 保存的 CRLF 能让行尾续接\断掉,工艺厂或同事在 GBK 环境下写的中文注释拿回来满屏乱码。这类问题的共同特征是报错位置和真实原因经常不在一起,且「文件路径看着完全正确却打不开」。SVRF 语句本身的语法错见 Calibre 语法/解析报错,启动配置与 runset 链路见 Calibre 配置解析失败,deck 五段结构见 Calibre SVRF rule deck 解剖,验证流程全貌见 Calibre 物理验证实操。
本文要回答的问题
- deck 第一行明明是
LAYOUT PRIMARY,为什么 Calibre 报首行命令不识别? - 行尾续接符
\后面没有空格,为什么下一行还是被当成独立语句? - 工艺厂给的 deck 在对方机器正常,我这里中文注释全是乱码甚至
invalid character,差在哪? - transcript 里路径逐字符看着都对,为什么
Cannot open file? - ASCII 报告和 PDF 报告里的中文一个变问号、一个变方块,分别是谁的问题?
一、报错原文与典型现象
编码类问题的第一信号往往不是「乱码」本身,而是莫名其妙的解析错或文件打不开。以下是四类典型文案,工程名与路径已占位:
1. 文件开头或首行命令解析失败(BOM 的典型咬法):
***** ERROR: Unrecognized command "LAYOUT PRIMARY" encountered at line 1.
***** ERROR: Illegal character encountered at line 1 of file "proj_rules.svrf".2. 续行断裂、行尾 token 不识别(CRLF 的典型咬法):
***** ERROR: Syntax error near "\" at line 87 of file "proj_rules.svrf".
***** ERROR: Unexpected token "LAYER" encountered while parsing statement.3. 非 ASCII 字节混入语句,或报告文本乱码:
***** ERROR: invalid character '\x80' in rule file at line 64.
// transcript / ASCII 报告里: M1 间距规则 -> M1 ?????
// PDF 报告里同样的位置:中文全部显示为空心方块4. 路径打不开,但肉眼核对无误:
***** ERROR: Cannot open include file "/proj/项目A/rules/stack.svrf".
***** ERROR: Cannot open layout file "/data/run 01/top.gds".第一条判据:报错落在 line 1、报文里夹着形如 \xEF 或看不见的前缀,直接怀疑编码,不用往后读;路径类报错先把路径用引号原样 ls 一遍,能 ls 通而 Calibre 打不开,问题就在字符编码或运行环境,而不是文件是否存在。
二、报错现象到根因总览
| 报错现象 | 可能原因 | 处置 |
|---|---|---|
| line 1 报错、首命令前有无可见前缀 | 文件带 UTF-8 BOM(EF BB BF) | 去 BOM 重存为 UTF-8 no BOM |
报在行尾 \ 之后,下一行被当独立语句 | CRLF 行尾,反斜杠后跟了 CR | dos2unix 转 LF |
| deck 注释或 TEXT 输出中文乱码 | 文件在 GBK 与 UTF-8 间编码不一致 | iconv 显式转 UTF-8,全流程统一 |
| invalid character 加十六进制码值 | 全角标点或多字节字符落进 SVRF 语句 | 全角符号改半角,注释改英文 |
| 日志中文变问号,两机表现不同 | 进程 locale 是 C/POSIX 或未设置 | 作业封装统一 LC_ALL=zh_CN.UTF-8 或 C.UTF-8 |
| 控制台正常、报告文件/PDF 方块 | 查看端或报告字体不支持中文 | 查看端按 UTF-8 重开;PDF 换支持中文的字体配置 |
| Cannot open file 但路径看着对 | 路径含中文、空格,老版本 calibredrv/xterm 处理异常 | 工程路径全 ASCII 化,空格用下划线 |
| 文件在 Windows 编辑后行为整体异常 | SFTP/FTP 文本模式自动转换了换行与编码 | 传输固定二进制模式,传后 file/xxd 复验 |
| 同一 deck 换机器或换提交账号才复现 | 账号 shell 的 LANG/LC_ALL 不一致 | 不靠交互环境,写进提交封装脚本 |
| 网上抄的 CALIBRE 编码变量设置后更乱 | 版本相关变量名与语义随发行版变化 | 只按当前版本手册核对,不照抄旧帖 |
三、逐条排查展开
先看文件字节,再看 locale,最后才怀疑路径与查看端。 三条命令把嫌疑对象钉死:
file -i proj_rules.svrf # charset=utf-8 / iso-8859-1 / us-ascii,加 CRLF 会另标
head -c 32 proj_rules.svrf | xxd # 头三字节 ef bb bf 即 BOM;行尾看到 0d0a 即 CRLF
grep -nP $'[\x80-\xff]' proj_rules.svrf | head # 列出所有含非 ASCII 字节的行file -i 给出文件自报的字符集:标 iso-8859-1 或 unknown-8bit 而内容里本该有中文,基本就是 GBK 文件被当成了单字节文本;xxd(或 hexdump -C)看头部和行尾,不依赖任何编辑器的解码行为。报错行号与真实问题的偏差规律:BOM 只咬第一行;CRLF 每行都带毒,但报错常落在第一个续行或第一个长 token 处;隐藏的多字节字符报错位置与肉眼位置差几个字符。
BOM:让首行命令「神秘不识别」的头号嫌犯。 Windows 记事本、部分编辑器默认给 UTF-8 文件加 BOM,即文件开头三个字节 EF BB BF。SVRF 解析器不认这个标记,把它当作首条命令名的一部分,于是 LAYOUT PRIMARY、@set 这类本应在第一行生效的环境语句全部失效,后面的 INCLUDE 找不到变量、层定义缺失,连环报错可以滚几十行。判别就是上面的 xxd;处置只动头三个字节:
sed -i '1s/^\xEF\xBB\xBF//' proj_rules.svrf根治纪律:所有 deck、runset、include 片段统一 UTF-8 no BOM,编辑器模板固化,别靠人记。
CRLF:让行尾续接 \ 失效的跨平台税。 SVRF 长语句用行尾反斜杠续行,规则极硬:反斜杠必须是该行最后一个字节。Windows 保存后行尾变成 0d 0a,反斜杠后面跟着的 CR 使续接中断,下一行被当作独立语句,报错落在下一行第一个 token 上——那一行怎么看都没问题。vim 里行尾的 ^M 就是它。处置:
dos2unix proj_rules.svrf proj_run.drc
# 没有 dos2unix 时:sed -i 's/\r$//' proj_rules.svrf预防靠仓库根的 .gitattributes 给 *.svrf、*.drc、*.lvs 强制 text eol=lf,Windows 侧检出也是 LF,比事后逐个转换省事。
字符集:GBK 与 UTF-8 不一致时,乱码和 invalid character 二选一。 工艺厂 deck、老项目归档、Windows 侧编辑器常常是 GBK;在 UTF-8 环境下直接读,多字节中文被拆成非法单字节,轻则注释乱码,重则某个字节恰好落进语句区触发 invalid character。反向事故也有:UTF-8 文件被 GBK 终端或旧脚本二次处理,中文与全角标点整体变形。不要在原文件上猜着改,先探测再显式转码,转完保留原始副本:
iconv -f GBK -t UTF-8 proj_rules.gbk.svrf -o proj_rules.svrfSVRF 注释符只有 //;稳妥做法是规则语句区只放 ASCII,规则说明确需中文时与工艺厂确认整条工具链(deck 编辑、提交、Calibre 版本、报告生成)都按 UTF-8 跑,任何一环是 GBK 就统一改英文注释。全角括号、全角逗号、中文引号一旦混进语句,解析器一律按非法字节处理,可用 grep -nP "[\x{FF01}-\x{FF5E}]" 扫出。
locale:决定 Calibre 怎么解释多字节字符和报错文本。 进程的 LANG/LC_ALL 为空、C 或 POSIX 时,多字节字符按单字节拆解,中文路径与中文报告文本就可能出问号;两台机器 locale 不同,「我这里能跑」是固定事故形态。网格作业继承的是提交时的环境,交互式 export 不算数:
locale | grep -E 'LANG|LC_ALL'处置是把 export LC_ALL=zh_CN.UTF-8(需要中文报告)或 C.UTF-8(纯英文环境的稳妥选择)写进作业提交封装,并在提交前 locale -a 确认该 locale 在机器上确实装了。至于网上流传的各种 CALIBRE_ 前缀编码变量,名称与语义随发行版本变化,不要照抄旧帖;确有特殊编码需求时,只以当前 Calibre 版本手册为准,并在项目内固定一处设置、加注释说明来由。
中文与空格路径:路径「看着对」却打不开的另一半。 老版本 calibredrv、xterm 启动的 GUI、部分脚本封装对非 ASCII 路径和空格的处理不完善:shell 里 ls 能通,是因为 shell 正确处理了字节;Calibre 内部拼接 include 路径或把路径传给 xterm 时可能二次解码或截断,报出 Cannot open file,而 transcript 里打印的路径与真实字节并不相同(显示层已经转过一道)。排查用 ls -lb 看转义后的真实字节;工程纪律是项目目录、GDS/OASIS 数据路径、deck 路径一律 ASCII,空格用下划线代替,从工程命名规范层面消灭问题,而不是逐个版本碰运气。
传输环节:SFTP 文本模式会替你「改」文件。 从 Windows 向 Linux 传 deck 时若客户端用文本/ASCII 模式,传输过程可能自动改写换行符,个别工具链还会触碰编码;二进制文件(GDS、OASIS)被文本模式处理则会直接损坏。固定做法:SFTP/SCP/传输工具一律二进制模式(binary/bin),传完在目标机用 file -i 与 xxd | head 复验头部和行尾,确认与源端字节一致再提交回归。
下面这张决策树把六类根因压成一条收敛路径,任何一层命中就在那一层修,不要跳着改文件:
读这张图抓住「先验字节、再查 locale、最后怀疑路径与查看端」:红色入口是现象,四个蓝色节点是排查动作,按 file -i 与 xxd 的输出对号入座;橙色是修复手段,一次只做一类转换并重跑;紫色是收尾防复发。控制台正常而报告/PDF 乱码属于查看端或报告字体问题,不在这棵树上——先在服务器上直接 file 报告文件确认实际编码,再让查看端匹配,不要反过来改 deck。
四、预防与纪律
- 源文件三统一:deck、runset、include 片段一律 UTF-8、no BOM、LF 换行,写进团队编辑器模板与提交检查。
.gitattributes强制换行:*.svrf *.drc *.lvs text eol=lf,跨平台协作不再带 CR。- 作业封装固定 locale:
LC_ALL写进提交脚本而不是交互环境,所有回归机器统一,提交前locale -a确认。 - 工程路径全 ASCII:目录名、数据文件名不用中文和空格;规则语句区只放 ASCII,中文注释要走就整条链确认 UTF-8。
- 传输固定二进制模式:传完
file -i+xxd | head复验头部与行尾,GDS/OASIS 严禁文本模式。 - CALIBRE 编码变量只信当前版本手册:不照抄旧帖,项目内集中设置并注明来由。
这一篇在知识体系里的位置
本篇是 EDA 排错速查簇中「字符编码」节点的 Calibre FAQ 页,总入口见 开源 EDA 报错排错中心。编码字节正常之后仍报 SVRF 语法错,按 Calibre 语法/解析报错 追括号、引号与续行符;启动阶段 runset、INCLUDE 变量与命令行开关问题见 Calibre 配置解析失败。deck 五段结构与 // @ 规则说明机制见 Calibre SVRF rule deck 解剖,验证流程与产物位置见 Calibre 物理验证实操。
一句话总结
Calibre 编码乱码按「文件字节 → 进程 locale → 路径与查看端」三层排查:xxd 认头三字节 BOM 与行尾 CRLF,file -i 判 GBK/UTF-8 字符集并用 iconv 显式转换,locale 确认 LC_ALL 不是 C/POSIX 且写进作业封装,中文与空格路径全 ASCII 化、SFTP 固定二进制传输;根治靠「UTF-8 no BOM + LF + ASCII 路径」三条纪律写进编辑器模板、.gitattributes 与工程命名规范,让编码问题从玄学变常识。