Brian Kirkpatrick
Posted on August 12, 2023
Background
A while back, I wrote an article on the evolution of game engines from beginner to intermediate architectures.
https://dev.to/tythos/engines-evolution-10gk
It was based on a series of projects I had worked on during grad school (a little over ten years ago), so there's definitely a lot of dust. My C++ days are largely behind me, but (after a lukewarm interview the other day) it seemed like an appropriate time to brush them off. In addition to a few HackerRank exercises, I decided to update an old project:
https://github.com/Tythos/Alphonse
This led to, among other thing things, a realization that C++ has really started to make a comeback. A lot of people would point to how active the committee is--and, to be clear, things like auto-iteration are an amazing improvement to the quality of life:
for (auto it : []) {}
But what has really struck me is, how potent the combination of submodules (the git construct) and cmake is. They complement each other so well that it's easy to see how isolated and archaic C++ code can suddenly leap into the modern era with an language-agnostic package management and automated, platform-neutral builds.
Dependencies
Based on an explorer project I had put together last month, there's a pretty straightforward pathway for leveraging the latest-and-greatest SDL using this combination of tools:
https://github.com/Tythos/sdlbox
So, the first step is to replace the library dependencies:
SDL (which will be bumped to SDL3), straight from the authoritative https://github.com/libsdl-org/sdl
glew (which needs a CMake-wrapped downstream mirror to completely automate the build hooks), from https://github.com/Perlmint/glew-cmake
We can add cmake dependencies from submodules with two easy modifications to our CMakeLists.txt file:
- The
add_subdirectory
imperative, passing exclusive subfolder names:
add_subdirectory(SDL EXCLUDE_FROM_ALL)
add_subdirectory(glew-cmake EXCLUDE_FROM_ALL)
- The
target_link_libraries
imperative, passing each library we want to link against. (Note that we also need OpenGL, and that we specify the static variant of glew here--it's a small library, and doing so reduces the DLLs we'll need to copy later.)
target_link_libraries(${PROJECT_NAME} PUBLIC SDL3::SDL3 opengl32 libglew_static)
Source Modifications
In addition to no longer needing glu
(farewell! you caused so many compile issues, I can't say I will shed many tears), we also need to update SDL for v3 calls.
The
SDL_CreateWindow()
signature has completely changed, and some parameters are no longer declared anywaySome event enumerations have changed
Since we'll be consolidating runtime resources within the CMake-managed build destination folder, we'll also remove the relative path references from the file reads for .GLSL
source.
Building and Running
We can now do the usual CMake two-step:
> cmake -S . -B build
> cmake --build build
This is sufficient to build our project, and now we can git rm -rf msvc
our way to happiness!
Before we run, though, we do need to copy in the runtime dependencies. Specifically, there are .GLSL
source files and a .DLL
to copy over for SDL3:
> copy *.glsl build\Debug
> copy build\SDL\Debug\*.dll build\Debug
(You'll note I'm using Windows/MSVC path assumptions here, but it should be easy to find your own folders regardless. There's probably a way in CMake to do this automatically, which would be great to add later.)
Conclusion
CMake and git submodules mean we never have to worry about maintaining separate projects (including relative paths and versions) for dependencies, and we don't even need to worry about maintaining a .SLN
file for Microsoft Visual Studio.
In a more general sense, though, what they mean is C++ is ready for the modern world.
Posted on August 12, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.