vs2010 创建预编译头 Debug 正常 Release Link Error问题解决

时间:2023-12-31 15:47:56

问题:创建预编译头 Debug 正常 Release Link Error

Main.obj : error LNK2005: ___@@_PchSym_@00@UmfilkilqUdrmzkkUkilqUehCAAIUnzpvnzkwzgzUnzpvnzkwzgzUivovzhvUyzhrxwzgzOlyq@ 已经在 BasicData.obj 中定义
warning C4727: 具有相同时间戳的名为 d:\nuroproj\winapp\proj\vs2008\makemapdata\makemapdata\release\makemapdata.pch 的 PCH 已存在于 d:\NuroProj\WinApp\proj\vs2008\MakeMapData\MakeMapData\Release\Make3Dm.obj 和 d:\NuroProj\WinApp\proj\vs2008\MakeMapData\MakeMapData\Release\Main.obj 中。使用第一个 PCH。
Make3Dm.obj : error LNK2005: ___@@_PchSym_@00@UmfilkilqUdrmzkkUkilqUehCAAIUnzpvnzkwzgzUnzpvnzkwzgzUivovzhvUyzhrxwzgzOlyq@ 已经在 BasicData.obj 中定义
warning C4727: 具有相同时间戳的名为 d:\nuroproj\winapp\proj\vs2008\makemapdata\makemapdata\release\makemapdata.pch 的 PCH 已存在于 d:\NuroProj\WinApp\proj\vs2008\MakeMapData\MakeMapData\Release\MakeBlkIdx.obj 和 d:\NuroProj\WinApp\proj\vs2008\MakeMapData\MakeMapData\Release\Main.obj 中。使用第一个 PCH。
MakeBlkIdx.obj : error LNK2005: ___@@_PchSym_@00@UmfilkilqUdrmzkkUkilqUehCAAIUnzpvnzkwzgzUnzpvnzkwzgzUivovzhvUyzhrxwzgzOlyq@ 已经在 BasicData.obj 中定义
warning C4727: 具有相同时间戳的名为 d:\nuroproj\winapp\proj\vs2008\makemapdata\makemapdata\release\makemapdata.pch 的 PCH 已存在于 d:\NuroProj\WinApp\proj\vs2008\MakeMapData\MakeMapData\Release\MakeDtm.obj 和 d:\NuroProj\WinApp\proj\vs2008\MakeMapData\MakeMapData\Release\Main.obj 中。使用第一个 PCH。

.\..\..\..\bin\MakeMapData\MakeMapData.exe : fatal error LNK1169: 找到一个或多个多重定义的符号
项目的debug和release下的预编译头设置看起来都一样。但是release下就是编译不过,还报以上的错误。
在网上看到网上有人提到:“工程属性里面设置的是使用哪个预编译头,但是预编译头的生成是在cpp文件的属性里面设置的,右键点击文件-属性-C/C++-预编译头,保证只有一个cpp文件会生成预编译头。
当时没怎么理解这句话的含义,不知道每个.cpp文件都可以设置预编译头。
后来通过对比正确版本、错误版本的.vcxproj文件,发现正确版本的文件 <ItemGroup>项下

<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
</ClCompile>,

而错误版本的

<ClCompile Include="stdafx.cpp">
</ClCompile> 没有中间的两项预编译头子项。

然后查看有关预编译头的相关介绍,知道了原来每个.cpp源文件都可以单独设置预编译头选项(使用预编译头,还是创建编译头,或者不使用)

创建预编译头 Debug 正常 Release Link Error 处理方法

这个问题的原因是stdafx.cpp源文件的预编译头设置的选项问题。右键stdafx.cpp文件,选中属性

vs2010 创建预编译头 Debug 正常 Release Link Error问题解决

发现这里的预编译头选项是“使用”,然后把预编译头的使用改成“创建”,然后重新编译,编译通过了。

下面转一篇关于预编译头介绍的问题

预编译头就是将程序的头文件部分编译成一个二进制中间文件,提高整个工程的编译效率,一般以.pch格式存储。

1. 在编译器重已经采用了时间戳的方式,为何还需要预编头呢?

对.obj加以时间戳的方式,可以根据时间戳来决定哪些文件需要重新编译,从而提高效率。但重新编译这个文件,包括这个文件的头文件里的信息和预处理(指头文件中的预处理)都重新进行一遍,而预编译头正是解决了这个问题,将稳定的头文件内容预先编译为一个二进制中间文件。

2. 只有头文件如何编译呢?

        编译器无法直接编译头文件,那么就需要一个CPP和结合头文件一起编译,这样就是为什么通常MFC工程中存在一个StdAfx.cpp,其内容仅仅显示:
  1. // stdafx.cpp : 只包括标准包含文件的源文件
  2. // TurnRound.pch 将作为预编译头
  3. // stdafx.obj 将包含预编译类型信息
  4. #include "stdafx.h"

通常将常用的头文件都放到stdafx.h头文件中。

3. fatal error C1010: unexpected end of file while looking for precompiled header. Did you forget to add '#include "stdafx.h" to your source?

在MFC中编程中最常见不过的了,因为MFC工程默认采用了预编译头,之后必须在.cpp文件头部包含stdafx.h(注意一定要放在头部,不然前面的头文件会被忽略);右击我们出错的的文件可以找到证据:

vs2010 创建预编译头 Debug 正常 Release Link Error问题解决

如果你关闭预编译头,可以发现没有了这个error。但既然预编译头带来这么多好处,为何不使用呢?

4. 创建属于自己的预编头(本人采用VS2005)

(1)第一步,创建stdafx.h 和 stdafx.cpp, 将常用的头文件放入stdafx.h中(一般选择稳定的头文件,因为编译产生预编译头时间比较长),在stdafx.cpp中添加代码

  1. #include "stdafx.h"

(2)第二步,右击工程属性=》配置属性=》c/c++ =》预编译头,选择使用预编头, "预编译头文件"项 填写 stdafx.h。

(3)第三步,右击stdafx.cpp文件 -》选中属性,配置属性=》c/c++ =》预编译头,选择创建预编译头,"预编译头文件"项 填写 stdafx.h。