【问题标题】:How can I make Visual Studio copy files before executing a built project如何在执行构建项目之前制作 Visual Studio 复制文件
【发布时间】:2018-02-06 16:23:41
【问题描述】:

我正在开发一款游戏和一个单独的游戏引擎(静态库)。 游戏副本包括游戏引擎项目并通过我在 CMake 中设置的预构建脚本从游戏引擎项目中输出。

当我更改引擎中的代码并想要对其进行测试时;我运行游戏项目。如果游戏项目不需要重新编译;引擎项目中的新 lib 文件永远不会被复制到游戏项目中(我在编译游戏项目之前已经设置了用于复制的预构建事件),因此在我运行游戏时不会进行更改。

这很烦人,并且在多次调试时误导了我,因此我希望每次启动游戏项目时都复制 lib 文件以确保它们始终是最新的。

我不想将引擎项目的依赖项添加到游戏项目中,因此我无法在引擎项目中使用构建后脚本来执行此操作。

我还研究了通过 VS 中的 Debugging->Comand 项目设置运行 .bat 文件,就像他们在这里建议的那样:How to run some script\excutable befure start debugging in VS2015?

这仅适用于发布版本,但是因为调试器在通过 .bat 文件启动时不会附加。

我尝试用于启动生成的 .exe 的批处理代码是:

  • start Absolute/Path/To/Generated/File.exe
  • call Absolute/Path/To/Generated/File.exe
  • Absolute/Path/To/Generated/File.exe

我想出的唯一完全可行的解决方案是通过我的游戏项目的源代码执行脚本。我想在源代码之外执行此操作,因为我希望能够将我的 CMake 复制到一个新项目并且已经处理了所有问题。

编辑:由于我的用例似乎有些混乱,我将进一步解释。我希望可以将游戏和引擎彼此分开开发,因此,游戏项目存储库具有引擎项目输出库的副本。由于以下情况的可能,我无法通过在游戏项目中指向引擎项目的输出目录来100%解决问题:

  1. 更改引擎代码并重新编译项目。
  2. 更改游戏代码并重新编译项目(用于复制 lib 文件的脚本触发)。
  3. 再次更改引擎代码并重新编译项目。
  4. 测试引擎更改时;游戏项目不需要重新编译(因此不会触发脚本,也不会发生复制),它使用引擎项目输出目录中的新 lib 文件运行,以测试两个项目中所做的更改。
  5. 一切正常,引擎代码被推送到引擎存储库,游戏代码连同开发人员错误地认为是最新的引擎库文件一起被推送到游戏存储库。
  6. 游戏存储库现在处于无法访问引擎项目的情况下无法运行的状态。

TL;DR:

每次通过 Visual Studio 启动项目时,我能否以某种方式(最好通过 Visual Studio 或 CMake)触发一堆文件的副本?

