ARMCC编译器安装配置指南:解决老工程编译报错与版本兼容问题

简介:ARM Compiler Version 5(ARMCC)是ARM公司面向ARM架构处理器推出的高效编译工具链,适合嵌入式开发工程师、物联网与汽车电子从业者,以及需要为Cortex-A/R/M系列编写、编译和优化底层软件的开发者。资源包共650个文件,约56.83MB,以242个b文件、242个l文件、70个h头文件、24个cc源文件为主,并包含exe可执行程序、s汇编文件、map与elmap映射文件,以及algorithm、vector、iostream、memory等C++标准库头文件,覆盖编译器、链接器、汇编器与调试工具链的完整组成。内容涉及ARM指令集支持、O0至O3代码优化、ELF链接、调试信息生成、浮点运算与代码大小优化,并集成CMSIS统一硬件访问接口。目前已有4270人学习下载,可帮助读者理解ARMCC的编译流程、优化策略与标准库组织方式,为嵌入式项目开发与工具链排错提供参考。

1. ARMCC 编译器安装:为什么老项目总卡在 Version 5 这一关

接手一个十年前量产的工业控制板项目,打开工程文件第一眼就看到ARMCC的路径指向C:\Keil_v5\ARM\ARMCC\bin,而本机装的却是 Keil MDK 5.37 自带的 ARM Compiler 6。编译按钮按下去,满屏error: unknown argument,那一刻你就明白,ARM Compiler Version 5 这个老家伙不是想绕就能绕过去的。ARMCC 是 ARM 公司被收购前推出的编译器套件,属于 ARM Compiler 5 工具链的核心组件,大量基于标准外设库、老版 RTOS 和遗留启动代码的工程都绑死在它上面。装不上或者装错版本,轻则编译报错,重则链接出来的镜像跑飞,连调试器都连不上。这篇笔记面向的是手里有老工程、需要把 ARMCC 环境重新搭起来的开发者,从版本选择、目录规划、环境变量配置一路写到编译验证和常见翻车现场,照着走完,至少能让你的老工程重新吐出.axf文件。

2. 装前准备:ARMCC 版本选择与目录规划

2.1 先搞清楚 ARMCC 和 ARM Compiler 5 的关系

很多人把 ARMCC 和 ARM Compiler 5 混着叫,实际上 ARMCC 是 ARM Compiler 5 里的 C/C++ 编译器可执行文件,同套件里还有armasm、armlink、fromelf这几个工具。ARM Compiler 5 的版本号通常以5.06结尾,比如5.06 update 6、5.06 update 7,这是最后几个被广泛使用的稳定版。再往后的 ARM Compiler 6 换成了基于 LLVM 的armclang,命令行参数和 ARMCC 不兼容,所以老工程迁移时最省事的做法不是改工程,而是把 ARMCC 装回来。

我一般会先确认工程里Options for Target的编译器版本要求。如果工程文件里写的是ARMCC而不是armclang,那就老老实实装 ARM Compiler 5。版本选择上,5.06 update 7是比较稳妥的选择,它对 C99 的支持比早期版本完整,又不像某些中间版本那样在链接脚本处理上有玄学问题。如果你手头有厂商提供的 BSP 包,优先用 BSP 里附带的编译器版本,因为厂商的启动文件和链接脚本往往是针对特定版本验证过的。

2.2 目录规划:别把 ARMCC 塞进系统盘默认路径

ARM Compiler 5 的安装包通常是一个自解压的 exe,默认会往C:\Keil_v5\ARM\ARMCC或者C:\Program Files\ARM\ARM_Compiler_5.06u7这类路径释放。我的习惯是把它放到一个独立目录,比如D:\Tools\ARM_Compiler_5.06u7,理由有两个:一是避免和 Keil MDK 自带的编译器目录打架,二是重装系统或者换机器时整个目录拷走就能用,不需要重新跑安装程序。

目录结构大概长这样:

D:\Tools\ARM_Compiler_5.06u7\ ├── bin\ │ ├── armcc.exe │ ├── armasm.exe │ ├── armlink.exe │ └── fromelf.exe ├── include\ │ ├── stdint.h │ └── ... ├── lib\ │ └── armlib\ └── license\

