[fpc-pascal] Calling function pointer to main program

Ryan Joseph genericptr at gmail.com
Fri Jan 3 20:19:45 CET 2020

> On Jan 3, 2020, at 11:35 AM, Jonas Maebe <jonas at freepascal.org> wrote:
> Additionally, you will also have to link in an object/library that does
> define a regular "main" function. And note that this will only work on
> libc-based targets (afaik only Darwin, Solaris, and AIX at this point).

So there needs to be a function named "main" that is linked to directly or can it just be in a unit? I tried doing this but still get linker errors (tested on MacOS of course). My example program is below.

It's possible I think -XM does something it doesn't also so here's is the main function for the SDL/ios bindings. Note how UIApplicationMain is called which then never returns control until the program exists. After that within the iOS event handlers a call is made to SDL_main (see the external definition) which if I understand correctly is set using -XP and this then in turn calls the begin..end block of the main Pascal program. Is that correct?

extern C_LINKAGE int SDL_main(int argc, char *argv[]);

int main(int argc, char **argv)
    int i;

    /* store arguments */
    forward_argc = argc;
    forward_argv = (char **)malloc((argc+1) * sizeof(char *));
    for (i = 0; i < argc; i++) {
        forward_argv[i] = malloc( (strlen(argv[i])+1) * sizeof(char));
        strcpy(forward_argv[i], argv[i]);
    forward_argv[i] = NULL;

    /* Give over control to run loop, SDLUIKitDelegate will handle most things from here */
    @autoreleasepool {
        UIApplicationMain(argc, argv, nil, [SDLUIKitDelegate getAppDelegateClassName]);

    /* free the memory we used to hold copies of argc and argv */
    for (i = 0; i < forward_argc; i++) {

    return exit_status;

Later on in the event handler called from UIApplicationMain:

 // call the user program main function so they can enter their own event loop logic
 exit_status = SDL_main(forward_argc, forward_argv);


here is my test case:

fpc main.pas -XMuser_main

unit umain;

function user_main(argc: cint; argv: pchar): cint; cdecl; external;

function main(argc: cint; argv: pchar): cint;


function main(argc: cint; argv: pchar): cint;
  result := user_main(args, args);


program main;

  writeln('called user main');

The linker error I can't get past:

Undefined symbols for architecture x86_64:
  "_main", referenced from:
      start in crt1.10.5.o
     (maybe you meant: _user_main)

	Ryan Joseph

More information about the fpc-pascal mailing list