如何在执行构建项目之前制作 Visual Studio 复制文件
How can I make Visual Studio copy files before executing a built project
我正在开发一款游戏和一个单独的游戏引擎(静态库)。
游戏副本包括游戏引擎项目并通过我在 CMake 中设置的预构建脚本输出。
当我在引擎中更改代码并想测试它时;我运行游戏项目。如果游戏项目不需要重新编译;引擎项目中的新 lib 文件将永远不会被复制到游戏项目中(我已经在编译游戏项目之前设置了用于复制的预构建事件)因此当我 运行 游戏时不会进行更改。
这很烦人,并且在调试时误导了我好几次,因此我希望每次启动游戏项目时都复制 lib 文件,以确保它们始终是最新的。
我不想将引擎项目的依赖项添加到游戏项目中,因此我无法在引擎项目中使用 post-build 脚本来执行此操作。
我还通过 VS 中的 Debugging->Comand 项目设置研究了 运行ning .bat 文件,就像他们在这里建议的那样:
这仅适用于发布版本,但是因为调试器在通过 .bat 文件启动时不会附加。
我尝试用于启动生成的 .exe 的批处理代码是:
start Absolute/Path/To/Generated/File.exe
call Absolute/Path/To/Generated/File.exe
Absolute/Path/To/Generated/File.exe
我想出的唯一完全可行的解决方案是通过我的游戏项目的源代码执行脚本。不过,我想在源代码之外执行此操作,因为我希望能够将我的 CMake 复制到一个新项目,并且所有问题都已经得到解决。
编辑: 由于我的用例似乎有些混乱,我将进一步解释。我希望能够将游戏和引擎彼此分开开发,因此,游戏项目存储库具有引擎项目输出库的副本。我在游戏工程中指向引擎工程的输出目录无法100%解决问题,可能会出现以下情况:
- 修改引擎代码并重新编译项目。
- 修改游戏代码,重新编译项目(复制lib文件触发脚本)。
- 再次更改引擎代码并重新编译项目。
- 在测试对引擎的更改时;游戏项目不需要重新编译(因此不会触发脚本,也不会发生复制),并且 运行 使用引擎项目输出目录中的新 lib 文件来测试两个项目中所做的更改。
- 一切正常,引擎代码被推送到引擎库,游戏代码连同开发人员误认为是最新的引擎库文件一起被推送到游戏库。
- 游戏仓库现在处于无法 运行 无法访问引擎项目的状态。
TL;DR:
每次通过 Visual Studio 启动项目时,我能否以某种方式(最好通过 Visual Studio 或 CMake)触发一堆文件的副本?
将我的评论变成答案
你的问题
我能够重现您的问题,不幸的是,即使像 Absolute/Path/To/Generated/File.exe
这样在批处理文件(cmd
或 powershell
)中直接调用可执行文件也会创建一个新进程(这意味着您的调试器不会自动附加到这个 new/dynamically 创建的进程)。
因此,没有简单的基于脚本的解决方案可以在您 "Start Debugging (F5)" 您的可执行文件时复制共享库依赖项。
这可以用一些简单的测试代码来测试(等待调试器连接然后触发断点):
main.cpp
#include <Windows.h>
int main()
{
while (IsDebuggerPresent() == FALSE);
DebugBreak();
}
CMakeLists.txt
cmake_minimum_required(VERSION 2.4)
project(HelloWorld)
add_executable(HelloWorld "main.cpp")
开始。ps1
.\HelloWorld.exe
配置Properties/Debugging(VS项目)
Command: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
Command Arguments: -ExecutionPolicy Bypass -File $(ProjectDir)\start.ps1
Working Directory: $(TargetDir)
现在您只能手动附加到新进程。我还尝试了以下 powershell
脚本:
开始。ps1
Start-Process -FilePath "HelloWorld.exe"
Debug-Process -Name "HelloWorld
但您仍然需要select调试器才能使用。可能 ReAttach
Visual Studio extension could help to automate the process or you could start from Attach Debugger to multiple processes via powershell 作为基础,但我还没有尝试过。
我以前用过的替代品...
我以前使用过的两种简单方法来测试带有外部 DLL 的可执行文件(一种类似于您在问题中描述的场景):
将游戏项目的可执行输出路径设置为构建到引擎项目的输出路径中。因此,如果您开始调试,您将始终拥有最新的引擎库。
参见 CMAKE_RUNTIME_OUTPUT_DIRECTORY
也可以从 cmake
命令行设置
> cmake -DCMAKE_RUNTIME_OUTPUT_DIRECTORY:PATH=....
将可执行文件的调试器 Working Directory
设置为引擎项目的输出路径。
查看你的 VS 项目的 Configuration Properties / Debugging
或者从 CMake VS_DEBUGGER_WORKING_DIRECTORY
目标 属性
中进行设置
不要在基于 CMake 的开源项目中使用 "Binary Delivery"
问题还在于为什么您需要复制或部署库的(预)构建文件 to/with 您的可执行文件?
问题是您需要为 "Platform + Compiler + Architecture + Configuration" 提供所有可能的组合的库,可以使用 CMake 为其生成构建环境。
并且您至少还需要提供头文件(如果接口契约不是库本身的一部分,例如托管代码)。如果您随后添加程序数据库 .pdb
文件,您还需要源文件才能调试到库中。这将总结为您完整的 git 包。
一般我会推荐阅读cmake-packages
from CMake's doku and e.g. take a look at "Code Review: Basic CMake C++ project structure" or
我正在开发一款游戏和一个单独的游戏引擎(静态库)。 游戏副本包括游戏引擎项目并通过我在 CMake 中设置的预构建脚本输出。
当我在引擎中更改代码并想测试它时;我运行游戏项目。如果游戏项目不需要重新编译;引擎项目中的新 lib 文件将永远不会被复制到游戏项目中(我已经在编译游戏项目之前设置了用于复制的预构建事件)因此当我 运行 游戏时不会进行更改。
这很烦人,并且在调试时误导了我好几次,因此我希望每次启动游戏项目时都复制 lib 文件,以确保它们始终是最新的。
我不想将引擎项目的依赖项添加到游戏项目中,因此我无法在引擎项目中使用 post-build 脚本来执行此操作。
我还通过 VS 中的 Debugging->Comand 项目设置研究了 运行ning .bat 文件,就像他们在这里建议的那样:
这仅适用于发布版本,但是因为调试器在通过 .bat 文件启动时不会附加。
我尝试用于启动生成的 .exe 的批处理代码是:
start Absolute/Path/To/Generated/File.exe
call Absolute/Path/To/Generated/File.exe
Absolute/Path/To/Generated/File.exe
我想出的唯一完全可行的解决方案是通过我的游戏项目的源代码执行脚本。不过,我想在源代码之外执行此操作,因为我希望能够将我的 CMake 复制到一个新项目,并且所有问题都已经得到解决。
编辑: 由于我的用例似乎有些混乱,我将进一步解释。我希望能够将游戏和引擎彼此分开开发,因此,游戏项目存储库具有引擎项目输出库的副本。我在游戏工程中指向引擎工程的输出目录无法100%解决问题,可能会出现以下情况:
- 修改引擎代码并重新编译项目。
- 修改游戏代码,重新编译项目(复制lib文件触发脚本)。
- 再次更改引擎代码并重新编译项目。
- 在测试对引擎的更改时;游戏项目不需要重新编译(因此不会触发脚本,也不会发生复制),并且 运行 使用引擎项目输出目录中的新 lib 文件来测试两个项目中所做的更改。
- 一切正常,引擎代码被推送到引擎库,游戏代码连同开发人员误认为是最新的引擎库文件一起被推送到游戏库。
- 游戏仓库现在处于无法 运行 无法访问引擎项目的状态。
TL;DR:
每次通过 Visual Studio 启动项目时,我能否以某种方式(最好通过 Visual Studio 或 CMake)触发一堆文件的副本?
将我的评论变成答案
你的问题
我能够重现您的问题,不幸的是,即使像 Absolute/Path/To/Generated/File.exe
这样在批处理文件(cmd
或 powershell
)中直接调用可执行文件也会创建一个新进程(这意味着您的调试器不会自动附加到这个 new/dynamically 创建的进程)。
因此,没有简单的基于脚本的解决方案可以在您 "Start Debugging (F5)" 您的可执行文件时复制共享库依赖项。
这可以用一些简单的测试代码来测试(等待调试器连接然后触发断点):
main.cpp
#include <Windows.h>
int main()
{
while (IsDebuggerPresent() == FALSE);
DebugBreak();
}
CMakeLists.txt
cmake_minimum_required(VERSION 2.4)
project(HelloWorld)
add_executable(HelloWorld "main.cpp")
开始。ps1
.\HelloWorld.exe
配置Properties/Debugging(VS项目)
Command: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
Command Arguments: -ExecutionPolicy Bypass -File $(ProjectDir)\start.ps1
Working Directory: $(TargetDir)
现在您只能手动附加到新进程。我还尝试了以下 powershell
脚本:
开始。ps1
Start-Process -FilePath "HelloWorld.exe"
Debug-Process -Name "HelloWorld
但您仍然需要select调试器才能使用。可能 ReAttach
Visual Studio extension could help to automate the process or you could start from Attach Debugger to multiple processes via powershell 作为基础,但我还没有尝试过。
我以前用过的替代品...
我以前使用过的两种简单方法来测试带有外部 DLL 的可执行文件(一种类似于您在问题中描述的场景):
将游戏项目的可执行输出路径设置为构建到引擎项目的输出路径中。因此,如果您开始调试,您将始终拥有最新的引擎库。
参见
CMAKE_RUNTIME_OUTPUT_DIRECTORY
也可以从cmake
命令行设置> cmake -DCMAKE_RUNTIME_OUTPUT_DIRECTORY:PATH=....
将可执行文件的调试器
Working Directory
设置为引擎项目的输出路径。查看你的 VS 项目的
Configuration Properties / Debugging
或者从 CMake
VS_DEBUGGER_WORKING_DIRECTORY
目标 属性 中进行设置
不要在基于 CMake 的开源项目中使用 "Binary Delivery"
问题还在于为什么您需要复制或部署库的(预)构建文件 to/with 您的可执行文件?
问题是您需要为 "Platform + Compiler + Architecture + Configuration" 提供所有可能的组合的库,可以使用 CMake 为其生成构建环境。
并且您至少还需要提供头文件(如果接口契约不是库本身的一部分,例如托管代码)。如果您随后添加程序数据库 .pdb
文件,您还需要源文件才能调试到库中。这将总结为您完整的 git 包。
一般我会推荐阅读cmake-packages
from CMake's doku and e.g. take a look at "Code Review: Basic CMake C++ project structure" or