I'm having problems linking SDL2 to my project, which probably are because I'm new to CMake, and I don't fully know how to create new projects with it. Every time and method I've tried to fix this problem has resulted in one of the following problems:
- "Cannot locate WinMain@16"
- Multiple undefined reference errors
- undefined reference to `SDL_main`
I have attempted to use find_package, linking directly to files, linking to library files, following tutorials (for example https://trenki2.github.io/blog/2017/06/02/using-sdl2-with-cmake/), searching for answers (most of them talk about using find_package which I can't get to work) (for example Using SDL2 with CMake).
Project dependencies
SDL 2.0.12, CMake 3.17.0, 7-Zip, mingw32-make, wget
The project is supposed to be cross-platform, but the main devenv is Windows 10. All scripts are run from the root folder "vivaria".
Project structure
vivaria/
├── build/
│ └── [cmake build files]
├── buildtools/
│ └── SDL2/SDL2-2.0.12/lib/x86 (and x64)
│ ├── SDL2.lib
│ └── SDL2main.libs
├── deploy/
├── resources/
├── scripts/
│ ├── build_windows_debug_x86.bat
│ └── install_buildtools_windows.bat
└── src/
├── CMakeLists.txt
└── vivaria.cpp
build_windows_debug_x86.bat
cmake -G "MinGW Makefiles" -S .\src\ -B .\build\ -DCMAKE_BUILD_TYPE=Debug
cd .\build\
mingw32-make
vivaria.cpp
#include <iostream>
#include "SDL.h"
int main() {
if (SDL_Init(SDL_INIT_VIDEO) != 0){
std::cout << "Hello world" << std::endl;
return 1;
}
SDL_Quit();
return 0;
}
CMakeLists.txt: undefined reference to SDL_main
cmake_minimum_required(VERSION 3.17)
project(Vivaria VERSION 1.0.0)
set(CMAKE_CXX_GLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -lmingw32")
# set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++")
set(INCLUDE_DIR "${CMAKE_SOURCE_DIR}/../buildtools")
set(SDL2_DIR "${INCLUDE_DIR}/SDL2/SDL2-2.0.12")
set(SDL2_INCLUDE_DIRS "${SDL2_DIR}/include")
set(CMAKE_BINARY_DIR "${CMAKE_SOURCE_DIR}/../deploy")
# Support both 32 and 64 bit builds
if (${CMAKE_SIZEOF_VOID_P} MATCHES 8)
set(SDL2_LIBRARIES "${SDL2_DIR}/lib/x64/SDL2main.lib;${SDL2_DIR}/lib/x64/SDL2.lib")
else ()
set(SDL2_LIBRARIES "${SDL2_DIR}/lib/x86/SDL2main.lib;${SDL2_DIR}/lib/x86/SDL2.lib")
endif ()
# link dependencies
include_directories(${SDL2_INCLUDE_DIRS})
link_directories(${SDL2_LIBRARIES})
# Project files and linking
set(SOURCES vivaria.cpp)
add_executable(${PROJECT_NAME} vivaria.cpp)
target_link_libraries(${PROJECT_NAME} ${SDL2_LIBRARIES})
Console output
F:\Koodit\Vivaria\build>mingw32-make
[ 50%] Linking CXX executable Vivaria.exe
c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: F:/Koodit/Vivaria/src/../buildtools/SDL2/SDL2-2.0.12/lib/x86/SDL2main.lib(Win32/Release/SDL_windows_main.obj):(.text[_main_getcmdline]+0xd1): undefined reference to `SDL_main'
collect2.exe: error: ld returned 1 exit status
CMakeFiles\Vivaria.dir\build.make:104: recipe for target 'Vivaria.exe' failed
mingw32-make[2]: *** [Vivaria.exe] Error 1
CMakeFiles\Makefile2:91: recipe for target 'CMakeFiles/Vivaria.dir/all' failed
mingw32-make[1]: *** [CMakeFiles/Vivaria.dir/all] Error 2
Makefile:99: recipe for target 'all' failed
mingw32-make: *** [all] Error 2
install_buildtools_windows.bat
set SDL2=SDL2-devel-2.0.12-VC.zip
set DOWNLOAD_DIR=%cd%\buildtools
set OUTPUT_DIR=%cd%\buildtools\SDL2
wget "https://libsdl.org/release/%SDL2%" -P "%DOWNLOAD_DIR%"
7z x "%DOWNLOAD_DIR%\%SDL2%" -y -o%OUTPUT_DIR%
del /F /Q %DOWNLOAD_DIR%\%SDL2%
As you can see I'm still "a bit" new to CMake, but I'm trying to learn.