python实现c++头文件合并器【完美版】

318 阅读1分钟

本文已参与「新人创作礼」活动.一起开启掘金创作之路。

首先我们需要把所有c++头文件放到src目录下面,然后创建一个py文件如下

"""Merges all the header files."""
from glob import glob
from os import path as pt
import re
import platform
from collections import defaultdict
import sys
OUTPUT = './'
contents = raw_input("Subdirectories name of total header files: ")
#使用raw_input能保证拿到的是字符串,而不是原始值
if contents[len(contents)-1]!='/':#这里是属于目录路径规范的判断
  OUTPUT+=contents+'_all.hh'
  contents += '/'
else: OUTPUT+=contents[0]+'_all.hh'#将合并的文件夹名拼接_all.hh用作合并后的文件名

ss=platform.system()#来一个跨平台的判断,保证全平台兼容
if ss=="Windows": ss='\\'
else: ss='/'
header_path = "./"
if len(sys.argv) > 1:
    header_path = sys.argv[1]
print(header_path)#打印一下输出目录 的路径
re_depends = re.compile('^#include "(.*)"', re.MULTILINE)
headers = [x.rsplit(ss, 1)[-1] for x in glob(pt.join(header_path, '*.h*'))]
headers += [contents+x.rsplit(ss, 1)[-1] for x in glob(pt.join(header_path, contents + '*.h*'))]
print(headers)#再来一个打印
edges = defaultdict(list)
for header in headers:
    d = open(pt.join(header_path, header)).read()
    match = re_depends.findall(d)
    for m in match:
        # m should included before header
        edges[m].append(header)

visited = defaultdict(bool)
order = []


def dfs(x):
    """Ensure all header files are visited."""
    visited[x] = True
    for y in edges[x]:
        if not visited[y]:
            dfs(y)
    order.append(x)

for header in headers:
    if not visited[header]:
        dfs(header)
        
order = order[::-1]
for x in edges:
    print(x, edges[x])
for x in edges:
    for y in edges[x]:
        assert order.index(x) < order.index(y), 'cyclic include detected'

print(order)
build = []
for header in order:
    d = open(pt.join(header_path, header)).read()
    build.append(re_depends.sub(lambda x: '\n', d))
    build.append('\n')

open(OUTPUT, 'w').write('\n'.join(build))#写入到文件中

然后,如果在windows下面我们需要按住shift键然后右键当前目录,打开powershell窗口。如果是linux下面就直接运行这个py文件就行了(我是在windows下)

image.png

那么所有的头文件就打包到一起了,注意,这里我没有加入判断输出文件是否已经存在,所以请勿多次使用,使用前需要保证该目录下没有合并后的文件,不然会重复加入到同样的文件中。