有没有办法比较Visual Studio中的obj文件
Is there a way to compare obj files from Visual Studio?
我有一个C++项目,它构建了多种配置(不仅仅是调试/发布(,这是一个相当大的项目。 让我们称之为KitchenSink.vcproj
我怀疑无论配置如何,这个项目的许多部分都以相同的方式构建。 例如,对于不使用字符串的源文件,使用/不使用 Unicode 支持进行构建无关紧要。
这将导致在多个配置中编译相同的源文件,但(有效地(生成相同的 .obj 文件。 它不会生成相同的文件,因为时间戳等嵌入在文件中,但目标文件的所有功能部分都是相同的。
有没有办法检查这一点? 我想将KitchenSink的各个部分提取到他们自己的,更简单的项目中,它们只需要构建一次。 这将加快构建时间,并简化我们的代码库。 但是我需要一种方法来自动查找构建相同的代码部分,无论配置如何。 有没有简单的方法可以做到这一点?
编辑:澄清我的观点。 想象一下以下文件:
// Some header file
int calculate_something(int a, int b);
// The source file
int calculate_something(int a, int b) {
return a * b;
}
现在,该源文件与 Unicode 无关。 因此,如果我们在 Unicode 配置中构建它,然后使用 MultiByte 配置再次构建它,我们只是在浪费时间。 我们可以把它放到它自己的静态库中,它是在没有Unicode支持的情况下构建的,然后这个新的库可以被我的其他项目使用。 这没有什么风险。
我只需要找到可以安全地移动到单独项目的这些文件。
编辑:进一步澄清:
KitchenSink.vcproj has the following files (among others)
StringUtils.h
StringUtils.cpp
MathStuff.h
MathStuff.cpp
现在,如果你用Unicode构建KitchenSink,再用MultiByte构建,你将构建StringUtils.obj两次,MathStuff.obj两次。 显然,这对于 StringUtils.obj 是必要的,因为它在 Unicode 和 MultiByte 中会有所不同。 但是MathStuff.obj应该构建完全相同的版本。
因此,我想重新排列/重组/重构以下内容:
KitchenSink.vcproj has the following files (among others)
StringUtils.h
StringUtils.cpp
NewProject.vcproj has the following files
MathStuff.h
MathStuff.cpp
现在,KitchenSink可以在其多种配置中构建,而NewProject只需一个调试/发布选项即可构建。
同样,我不是在谈论共享 obj 文件。 我说的是从一个项目中删除 cpp/h 文件,并将它们放在另一个项目中。
另请注意,Unicode/Multibyte 是具有多个配置的项目示例。 我的项目中的现实实际上更复杂,因此每个源文件被编译 4 次,而不是 Unicode/Multibyte 中发生的 2 次。
在 Linux 和 Cygwin/MINGW 上,有 ccache 可以帮助解决这个问题(检测具有相同编译标志的相同预处理源(。SCons(使用python的make
替代品(也可以做同样的事情。
对于Visual Studio,恐怕你会关注IncrediBuild。
也就是说,这个答案列出了一些对其他候选人(正在进行的项目(的引用:有Visual Studio的Ccache吗?
好吧,您可以使用diff -b
来比较 .obj 文件,但我认为您走这条路是愚蠢的。只需对源代码进行一次小小的更改,即可使优化的构建过程无效。我不会考虑做这样的事情。
在Visual Studio中,检查编译器/链接器生成的二进制文件的主要工具是dumpbin.exe。检查如何比较同一项目生成的二进制映像
请注意,翻译单元不使用字符串的事实并不意味着 Unicode 和非 Unicode 构建将是相同的。Unicode 构建会影响 Windows API 的使用,因此目标文件最终将链接到系统库中的不同符号。
旁注,在构建之间重用 .obj 文件的想法非常弱,尤其是在配置略有不同的构建之间。可能有许多微妙的问题。例如,考虑到完全相同的构建配置,理论上,静态库等效于 .obj 文件的集合。但是,我遇到了非常奇怪的差异和问题,将我的应用程序链接到静态库与链接到该库的 *.obj 文件。这是我在 MSDN 论坛中的帖子,您可以在其中找到与 .obj 文件相关的一些详细信息,作为静态库的直接替代品。
要查看项目是否在不同的配置中构建相同的文件,但毫无意义,最好比较预处理器的输出。 比较对象文件太容易失败,而且没有必要。
基本思想是:在多个配置中对文件运行预处理器,并比较输出文件。 如果它们是相同的,那么在不同的配置中构建该文件就没有多大意义,并且使用较少的配置重构到不同的项目是一个很好的候选者。
在 Visual Studio 中:
- 右键单击项目,然后转到"属性">
- 在"配置属性"-> C/C++ -> 预处理器下,编辑"生成预处理的文件">
- 将其设置为
Without Line Numbers (/EP /P)
- 在配置 A 中执行构建
- 预处理的文件在与源文件相同的目录中生成,而不是在配置子目录中生成,因此请将所有
*.i
文件移动到ConfigurationA
子目录中以便安全保存。 - 对配置 B(和任何其他配置(重复步骤
4
和5
- 比较每个配置子目录中的各个
*.i
文件。 如果源文件在所有配置中生成相同的.i
文件,则最好将其提取到不同的(单配置(库中。 - 将
Generate Preprocessed File
设置回其原始设置。
但是,如果您使用的是预编译标头,则可能会搞砸它。 预编译标头可能包含给定文件根本不需要的内容,但会导致预处理器输出发生不必要的更改。
例如 SimpleFile.cpp
和SimpleFile.h
仅使用基本类型,因此它们根本不需要包含任何内容。 但是,SimpleFile.cpp
包括stdafx.h
,因为VisualStudio要求项目中的每个文件都包含预编译的标头。 stdafx.h
包括多个文件,包括 HighlyConfigurable.h
-- 它有几个#ifdef
语句,并且根据配置的行为非常不同。 因此,由于SimpleFile.cpp
包括stdafx.h
,包括HighlyConfigurable.h
,预处理器输出SimpleFile.i
对于每个配置将大不相同。 然而,如果不使用 stdafx.h
,则SimpleFile.i
在所有配置中都是相同的。
这里的简单解决方法是注释掉整个stdafx.h
。 这听起来可能很激烈,但您不会以这种方式保存文件 - 您只需按照上述步骤生成预处理器文件进行比较,然后将stdafx.h
恢复到以前的辉煌。
- makefile 没有将 .o 和可执行文件放在各自的 obj 和 bin 目录中
- 检测到"运行时库"的不匹配LNK2038:值"MT_StaticRelease"与 xxx.obj 中的值"MTd_StaticDebug"不匹配
- 了解现代OpenGL中的代码绘图.OBJ并设置不同的位置
- makefile:不同目录中的CPP文件,将对象文件重定向为./obj,并且可执行到./bin
- MSVS 2015构建DLL-在MSVCRTD.LIB(EXE_MAIN.OBJ)中的Indoke_main中未解决的外
- 尝试加载DirectX 11中的obj文件时,向量下标
- 从2D纹理上的位置(x,y)计算.obj文件中的vt(u,v)坐标
- Visual Studios C++代码中的错误。Lab4.obj : 错误 LNK2019: 未解析的外部符号"bool __cdecl
- 与VS6相比,VS2008 C++编译中存在巨大的OBJ文件
- 错误 LNK2038:检测到"_MSC_VER"不匹配:值 '1600' 与 CppFile1.obj 中的值"1700"不匹配
- 分割 使用指针访问 obj 向量中的第二个元素时出错
- OBJ-C中的C++图形等价
- 通过C++中的#pragma将.obj文件包含到Visual Studio中的项目中
- 在Opengl中为加载的OBJ模型制作着色器
- OpenGL中用于OBJ导入的平滑着色器
- 从MAC OS X中的c++dylib调用cocoa/obj-c方法
- 如何从Obj-c文件调用Obj-c++文件中的函数
- LNK2019:无法解析的外部符号,在不存在的*中搜索.obj文件
- 有没有办法比较Visual Studio中的obj文件
- 返回c++代码中的Obj-C块