生成库之间的依赖关系

直接上 Python 源码

#!/usr/bin/python
# -*- coding: UTF-8 -*-
#
# Copyright (C) 2024 by cuzperf <cuzperf@outlook.com>
#
# 文件名: deps.py
# 用法: 将此文件复制到库所在路径,再运行 python deps.py [库文件路径] > 1.md
#       库文件路径如果没有则使用当前路径,注意路径中如果有空格,请用 "" 包起来

import sys
import os
import shutil
import random
import re

def GetDeps():
  # 在当前路径下创建 tmp 打头的随机名文件夹
  rand_int = random.randint(1, 1 << 30)
  # tmpHeader = './tmp'
  # rand_int_tmp = str(rand_int)
  # tmpdir = tmpHeader + rand_int_tmp
  tmpdir = './tmp' + "{}".format(rand_int)
  os.makedirs(tmpdir)

  directory = '.'
  if len(sys.argv) > 1:
    directory = sys.argv[1]

  # 将以 extensions 为后缀的文件用 nm 命令得到符号并保存在 txt 文本中
  extensions = ('.a', '.o', '.obj')
  for filename in os.listdir(directory):
    filepath = os.path.join(directory, filename)
    sys.stderr.write(filepath + '\n')
    if os.path.isfile(filepath) and filename.endswith(extensions):
      os.system('nm "' + filepath + '" > ' + tmpdir + '/' + filename + '.txt')

  # 解析生成的 txt 文本,记录所有符号的声明 inlist 和定义 outlist 和所有文件名 filelist
  inlist = []
  outlist = []
  filelist = []
  for filename in os.listdir(tmpdir):
    filepath = os.path.join(tmpdir, filename)
    if os.path.isfile(filepath):
      with open(filepath, 'r') as file:
        fileinlist = set()
        fileoutlist = set()
        for line in file:
          str = line.strip()
          linelist = str.split(' ')
          if len(linelist) >= 2:
            if linelist[-2] == 'U':
              fileinlist.add(linelist[-1])
            elif linelist[-2] == 'T' or linelist[-2] == 't':
              fileoutlist.add(linelist[-1])
        fileinlist.difference_update(fileoutlist)
        fileinlist.discard('printf')

        inlist.append(fileinlist)
        outlist.append(fileoutlist)
        filenameWithOutExtension = '.'.join(filename.split('.')[:-1])
        filenameWithOutLib = re.sub(r'^lib', '', filenameWithOutExtension)
        filelist.append(filenameWithOutLib)
  shutil.rmtree(tmpdir)

  ## 基于依赖关系生成 markdown 文档
  n = len(inlist)
  print('## 依赖关系图\n')
  print('``` mermaid')
  print('graph LR')
  for i in range(n):
    set1 = inlist[i]
    for j in range(n):
      set2 = outlist[j]
      interSet = set1.intersection(set2)
      if len(interSet) > 0:
        print(' ' + filelist[i] + ' --> ' + filelist[j])
  print('```\n')

  # 考虑到库很多的时候生成的图无法展示故添加单个库依赖的关系图
  print('## 单个库所依赖关系图\n')
  for i in range(n):
    print('### ' + filelist[i] + ' 的依赖关系图\n')
    setIn1 = inlist[i]
    setOut1 = outlist[i]
    print('``` mermaid')
    print('graph LR')
    for j in range(n):
      setIn2 = inlist[j]
      setOut2 = outlist[j]
      interSet12 = setIn1.intersection(setOut2)
      if len(interSet12) > 0:
        print(' ' + filelist[i] + ' --> ' + filelist[j])
      interSet21 = setIn2.intersection(setOut1)
      if len(interSet21) > 0:
        print(' ' + filelist[j] + ' --> ' + filelist[i])
    print('```\n')

  # 将依赖关系中具体的符号保存下来
  print('## 原始依赖关系数据\n')
  print('``` text')
  for i in range(n):
    set1 = inlist[i]
    for j in range(n):
      set2 = outlist[j]
      interSet = set2.intersection(set1)
      if len(interSet) > 0:
        print(filelist[i] + ' ---> ' + filelist[j] + ':')
        print(interSet)
        print('')
  print('```')

if __name__ == "__main__":
    GetDeps()

用 OpenModelica 中的库查看输出

posted @ 2024-12-26 16:41  cuzperf  阅读(10)  评论(0编辑  收藏  举报