Trouble using scriptedmain in MinGW
Question: I want to reproduce [this Perl
code](https://github.com/mcandre/scriptedmain/tree/master/perl) in C, bundling
API and CLI in the same C source code file
([scriptedmain](http://rosettacode.org/wiki/Scripted_Main#C)). This is done in
Python with `if __name__=="__main__": main()` and in gcc/Unix, this looks
like:

    
    
    $ gcc -o scriptedmain scriptedmain.c scriptedmain.h
    $ ./scriptedmain
    Main: The meaning of life is 42
    $ gcc -o test test.c scriptedmain.c scriptedmain.h
    $ ./test
    Test: The meaning of life is 42
    

scriptedmain.h

    
    
    int meaning_of_life();
    

scriptedmain.c

    
    
    #include <stdio.h>
    
    int meaning_of_life() {
        return 42;
    }
    
    int __attribute__((weak)) main() {
        printf("Main: The meaning of life is %d\n", meaning_of_life());
    
        return 0;
    }
    

test.c

    
    
    #include "scriptedmain.h"
    #include <stdio.h>
    
    extern int meaning_of_life();
    
    int main() {
        printf("Test: The meaning of life is %d\n", meaning_of_life());
        return 0;
    }
    

However, when I try to compile with gcc/Strawberry, I get:

    
    
    C:\>gcc -o scriptedmain scriptedmain.c scriptedmain.h
    c:/strawberry/c/bin/../lib/gcc/i686-w64-mingw32/4.4.3/../../../../i686-w64-mingw32/lib/libmingw32.a(lib32_libmingw32_a-crt0_c.o): In function `main':
    /opt/W64_156151-src.32/build-crt/../mingw-w64-crt/crt/crt0_c.c:18: undefined reference to `WinMain@16'
    collect2: ld returned 1 exit status
    

And when I try to compile with gcc/MinGW, I get:

    
    
    $ gcc -o scriptedmain -mwindows scriptedmain.c scriptedmain.h
    c:/mingw/bin/../lib/gcc/mingw32/4.5.2/../../../libmingw32.a(main.o):main.c:(.text+0x104): undefined reference to `WinMain@16'
    collect2: ld returned 1 exit status
    

How can I get GCC in Windows to recognize the `__attribute__((weak))` syntax?

Also, G++ shows the same error.


Answer: I found a solution that works in Windows and in Unix: Simply wrap `main()` in
preprocessor instructions that omits it unless explicit compiler flags are
set.

scriptedmain.c:

    
    
    #include <stdio.h>
    
    int meaning_of_life() {
        return 42;
    }
    
    #ifdef SCRIPTEDMAIN
    
    int main() {
        printf("Main: The meaning of life is %d\n", meaning_of_life());
    
        return 0;
    }
    
    #endif
    

Now `main()` will be entirely omitted unless you compile with

    
    
    gcc -o scriptedmain -DSCRIPTEDMAIN scriptedmain.c scriptedmain.h
    

This code is safe to import into other C code, because the preprocessor will
strip out `main()`, leaving you to code your own main. The best part is that
this solution no longer depends on obscure compiler macros, only simple
preprocessor instructions. This solution works for
[C++](http://rosettacode.org/wiki/Scripted_main#C.2B.2B) as well.

