Undefined reference to SDL_main

I’ve been getting this error while trying to compile an SDL appilication.
I do not think it is an SDL error, as I have read and followed two SDL
tutorials to the letter. I have already done as much googling as I can
(an hour and a half), read all the faqs, and searched the forums and my
searches reveal nothing. I have set my Linker options to

-lmingw32 -lSDLmain -lSDL

without the -lmingw32, it gives “undefined reference to winmain at 16” With
it, it gives “undefined reference to SDL_main” It seems to me that I am
linking against a library with that very name. If you can help me, I’d
much appreciate it.

Here is my(very short) code:

#include
#include <SDL\SDL.h>
using namespace std;

int main()
{
/* if (SDL_Init(SDL_INIT_VIDEO) != 0)
{
cout<<"SDL: "<<SDL_GetError()<<endl;
exit(-1);
}
atexit(SDL_Quit);
*/
system(“PAUSE”);
return 0;
}

You can see that at this point I’ve cut out everything: I’m just trying to link
against SDL at this point.

Please help me.

SDL requires that main has one of the following signatures (the two
are identical to the compiler, but different people have preferences).

int main( int argc, char *argv[] )
int main( int argc, char **argv )

Tim Rau wrote:

I’ve been getting this error while trying to compile an SDL appilication.
I do not think it is an SDL error, as I have read and followed two SDL
tutorials to the letter. I have already done as much googling as I can
(an hour and a half), read all the faqs, and searched the forums and my
searches reveal nothing. I have set my Linker options to

-lmingw32 -lSDLmain -lSDL

Assuming you are using Mingw, and assuming you have managed to do
the two tutorials properly, I guess your setup works. However,
there’s no need to fiddle with link options like the above if you
use sdl-config in your Makefiles. Please see the test programs in
your SDL installation and follow how it calls sdl-config to
generate the proper CFLAGS and LDFLAGS options.

without the -lmingw32, it gives “undefined reference to winmain at 16” With
it, it gives “undefined reference to SDL_main” It seems to me that I am
linking against a library with that very name. If you can help me, I’d
much appreciate it.

Here is my(very short) code:

#include
#include <SDL\SDL.h>

A backslash in a path is an awful thing to feed into gcc… If
this was taught by the tutorials, then they are shockingly bad.
Can you provide the list with the URLs of the tutorials? With
sdl-config, you include the path and use “SDL.h” instead.

sdl-config simplifies a lot of things. sdl-config can also show
you what parameters to use, and you can plug that in if you really
do not want to call sdl-config in your Makefile. For example, you
can run the script on the command line:

$ sdl-config --cflags
-I/usr/include/SDL -D_GNU_SOURCE=1 -Dmain=SDL_main

$ sdl-config --libs
-L/usr/lib -lmingw32 -lSDLmain -lSDL -mwindows

Since the library settings look similar, your problem may be with
C flags. Use the following in your Makefiles instead:

CFLAGS = $(shell sdl-config --cflags) … blah blah
LDFLAGS = $(shell sdl-config --libs) … blah blah

HTH,–
Cheers,
Kein-Hong Man (esq.)
Kuala Lumpur, Malaysia

int main()
In C++, this should be:
extern “C” int main(int argc, char** argv)
The parameters are optional but good form.
You’ll likely only be bitten by this problem on Windows and Mac OS,
since Linux doesn’t require an SDL_main hack.
-:sigma.SBOn Jan 17, 2008 12:40 AM, Tim Rau wrote:

Solra Bizna wrote:> On Jan 17, 2008 12:40 AM, Tim Rau wrote:

int main()
In C++, this should be:
extern “C” int main(int argc, char** argv)
The parameters are optional but good form.
You’ll likely only be bitten by this problem on Windows and Mac OS,
since Linux doesn’t require an SDL_main hack.
-:sigma.SB

Yeah, Brian was right, sorry for the noise. In penance, if Tim
wishes to avoid using autoconf, here is a Makefile that is more
convenient, it tested okay on the fixed version of his program:

Makefile

CPPFLAGS = $(shell sdl-config --cflags)
LDFLAGS = $(shell sdl-config --libs) -lm

APPNAME = try
EXT = .exe

all: $(APPNAME)

$(APPNAME): $(APPNAME).cpp

clean:
rm -f $(APPNAME)$(EXT)

.PHONY: all


khman
KL, MY

KHMan <keinhong gmail.com> writes:

Solra Bizna wrote:

int main()
In C++, this should be:
extern “C” int main(int argc, char** argv)

What is the extern “C” for? I tried it without, and it worked.
It seems that SDL likes it just fine when main is defined that way. No other
changes. I’d really rather not just make that change without knowing why though.
I don’t want it to work, I want to understand it. Why does it matter what my
main is? Explanations or pointers to such are much appreciated.

