Keil MDK 添加外部工具用clang-format 格式化代码

原理:

  1. 所有代码文件和Keil 项目文件在同一个文件夹;
  2. python 脚本里调用clang-format.exe 格式化所有.c .h .cpp .hpp 文件;
  3. Keil 菜单里添加外部工具,调用python 脚本;

1、 文件夹结构

要求所有源代码都和Keil 项目文件在同一个文件夹,或者在子文件夹里,比如:

在这里插入图片描述

C/C++ 源代码都在src 或者lib 文件夹下。库代码如果也在同一个文件夹,比如把CMSIS 放这里,那就也会被格式化。

2.1、clang-format

是个专门用来格式化C/C++ 代码文件的程序,安装LLVM 或者CLANG 编译器的时候会带上,Keil 的armclang 编译器也带了这个,要加到PATH 里。

clang-format 默认的美化风格很可能不是想要的效果,需要自己整个配置文件.clang-format,一样放在项目文件夹底下,上面截图里就有。我用的配置文件是这样:

BasedOnStyle: google

# 缩进格式:4 空格
IndentWidth: 4
TabWidth: 4
UseTab: Never

NamespaceIndentation: All

ColumnLimit: 0

AlignTrailingComments: true
MaxEmptyLinesToKeep: 2

# 花括号风格:else 块另起一行
BreakBeforeBraces: Custom
BraceWrapping:
  BeforeElse: True

BreakConstructorInitializers: AfterColon

# BracketAlignmentStyle: Align

AlignConsecutiveMacros:
  Enabled: true
  AcrossComments: false
  
AlignOperands: AlignAfterOperator

BreakBeforeBinaryOperators: All
BreakBeforeTernaryOperators: true

IndentPPDirectives: BeforeHash

AlwaysBreakAfterReturnType: None
AlwaysBreakAfterDefinitionReturnType: None

这个配置文件应该是YAML 格式,和python 一样,不能随便缩进,每个空格都是有用的[doge]。用这个配置,格式化出来是这样:

int main(void) {
    setup();

    using namespace scheduler_basic;

    for (const auto& p : TUBE.pin.seg) {
        p.set();
    }

    TimeCycle<TimeSource> c;
    int i = 0;

    while (1) {
        if (c.cycle(200)) {
            TUBE.pin.dig[i].toggle();
            i++;
            if (i == DIG_COUNT) {
                i = 0;
            }
        }
    }
}

直接执行clang-format.exe 没办法一次性把全部代码文件格式化,它的命令行参数好像只能一个一个文件来,或者用另外一个文件先把所有要格式化的文件的路径放进去,作为列表文件,再把这个列表文件放在命令行参数里传进去,所以我用了个python 脚本来生成列表文件。

2.2、Python 脚本

脚本内容如下:

from pathlib import Path
import os
import subprocess
from itertools import chain
from typing import List, Iterable


def multi_glob(parent: Path, pattern_list: List[str], *, recursive=False) -> Iterable[Path]:
    if not recursive:
        func_glob = lambda s: parent.glob(s)
    else:
        func_glob = lambda s: parent.rglob(s)
        
    return chain(*(map(func_glob, pattern_list)))


# ===========================================================

here = os.path.dirname(__file__)
here = Path(here)

# 找到.c, .h, .cpp, .hpp, .cxx, .hxx
file_list = multi_glob(here, [ '*.[ch]', '*.[ch]pp', '*.[ch]xx' ], recursive=True)

file_path_list = map(lambda f: str(f.relative_to(here)), file_list)
text = '\n'.join(file_path_list)

list_file = here / 'temp-clang-format-source-files.txt'
list_file.write_text(text)

print('== SOURCE FILE LIST ==')
print(text)
print('======================')

input('PROCEED? ')

subprocess.call(f'clang-format -i -files="{list_file.name}"', shell=True)

input('EXIT→')

os.remove(list_file)

第37 行调用clang-format,用命令行参数传入列表文件。

subprocess.call(f'clang-format -i -files="{list_file.name}"', shell=True)

第23 行递归搜索当前目录及所有子目录下的代码文件,过滤出C/C++ 的代码和头文件:

file_list = multi_glob(cwd, [ '*.[ch]', '*.[ch]pp', '*.[ch]xx' ], recursive=True)

然后会在项目目录底下生成个临时的列表文件temp-clang-format-source-files.txt,脚本执行完就自动删除。

3、KEIL 添加外部工具

菜单栏Tools > Customize Tools Menu,打开对话框,设置调用python 脚本的命令:

在这里插入图片描述

Run Independent 勾上。需要本地电脑安装了Python 环境,版本应该至少3.6。然后Tools 菜单底下就多了个自定义命令,单击运行后弹出黑窗口:

在这里插入图片描述

上面显示了所有被过滤出来的文件,再按一下回车确认,就调用clang-format 执行格式化。

在这里插入图片描述

没有报错,就再点一次回车退出窗口。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值