如何找出OSS的引用所有的头文件
对于正式版本软件的release, 在release之前我们都要做一下OSS检查, 以防我们的代码引用了一些有一些不合适的license的第三方代码,正好最近有一个需求需要将我们所用到的OSS库的头文件全部取出来,对于OSS库, 我们正常用到哪些功能, 我们就引用哪些功能的库, 所以不可能将所有的头文件全部取出来, 那么如何正确的找到引用的部分,就需要借助编译工具了
这里我们借助了clang工具
什么是 Clang?
Clang 是一个现代化的 C、C++、Objective-C 和 Objective-C++ 编译器,基于 LLVM 项目开发。它具有以下特点:
- 高性能:快速编译,同时支持增量编译。
- 模块化设计:与 LLVM 集成,支持自定义编译流程。
- 丰富的工具链:除了编译,还能生成头文件依赖、分析代码、静态检查等。
- 清晰的错误信息:比传统编译器(如 GCC)提供更人性化的诊断输出。
Clang 在实际使用中,不仅用于代码编译,还可用于代码分析和依赖生成。
如何用 Clang 找出 OSS 的引用头文件?
如果你想找出某个开源项目(OSS)中所有源文件引用的头文件,可以按照以下步骤操作:
1. 使用 clang -M
或 clang -MM
-M
:生成完整的依赖信息(包括用户头文件和系统头文件)。-MM
:生成精简的依赖信息(仅包含用户头文件)。
clang -M -I<include_paths> source_file.c
说明:
-I<include_paths>
:指定头文件的搜索路径(可重复,支持多个-I
)。source_file.c
:你想分析的 C 文件。
2. 遍历所有源文件
如果需要处理整个项目,可以对所有源文件执行依赖分析:
find . -name "*.c" -exec clang -M -I<include_paths> {} \;
解释:
find . -name "*.c"
:查找项目中的所有.c
源文件。-exec clang -M ... {}
:对每个找到的源文件运行clang -M
。
3. 使用工具生成完整的依赖清单
为了得到项目所有头文件的完整引用,可以结合 make
或脚本处理输出。例如:
脚本示例:
#!/bin/bash
INCLUDE_FLAGS="-I./include -I/usr/include"
for file in $(find . -name "*.c"); do
clang -M $INCLUDE_FLAGS "$file" >> dependencies.txt
done
- 输出的
dependencies.txt
会包含所有头文件的引用关系。
4. 可视化依赖
将结果转化为可读性更好的格式,比如依赖图:
- 使用工具如
graphviz
转换依赖为图形。 - 将输出依赖解析为图形工具的输入格式。
示例
假设项目中有以下文件:
-
main.c
:#include <stdio.h> #include "myheader.h"
-
myheader.h
:#ifndef MYHEADER_H #define MYHEADER_H void my_function(); #endif
运行以下命令:
clang -M -I./include main.c
输出:
main.o: main.c /usr/include/stdio.h ./myheader.h
总结流程
- 确定头文件搜索路径:使用
-I
指定项目和系统头文件路径。 - 使用 Clang 生成依赖:选择
-M
(完整)或-MM
(仅用户头文件)。 - 处理所有文件:用脚本或
find
遍历项目所有源文件。 - 存储或分析结果:输出结果供构建系统或代码审查使用。
这个方法可以帮助你清晰地看到项目中引用的所有头文件及其依赖关系。