Undefined symbol _SDL_main on OS X

I’m trying to port a piece of software from Linux to Apple’s OS X that
makes use of SDL. When I try to do the final linking:
g++ custom/lib/DROD.a custom/lib/FrontEndLib.a custom/lib/DRODLib.a
custom/lib/BackEndLib.a -lmk4 -lz -lexpat -lfmod -lSDL_ttf -L/sw/lib
-lSDLmain -lSDL -framework Cocoa -framework OpenGL -o custom/bin/drod

I get the following:
ld: Undefined symbols:
_SDL_main

I installed SDL 1.2.7 using the Fink package manager. I looked at the
FAQ for OS X and ensured that the class that defines main
(DROD/Main.cpp) includes SDL_main.h and SDL.h. The main function
starts like this:
int main(int argc, char *argv[])
which is the format that the FAQ claims is wanted. I ran gcc -E on
Main.cpp, and the main method is getting renamed to SDL_main.

Can anyone tell me what the problem is and what I need to do to get
the program to compile?

Thanks!

Jamie

Jamieson M. Cobleigh wrote:

I’m trying to port a piece of software from Linux to Apple’s OS X that
makes use of SDL. When I try to do the final linking:
g++ custom/lib/DROD.a custom/lib/FrontEndLib.a custom/lib/DRODLib.a
custom/lib/BackEndLib.a -lmk4 -lz -lexpat -lfmod -lSDL_ttf -L/sw/lib
-lSDLmain -lSDL -framework Cocoa -framework OpenGL -o custom/bin/drod

I get the following:
ld: Undefined symbols:
_SDL_main

I installed SDL 1.2.7 using the Fink package manager. I looked at the
FAQ for OS X and ensured that the class that defines main
(DROD/Main.cpp) includes SDL_main.h and SDL.h. The main function
starts like this:
int main(int argc, char *argv[])
which is the format that the FAQ claims is wanted. I ran gcc -E on
Main.cpp, and the main method is getting renamed to SDL_main.

Can anyone tell me what the problem is and what I need to do to get
the program to compile?

Thanks!

Jamie

On some operating systems (OS X but not Linux), SDL defines its own main() function which calls yours, hence the rename to SDL_main.
When using C++, you’ve got to declare your main() function like this:

extern “C” int main(int argc, char *argv[])
{
// Code here
}

This is required for SDL, written in C, to be able to call the C++ function.

Chris E.
-------------- next part --------------
A non-text attachment was scrubbed…
Name: signature.asc
Type: application/pgp-signature
Size: 256 bytes
Desc: OpenPGP digital signature
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20040510/438a8e0a/attachment.pgp

On some operating systems (OS X but not Linux), SDL defines its own main()
function which calls yours, hence the rename to SDL_main.
When using C++, you’ve got to declare your main() function like this:

extern “C” int main(int argc, char *argv[])
{
// Code here
}

This is required for SDL, written in C, to be able to call the C++ function.

I changed my Main.cpp so that the main method is declared:
extern “C” int main(int argc, char *argv[])

I still get the same result, however:
g++ custom/lib/DROD.a custom/lib/FrontEndLib.a custom/lib/DRODLib.a
custom/lib/BackEndLib.a -lmk4 -lz -lexpat -lfmod -lSDL_ttf -L/sw/lib
-lSDLmain -lSDL -framework Cocoa -framework OpenGL -o
custom/bin/drod

ld: Undefined symbols:
_SDL_main

When I use gcc -E to run the preprocessor, the method main is getting
renamed SDL_main, as expected. I’m very confused.

Jamie

Not in g++ or VC, at least.

The reason for this is that SDL_main.h declares the function in the C
namespace: SDL_main is prototyped as extern “C”, and main is defined to
SDL_main.

Then, when you later declare main() on your own, it has C linkage,
because it was previously defined to.

A simple example of this is:

(snip: test1.c)
void foo(int n);
main() { foo(1); }
(snip)

(snip: test2.cc)
#include <stdio.h>
extern “C” void foo(int n);
void foo(int n) { xprintf(“x\n”); }
(snip)

The actual definition of the function (third line) does not have to
repeat ‘extern “C”’, because that was included in the declaration
(second line).

The above code does not work if the foo() prototype in test2.cc is
omitted, because foo(int) is exported with C++ linkage, and test1.c
doesn’t find it.

I don’t know what the C++ standard has to say about it, but I never
put ‘extern “C”’ on my main() definition, and it works fine in at
least Windows, OSX and Linux.On Mon, May 10, 2004 at 09:41:59PM +0100, Chris E. wrote:

extern “C” int main(int argc, char *argv[])
{
// Code here
}


Glenn Maynard

The actual definition of the function (third line) does not have to
repeat ‘extern “C”’, because that was included in the declaration
(second line).

Thanks for the clarification. Looking at what “g++ -E” produces,
SDL_main.h is being included and is declaring:

56 “/sw/include/SDL/SDL_main.h”

extern “C” int SDL_main(int argc, char *argv[]);

and farther down, main is getting renamed correctly:
int SDL_main(int argc, char *argv[])

When I get to the linking step of my application, things are still
failing:
$ g++ custom/lib/DROD.a custom/lib/FrontEndLib.a custom/lib/DRODLib.a
custom/lib/BackEndLib.a -lmk4 -lz -lexpat -lfmod -lSDL_ttf -L/sw/lib
-lSDLmain -lSDL -framework Cocoa -framework OpenGL -o custom/bin/drod
ld: Undefined symbols:
_SDL_main

However, it looks like _SDL_main should be found:
$ nm custom/lib/DROD.a | grep SDL_main
00005c20 S SDL_main.eh
00000000 T _SDL_main

Any thoughts?

Jamie