bin目录是后面要加进 PATH 的,include和lib是编译时自动引用的,license目录里放的是授权文件。如果你用的是 Keil MDK 自带的 ARMCC,路径通常在C:\Keil_v5\ARM\ARMCC,但那个版本可能被 Keil 改过配置,独立安装的版本更干净。

2.3 环境变量配置:PATH 和 ARMCC5 相关变量

装完之后最关键的一步是把bin目录加进系统 PATH。Windows 下我一般用命令行改,避免图形界面点错:

# 以管理员身份打开 cmd,把 ARMCC 的 bin 目录追加到系统 PATH setx /M PATH "%PATH%;D:\Tools\ARM_Compiler_5.06u7\bin"

这条命令会把路径写进系统环境变量,重启终端后生效。注意setx有长度限制,如果 PATH 已经很长,可能会截断,这时候建议用图形界面手动编辑,或者用 PowerShell 的[Environment]::SetEnvironmentVariable方法。

除了 PATH,有些老工程还会引用ARMCC5_INC和ARMCC5_LIB这两个变量,用来指定头文件和库文件路径。如果你的工程 Makefile 里有类似-I$(ARMCC5_INC)的写法,就需要补上:

setx /M ARMCC5_INC "D:\Tools\ARM_Compiler_5.06u7\include" setx /M ARMCC5_LIB "D:\Tools\ARM_Compiler_5.06u7\lib"

配完之后开一个新的 cmd 窗口,敲armcc --version,如果能看到版本号输出,说明 PATH 生效了。如果提示「不是内部或外部命令」,先检查路径里有没有空格或者中文,ARMCC 对中文路径的支持时好时坏,尽量用纯英文路径。

3. 安装与授权:ARMCC 5.06u7 落地步骤

3.1 获取安装包与校验文件完整性

ARM Compiler 5 的安装包通常以ARMCompiler5.06u7.exe或者ARM_Compiler_5.06u7_Win.exe命名,大小在 200MB 到 400MB 之间。拿到安装包之后,先核对一下文件哈希,避免下载过程中损坏。我一般用certutil算 SHA256:

certutil -hashfile ARMCompiler5.06u7.exe SHA256

把输出和官方提供的哈希值对比,一致再往下走。如果哈希对不上,重新下载,别抱着侥幸心理硬装,编译器文件损坏导致的报错往往很隐蔽,可能编译到一半才崩。

3.2 静默安装与自定义路径

ARM Compiler 5 的安装程序支持静默安装,适合批量部署或者写进自动化脚本。命令大概是这样:

# 静默安装到指定目录,不创建桌面快捷方式 ARMCompiler5.06u7.exe --mode silent --install_to D:\Tools\ARM_Compiler_5.06u7 --no_shortcut

参数说明:--mode silent表示无交互安装,--install_to指定目标路径,--no_shortcut跳过快捷方式创建。如果你不确定安装程序支持哪些参数,可以先跑ARMCompiler5.06u7.exe --help看看。有些版本的安装包参数名不太一样,比如用-silent而不是--mode silent,这个要按实际安装包的提示来。

安装完成后,去目标目录下确认bin\armcc.exe存在,并且文件大小正常。如果安装程序中途报错,先看日志文件,通常在%TEMP%目录下,文件名类似ARMCompiler_install.log。

3.3 授权文件配置:License 放哪里、怎么指向

ARM Compiler 5 需要授权文件才能正常编译,未授权版本会在编译时提示License error或者限制代码大小。授权文件通常是一个.dat文件,比如license.dat。配置方式有两种:一种是把授权文件放到license目录下,另一种是通过环境变量ARMCC5_LICENSE指向授权文件路径。

我一般用环境变量方式,方便切换不同授权:

setx /M ARMCC5_LICENSE "D:\Tools\ARM_Compiler_5.06u7\license\license.dat"

配完之后,在 cmd 里跑armcc --license或者直接编译一个简单文件,看是否还有授权报错。如果提示找不到授权,检查文件路径有没有写错,以及授权文件是否和编译器版本匹配。不同版本的 ARMCC 对授权文件的格式要求不一样,5.06u7 的授权不能直接给 5.06u6 用。

