Search code examples
cmakemingwstatic-librariesclion

SDL2 Cmake undefined reference to `WinMain@16' on Win10 MinGW


I am trying to set up SDL in CLion with MinGW, but I get errors after errors, and I just can't imagine where do I go wrong. Now I have this Cmake code, and I get the error undefined reference to 'WinMain@16' . I suppose I forget to link something, probably SDLmain, but I think I wrote it there in the target_link_libraries(). I would greatly appreciate some help to make it work.

cmake_minimum_required(VERSION 3.15)
project(SDL_project)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)

find_package(SDL2 REQUIRED)
include_directories(${SDL2_INCLUDE_DIR})

add_executable(SDL_project main.cpp)

target_link_libraries(${PROJECT_NAME} ${SDL2_LIBRARY} -lmingw32 -lSDL2main -lSDL2 -mwindows)

The error message:

    ====================[ Build | SDL_project | Debug ]=============================
"A:\CLion 2019.2.5\bin\cmake\win\bin\cmake.exe" --build D:\SDL_project\cmake-build-debug --target SDL_project -- -j 4
Scanning dependencies of target SDL_project
[ 50%] Building CXX object CMakeFiles/SDL_project.dir/main.cpp.obj
[100%] Linking CXX executable SDL_project.exe
A:/MSYS2/mingw32/bin/../lib/gcc/i686-w64-mingw32/9.3.0/../../../../i686-w64-mingw32/bin/ld.exe: A:/MSYS2/mingw32/bin/../lib/gcc/i686-w64-mingw32/9.3.0/../../../../i686-w64-mingw32/lib/../lib/libmingw32.a(lib32_libmingw32_a-crt0_c.o): in function `main':
D:/mingwbuild/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crt0_c.c:18: undefined reference to `WinMain@16'
collect2.exe: error: ld returned 1 exit status
CMakeFiles\SDL_project.dir\build.make:86: recipe for target 'SDL_project.exe' failed
CMakeFiles\Makefile2:74: recipe for target 'CMakeFiles/SDL_project.dir/all' failed
CMakeFiles\Makefile2:81: recipe for target 'CMakeFiles/SDL_project.dir/rule' failed
mingw32-make.exe[3]: *** [SDL_project.exe] Error 1
mingw32-make.exe[2]: *** [CMakeFiles/SDL_project.dir/all] Error 2
mingw32-make.exe[1]: *** [CMakeFiles/SDL_project.dir/rule] Error 2
mingw32-make.exe: *** [SDL_project] Error 2
Makefile:117: recipe for target 'SDL_project' failed

And I also made a cmake folder in the project folder, for the SDL find, but I am not sure if it is necessary.

set(FIND_SDL2_PATHS D:/SDL2/SDL2-devel-2.0.12-mingw/SDL2-2.0.12/x86_64-w64-mingw32)

find_path(SDL2_INCLUDE_DIR SDL2
        PATH_SUFFIXES include
        PATHS ${FIND_SDL2_PATHS})

find_library(SDL2_LIBRARY
        NAMES SDL2
        PATH_SUFFIXES lib
        PATHS ${FIND_SDL2_PATHS})

Solution

  • The solution was to add a new line to the end: add_definitions(-DSDL_MAIN_HANDLED).

    Now the CMakeLists.txt code looks like this:

    cmake_minimum_required(VERSION 3.15)
    project(SDL_project)
    
    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
    
    find_package(SDL2 REQUIRED)
    include_directories(${SDL2_INCLUDE_DIR})
    
    add_executable(SDL_project main.cpp)
    
    target_link_libraries(${PROJECT_NAME} ${SDL2_LIBRARY} -lmingw32 -mwindows)
    add_definitions(-DSDL_MAIN_HANDLED)
    

    And in the project folder in a separete folder called cmake there is the FindSDL2.cmake file, to locate SDL2:

    set(FIND_SDL2_PATHS D:/SDL2/SDL2-devel-2.0.12-mingw/SDL2-2.0.12/x86_64-w64-mingw32)
    
    find_path(SDL2_INCLUDE_DIR SDL2
            PATH_SUFFIXES include
            PATHS ${FIND_SDL2_PATHS})
    
    find_library(SDL2_LIBRARY
            NAMES SDL2 SDL2main
            PATH_SUFFIXES lib
            PATHS ${FIND_SDL2_PATHS})
    

    From the CMakeLists.txt I removed -lSDL2 and -lSDL2main flags, because they resulted in errors:

    ====================[ Build | SDL_project | Debug ]=============================
    "A:\CLion 2019.2.5\bin\cmake\win\bin\cmake.exe" --build D:\SDL_project\cmake-build-debug --target SDL_project -- -j 4
    [ 50%] Linking CXX executable SDL_project.exe
    A:/MSYS2/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lSDL2
    A:/MSYS2/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lSDL2main
    collect2.exe: error: ld returned 1 exit status
    CMakeFiles\SDL_project.dir\build.make:86: recipe for target 'SDL_project.exe' failed
    CMakeFiles\Makefile2:74: recipe for target 'CMakeFiles/SDL_project.dir/all' failed
    CMakeFiles\Makefile2:81: recipe for target 'CMakeFiles/SDL_project.dir/rule' failed
    Makefile:117: recipe for target 'SDL_project' failed
    mingw32-make.exe[3]: *** [SDL_project.exe] Error 1
    mingw32-make.exe[2]: *** [CMakeFiles/SDL_project.dir/all] Error 2
    mingw32-make.exe[1]: *** [CMakeFiles/SDL_project.dir/rule] Error 2
    mingw32-make.exe: *** [SDL_project] Error 2
    

    Also, it is important to use 64-bit mingw-w64, because mingw-w32 also gives errors, like:

    ====================[ Build | SDL_project | Debug ]=============================
    "A:\CLion 2019.2.5\bin\cmake\win\bin\cmake.exe" --build D:\SDL_project\cmake-build-debug --target SDL_project -- -j 4
    [ 50%] Linking CXX executable SDL_project.exe
    A:/MSYS2/mingw32/bin/../lib/gcc/i686-w64-mingw32/9.3.0/../../../../i686-w64-mingw32/bin/ld.exe: CMakeFiles\SDL_project.dir/objects.a(main.cpp.obj):D:/SDL_project/main.cpp:17: undefined reference to `SDL_Init'
    A:/MSYS2/mingw32/bin/../lib/gcc/i686-w64-mingw32/9.3.0/../../../../i686-w64-mingw32/bin/ld.exe: CMakeFiles\SDL_project.dir/objects.a(main.cpp.obj): in function `main':
    D:/SDL_project/main.cpp:19: undefined reference to `SDL_GetError'
    A:/MSYS2/mingw32/bin/../lib/gcc/i686-w64-mingw32/9.3.0/../../../../i686-w64-mingw32/bin/ld.exe: D:/SDL_project/main.cpp:24: undefined reference to `SDL_CreateWindow'
    A:/MSYS2/mingw32/bin/../lib/gcc/i686-w64-mingw32/9.3.0/../../../../i686-w64-mingw32/bin/ld.exe: D:/SDL_project/main.cpp:27: undefined reference to `SDL_GetError'
    A:/MSYS2/mingw32/bin/../lib/gcc/i686-w64-mingw32/9.3.0/../../../../i686-w64-mingw32/bin/ld.exe: D:/SDL_project/main.cpp:32: undefined reference to `SDL_GetWindowSurface'
    A:/MSYS2/mingw32/bin/../lib/gcc/i686-w64-mingw32/9.3.0/../../../../i686-w64-mingw32/bin/ld.exe: D:/SDL_project/main.cpp:35: undefined reference to `SDL_MapRGB'
    A:/MSYS2/mingw32/bin/../lib/gcc/i686-w64-mingw32/9.3.0/../../../../i686-w64-mingw32/bin/ld.exe: D:/SDL_project/main.cpp:35: undefined reference to `SDL_FillRect'
    A:/MSYS2/mingw32/bin/../lib/gcc/i686-w64-mingw32/9.3.0/../../../../i686-w64-mingw32/bin/ld.exe: D:/SDL_project/main.cpp:38: undefined reference to `SDL_UpdateWindowSurface'
    A:/MSYS2/mingw32/bin/../lib/gcc/i686-w64-mingw32/9.3.0/../../../../i686-w64-mingw32/bin/ld.exe: D:/SDL_project/main.cpp:41: undefined reference to `SDL_Delay'
    A:/MSYS2/mingw32/bin/../lib/gcc/i686-w64-mingw32/9.3.0/../../../../i686-w64-mingw32/bin/ld.exe: D:/SDL_project/main.cpp:45: undefined reference to `SDL_DestroyWindow'
    A:/MSYS2/mingw32/bin/../lib/gcc/i686-w64-mingw32/9.3.0/../../../../i686-w64-mingw32/bin/ld.exe: D:/SDL_project/main.cpp:48: undefined reference to `SDL_Quit'
    collect2.exe: error: ld returned 1 exit status
    CMakeFiles\SDL_project.dir\build.make:86: recipe for target 'SDL_project.exe' failed
    CMakeFiles\Makefile2:74: recipe for target 'CMakeFiles/SDL_project.dir/all' failed
    CMakeFiles\Makefile2:81: recipe for target 'CMakeFiles/SDL_project.dir/rule' failed
    Makefile:117: recipe for target 'SDL_project' failed
    mingw32-make.exe[3]: *** [SDL_project.exe] Error 1
    mingw32-make.exe[2]: *** [CMakeFiles/SDL_project.dir/all] Error 2
    mingw32-make.exe[1]: *** [CMakeFiles/SDL_project.dir/rule] Error 2
    mingw32-make.exe: *** [SDL_project] Error 2
    

    And, the SDL.dll file from the binary folder has to be added to the compiler, to avoid exit code -1073741515 (0xC0000135). It can be done by setting a path to the folder, or by copying the SDL.dll from the SDL\bin folder to the mingw64\bin folder.