The parameters are optional but good form.
You’ll likely only be bitten by this problem on Windows and Mac OS,
since Linux doesn’t require an SDL_main hack.
-:sigma.SB

I got SDL 1.2.13, and It doesn’t seem to have a windows binary for sdl-config. I
found the linux one in bin(It ran alright on my other(linux) system) Is there
some other thing that goes on for windows?> > On Jan 17, 2008 12:40 AM, Tim Rau <bladedpenguin yahoo.com> wrote:

Yeah, Brian was right, sorry for the noise. In penance, if Tim
wishes to avoid using autoconf, here is a Makefile that is more
convenient, it tested okay on the fixed version of his program:

Makefile

CPPFLAGS = $(shell sdl-config --cflags)
LDFLAGS = $(shell sdl-config --libs) -lm

APPNAME = try
EXT = .exe

all: $(APPNAME)

$(APPNAME): $(APPNAME).cpp

clean:
rm -f $(APPNAME)$(EXT)

.PHONY: all

extern “C” disables C++ name mangling. You don’t need this because
SDL_main.h declares SDL_main for you, and you only need the extern "C"
in the declaration (I think).

What main looks like matters to SDL because SDL works on platforms,
such as windows, where the entry point might be different. In windows,
a non-console application has an entry point called WinMain().
SDL_main provides this for you, by #defining your main to SDL_main. So
really, the main() you write isn’t main() at all, so you must conform
to SDL’s SDL_main signature, which includes argc and argv. Likewise,
even though the C++ standard allows main() to not explicitly return a
value (in which case the implementation should make it return 0), your
SDL_main must return a value (if you have a high enough warning level
you’ll see this).> What is the extern “C” for? I tried it without, and it worked.

It seems that SDL likes it just fine when main is defined that way. No other
changes. I’d really rather not just make that change without knowing why though.
I don’t want it to work, I want to understand it. Why does it matter what my
main is? Explanations or pointers to such are much appreciated.

I vaguely remember having to deal with a relatively obscure compiler
that barfed on SDL programs without it, but that would’ve been years
ago.
-:sigma.SBOn Jan 19, 2008 9:48 AM, Brian <brian.ripoff at gmail.com> wrote:

extern “C” disables C++ name mangling. You don’t need this because
SDL_main.h declares SDL_main for you, and you only need the extern "C"
in the declaration (I think).

Hello !

atexit(SDL_Quit);

Better call your own function with atexit.
atexiting SDL_Quit can be evil.

CU

Torsten scrisse:

[…]

atexit(SDL_Quit);

Better call your own function with atexit.
atexiting SDL_Quit can be evil.

That’s pretty vague, Torsten. Wanna elaborate?

Tim Rau wrote:

KHMan <keinhong gmail.com> writes:

[snip snip]
[snip snip]

I got SDL 1.2.13, and It doesn’t seem to have a windows binary for sdl-config. I
found the linux one in bin(It ran alright on my other(linux) system) Is there
some other thing that goes on for windows?

I usually am too lazy to build from sources, so I always grab the
mingw developer library version. If installed according to
instructions, you should be able to run sdl-config in your bash
shell; it’s a shell script. In the SDL sources, sdl-config is
generated from sdl-config.in. Try searching your msys directory
tree and see if you can find it; it should be in there somewhere.

[snip snip]

Makefile

CPPFLAGS = $(shell sdl-config --cflags)
LDFLAGS = $(shell sdl-config --libs) -lm

APPNAME = try
EXT = .exe

all: $(APPNAME)

$(APPNAME): $(APPNAME).cpp

clean:
rm -f $(APPNAME)$(EXT)

.PHONY: all

Ought to be “.PHONY: all clean” and testing for OS/OSTYPE will
probably help with appending .exe automatically… (the more
popular scheme is to separate out these things and put them in a
separate config file, see tcc’s Makefile for example) the suffix
is always a little troublesome for portable Makefiles. Using
$(APPNAME)$(EXT) might be better… I dunno what is better. If you
have a bunch of source files, then it is usually something like:

OBJS = foo.o
bar.o

$(APPNAME)$(EXT): $(OBJS)

dependencies here, or generate automatically and add an

include statement

foo.cpp: foo.h
bar.cpp: bar.h foo.h

And I believe the implicit rules should be able to handle
everything else. Something like that. A few simple Makefile
examples in the SDL wiki ought to be helpful.–
Cheers,
khman
KL, MY

Try renaming appending the .exe extension to sdl-config… worked for me. :stuck_out_tongue:

KHMan wrote:> Tim Rau wrote:

KHMan <keinhong gmail.com> writes:

[snip snip]

[snip snip]

I got SDL 1.2.13, and It doesn’t seem to have a windows binary for sdl-config. I
found the linux one in bin(It ran alright on my other(linux) system) Is there
some other thing that goes on for windows?