提示:授权文件属于敏感文件,不要放到版本控制仓库里,也不要通过公开渠道传输。我一般会在.gitignore里加上*.dat和license/目录。

4. 工程集成:让 Keil 和 Makefile 都认到 ARMCC

4.1 Keil MDK 里切换编译器版本

如果你用的是 Keil MDK,切换编译器版本在Project -> Options for Target -> Target标签页里,有一个ARM Compiler下拉框。默认可能是Use default compiler version 6,改成Use default compiler version 5或者手动指定ARMCC路径。

但这里有个坑:Keil MDK 5.37 之后的版本默认不再附带 ARM Compiler 5,下拉框里可能根本没有 Version 5 选项。这时候需要手动把独立安装的 ARMCC 目录注册到 Keil 里。做法是打开 Keil 的Pack Installer,或者直接改 Keil 的配置文件TOOLS.INI,在[ARMCC]段里加上路径:

[ARMCC] PATH="D:\Tools\ARM_Compiler_5.06u7\bin"

改完之后重启 Keil,再看编译器下拉框,应该就能选到 Version 5 了。如果还是不行,检查TOOLS.INI的路径是否正确,以及 Keil 是否有权限读取该文件。

4.2 Makefile 工程里指定 ARMCC 路径

对于用 Makefile 构建的工程,需要在 Makefile 里显式指定CC、AS、LD等变量。一个典型的配置片段:

# 指定 ARMCC 工具链路径 ARMCC_DIR = D:/Tools/ARM_Compiler_5.06u7/bin CC = $(ARMCC_DIR)/armcc.exe AS = $(ARMCC_DIR)/armasm.exe LD = $(ARMCC_DIR)/armlink.exe FROMELF = $(ARMCC_DIR)/fromelf.exe # 编译选项:C99 标准,优化等级 -O2,输出调试信息 CFLAGS = --c99 -O2 -g -I./inc -I$(ARMCC_DIR)/../include

这里--c99是启用 C99 标准,-O2是优化等级,-g生成调试信息。注意 ARMCC 的优化选项和 GCC 不完全一样,-O0到-O3都有,但-O3在某些老版本上会触发过度优化导致逻辑错误,我一般用-O2或者-O1。

4.3 链接脚本与启动文件适配

ARMCC 使用的链接脚本是.sct格式,和 GCC 的.ld不一样。老工程的.sct文件通常长这样:

LR_IROM1 0x08000000 0x00080000 { ER_IROM1 0x08000000 0x00080000 { *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) } RW_IRAM1 0x20000000 0x00010000 { .ANY (+RW +ZI) } }

这段脚本定义了 Flash 和 RAM 的地址范围,以及各个段的放置规则。如果你换了芯片型号,需要同步改这里的地址和大小。启动文件一般是startup_xxx.s,用armasm汇编,和 ARMCC 是配套的。如果启动文件是用 GCC 语法写的,需要换成 ARMCC 版本的启动文件,否则汇编阶段就会报错。

5. 避坑与排查:ARMCC 安装配置常见问题

5.1 编译报错 “unknown argument –c99”

现象:在命令行或者 Makefile 里用了--c99,但 armcc 提示不识别该参数。

原因:不同版本的 ARMCC 对 C99 参数的支持不一样,早期版本可能用--c99,某些版本用-c99或者需要在--c99前面加--strict。

解决:先跑armcc --help看当前版本支持哪些参数,把--c99换成-c99或者--c90试试。如果工程不依赖 C99 特性,直接去掉这个参数也能编过。

5.2 链接时报 “L6218E: Undefined symbol”

现象:编译单个文件没问题,链接时提示某个符号未定义,比如_main或者SystemInit。

原因:通常是启动文件或者库文件没参与链接,或者链接脚本里没有包含对应的段。

解决:检查 Makefile 里是否把启动文件的.o加进了链接列表,以及.sct脚本里是否有*(InRoot$$Sections)这一行。如果是库函数缺失,确认lib目录下的armlib是否被正确引用。

