有没有办法比较Visual Studio的obj文件? [英] Is there a way to compare obj files from Visual Studio?

查看:447
本文介绍了有没有办法比较Visual Studio的obj文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个C ++项目,它建立在几个配置(不只是Debug / Release),它是一个相当大的项目。让我们称之为KitchenSink.vcproj



我怀疑这个项目的许多部分建立完全相同,不管配置如何。例如。



这将导致相同的源文件在多个配置中被编译,但是,生成(有效地)相同的.obj文件。它不会生成相同的文件,因为时间戳等嵌入在文件中,但是对象文件的所有功能部分都是相同的。



有办法检查这个?我想提取的KitchenSink的片段到自己的,更简单的项目,他们只需要建一次。这将加快构建时间,并简化我们的代码库。但我需要一种方法来自动找到构建相同的代码的部分,而不管配置。有很简单的方法吗?



编辑:澄清我的观点。想象下面的文件:

  //一些头文件
int calculate_something(int a,int b);

//源文件
int calculate_something(int a,int b){
return a * b;
}

现在,该源文件与Unicode无关。因此,如果我们在U​​nicode配置中构建它,然后使用MultiByte配置再次构建它,我们只是浪费时间。我们可以把它放入自己的静态库,这是建立没有Unicode支持,然后新的lib可以使用我的其他项目。没有任何风险。



我只需要找到这些文件,可以安全地移动到一个单独的项目。



编辑:进一步说明:

  KitchenSink.vcproj有以下文件
StringUtils.h
StringUtils.cpp
MathStuff.h
MathStuff.cpp

现在,如果你在Unicode中构建KitchenSink,再次在MultiByte中,你将构建StringUtils.obj两次,并创建两次MathStuff.obj。显然,这是必要的StringUtils.obj,因为它会不同的Unicode和MultiByte。但是MathStuff.obj应该构建完全相同。



所以,我想重新整理/重构/重构到以下:

  KitchenSink.vcproj有以下文件(其他)
StringUtils.h
StringUtils.cpp

NewProject.vcproj有以下文件
MathStuff.h
MathStuff.cpp

现在,KitchenSink可以在其多个配置中构建,而NewProject可以只使用一个单独的Debug / Release选项构建。



同样,我不是说SHARING obj文件。我要说的是从一个项目中删除cpp / h文件,并将它们放在另一个项目中。



还要注意,Unicode / Multibyte是一个具有多个配置。我的项目中的现实实际上更复杂,所以每个源文件被编译4次,而不是使用Unicode / Multibyte会出现的2次。

解决方案

要查看项目是否以不同的配置构建同一个文件,但无意义,最好是比较预处理器的输出。

的基本思想是:在多个配置文件中运行预处理器,并比较输出文件。如果它们是相同的,那么在不同的配置中构建该文件没有太多意义,并且它是重构到不同项目并且配置较少的好候选者。



在Visual Studio中:


  1. 右键单击项目,然后转到属性

  2. 在配置属性 - > C / C ++ - >预处理器下编辑生成预处理文件

  3. 将其设置为 EP / P)

  4. 在ConfigurationA中进行构建

  5. 预处理的文件在与源文件和NOT在配置子目录中,所以将所有 *。i 文件移动到 ConfigurationA

  6. 对ConfigurationB(以及任何其他配置)重复步骤 4 5

  7. 比较每个Configuration子目录中的个别 *。i 文件。如果源文件在所有配置中生成相同的 .i 文件,则它是一个很好的候选项,可以提取到其他(单配置)库。

  8. 生成预处理文件恢复为原始设置。

,如果您使用预先编译的标头,这可能会搞砸。预编译头可以包括给定文件根本不需要的东西,但会使预处理器输出不必要地改变。



例如。 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 以前的荣耀。


I've got a C++ project that builds in several configurations (not just Debug/Release), and it's a rather massive project. Let's call it KitchenSink.vcproj

I suspect that many pieces of this project build identically, regardless of the configuration. E.g. Building with/without Unicode support will not matter for a source file that doesn't use strings.

