Always getting "undefined reference to `WinMain@16'" when compiling with CLion

Answered

Greetings!

PyCharm is an IDE I'm quite familiar with, so when (again) starting with C/C++ it was only natural to take a peek at CLion (nice timing to pushing out the 1.0 btw).
But I'm running into troubles that I did not expect before.

Normally I'm more of a console guy, therefore I know the manual statements and how to use Makefile.
CMake is completely new to me. While working nicely on linux, the Windows part is driving me crazy.

I'm currently learning SDL and using the Lazy Foo Tutorial (http://lazyfoo.net/tutorials/SDL).  So my example code is the following (01_hello_sdl.cpp):

 
//
// http://lazyfoo.net/tutorials/SDL/01_hello_SDL/index2.php
//

//Using SDL and standard IO
#include <SDL2/SDL.h>
#include <iostream>

//Screen dimension constants
const int SCREEN_WIDTH = 640;
const int
SCREEN_HEIGHT = 480;

int main
(int argc, char *argv[]) {
    //The window we'll be rendering to
    SDL_Window
* window = NULL;
    
    //The surface contained by the window
    SDL_Surface
* screenSurface = NULL;

    //Initialize SDL
    if
( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
        std::cout << "SDL could not initialize! SDL_Error: " << SDL_GetError() << std::endl;
    
}
    else
    
{
        //Create window
        
window = SDL_CreateWindow( "SDL Tutorial - Hello SDL", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN );
        if
( window == NULL ) {
            std::cout << "Window could not be created! SDL_Error: " << SDL_GetError() << std::endl;
        
}
        else {
            //Get window surface
            
screenSurface = SDL_GetWindowSurface( window );

            //Fill the surface white
            
SDL_FillRect( screenSurface, NULL, SDL_MapRGB( screenSurface->format, 0x33, 0xFF, 0x33 ) );
            
            //Update the surface
            
SDL_UpdateWindowSurface( window );

            //Wait two seconds
            
SDL_Delay( 2000 );
        
}
    }
    
    //Destroy window
    
SDL_DestroyWindow( window );

    //Quit SDL subsystems
    
SDL_Quit();

    return 0;
}


Well, the code isn't too complex and shows a nice green screen.  When compiling manually, everything works perfect:

set PATH=%PATH%;c:/MinGW/bin
g++ 01_hello_sdl.cpp -Ic:/devcpp/SDL2/i686-w64-mingw32/include -Lc:/devcpp/SDL2/i686-w64-mingw32/lib -w -Wl,-subsystem,windows -lmingw32 -lSDL2main -lSDL2 -o 01_hello_sdl.exe


But beware of CMake... Windows Hell incoming.

cmake_minimum_required(VERSION 3.1)
project(sdl_tutorial_lazyfoo)

# inserted by CLion
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

# set paths (only needed on windows)
if
(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
    # where is the SDL2 development package copied to?
    
set(WINPATH_SDL "c:/devcpp/SDL2/i686-w64-mingw32")

    # add path do search path (windows requires ";" instead of ":" )
    
set(CMAKE_PREFIX_PATH ${WINPATH_SDL};${WINPATH_SDLIMAGE};$ENV{CMAKE_PREFIX_PATH})

    # where is the pkg-config executable?
    
set(PKG_CONFIG_EXECUTABLE c:/devcpp/pkg-config/bin/pkg-config.exe)
endif()

# PkgConfig to get SDL2 information
Include(FindPkgConfig)
PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2)

# load SDL2
if
(SDL2_FOUND)
    include_directories(${SDL2_INCLUDEDIR})
    link_directories(${SDL2_LIBRARY_DIRS})
endif()

##### 01: Hello SDL
set(SOURCES 01_hello_sdl.cpp)
set(EXEPROJECT 01_hello_sdl)
add_executable(${EXEPROJECT} ${SOURCES})
target_link_libraries(${EXEPROJECT} SDL2)
install(TARGETS ${EXEPROJECT} RUNTIME DESTINATION bin)


Should be working fine. But isn't. And most funny, it does not seem to be the SDL part to cause the problem:

"C:\Program Files (x86)\JetBrains\CLion 1.0.3\bin\cmake\bin\cmake.exe" --build C:\Users\viktor.zacek\.clion10\system\cmake\generated\17bc7385\17bc7385\Debug --target all -- -j 8
Linking CXX executable 01_hello_sdl.exe
C:/MinGW/bin/../lib/gcc/mingw32/4.9.2/../../../libmingw32.a(main.o):main.c:(.text.startup+0xa7): undefined reference to `WinMain@16'
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe[2]: *** [01_hello_sdl.exe] Error 1
CMakeFiles\01_hello_sdl.dir\build.make:87: recipe for target '01_hello_sdl.exe' failed
CMakeFiles\Makefile2:59: recipe for target 'CMakeFiles/01_hello_sdl.dir/all' failed
mingw32-make.exe[1]: *** [CMakeFiles/01_hello_sdl.dir/all] Error 2
mingw32-make.exe: *** [all] Error 2
Makefile:115: recipe for target 'all' failed



I would really appreciate any help I can get!


Kind regards,
Viktor

0
1 comment

When using the approach of Sebastian Tarach (find_package instead of FindPkgConfig, https://devnet.jetbrains.com/thread/464038) I changed my CMakeLists.txt to the following, now it works:

cmake_minimum_required(VERSION 3.2)
project(sample_clion_sdl)


# inserted by CLion
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

# set paths (only needed on windows)
if
(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
    # where is the SDL2 development package copied to?
    
set(SDL2_PATH "c:/devcpp/SDL2/i686-w64-mingw32")

    # add path do search path (windows requires ";" instead of ":" )
    
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${sample_clion_sdl_SOURCE_DIR}/cmake")
endif()

find_package(SDL2)

# include SDL2
include_directories(${SDL2_INCLUDE_DIR})

##### 01: Hello SDL
set(SOURCES main.cpp)
set(EXEPROJECT sample_clion_sdl)
add_executable(${EXEPROJECT} ${SOURCES})
target_link_libraries(${EXEPROJECT} ${SDL2_LIBRARY})
0

Please sign in to leave a comment.