找回密码
 register
搜索
查看: 7|回复: 0

[自写函数] VS2008 SP1 与 GameServer PCH 构建故障解决教程

[复制链接]
  • 打卡等级:本地老炮
  • 打卡总天数:560
  • 打卡月天数:21
  • 打卡总奖励:557
  • 最近打卡:2026-07-24 16:00:52
Waylee 发表于 2026-7-22 17:25 | 显示全部楼层 |阅读模式 | Google Chrome | Windows 10

马上注册,查看网站隐藏内容!!

您需要 登录 才可以下载或查看,没有账号?register

×

1. 适用范围

本文适用于以下工程:

  • 版本根目录:H:\TLBB\Temp_Release_v0-85-8130
  • 解决方案:Prj\GameCode\Server\Server.sln
  • 项目:GameServer
  • 配置:Debug|Win32Release|Win32
  • 工具链:Microsoft Visual Studio 2008 C++

本文记录的是本机已经复现并解决的 PCH 编译故障,不是通用的源码错误规避方案。

2. 故障现象

原工具链为 Visual Studio 2008 RTM:

cl.exe 15.00.21022.08

GameServer 同时启用预编译头和多进程编译:

/MP4
/Yu"stdafx.h"

全量构建时会在生成或使用 PCH 的过程中反复失败,典型错误为:

fatal error C1859: Too many open files

该现象的识别要点:

  1. 错误发生在大量源文件并行编译阶段。
  2. 重试后失败文件可能变化,不稳定地指向某个业务源码。
  3. 改动业务源码不能稳定消除错误。
  4. 串行构建可能绕过一部分问题,但编译速度显著下降。

因此,这类错误不能直接判定为当前报错 .cpp 文件存在逻辑错误。

3. 已确认原因

本机使用的是 VS2008 RTM 编译器。该版本在大型工程的 /MP 并行编译与 PCH 组合下存在稳定性问题,GameServer 的源文件数量足以触发该问题。

本次升级到 VS2008 SP1 后,编译器版本变为:

FileVersion:    15.00.30729.01 built by: SP
ProductVersion: 9.00.30729.01

工程保持 /MP4 和 PCH,不修改业务源码,即可完成全量重建。因此本次故障的有效解决方案是升级 SP1 工具链,而不是关闭 PCH。

4. 安装 VS2008 SP1

本机安装包位置:

E:\vs90sp1\SPInstaller.exe

安装步骤:

  1. 结束正在运行的 Visual Studio、devenv.comcl.exe 和其他构建任务。
  2. 以管理员身份运行 SPInstaller.exe
  3. 等待安装器完成 Visual Studio 2008 SP1 更新。
  4. 安装完成后重启 Windows,确保编译器、链接器和调试组件均加载新版本。

不要在安装仍进行时重复启动安装器,也不要同时运行项目编译。

5. 验证 SP1 是否生效

重启后在 PowerShell 执行:

$cl = 'C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\cl.exe'
(Get-Item -LiteralPath $cl).VersionInfo |
    Select-Object FileVersion, ProductVersion

正确结果应包含:

FileVersion     15.00.30729.01 built by: SP
ProductVersion  9.00.30729.01

如果仍显示 15.00.21022.08,说明当前调用的仍是 RTM 工具链。此时不要继续调整项目源码,应先检查 SP1 安装结果、系统重启状态以及实际使用的 cl.exe 路径。

6. GameServer 的 PCH 配置

项目文件:

Prj\GameCode\Server\Server\GameServer\Server\Server.vcproj

当前 Debug 配置的关键项为:

AdditionalOptions="/MP4"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="stdafx.h"
MultiProcessorCompilation="true"

含义如下:

  • /MP4:最多使用 4 个编译进程。
  • UsePrecompiledHeader="2":普通 C++ 文件使用已有 PCH,对应 /Yu
  • PrecompiledHeaderThrough="stdafx.h":统一通过 stdafx.h 使用 PCH。
  • stdafx.cpp 单文件设置为 UsePrecompiledHeader="1",负责创建 PCH,对应 /Yc
  • 不适合 PCH 的个别 C 文件保持 UsePrecompiledHeader="0"

不要把所有文件都改为创建 PCH,也不要为了临时绕过 C1859 永久关闭 PCH。GameServer 文件很多,关闭 PCH 会显著增加每次构建耗时。

7. 推荐构建命令

以下命令会把日志统一写入 _Build\Logs,不会在源码目录生成临时日志:

$root = 'H:\TLBB\Temp_Release_v0-85-8130'
$devenv = 'C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\devenv.com'
$solution = Join-Path $root 'Prj\GameCode\Server\Server.sln'
$logDir = Join-Path $root '_Build\Logs'
$log = Join-Path $logDir 'GameServer_Debug_Win32_SP1.log'

New-Item -ItemType Directory -Force -Path $logDir | Out-Null
& $devenv $solution /Rebuild 'Debug|Win32' /Project GameServer /Out $log
if ($LASTEXITCODE -ne 0) {
    throw "GameServer 构建失败,退出码:$LASTEXITCODE"
}

Release 构建只需修改配置和日志名:

$log = Join-Path $logDir 'GameServer_Release_Win32_SP1.log'
& $devenv $solution /Rebuild 'Release|Win32' /Project GameServer /Out $log

本次 Debug 全量重建的实际结果为:

GameServer - 0 个错误,0 个警告
========== 全部重新生成: 成功 1 个,失败 0 个,跳过 0 个 ==========

8. 不推荐的处理方式

  • 不推荐永久禁用 PCH,构建速度损失较大。
  • 不推荐长期改为单线程编译,除非用于定位并发问题。
  • 不推荐给所有源码全局设置 ObjectFile="$(IntDir)\$(InputName).obj"。项目中同名源文件需要单独处理,全局设置可能重新引入对象文件重名覆盖。
  • 不推荐反复重试 RTM 编译器,希望随机绕过 C1859
  • 不推荐在源码目录或版本根目录临时生成 .log、构建 JSON 和部署清单。
  • 不推荐构建失败后仍覆盖 resources\Server\Server.exe
您需要登录后才可以回帖 登录 | register

本版积分规则

QQ|手机版|雪舞知识库 ( 浙ICP备15015590号-1 | 萌ICP备20232229号|浙公网安备33048102000118号 )|天天打卡

GMT+8, 2026-7-25 07:31 , Processed in 0.063882 second(s), 26 queries .

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表