CD Code Digest Hub /CS:GO

构建系统与物理组织

18 分钟阅读 9 个章节 1 张图

本页回答两个问题:哪些目录真的会被编译,以及编译产物落在哪里。在 Source 代码树里“目录存在”和“参与构建”是两回事,后续所有页面都以这里确定的有效范围为准。

相关页面:概览 · 接口工厂与 AppSystem · 审计

相关源码文件#

  • 入口脚本:CreateSolution.bat
  • 工程注册与分组:vpc_scripts/default.vgc、vpc_scripts/projects.vgc、vpc_scripts/groups.vgc
  • 公共基础配置:vpc_scripts/source_base.vpc、vpc_scripts/protobuf_builder.vpc
  • 代表性工程:game/client/client_cstrike15.vpc、game/server/server_cstrike15_inc.vpc、engine/engine_inc.vpc、engine_ds/engine_ds.vpc

1. VPC 的三层解析#

证据:

  • 解决方案生成命令是 devtools\bin\vpc.exe /csgo +csgo_partner /mksln csgo_partner.sln:CreateSolution.bat:1。
  • default.vgc 只声明 CSGO 一个游戏,并引入工程表与分组表:vpc_scripts/default.vgc:11-24。
  • projects.vgc 把同一个工程名映射到按游戏/平台条件选择的 .vpc,例如 client 只有 client_cstrike15.vpc 在 $CSGO 下生效,其它游戏的行被注释:vpc_scripts/projects.vgc:176-186;server 同理:vpc_scripts/projects.vgc:1234-1244。
  • groups.vgc 中 csgo_partner 组列出 90 个工程名:vpc_scripts/groups.vgc:11-103。

推断:本仓库内的 vpc.exe 是二进制(devtools/bin/vpc.exe),其源码位于 utils/vpc;本次没有运行它,因此上图描述的是脚本声明的装配关系,而非实际生成结果。

2. csgo_partner 组的有效范围#

把 csgo_partner 组中的 90 个工程名逐一映射回 projects.vgc,所引用的 .vpc 文件在本仓库中全部存在(本次脚本核对)。该组覆盖:

类别组内工程(节选)证据
进程入口launcher_main、launcher、dedicated_main、dedicated、hammer_launchervpc_scripts/groups.vgc:21-37
引擎engine、engine_dsvpc_scripts/groups.vgc:25-26
游戏 DLLclient、server、matchmaking、matchmaking_ds 及其 base 库vpc_scripts/groups.vgc:30-41
渲染materialsystem、shaderapiempty、shaderlib、stdshader_dbg、stdshader_dx9、studiorender、particlesvpc_scripts/groups.vgc:43-63
工具vbsp、vvis_*、vrad_*、vtex_*、shadercompile_*、hlmv、pet、vmt、commeditvpc_scripts/groups.vgc:69-85
基础库tier0~tier3、vstdlib、mathlib、interfaces、appframeworkvpc_scripts/groups.vgc:13、vpc_scripts/groups.vgc:35、vpc_scripts/groups.vgc:48、vpc_scripts/groups.vgc:65-68、vpc_scripts/groups.vgc:101

值得注意的是该组不包含以下运行时必需模块:

不在组内的模块现状证据
shaderapidx9(D3D9 设备层)源码目录存在(75 个文件),工程注册存在,但不在 csgo_partner 组vpc_scripts/projects.vgc:1291-1294
scaleformui源码存在,SDK 缺失vpc_scripts/projects.vgc:1194-1197、scaleformui/scaleformui.vpc:33-43
vphysics工程注册存在,目录不存在vpc_scripts/projects.vgc:1956-1959
gcsdk注册指向 gcsdk\gcsdk_game.vpc,该文件不存在;目录里只有 gcsdk_game_include.vpc 与少量辅助源码vpc_scripts/projects.vgc:445-448、gcsdk/gcsdk_game_include.vpc

这表明 csgo_partner 是一个“合作方”构建集合:上述模块预期以二进制形式提供(推断,依据是这些模块被启动器直接按名字加载,见 客户端启动链)。

dedicated 组则显式要求 vphysics、IVP/Havana 物理库、gcsdk、server_valve、steamdatagramlib 等,其中 10 个工程的 .vpc 在本仓库中缺失:vpc_scripts/groups.vgc:1143-1191。

从整体看,projects.vgc 中共有 445 条 .vpc 引用,其中 327 条指向不存在的文件(大部分属于其它游戏或工具),所以不能把工程表当成本仓库的目录清单。

3. 双端编译与宏#

工程关键宏证据
client 基础CLIENT_DLLgame/client/client_base.vpc:60
server 基础GAME_DLLgame/server/server_base.vpc:56
CS:GO clientCSTRIKE_CLIENT_DLL;CSTRIKE_DLL;INCLUDE_SCALEFORM;USE_ECONOMY_FEATURES 等game/client/client_cstrike15.vpc:39
CS:GO serverBOTS;CSTRIKE_DLL;USE_ECONOMY_FEATURESgame/server/server_cstrike15_inc.vpc:30
分支CSTRIKE_REL_BUILD=1(rel 分支)vpc_scripts/source_base.vpc:13-15

