1

I'm working on a game and a separate game engine(static library). The game copies includes and output from the game engine project via a pre-build script that I have set up in CMake.

When I'm changing code in the engine and want to test it; I run the game project. If the game project doesn't need recompiling though; the new lib files from the engine project will never be copied into the game project (I have set up pre-build events for copying before compiling the game project) and thus the changes wont take when I run the game.

This is annoying and has mislead me while debugging several times and I would therefore like the lib files to be copied every time the game project is started to ensure that they are always up to date.

I don't want to add a dependency from the engine project to the game project and therefore I cannot use a post-build script in the engine project to do this.

I have also looked into running a .bat file through the Debugging->Comand project setting in VS like they suggest here: How to run some script\excutable befure start debugging in VS2015?

This only works for release builds however since the debugger won't attach when starting through a .bat-file.

The batch code I've tried using for starting the generated .exe is:

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

The only fully working solution that I have come up with is executing the script through the source code of my game project. I would like to do this outside the source though since I want to be able to copy my CMake to a new project and have all the problems already dealt with.

Edit: Since there seems to be some confusion about my use case I will explain it further. I want it to be possible to develop the game and the engine separate of each other and therefore, the game project repository has copies of the engine project's outputted libs. I can't solve the issue 100% by pointing to the engine project's output directory in the game project because of the possiblity of the following situation:

  1. Changes are made to the engine code and the project is recompiled.
  2. Changes are made to the game code and the project is recompiled (Script for copying lib files trigger).
  3. Changes are made to the engine code again and the project is recompiled.
  4. When testing the changes to the engine; the game project does not require a recompile (So no scripts trigger and no copying occurs) and it is run with the new lib files from the engine project's output directory to test the changes made in both projects.
  5. Everything works and the engine code is pushed to the engine repo and the game code is pushed to the game repo along with what the developer mistakenly thinks are the newest engine lib files.
  6. The game repo is now in a state where it doesn't run without access to the engine project.

TL;DR:

Can I somehow (through Visual Studio or CMake preferably) trigger a copy of a bunch of files every time a project is started through Visual Studio?

