Tracking C++ lib public API changes
我目前正在研究基于大型C++的基于Qt的项目,它将在其公共API的一个主要的Re因数下运行,如果有一个工具可以生成一个关于从构建到构建中添加或移除了哪些方法的报告,那就太好了。
我知道有一个Java工具可以做到这一点,我认为可能有.NET的一个,但是在搜索一点之后,我找不到C++的任何东西。
是否存在。跨平台应该很好,或者如果只有在Linux中也可以。
如果您使用doxygen或类似的工具来记录您的API,那么您可以使用
- 不管怎样,这是你应该做的事情。
- (您还可以告诉doxygen查找未记录的函数。)
- 您可以很容易地将其应用于古代的签入,而无需更改任何内容。
- doxygen及其同龄人对语言的了解足以对
private 和public 敏感。 - 此解决方案可以应用于多种语言,并且不依赖于特定的IDE。
- 不需要第三方软件(考虑到您已经有了文档生成器)。
检查商业列表的底部是否有apidiff,我认为这将是最接近的匹配。
使用"NM"的建议不错,你可以试试看。
1 | nm <binary_or_lib> | c++filt |
它将生成一个合适的快照,这将需要相当数量的后处理。
在这一点上,有很多方法可以让你自己动手:
Doxygen可以生成一个XML文件,该文件包含所有类/成员/方法信息,然后可以挖掘这些信息来构建类树。那就是比较树木的问题。可以在http://www.doxygen.nl/helpers.html上找到一些有用的后处理脚本/实用程序。
如果您使用gcc进行编译,那么埃及是一种使用中间RTL生成调用依赖关系图的新方法——似乎使用类似的方法生成基本API信息并不那么困难。
gcc-xml将生成编译代码的XML表示,比doxygen低一点,因为它提供了一种编写包装代码的机制。
cppHeaderParser,一个python模块将生成很好的头的python对象表示,从而提供一种生成API映射的简单方法。
CTags生成一个标签数据库,该数据库可能会被处理。不过,它仍然存在C++命名空间的问题。
一些商业解决方案
Scitool的理解在映射软件方面做得很好,并且有一个用于查询其数据库的PerlAPI。
MAGICDRAP是一种以UML为核心的重量级工具,但它可以逆向设计现有的C++代码库并生成元信息。
APIIFIFF似乎是一个相当负担得起的工具,并给出了标准(跨平台,C++)可能是最接近的匹配。
不允许从库中自动导出所有可见符号,您可以使用导出符号的显式列表。对于较大的库,甚至建议这样做。
在Windows中,使用.def文件从DLL导出符号。
在Unix中,喜欢使用链接器脚本。
尝试ABI合规性检查器。此工具显示API中添加/删除的符号、参数/数据类型的更改以及从二进制兼容性角度看的其他更改。是跨平台的。最好的性能是在Linux上,但它也可以在Windows和Mac上运行。
用途:
1 | abi-compliance-checker -lib NAME -old OLD.abidump -new NEW.abidump |
*.abidump文件是由abi dumper工具生成的abi转储。
此qt库的兼容性表是使用以下工具创建的:
。
请随意在下面的评论中提出任何使用问题。
添加一个在Unix上使用
每次生成后,将此文件提交到版本控制。然后您可以看到每个构建的差异。
因为它是一个C++应用程序,名称也会捕获参数类型的变化。
如果您使用git,那么应该创建一个新的分支,并使用shell脚本比较定义分支之间api bweet的所有头文件。如果您还没有这样做,您应该为您的API头文件使用impl模式,以使库二进制兼容/对未来版本更稳定。请参见qt开发人员wiki中的d_指针条目或kde techbase中关于d-pointers的部分。
除了使用Doxygen来滚动您自己的分析工具之外,我还建议您考虑使用BSC工具包。这允许您访问由MS编译器生成的代码/类浏览器信息,并且免费提供。该工具包提供对所有定义、使用参考、源和行号、参数、访问修饰符等的编程访问。名称以其损坏的形式提供,并包括必要时将其转换为人类可读格式的工具。
下面是我正在进行的一个项目的一些非常基本的输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | IXConnection (struct_name) IXConnection::STATE (enum_name) IXConnection::setState(enum STATE) (mem_func public) IXConnection::setAccount(struct IXAccount *) (mem_func public) IXConnection::setDisplayName(class String *) (mem_func public) IXConnection::setProtocolData(void *) (mem_func public) IXConnection::getState(enum STATE *) (mem_func public) IXConnection::getAccount(struct IXAccount * *) (mem_func public) IXConnection::getProtocol(struct IXProtocol * *) (mem_func public) IXConnection::getPassword(class String * *) (mem_func public) IXConnection::getDisplayName(class String * *) (mem_func public) IXConnection::getProtocolData(void * *) (mem_func public) IXConnection::setProgress(class String *,int,int) (mem_func public) IXConnection::notice(class String *) (mem_func public) IXConnection::error(enum REASON,class String *) (mem_func public) |
号