SDL on Cygwin: Undefined reference to 'WinMain@16'

From my googling, a lot of people have been getting this error, but none of them solutions worked for me since I am using Cygwin. I have to learn the UNIX environment for my class, but I have a windows OS, so I am using Cygwin. I am using windows 7 64-bit.

I followed LazyFoo's tutorials here:

Setting up using g++ tutorial:
http://lazyfoo.net/tutorials/SDL/01_hello_SDL/linux/index.php


Make file tutorial:
http://lazyfoo.net/tutorials/SDL/01_hello_SDL/linux/cli/index.php

The error:

1
2
3
4
5
6
7
$ make all
g++ 01_hello_SDL.cpp -w -lSDL2 -o 01_hello_SDL
/usr/lib/gcc/i686-pc-cygwin/4.8.3/../../../libcygwin.a(libcmain.o): In function `main':
/usr/src/debug/cygwin-1.7.33-1/winsup/cygwin/lib/libcmain.c:39: undefined reference to `WinMain@16'
collect2: error: ld returned 1 exit status
Makefile:23: recipe for target 'all' failed
make: *** [all] Error 1


The libcmain.c file(that the error above refers to):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/* libcmain.c

   Copyright 1996, 1997, 1998, 2000, 2001, 2004, 2006, 2009 Red Hat, Inc.

This file is part of Cygwin.

This software is a copyrighted work licensed under the terms of the
Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
details. */

#include <windows.h>

#define SP " \t\n"

/* Allow apps which don't have a main to work, as long as they define WinMain */
int
main ()
{
  HMODULE x = GetModuleHandle (0);
  char *s = GetCommandLine ();
  STARTUPINFO si;
  char *nexts;

  s += strspn (s, SP);

  if (*s != '"')
    nexts = strpbrk (s, SP);
  else
    while ((nexts = strchr (s + 1, '"')) != NULL && nexts[-1] == '\\')
      s = nexts;

  if (!nexts)
    nexts = strchr (s, '\0');
  else if (*++nexts)
    nexts += strspn (nexts, SP);

  GetStartupInfo (&si);

  return WinMain (x, 0, nexts,
          ((si.dwFlags & STARTF_USESHOWWINDOW) != 0
           ? si.wShowWindow
           : SW_SHOWNORMAL));
}


Make file:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#Copyright Notice:
#The files within this zip file are copyrighted by Lazy Foo' Productions (2004-2014)
#and may not be redistributed without written permission.

#OBJS specifies which files to compile as part of the project
OBJS = 01_hello_SDL.cpp

#CC specifies which compiler we're using
CC = g++

#COMPILER_FLAGS specifies the additional compilation options we're using
# -w suppresses all warnings
COMPILER_FLAGS = -w

#LINKER_FLAGS specifies the libraries we're linking against
LINKER_FLAGS = -lSDL2

#OBJ_NAME specifies the name of our exectuable
OBJ_NAME = 01_hello_SDL

#This is the target that compiles our executable
all : $(OBJS)
    $(CC) $(OBJS) $(COMPILER_FLAGS) $(LINKER_FLAGS) -o $(OBJ_NAME)


Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
/*This source code copyrighted by Lazy Foo' Productions (2004-2013)
and may not be redistributed without written permission.*/

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

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



int main( int argc, char* args[] )
{

    //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 )
    {
        printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() );
    }

    else
    {

        //Create window
        window = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN );

        if( window == NULL )
        {
            printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() );
        }

        else
        {

            //Get window surface
            screenSurface = SDL_GetWindowSurface( window );



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

            //Wait two seconds
            SDL_Delay( 2000 );

        }
    }

    //Destroy window
    SDL_DestroyWindow( window );

    //Quit SDL subsystems
    SDL_Quit();

    return 0;
}



Anyone know what's going on?
Last edited on
If you are using SUBSYSTEM:WINDOWS changing your main to:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
should work. Or changing your subsystem to console.
Last edited on
1
2
3
If you are using SUBSYSTEM:WINDOWS changing your main to:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
should work. Or changing your subsystem to console. 


I am using windows 7 64-bit. Sorry I am not familiar with windows subsystem. How do you change my subsystem to console? Also which main are you talking of? I tried using

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)

in place of main function signature, but it doesn't work(it gave different errors such as:

1
2
3
4
5
6
7
$ make all
g++ 01_hello_SDL.cpp -w -lSDL2 -o 01_hello_SDL
01_hello_SDL.cpp:12:12: error: expected initializer before ‘WinMain’
 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
            ^