This would lead to the same source file being compiled in multiple configurations, but generating (effectively) the same .obj file. It doesn't generate the same file, because timestamps and the like are embedded in the file, but all the functional pieces of the object file would be the same.

Is there a way to check this? I would like to extract pieces of KitchenSink to their own, simpler, projects, where they only need to be built once. This would speed up build times, and simplify our codebase. But I need a way to automatically find the parts of the code that build the same, regardless of configuration. Is there an easy way to do that?

EDIT: Clarifying my point. Imagine the following file:

// Some header file
int calculate_something(int a, int b);

// The source file
int calculate_something(int a, int b) {
    return a * b;
}

Now, that source file has nothing to do with Unicode. So, if we build it in a Unicode configuration, and then build it again with a MultiByte configuration, we're just wasting time. We could put it into its own static library, that's built without Unicode support, and then that new lib could be used by my other projects. There's nothing risky in that.

I just need to find these files that can be safely moved to a separate project.

EDIT: Further clarification:

KitchenSink.vcproj has the following files (among others)
    StringUtils.h
    StringUtils.cpp
    MathStuff.h
    MathStuff.cpp

Now, if you build KitchenSink in Unicode, and again in MultiByte, you will build StringUtils.obj twice, and MathStuff.obj twice. Obviously, this is necessary for StringUtils.obj, since it will be different in Unicode and MultiByte. But MathStuff.obj should build the exact same.

So, I would like to rearrange/restructure/refactor to the following:

KitchenSink.vcproj has the following files (among others)
    StringUtils.h
    StringUtils.cpp

NewProject.vcproj has the following files
    MathStuff.h
    MathStuff.cpp

Now, KitchenSink can be built in its multiple configurations, while NewProject can be built with just a single Debug/Release option.

Again, I'm NOT talking about SHARING obj files. I'm talking about removing cpp/h files from one project, and putting them in another.

Also note that Unicode/Multibyte is an example of a project with multiple configurations. The reality in my project is actually more complicated, so each source file is compiled 4 times, rather than the 2 that would occur with Unicode/Multibyte.

解决方案

To see if a project is building the same file in different configurations, but pointlessly, it is best to compare the output of the preprocessor. Comparing object files is simply too prone to failure, and not necessary.

The basic idea is: Run the preprocessor on a file in multiple configurations, and compare the output files. If they're identical, then there's not much point to building that file in the different configurations, and it's a good candidate to be refactored to a different project, with fewer configurations.

In Visual Studio:

  1. Right-click on the Project, and go to Properties
  2. Under Configuration Properties -> C/C++ -> Preprocessor, edit "Generate Preprocessed File"
  3. Set it to Without Line Numbers (/EP /P)
  4. do a build in ConfigurationA
  5. the preprocessed files are generated in the same directory as the source file, and NOT in the Configuration Subdirectory, so move all the *.i files to the ConfigurationA subdirectory for safe keeping.
  6. Repeat steps 4 and 5 for ConfigurationB (and any other configurations)
  7. Compare the individual *.i files in each Configuration subdirectory. If a source file produces the same .i file in all configurations, it is a good candidate to be extracted to a different (single-configuration) library.
  8. Set Generate Preprocessed File back to its original setting.

However, if you're using precompiled headers, that will probably mess this up. The precompiled header may include things that are simply not needed by a given file, but cause the preprocessor output to change unecessarily.

E.g. SimpleFile.cpp and SimpleFile.h only use basic types, so they don't need to include anything at all. But, SimpleFile.cpp includes stdafx.h, because VisualStudio requires every file in a project to include the precompiled header. stdafx.h includes several files, including HighlyConfigurable.h -- which has several #ifdef statements, and behaves very different, depending on the configuration. Thus, since SimpleFile.cpp includes stdafx.h which includes HighlyConfigurable.h, the preprocessor output SimpleFile.i will be quite different for each configuration. Whereas, if stdafx.h were not used, SimpleFile.i would be the same in all configurations.

The simple workaround here is to comment out the entirety of stdafx.h. That may sound drastic, but you're not going to save the file that way - you're just going to follow the steps above to generate preprocessor files for comparison, and then restore stdafx.h to its former glory.

这篇关于有没有办法比较Visual Studio的obj文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