MonzUn
  • 53
  • 1
  • 9
  • A quick and dirty solution would be to set the executable output path of your game project to build into the output path of your engine project. So if you start debugging you will always have the latest engine libraries. And I don't understand why your batch file approach wouldn't attach to the debugger as long as you don't start a separate process in your batch through something like a `start` command. – Florian Feb 06 '18 at 20:10
  • @flor Heh, hadn't though of that solution :P It won't work for me though since there are more projects involved than the engine (didn't mention it to keep it simple in my question). Regarding the batch file solution; I'm not at all used to batch so I used start (Sounds like it was a bad move >.<). What can I use instead to run it under the same process? (I also read in some thread that I've lost now that it wouldn't work since the debugger can't attach to the batch file so I only tried it quickly. – MonzUn Feb 06 '18 at 20:14
  • @Florian I also tried using call and no command at all (just the path) now and it behaves the same way for my purposes (Debugger wont't attach). – MonzUn Feb 06 '18 at 20:28
  • Can you please add the batch scripts code to your question? Do you still generate a solution project or use the new "Open Folder" feature of VS2017? And I can remember that you have to set "Debugger Type" under "Configuration Properties/Debugging" to specific value (I think "Mixed" does work, depends on if your code base in managed code). – Florian Feb 06 '18 at 20:53
  • @Florian I've added the lines I used to start my .exe with. I only need to get that part working as the copying is trivial to do at that point. I also tried fiddling with the Debugging value you talked about but whatever I choose there it doesn't matter (debugger never attaches to my program). My code is unmanaged as it is all C/C++ and I'm checking for the compiler being attached using `IsDebuggerPresent()` from the WINAPI. I generate a solution containing both my projects using CMake. I don't recognize what the "Open Folder" feature should be and a quick Google let me down :/ – MonzUn Feb 06 '18 at 23:16
  • I will try reproducing it. Hadn't had the time yesterday. One - I admit a little outdated - link that might be useful to you: [How to: Launch the Debugger Automatically](https://msdn.microsoft.com/en-us/library/a329t4ed(v=vs.100).aspx). But several easier solution are possible if your engine project is part of your game project's solution. At least the engine should be included as `IMPORT` libraries (see e.g. [CMake Include dependencies of imported library without linking](https://stackoverflow.com/questions/38534215)). Can please give more details on your game's project CMake setup? – Florian Feb 08 '18 at 08:35
  • The option of automatic debugger attaching does work but is a hassle to set up, cannot be pushed into version control and requires the starting program to be run in administrator mode while also triggering this [bug] (https://developercommunity.visualstudio.com/content/problem/44742/vs2017-running-instance-not-available-in-jit-debug.html) (Even though my VS is v.15.3.4) – MonzUn Feb 08 '18 at 12:42
  • I had a look at the `IMPORT` functionality of CMake but if I've understood it corectly; that would make my game link to the output files of the engine. This would of course work but in the case where I change code in the engine and test it through the game (and everything works fine) and then proceed to commit to the game repo without recompiling (and thus copying the new lib files) I could mistakenly commit lib files that aren't up to date. – MonzUn Feb 08 '18 at 12:45
  • Here's a short version of the CMake I use https://pastebin.com/TsbAgbne. If you need the full files they can be found [here](https://github.com/MonzUn) named TeamSync("Game" (but not actually a game)) MEngine(Engine), Tubes and MUtility. This is the first time for me using CMake and it's probably messier than it needs to be so feel free to point out any stupid stuff I do :) I'm doing this to learn how to efficiently handle dependencies with and without access to the source meaning it should be possible to just download one of the repos and develop them without access to the dependency source. – MonzUn Feb 08 '18 at 12:51
  • Uh, CMake is not meant for binary delivery. It's meant for cross-platform and the freedom the your project's user to take whatever build-environment or toolchain they prefer. So the user normally installs or builds the dependent library packages and tells CMake - if it is not finding it by itself - where to find the build artifacts (see [`cmake-packages`](https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html)). So yes, I can definitely help you getting your current approach to run properly, but I just wouldn't recommend it. – Florian Feb 08 '18 at 21:21
  • First of all; thank you for trying to help me and having patience with me! – MonzUn Feb 09 '18 at 11:10
  • What do you mean by "Binary delivery"? I do not intend to ship the CMake with my game binary if that's what you mean. What I want to achieve is being able to develop each project with or without access to the source of the dependencies; which is why the engine libs are copied to the game repo and linked from there rather than being linked directly from the engine output. With this method I also always know where the libs are going to be located and that is why I don't let CMake find them for me (more direct & simple for me which I prefer now as I'm inexperienced with CMake). – MonzUn Feb 09 '18 at 11:18

1 Answers1

0

Turning my comments into an answer

Your Problem

I was able to reproduce your problem and unfortunately even the direct call of the executable in a batch file (cmd or powershell) like Absolute/Path/To/Generated/File.exe does create a new process (which means your debugger won't automatically attach to this new/dynamically created process).

So there is no simple script based solution that will allow for copying the shared library dependencies at the moment you "Start Debugging (F5)" your executable.

This can be tested with some simple test code (waiting until a Debugger is attached and then triggering a break-point):

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")

start.ps1

.\HelloWorld.exe

Configuration Properties/Debugging (VS Project)

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

Now you can only attach to the new process manually. I've also tried the following powershell script:

start.ps1

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

But you still need to select the debugger to use. Possibly the ReAttach Visual Studio extension could help to automate the process or you could start from Attach Debugger to multiple processes via powershell as a base, but I haven't tried this.

Alternatives I've used before ...

Two simple approaches I've used before for testing an executable with an external DLL (a scenario like the one you describe in your question):

  1. Set the executable output path of your game project to build into the output path of your engine project. So if you start debugging you will always have the latest engine libraries.

    See CMAKE_RUNTIME_OUTPUT_DIRECTORY which can also be set from cmake command line

    > cmake -DCMAKE_RUNTIME_OUTPUT_DIRECTORY:PATH=.... 
    
  2. Set the executable's debugger Working Directory to the output path of your engine project.

    See your VS project's Configuration Properties / Debugging

    Or for setting this from within CMake VS_DEBUGGER_WORKING_DIRECTORY target property

Don't use "Binary Delivery" in CMake based Open Source Project

The question is also why you need to copy or deploy the (pre-)build files of your library to/with your executable?

The problem would be that you need to deliver libraries for "Platform + Compiler + Architecture + Configuration" for all possible combinations one could use CMake to generate a build environment for.

And you at least also need to deliver the header files (if the interface contract is not part of the library itself, e.g. as for managed code). If you then add program data base .pdb files, you would also need the source files to be able to debug into the library. This would summarize to your complete git package.

Generally I would recommend to read cmake-packages from CMake's doku and e.g. take a look at "Code Review: Basic CMake C++ project structure" or Making cmake library accessible by other cmake packages automatically

Florian
  • 39,996
  • 9
  • 133
  • 149
  • The script solution would have worked if there wasn't the aforementioned bug in VS2017 (Given that the solution in your second link works; as the first oen requires the developer to have a specific extension). Both of your other alternatives still have the problem of accidentally uploading the wrong lib files to the repo (I use a similar solution right now but it's not foolproof). "The question is also why you need to copy or deploy the (pre-)build files of your library to/with your executable?" - I do not need or want to do that. I only want the projects to be independent repo-wise. – MonzUn Feb 14 '18 at 16:09
  • I'm marking this as accepted answer since it answers the initial question in multiple ways. I'm going to have a read at your last links there and see if I can just restructure the whole thing to get around the problem. Thanks for the help! – MonzUn Feb 14 '18 at 16:18