game/shared/cstrike15 中的核心文件同时被两端工程列出,例如 cs_gamemovement.cpp、cs_gamerules.cpp、cs_player_shared.cpp、fx_cs_shared.cpp、weapon_csbase.cpp:client 侧 game/client/client_cstrike15.vpc:175-181、game/client/client_cstrike15.vpc:214、game/client/client_cstrike15.vpc:470;server 侧 game/server/server_cstrike15_inc.vpc:96-97、game/server/server_cstrike15_inc.vpc:110、game/server/server_cstrike15_inc.vpc:139、game/server/server_cstrike15_inc.vpc:211。gametypes.cpp 甚至被编译进三个模块(client、server、matchmaking),见 比赛模式。

4. 引擎的两个变体#

engine_ds.vpc 只是用不同的工程名 include 同一份 engine_inc.vpc:engine_ds/engine_ds.vpc:7-10。engine_inc.vpc 只有在 VPC 条件 $DEDICATED 为真时才注入 DEDICATED;SWDS;NO_BINK 宏,并按 !$DEDICATED 排除客户端文件:engine/engine_inc.vpc:28-31、engine/engine_inc.vpc:81-116。因此“专用服务器引擎”与“客户端引擎”共享源码,差异完全由宏和文件条件产生。

5. 产物位置#

产物输出目录宏证据
csgo.exe 等启动程序$SRCDIR\..\game,按平台命名 csgo/csgo_win64/csgo_linux…launcher_main/launcher_main.vpc:8-17
srcds.exe$SRCDIR\..\game,命名 srcds/srcds_x64/srcds_linux…dedicated_main/dedicated_main.vpc:8-14
launcher、engine 等公共模块$SRCDIR\..\game\binlauncher/launcher.vpc:8、engine/engine_inc.vpc:8
client、server$SRCDIR\..\game\$GAMENAME\bin(GAMENAME=csgo)game/client/client_base.vpc:8、game/server/server_base.vpc:7、game/client/client_cstrike15.vpc:8

由于 $SRCDIR 指向本仓库根,产物会落在仓库之外的同级 game/ 目录(推断,按宏展开)。

6. Protobuf 生成#

protobuf_builder.vpc 定义名为 proto 的自定义构建步骤,调用 $SRCDIR\devtools\bin\protoc.exe,包含 thirdparty/protobuf-2.5.0/src、gcsdk、game/shared、game/shared/cstrike15、common 等 proto 路径,输出 .pb.cc/.pb.h 到 $GENERATED_PROTO_DIR:vpc_scripts/protobuf_builder.vpc:9-19。引擎在 engine_inc.vpc 中包含它与 netmessages_include.vpc:engine/engine_inc.vpc:11-15;CS:GO 用户消息通过 cstrike15_usermessages_include.vpc 加入工程:game/shared/cstrike15/cstrike15_usermessages_include.vpc。

仓库同时跟踪了部分生成结果(例如 game/client/generated_proto/*.pb.* 与 game/server/generated_proto/*.pb.*),client 工程把生成目录设为绝对的 $SRCDIR\game\client\generated_proto:game/client/client_base.vpc:11,server 使用相对的 generated_proto:game/server/server_base.vpc:10。修改协议时应改 .proto 并重新生成,而不是手改 .pb.*。

一方 .proto 文件共 8 个:common/netmessages.proto、common/network_connection.proto、common/engine_gcmessages.proto、game/shared/base_gcmessages*.proto、game/shared/cstrike15/cstrike15_gcmessages.proto、game/shared/cstrike15/cstrike15_usermessages.proto、gcsdk/steammessages.proto。

7. 顶层目录分类#

角色目录
进程入口launcher_main、launcher、dedicated_main、dedicated、hammer_launcher
模块装配与基础库appframework、interfaces、tier0、tier1、tier2、tier3、vstdlib、mathlib、unitlib
引擎engine、engine_ds
游戏game(client/server/shared)、matchmaking、gcsdk、responserules、serverbrowser、tracker
渲染与视觉materialsystem、studiorender、bonesetup、particles、togl、videocfg、bitmap、vtf、raytrace、fow、vguimatsurface
UI 与输入vgui2、scaleformui、inputsystem、localize
资源与数据filesystem、vpklib、datacache、resourcefile、datamodel、dmserializers、dmxloader、dmxeditlib、dmeutils、movieobjects、materialobjects、mdlobjects、mdllib、meshutils、fbxutils、choreoobjects、scenefilecache、soundemittersystem、soundsystem、avi
脚本vscript
工具hammer、fgdlib、utils、tools、devtools、vpc_scripts
第三方与预编译thirdparty、external、dx9sdk、dx10sdk、lib、common(含部分 SDK 与协议)、public(跨模块接口头文件)
非代码aREADTHEREADME、docs(未被 git 跟踪的既有报告,本 Wiki 不将其作为证据)

lib/ 中有大量平台预编译库,例如 lib/public/gcsdk.lib、lib/public/steamdatagramlib.lib、lib/common/ivp_physics.lib;.gitattributes 对 *.lib 配置了 Git LFS:.gitattributes:1-2。本次读取到的 .lib 文件大小为数百 KB 到十几 MB,不是 LFS 指针文本。

约束与边界#

  • 判断“某功能是否会被编译”的顺序应是:groups.vgc 是否包含工程 → projects.vgc 条件是否成立 → .vpc 是否列入该文件且文件条件成立 → 源码中的 #if 分支。
  • 本次没有执行 CreateSolution.bat、vpc.exe 或任何编译;所有可构建性判断都是静态推断。