I usually am too lazy to build from sources, so I always grab the
mingw developer library version. If installed according to
instructions, you should be able to run sdl-config in your bash
shell; it’s a shell script. In the SDL sources, sdl-config is
generated from sdl-config.in. Try searching your msys directory
tree and see if you can find it; it should be in there somewhere.

[snip snip]

Makefile

CPPFLAGS = $(shell sdl-config --cflags)
LDFLAGS = $(shell sdl-config --libs) -lm

APPNAME = try
EXT = .exe

all: $(APPNAME)

$(APPNAME): $(APPNAME).cpp

clean:
rm -f $(APPNAME)$(EXT)

.PHONY: all

Ought to be “.PHONY: all clean” and testing for OS/OSTYPE will
probably help with appending .exe automatically… (the more
popular scheme is to separate out these things and put them in a
separate config file, see tcc’s Makefile for example) the suffix
is always a little troublesome for portable Makefiles. Using
$(APPNAME)$(EXT) might be better… I dunno what is better. If you
have a bunch of source files, then it is usually something like:

OBJS = foo.o
bar.o

$(APPNAME)$(EXT): $(OBJS)

dependencies here, or generate automatically and add an

include statement

foo.cpp: foo.h
bar.cpp: bar.h foo.h

And I believe the implicit rules should be able to handle
everything else. Something like that. A few simple Makefile
examples in the SDL wiki ought to be helpful.

Leo M. Cabrera wrote:

Try renaming appending the .exe extension to sdl-config… worked for me. :stuck_out_tongue:

The above suggestion is unclear and ambiguous. I fear it will only
confuse matters. What does “renaming appending” mean? What are you
actually suggesting?

I think we should all strive to ask clear questions to help others
diagnose problems and find solutions, and we should also all
strive to provide clear solutions or suggestions. Clear questions
and clear answers will help those Googling for solutions to
problems in the future.> KHMan wrote:

Tim Rau wrote:
[snip everything]


Cheers,
khman
KL, MY

On linux, executable files are denoted by a bit in the filesystem. On
windows, files are executable based on their file extension.
sdl-config cannot be executed unless it has an executable extension.
While renaming the file to sdl-config.exe works, a more suitable
executable extension would probably by “bat”.On Jan 20, 2008 5:30 AM, KHMan wrote:

Leo M. Cabrera wrote:

Try renaming appending the .exe extension to sdl-config… worked for me. :stuck_out_tongue:

The above suggestion is unclear and ambiguous. I fear it will only
confuse matters. What does “renaming appending” mean? What are you
actually suggesting?

Brian wrote:

On linux, executable files are denoted by a bit in the filesystem. On
windows, files are executable based on their file extension.
sdl-config cannot be executed unless it has an executable extension.
While renaming the file to sdl-config.exe works, a more suitable
executable extension would probably by “bat”.

I heartily admit I don’t understand the point of this, and for
good reason. I’ve installed the SDL mingw libraries multiple times
in the past and I’ve used Mingw/Msys for years and I don’t recall
of ever encountering such a need. I assume that we want to run
"sdl-config" and thus Msys is installed and we are using bash.

AFAIK, Msys allows execution of a text file like “sdl-config” by
virtue of shbang (’#!’) header detection; I’ve just verified this
on Msys with a “touch foo”, “vi foo”, then “ls”. “foo” is marked
as executable automatically and I can run it on Msys/bash. So why
rename? Seems awfully strange to be doing so when so many
projects, including SDL, has been distributing shell scripts for
Mingw/Msys without a “.bat” or “.exe” extension for years. It is
strange that developers are distributing libraries with shell
scripts that do not work unless there is a rename, or are they?

My question is this: Under what conditions does one has to modify
the extension of a shell script? I’ve never, ever had to do such a
thing, and I’ve never read of the install/compile notes of any
FLOSS project that can use Mingw/Msys speak of such a thing.> On Jan 20, 2008 5:30 AM, KHMan wrote:

Leo M. Cabrera wrote:

Try renaming appending the .exe extension to sdl-config… worked for me. :stuck_out_tongue:
The above suggestion is unclear and ambiguous. I fear it will only
confuse matters. What does “renaming appending” mean? What are you
actually suggesting?


Cheers,
khman
KL, MY

El Saturday 19 January 2008 22:26:59 Rhythmic Fistman escribi?:

Torsten scrisse:

[…]

atexit(SDL_Quit);

Better call your own function with atexit.
atexiting SDL_Quit can be evil.

That’s pretty vague, Torsten. Wanna elaborate?

Furthermore, calling atexit() with SDL_Quit() as argument is in fact
encouraged by the SDL documentation:

http://libsdl.org/intro.en/usinginit.html