【问题讨论】:

  • 一个快速而肮脏的解决方案是将游戏项目的可执行输出路径设置为构建到引擎项目的输出路径中。因此,如果您开始调试,您将始终拥有最新的引擎库。而且我不明白为什么您的批处理文件方法不会附加到调试器,只要您不通过start 命令之类的方式在批处理中启动单独的进程。
  • @flor Heh,虽然没有那个解决方案:P 但它对我不起作用,因为涉及的项目比引擎多(没有提到它以保持它在我的题)。关于批处理文件解决方案;我根本不习惯批处理,所以我使用了 start (听起来这是一个糟糕的举动>.
  • @Florian 我现在也尝试使用 call 而根本没有命令(只是路径),它的行为方式与我的目的相同(调试器不会附加)。
  • 能否将批处理脚本代码添加到您的问题中?还是生成解决方案项目还是使用VS2017新增的“打开文件夹”功能?而且我记得您必须将“配置属性/调试”下的“调试器类型”设置为特定值(我认为“混合”确实有效,取决于您的代码库是否在托管代码中)。
  • @Florian 我已经添加了用于启动 .exe 的行。我只需要让那部分工作,因为那时复制很简单。我还尝试摆弄您谈到的调试值,但无论我在那里选择什么都没关系(调试器从不附加到我的程序)。我的代码是非托管的,因为它都是 C/C++,我正在检查使用来自 WINAPI 的IsDebuggerPresent() 附加的编译器。我使用 CMake 生成了一个包含我的两个项目的解决方案。我不知道“打开文件夹”功能应该是什么,快速的谷歌让我失望了:/

标签: visual-studio cmake visual-studio-2017 static-libraries


【解决方案1】:

把我的 cmets 变成答案

你的问题

我能够重现您的问题,不幸的是,即使直接调用批处理文件(cmdpowershell)中的可执行文件(如 Absolute/Path/To/Generated/File.exe)也会创建一个新进程(这意味着您的调试器不会自动附加到这个新的/动态创建的进程)。

因此,在您“开始调试 (F5)”可执行文件时,没有简单的基于脚本的解决方案允许复制共享库依赖项。

这可以用一些简单的测试代码来测试(等到一个调试器被附加然后触发一个断点):

ma​​in.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")

start.ps1

.\HelloWorld.exe

配置属性/调试(VS项目)

Command:            C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
Command Arguments:  -ExecutionPolicy Bypass -File $(ProjectDir)\start.ps1
Working Directory:  $(TargetDir)

现在您只能手动附加到新进程。我还尝试了以下powershell 脚本:

start.ps1

Start-Process -FilePath "HelloWorld.exe"
Debug-Process -Name "HelloWorld

但您仍然需要选择要使用的调试器。可能ReAttach Visual Studio extension 可以帮助自动化流程,或者您可以从Attach Debugger to multiple processes via powershell 作为基础开始,但我还没有尝试过。

我以前用过的替代品...

我以前使用过两种简单的方法来测试带有外部 DLL 的可执行文件(类似于您在问题中描述的场景):

  1. 将游戏项目的可执行输出路径设置为构建到引擎项目的输出路径中。因此,如果您开始调试,您将始终拥有最新的引擎库。

    CMAKE_RUNTIME_OUTPUT_DIRECTORY,也可以从cmake命令行设置

    > cmake -DCMAKE_RUNTIME_OUTPUT_DIRECTORY:PATH=.... 
    
  2. 将可执行文件的调试器Working Directory 设置为引擎项目的输出路径。

    查看你的 VS 项目的Configuration Properties / Debugging

    或者从 CMake VS_DEBUGGER_WORKING_DIRECTORY 目标属性中设置它

不要在基于 CMake 的开源项目中使用“二进制交付”

问题也是为什么您需要将库的(预)构建文件复制或部署到/与您的可执行文件一起?

问题是您需要为“平台 + 编译器 + 架构 + 配置” 提供库,以便使用 CMake 为其生成构建环境的所有可能组合。

您至少还需要交付头文件(如果接口契约不是库本身的一部分,例如托管代码)。如果您随后添加程序数据库.pdb 文件,您还需要源文件才能调试到库中。这将总结为您完整的 git 包。

通常我会推荐阅读cmake-packages from CMake's doku 和例如看看"Code Review: Basic CMake C++ project structure"Making cmake library accessible by other cmake packages automatically

【讨论】:

  • 如果 VS2017 中没有上述错误,脚本解决方案会起作用(鉴于您的第二个链接中的解决方案有效;因为第一个 oen 要求开发人员具有特定的扩展名)。您的其他两个替代方案仍然存在意外将错误的 lib 文件上传到 repo 的问题(我现在使用类似的解决方案,但它不是万无一失的)。 “问题也是为什么您需要将库的(预)构建文件复制或部署到/与您的可执行文件一起?” - 我不需要或不想这样做。我只希望项目是独立的回购方式。
  • 我将此标记为已接受的答案,因为它以多种方式回答了最初的问题。我将阅读您那里的最后一个链接,看看我是否可以重组整个事情来解决这个问题。感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-10
  • 1970-01-01
  • 1970-01-01
  • 2020-03-02
相关资源
最近更新 更多