When I first started learning C++, every project looked almost the same.
main.cpp
Everything lived in one file.
As projects became larger, I started splitting code into multiple .cpp and .h files. It worked, but something still felt wrong. The files were separated, yet the project itself didn't feel organized.
The biggest lesson I learned wasn't about writing C++.
It was about organizing software.
At first, I thought creating folders like this was enough.
Project
├── engine/
├── sandbox/
├── docs/
└── external/
It certainly looked cleaner.
But I eventually realized folders are only for humans.
The compiler doesn't care about folders.
The build system doesn't magically understand that engine should be built before sandbox just because they're in different directories.
Someone has to describe those relationships.
That's where CMake completely changed how I think about projects.
The biggest idea I learned is that CMake doesn't organize files.
It organizes targets.
Instead of saying,
"Compile every file in this folder."
I started saying,
"Build an engine library."
and
"Build a sandbox application."
Those are two completely different ideas.
My project became something like this.
Sandbox
│
▼
VEngine
│
▼
Raylib
That simple diagram explains my project much better than the folder structure ever could.
Sandbox depends on VEngine.
VEngine depends on Raylib.
The direction of the arrows tells the whole story.
Once I separated the project into targets, each part had a single responsibility.
Sandbox is where I experiment.VEngine contains the engine code.Raylib is an implementation detail hidden behind the engine.The sandbox no longer knows how windows are created or how drawing works.
It simply talks to the engine.
VEngine::Init();
while (VEngine::Running())
{
VEngine::BeginFrame();
// Game code
VEngine::EndFrame();
}
VEngine::Shutdown();
Looking at this code, there isn't a single Raylib function.
That was the architecture I wanted to build.
Before learning CMake, I thought it was just a tool that compiled code.
Now I see it differently.
CMake became the place where I describe how every part of the project relates to every other part.
It tells the build system:
It became the blueprint of the project.
The most valuable thing CMake taught me wasn't another command.
It was that software grows much more naturally when responsibilities are separated.
It makes the project easier to understand, easier to extend, and easier to maintain.
Looking back, I don't think the first milestone of VEngine was integrating Raylib.
It was learning how to organize the project before adding more features.
I'm glad I learned that lesson first.
The project is still in its early stages, but this idea has already changed how I think about building software.
GitHub: VEngine Blog: Building VEngine