Makefile:23: recipe for target 'all' failed
make: *** [all] Error 1
If you're using Visual Studios, you can go to your properties. I'm not sure for other IDE's.
Properties -> Configuration Properties -> Linker -> System

I'm not so familiar with using makefile. But your error looks like it saying it missing it's entry point, which for console should be:
int main(int argc, char* argv[])

Or on Windows:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)


Check out this link and see if it any help.

http://stackoverflow.com/questions/11932809/cygwin-makefile-error-recipe-for-target-main-o-failed
Last edited on
@OP: ¿have you tried http://wiki.libsdl.org/FAQWindows#I_get_.22Undefined_reference_to_.27WinMain.4016.27.22 ?


I am not using visual c++. But maybe Cygwin is somehow? I don't have visual studios, at least I don't think I have.

Either way, I have tried using a makefile like this:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#Copyright Notice:
#The files within this zip file are copyrighted by Lazy Foo' Productions (2004-2014)
#and may not be redistributed without written permission.

#OBJS specifies which files to compile as part of the project
OBJS = 01_hello_SDL.cpp

#CC specifies which compiler we're using
CC = g++

#COMPILER_FLAGS specifies the additional compilation options we're using
# -w suppresses all warnings
COMPILER_FLAGS = -w

#LINKER_FLAGS specifies the libraries we're linking against
LINKER_FLAGS = -lmingw32
LINKER_FLAGS1 = -lSDL2main
LINKER_FLAGS2 = -lSDL2
LINKER_FLAGS3 = -mwindows


#OBJ_NAME specifies the name of our exectuable
OBJ_NAME = 01_hello_SDL

#This is the target that compiles our executable
all : $(OBJS)
	$(CC) $(OBJS) $(COMPILER_FLAGS) $(LINKER_FLAGS) $(LINKER_FLAGS1) $(LINKER_FLAGS2) $(LINKER_FLAGS3) -o $(OBJ_NAME)



I get this error:


1
2
3
4
5
6
$ make all
g++ 01_hello_SDL.cpp -w -lmingw32 -lSDL2main -lSDL2 -mwindows -o 01_hello_SDL
/usr/lib/gcc/i686-pc-cygwin/4.8.3/../../../../i686-pc-cygwin/bin/ld: cannot find -lmingw32
collect2: error: ld returned 1 exit status
Makefile:27: recipe for target 'all' failed
make: *** [all] Error 1


I have tried every combination of the linkers, removing some of the links and etc and it gives "cannot find" errors. If I remove -lmingw32, I get the same error as I did from the original post.

I don't have trouble doing this on Codeblock. I just want to familiarize myself with the Linux commands using Cygwin since my classes needs us to use Linux.


Last edited on
If you're using Visual Studios, you can go to your properties. I'm not sure for other IDE's.
Properties -> Configuration Properties -> Linker -> System

I'm not so familiar with using makefile. But your error looks like it saying it missing it's entry point, which for console should be:
int main(int argc, char* argv[])
Edit & Run


Or on Windows:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)


Check out this link and see if it any help.

http://stackoverflow.com/questions/11932809/cygwin-makefile-error-recipe-for-target-main-o-failed


The problem is that I am not using visual studios.

Solution for Lazyfoo's tutorials for SDL on cygwin:

So I played around with stuff and created this make file after I saw what cygwin used to link when I configured the SDL test file. I decided to use the same linkers for my make file and it works.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#Copyright Notice:
#The files within this zip file are copyrighted by Lazy Foo' Productions (2004-2014)
#and may not be redistributed without written permission.

#OBJS specifies which files to compile as part of the project
OBJS = 01_hello_SDL.cpp

#CC specifies which compiler we're using
CC = g++

#COMPILER_FLAGS specifies the additional compilation options we're using
# -w suppresses all warnings
COMPILER_FLAGS = -w

#LINKER_FLAGS specifies the libraries we're linking against
LINKER_FLAGS = -L/usr/local/lib 
LINKER_FLAGS1 = -lcygwin
LINKER_FLAGS2 = -lSDL2main
LINKER_FLAGS3 = -lSDL2
LINKER_FLAGS4 = -mwindows

#OBJ_NAME specifies the name of our exectuable
OBJ_NAME = 01_hello_SDL

#This is the target that compiles our executable
all : $(OBJS)

	$(CC) $(OBJS) $(COMPILER_FLAGS) $(LINKER_FLAGS) $(LINKER_FLAGS1) $(LINKER_FLAGS2) $(LINKER_FLAGS3) $(LINKER_FLAGS4) -o $(OBJ_NAME)


Last edited on
Topic archived. No new replies allowed.