Setting up SDL2 in Windows (Visual Studio)

A step-by-step tutorial on configuring SDL2, SDL_image and SDL_ttf in a Visual Studio C++ project on Windows
This lesson is part of the course:

Game Dev with SDL2

Learn C++ and SDL development by creating hands on, practical projects inspired by classic retro games

Free, Unlimited Access
Abstract art representing computer programming
Ryan McCombe
Ryan McCombe
Updated

In this lesson, we’ll get SDL installed, along with two extensions which we’ll need later in this chapter.

  • SDL is a cross-platform library that allows us to create windows, access input devices, and create graphics.
  • SDL_image is an extension that allows us to work with images in all the common formats, such as jpeg and png
  • SDL_ttf is an extension that we can use to render text at run-time

This setup guide downloads the libraries that have been precompiled for use on Windows, and then demonstrates how to add them to a project that uses Visual Studio

Downloading the Libraries

The libraries can be downloaded from the official GitHub release pages, here:

Important Note: these release pages may include preview versions of SDL3. This course is using SDL2, so ensure the release you download starts with 2 (for example, 2.26.4)

Once we’ve found the latest version 2 release, Windows users should download the -VC package of each library:

Screenshot showing the SDL releases page on GitHub

Installing the Libraries

Once we have our three zip files, we should extract them to a location on our hard drive. It can be helpful to add them to our project directory so that everything our project needs is in one place. However, for the sake of this demo, I have extracted them to c:\sdl:

Screenshot showing the SDL libraries unzipped in Windows

Each of the folders includes 3 things we are interested in:

  • Header files (.h) within an include directory
  • Object Library files (.lib) within the lib directory
  • Dynamic Library files (.dll) within the lib directory

The lib directory includes both 32-bit (x86) and 64-bit (x64) versions of the libraries. In this guide we’ll only be setting up the x64 version but, if your project needs 32-bit as well, the steps can be repeated for that configuration.

Project Setup in Visual Studio

Let’s walk through how we’d add these libraries to our Visual Studio project. We can add the libraries to an existing project, or create a new project if needed.

Once we have our project open, we need to open the project properties window, available from the top menu under Project > Properties

Within our project properties, we need to change three things:

  1. Include Directories: This tells the preprocessor where the SDL header files are, so we can #include them in our own files.
  2. Library Directories: This tells the linker where to find SDL libraries, once we declare that our project depends upon them.
  3. Dependencies: This tells the linker that our project depends on SDL. Specifically, it means some of the variables we’ll be accessing and functions we’ll be calling are defined in the SDL libraries, so it needs to link them into our project

1. Adding SDL Include Directories

Under Configuration Properties > VC++ Directories, ensure we’re configuring the x64 version of our project by looking at the Platform dropdown at the top. Then, open the Include Directories list, and click Edit:

Screenshot showing the Include Directories configuration in Visual Studio

Here, we need to add the include directory of each of the three zips we extracted earlier:

Screenshot showing the include directories we need to set

2. Adding SDL Library Directories

Under Configuration Properties > VC++ Directories, open the Library Directories list, and click Edit

Screenshot showing the Library Directories in Visual Studio Project Settings

Here, we need to add the library directory from each of the three zips we extracted earlier. Because we’re configuring the 64-bit version of our project (x64) we use the x64 directories:

Screenshot showing the Library Directories we need to set

3. Adding SDL Libraries as Dependencies

Under Configuration Properties > Linker > Input, open the Additional Dependencies list, and click Edit:

Screenshot showing the Additional Dependencies in Visual Studio project settings

Here, we need to add a list of .lib files:

SDL2.lib
SDL2main.lib
SDL2_ttf.lib
SDL2_image.lib

These are file names that should exist within the lib directories we added to our project in step 2

Screenshot showing the additional dependencies we need to set

Compiling the Project

If everything is set up correctly, the following simple program should now compile successfully. Note that the program may not yet run successfully, but at this point, we just want to ensure it compiles:

#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>

int main(int argc, char** argv) {
  SDL_Init(SDL_INIT_VIDEO);
  IMG_Init(IMG_INIT_PNG);
  TTF_Init();

  return 0;
}