5.3 Keil 里切换编译器后工程配置丢失

现象:从 ARM Compiler 6 切回 5 之后,之前配的 include 路径、宏定义、优化选项全没了。

原因:Keil 的工程文件.uvprojx里,不同编译器版本的配置是分开存储的,切换编译器相当于换了一套配置。

解决:切换之前先备份.uvprojx文件,切换后手动把 include 路径和宏定义重新填一遍。或者用文本编辑器打开.uvprojx,把<ArmAdsMisc>段里的配置复制到<Cads>段里。

5.4 授权报错 “License file does not support this version”

现象:编译时提示授权文件不支持当前版本,但授权文件明明是从正常工作的机器上拷过来的。

原因:ARMCC 的授权文件通常和版本号绑定,5.06u6 的授权不能给 5.06u7 用。

解决:确认授权文件对应的版本号,和当前安装的 ARMCC 版本一致。如果版本不匹配,要么换授权文件,要么换编译器版本。

5.5 命令行能编译但 Keil 里报错

现象:在 cmd 里跑armcc --version正常,但 Keil 里编译提示找不到编译器。

原因:Keil 使用的是自己的环境变量和路径配置,不一定继承系统 PATH。

解决:在 Keil 的TOOLS.INI里显式指定 ARMCC 路径,或者把 ARMCC 的bin目录加到 Keil 的Options for Target -> Target -> ARM Compiler的自定义路径里。

6. 装完怎么验证:从编译到烧录的完整检查

装完 ARMCC 之后,别急着打开老工程就编,先跑一个最小验证流程,确认工具链本身没问题。我一般会建一个临时目录,写一个最简单的main.c和启动文件,用命令行编译一遍,看能不能生成.axf和.hex。

// main.c:最小验证程序,只做一次空循环 #include <stdint.h> volatile uint32_t counter = 0; int main(void) { while (1) { counter++; } return 0; }

编译命令:

# 编译 main.c,指定 Cortex-M3 内核,输出调试信息 armcc --cpu Cortex-M3 -c -g -O1 main.c -o main.o # 链接生成 axf 文件,指定链接脚本 armlink --cpu Cortex-M3 main.o --scatter=link.sct -o demo.axf # 从 axf 生成 hex 文件 fromelf --i32 --output=demo.hex demo.axf

这三条命令跑完,如果目录下出现了demo.axf和demo.hex,说明 ARMCC 的编译、链接、格式转换三个环节都通了。接下来用fromelf --text -c demo.axf看一下反汇编,确认代码段和数据段的地址和链接脚本里写的一致。

然后把这个最小工程导入 Keil,用 Keil 的编译按钮再编一遍,确认 IDE 环境下也能正常构建。最后用调试器烧录到板子上,看程序能不能停在main函数入口。如果烧录后跑飞,先检查链接脚本里的 Flash 和 RAM 地址是否和芯片手册一致,再检查启动文件里的堆栈指针初始化是否正确。

注意:验证阶段不要直接拿量产工程的完整代码来试,先用最小工程确认工具链没问题,再逐步把老工程的源文件加进来,这样出问题时容易定位是工具链的问题还是工程代码的问题。

从那以后我每次装完 ARMCC,都会强制走一遍这个最小验证流程,哪怕只是换了一台机器或者重装了系统。因为编译器这东西,版本号看着一样,实际行为可能差很多,只有亲手编出一个能烧录的 hex,才算真正装好了。希望帮到你。

本文还有配套的精品资源,点击获取

相关新闻

AI赋能学术专著写作:知识工程视角下的完整工具链与实操工作流

AI赋能学术专著写作:知识工程视角下的完整工具链与实操工作流

前阵子有作者找我聊书稿的事&#xff0c;说他手里研究资料攒了一堆&#xff0c;想整理成一部学术专著&#xff0c;可两三年过去&#xff0c;目录还在改第N版。这种事我见得不少——专著不是论文&#xff0c;动辄二三十万字&#xff0c;写作周期按年算&#xff0c;真正卡人的往往…

2026/10/20 2:40:37 阅读更多 →
ARM编译器版本5(AC5)工具链详解:从armcc到fromelf的嵌入式开发实践

ARM编译器版本5(AC5)工具链详解:从armcc到fromelf的嵌入式开发实践

简介&#xff1a;ARM编译器版本5是ARM公司面向嵌入式系统开发者推出的优化编译工具&#xff0c;适用于从ARM7到ARM11及多核Cortex系列处理器的代码构建&#xff0c;帮助开发者在代码效率、资源占用与硬件兼容性之间取得平衡。资源包共3个文件&#xff0c;包含1个html发行说明、…

2026/10/20 2:40:37 阅读更多 →
三维可视化实践:用立方体同时展示等高线与方向标记

三维可视化实践:用立方体同时展示等高线与方向标记

做三维可视化时&#xff0c;我经常碰到一个很现实的问题&#xff1a;数据本身是三维的&#xff0c;但传统平面图只能表达二维关系。前阵子做一个地形相关的模拟项目&#xff0c;需要同时展示高度变化和方向趋势&#xff0c;一开始画了好几版平面等高线图&#xff0c;怎么看都别…

2026/10/20 2:39:36 阅读更多 →

最新新闻

SQL布尔盲注实战:从sqli-labs第十五、十六关拆解无回显渗透

SQL布尔盲注实战:从sqli-labs第十五、十六关拆解无回显渗透

1. 项目概述&#xff1a;从“看不见的输入框”开始理解布尔盲注的真实战场你有没有遇到过这样的页面&#xff1a;一个登录框&#xff0c;输入错误的账号密码&#xff0c;它不告诉你“用户名不存在”或“密码错误”&#xff0c;只冷冷地回一句“登录失败”&#xff1b;再试一次&…

2026/10/20 3:28:05 阅读更多 →
免费高精度IP定位查询入口:数据源拆解、实测对比与评估指南

免费高精度IP定位查询入口:数据源拆解、实测对比与评估指南

这些年我见过太多人带着“免费高精度IP地址定位查询入口”这个想法找上门&#xff0c;搜了一圈之后拿回来的要么是某个商业平台体验版&#xff0c;要么是挂着“全球精准定位”横幅、实际只能定位到城市甚至省份的普通接口。今天不绕弯子&#xff0c;直接把这几个问题拆开聊&…

2026/10/20 3:28:05 阅读更多 →
推理引擎原理与优化:从计算图到性能调优的完整指南

推理引擎原理与优化:从计算图到性能调优的完整指南

做推理引擎这几年&#xff0c;我最大的感受是&#xff1a;很多人手上的模型跑得起来&#xff0c;但跑不快、跑不稳&#xff0c;出了问题也不知道该从哪一层开始查。根本原因是把“AI 模型”和“推理引擎”当成两个隔离的黑盒——模型文件一丢&#xff0c;引擎一跑&#xff0c;结…

2026/10/20 3:28:05 阅读更多 →
模型压缩 - 量化剪枝边缘部署实战

模型压缩 - 量化剪枝边缘部署实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 3:28:05 阅读更多 →
SpringBoot+Vue全栈实战:服装销售平台管理系统设计

SpringBoot+Vue全栈实战:服装销售平台管理系统设计

不是毕业设计模板&#xff0c;也不是网上那些CtrlC就能跑的教学项目。我最近刚把一个服装销售平台管理系统从零搭完&#xff0c;项目代号就叫“衣依”&#xff0c;技术栈是SpringBoot Vue MyBatis MySQL。从需求梳理到数据库设计&#xff0c;再到前后端联调、部署上线&#…

2026/10/20 3:28:05 阅读更多 →
调教Stable Diffusion注意力机制,让出图更清晰

调教Stable Diffusion注意力机制,让出图更清晰

1. 先别急着加高清修复&#xff0c;问题多半出在注意力分配上先说个不少人踩过的坑&#xff1a;用Stable Diffusion出图&#xff0c;总感觉边缘发虚、细节糊成一团&#xff0c;第一反应往往是把分辨率从512拉高到1024&#xff0c;或者直接开Hires. fix&#xff0c;结果要么显存…

2026/10/20 3:27:05 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →