背景
做 Cocos2d-x 游戏经常要给策划和测试打包 Win32 版本。每次手动复制资源太麻烦了,这篇文章分享如何配置 VS 的输出目录和生成后事件,实现资源自动复制。
配置目标
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 项目目录 ├── proj.win32/ │ ├── 项目名.sln │ └── 项目名.vcxproj ├── Resources/ # 游戏资源目录 │ ├── images/ │ ├── sounds/ │ └── config/ ├── Debug.win32/ # Debug 输出目录 │ ├── 项目名.exe │ ├── images/ # 自动复制 │ ├── sounds/ # 自动复制 │ └── config/ # 自动复制 └── Release.win32/ # Release 输出目录 ├── 项目名.exe └── ...
|
配置步骤
1. 配置输出目录
位置: 项目属性 → 配置属性 → 常规 → 输出目录
配置值:
1
| $(SolutionDir)$(Configuration).win32\
|
说明:
| 宏变量 |
含义 |
$(SolutionDir) |
解决方案目录(以 \ 结尾) |
$(Configuration) |
当前配置(Debug 或 Release) |
效果:
- Debug 配置:
项目目录/Debug.win32/
- Release 配置:
项目目录/Release.win32/
2. 配置中间文件目录
位置: 项目属性 → 配置属性 → 常规 → 中间目录
配置值:
1
| $(Configuration).win32\\$(ProjectName).tlog\
|
3. 配置附加库目录
位置: 项目属性 → 链接器 → 常规 → 附加库目录
配置值:
1
| $(SolutionDir)$(Configuration).win32
|
说明:
4. 配置生成后事件(自动复制资源)
位置: 项目属性 → 生成事件 → 生成后事件 → 命令行
添加命令:
1 2
| xcopy "$(ProjectDir)..\Resources" "$(OutDir)" /D /E /I /F /Y xcopy "$(OutDir)..\*.dll" "$(OutDir)" /D /Y
|
命令详解:
| 参数 |
说明 |
/D |
仅复制新文件(根据日期判断) |
/E |
复制子目录,包括空目录 |
/I |
如果目标目录不存在则创建 |
/F |
显示复制的完整文件名 |
/Y |
自动覆盖不提示 |
第一条命令: 复制 Resources 目录到输出目录
1
| xcopy "$(ProjectDir)..\Resources" "$(OutDir)" /D /E /I /F /Y
|
$(ProjectDir):项目文件目录
..\Resources:项目目录的 Resources 文件夹
$(OutDir):输出目录(即前面配置的 $(Configuration).win32)
第二条命令: 复制 DLL 文件到输出目录
1
| xcopy "$(OutDir)..\*.dll" "$(OutDir)" /D /Y
|
- 复制 Cocos2d-x 引擎的 DLL 文件
- 确保运行时可以找到依赖库
完整配置示例
.vcxproj 文件中的配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| <?xml version="1.0" encoding="utf-8"?> <Project>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <OutDir>$(SolutionDir)$(Configuration).win32\</OutDir> <IntDir>$(Configuration).win32\$(ProjectName).tlog\</IntDir>
<PostBuildEvent> <Command> xcopy "$(ProjectDir)..\Resources" "$(OutDir)" /D /E /I /F /Y xcopy "$(OutDir)..\*.dll" "$(OutDir)" /D /Y </Command> </PostBuildEvent> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <OutDir>$(SolutionDir)$(Configuration).win32\</OutDir> <IntDir>$(Configuration).win32\$(ProjectName).tlog\</IntDir>
<PostBuildEvent> <Command> xcopy "$(ProjectDir)..\Resources" "$(OutDir)" /D /E /I /F /Y xcopy "$(OutDir)..\*.dll" "$(OutDir)" /D /Y </Command> </PostBuildEvent> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <Link> <AdditionalLibraryDirectories> $(SolutionDir)$(Configuration).win32 </AdditionalLibraryDirectories> </Link> </ItemDefinitionGroup>
</Project>
|
常见问题和解决方案
1. xcopy 命令失败
错误信息:
解决方案:
1 2 3 4
| <!-- 使用完整路径 --> <Command> "C:\Windows\System32\xcopy.exe" "$(ProjectDir)..\Resources" "$(OutDir)" /D /E /I /F /Y </Command>
|
或者使用 robocopy(更现代的复制工具):
1
| robocopy "$(ProjectDir)..\Resources" "$(OutDir)\Resources" /E /MIR
|
2. 路径包含空格导致失败
解决方案: 使用引号包裹路径
1
| xcopy "$(ProjectDir)..\Resources" "$(OutDir)" /D /E /I /F /Y
|
3. 复制速度慢
优化方案: 只复制有变更的文件
1 2
| <!-- 添加 /D 参数,只复制新文件 --> xcopy "$(ProjectDir)..\Resources" "$(OutDir)" /D /E /I /F /Y
|
4. 排除特定文件
创建排除列表:
1 2
| <!-- 使用 /EXCLUDE 参数 --> xcopy "$(ProjectDir)..\Resources" "$(OutDir)" /D /E /I /F /Y /EXCLUDE:exclude.txt
|
exclude.txt 内容:
5. 条件复制(Debug/Release 不同)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <PostBuildEvent> <Command> xcopy "$(ProjectDir)..\Resources" "$(OutDir)" /D /E /I /F /Y xcopy "$(ProjectDir)..\Resources-Debug" "$(OutDir)" /D /E /I /F /Y xcopy "$(OutDir)..\*.dll" "$(OutDir)" /D /Y </Command> </PostBuildEvent> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <PostBuildEvent> <Command> xcopy "$(ProjectDir)..\Resources" "$(OutDir)" /D /E /I /F /Y xcopy "$(ProjectDir)..\Resources-Release" "$(OutDir)" /D /E /I /F /Y xcopy "$(OutDir)..\*.dll" "$(OutDir)" /D /Y </Command> </PostBuildEvent> </PropertyGroup>
|
高级配置
使用 PowerShell 脚本
更灵活的资源复制方案:
1 2 3 4 5
| <PostBuildEvent> <Command> powershell -ExecutionPolicy Bypass -Command "& '$(ProjectDir)..\tools\copy-resources.ps1' -Source '$(ProjectDir)..\Resources' -Destination '$(OutDir)'" </Command> </PostBuildEvent>
|
copy-resources.ps1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| param( [string]$Source, [string]$Destination )
if (!(Test-Path $Destination)) { New-Item -ItemType Directory -Path $Destination -Force }
Copy-Item -Path "$Source\*" -Destination $Destination -Recurse -Force
Write-Host "Resources copied from $Source to $Destination"
|
多平台资源管理
1 2 3 4 5
| Resources/ ├── common/ # 通用资源 ├── win32/ # Win32 特有 ├── android/ # Android 特有 └── ios/ # iOS 特有
|
1 2 3 4 5
| <!-- 复制通用资源 --> xcopy "$(ProjectDir)..\Resources\common" "$(OutDir)" /D /E /I /F /Y
<!-- 复制平台特有资源 --> xcopy "$(ProjectDir)..\Resources\win32" "$(OutDir)" /D /E /I /F /Y
|
最佳实践
版本控制: 不要将输出目录(Debug.win32/Release.win32)提交到版本控制
.gitignore 配置:
1 2 3 4 5 6 7
| # Cocos2d-x Win32 Debug.win32/ Release.win32/ *.suo *.user *.tlog ipch/
|
定期清理: 资源文件变更频繁时,定期清理输出目录
自动化测试: 结合 CI/CD 流程,自动执行构建和资源复制
小结
通过配置 VS 的输出目录和生成后事件,可以实现:
- 清晰的目录结构
- 自动的资源复制
- 方便的测试分发
- 高效的开发流程
配置要点:
- 输出目录:
$(SolutionDir)$(Configuration).win32\
- 库目录:
$(SolutionDir)$(Configuration).win32
- 生成后事件:使用 xcopy 自动复制资源和 DLL
搞定这些配置后,给测试发包就方便多了。