Troubleshooting: unresolved external symbol SDL_main referenced in function main_getcmdline

This error is generally going to be caused if we define our main function with one of the shorter signatures:

int main() {
  // ...
  
  return 0;
}
int main(void) {
  // ...
  
  return 0;
}

Normally, the abbreviated main function would work, but SDL sometimes needs to change the entry point of our program to ensure it is compatible with the platform we’re running it on. The Windows operating system is one such environment where this is necessary,

Therefore, to ensure our code is compatible with SDL, we need to use the full signature for our main function:

int main(int argc, char** argv) {
  // ...

  return 0;
}

Troubleshooting: 'SDL_main': must return a value

This error often indicates that the main function in our code is not explicitly returning a value:

int main(int argc, char** argv) {
  // ...
}

Normally, this would work - the C++ specification states that if our entry function doesn’t return a value, it’s treated as if it returned 0.

However, SDL needs to rename our main function behind the scenes to ensure our program is compatible with the platform it’s running on. As such, our main function needs to adhere to the rules as if it were a regular function, and return an appropriate value:

int main(int argc, char** argv) {
  // ...

  return 0;
}

Copying the SDL2 DLLs

Even though our program now compiles successfully, we may be getting errors when we try to run it. Our program may crash and report an error like:

The code execution cannot proceed because SDL2.dll was not found

To fix this, we need to ensure our system can find the SDL libraries our program is using. The three DLL files we need are:

SDL2.dll
SDL2_image.dll
SDL2_ttf.dll

These are included within the zips we downloaded earlier, within the /lib/x64 directory of each zip file. The easiest way we can help our system find these DLLs is to copy them to the same location as the executable that runs our program.

Note that in this image, my project is called SDL2, so the executable is called SDL2.exe. Yours will likely be different:

Screenshot showing the DLL files colocated with our executable file

It’s important to remember our compiled project is no longer a single .exe file - it now includes these .dll files. When we ship our program, we need to include all of the required .dll files so our users can run it.

Where is our .exe file?

The location where Visual Studio places your executable is called the Output Directory, and is configured from project properties under Configuration Properties > General > Output Directory

By default, the output directory will be within your project directory, in a subdirectory based on the release configuration such as x64\debug

The location will also be listed within your output window when you build the project. For example, the second line in the following output shows the location of the executable that was created:

Build started: Project: SDL2, Config: Debug x64
SDL2.vcxproj -> C:\SDL2\x64\Debug\SDL2.exe
Build: 1 succeeded
Build took 01.580 seconds

Path Variables

There is another mechanism we can use to help our system find the files our programs depend on. Windows maintains a list of locations it will automatically search for objects such as .dll files.

It is called the path variable, and it is available under System Properties > Advanced > Environment Variables > Path

Rather than moving the .dll files next to the executable, we could move them into one of the directories in that variable, such as windows/system32. Alternatively, we could add a new directory to the path variable, and store our DLLs there.

The main use for this is when the same library is going to be used by multiple executables. Rather than having unnecessary copies of the same DLL, we could store it in a shared location, accessible to all executables that need it.

Summary

In this lesson, we covered how to set up the SDL2 library for Windows development using Visual Studio. The key steps are:

  • Download the SDL, SDL_image and SDL_ttf libraries
  • Add the include and library directories to your project settings
  • Add the .lib files as additional dependencies
  • Copy the .dll files to the same directory as your executable

With SDL2 set up, you're now ready to start using it in the next chapter!

Was this lesson useful?

Next Lesson

Setting up SDL2 in macOS (Xcode or CMake)

This step-by-step guide shows you how to set up SDL2 in an Xcode or CMake project on macOS
Abstract art representing computer programming
Ryan McCombe
Ryan McCombe
Updated
sdl2-promo.jpg
This lesson is part of the course:

Game Dev with SDL2

Learn C++ and SDL development by creating hands on, practical projects inspired by classic retro games

Free, Unlimited Access
Setting up an SDL2 Development Environment
Next Lesson

Setting up SDL2 in macOS (Xcode or CMake)

This step-by-step guide shows you how to set up SDL2 in an Xcode or CMake project on macOS
Abstract art representing computer programming
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved