构建系统与物理组织
本页回答两个问题:哪些目录真的会被编译,以及编译产物落在哪里。在 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_launcher | vpc_scripts/groups.vgc:21-37 |
| 引擎 | engine、engine_ds | vpc_scripts/groups.vgc:25-26 |
| 游戏 DLL | client、server、matchmaking、matchmaking_ds 及其 base 库 | vpc_scripts/groups.vgc:30-41 |
| 渲染 | materialsystem、shaderapiempty、shaderlib、stdshader_dbg、stdshader_dx9、studiorender、particles | vpc_scripts/groups.vgc:43-63 |
| 工具 | vbsp、vvis_*、vrad_*、vtex_*、shadercompile_*、hlmv、pet、vmt、commedit | vpc_scripts/groups.vgc:69-85 |
| 基础库 | tier0~tier3、vstdlib、mathlib、interfaces、appframework | vpc_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_DLL | game/client/client_base.vpc:60 |
| server 基础 | GAME_DLL | game/server/server_base.vpc:56 |
| CS:GO client | CSTRIKE_CLIENT_DLL;CSTRIKE_DLL;INCLUDE_SCALEFORM;USE_ECONOMY_FEATURES 等 | game/client/client_cstrike15.vpc:39 |
| CS:GO server | BOTS;CSTRIKE_DLL;USE_ECONOMY_FEATURES | game/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\bin | launcher/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或任何编译;所有可构建性判断都是静态推断。