0
votes

I'm trying to set up my Code::Blocks installation to work with the SDL2 graphics API. As the documentation suggests, once I had everything installed and specified correctly, I tried the SDL_Init(SDL_INIT_EVERYTHING) test, as:

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <SDL2/SDL.h>

int main (int argc, char *argv[])
{
    if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
    {
        printf("\nSDL2 could not be initialized! Code: %s\n", SDL_GetError());
    }

    return EXIT_SUCCESS;
}

However, I got the following errors:

...in function 'SDL_Main':
undefined reference to `SDL_Init`
undefined reference to `SDL_GetError`
undefined reference to 'WinMain@16'

I looked these errors up and they seem to be due to CodeBlocks using a 32-bit compiler, but I'm using the 64-bit SDL2 library. Which makes sense, as my linked options are:

-lmingw32 -lSDL2main -lSDL2

So, I used MinGW's WinBuilds tool to download the 64-bit MinGW fork, which gave me a massive amount of files in a new /mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/... folder. Then I went to CodeBlocks' Settings -> Compiler -> Toolchain Executables and pointed the respective compiler executables at the exe's in bin. My first thought was to then change -lmingw32 to -lmingw64, but this doesn't work. I get the error:

cannot find -lmingw64

At this point I'm not sure what I've done correctly, incorrectly, what is broken/working etc. and would really appreciate any help possible.

It may also be worth noting that I extracted the 64-bit compiler to C:\MinGW and pointed CodeBlocks at C:\MinGW\bin as the compiler installation directory. When I click Auto-Detect, it seems happy enough and states it has automatically found the GCC compiler in that location. Therefore, it must be my -lmingw64 flag that is wrong, or something else I have specified.

Edit: The 64-bit compiler was set up and detected correctly but continued to produce errors relating to SDL functions:

||=== Build: Debug in Initialization_Test (compiler: GNU GCC Compiler) ===|
obj\Debug\main.o||In function `SDL_main':|
C:\C\SDL_C_Graphics\Init_Test\Initialization_Test\main.cpp|8|undefined reference to `_SDL_Init'|
C:\C\SDL_C_Graphics\Init_Test\Initialization_Test\main.cpp|10|undefined reference to `_SDL_GetError'|
C:\C\SDL_C_Graphics\Init_Test\Initialization_Test\main.cpp|10|undefined reference to `_printf'|
obj\Debug\main.o||In function `__tcf_0':|
c:\mingw\lib\gcc\mingw32\8.2.0\include\c++\iostream|74|undefined reference to `__ZNSt8ios_base4InitD1Ev'|
obj\Debug\main.o||In function `__static_initialization_and_destruction_0':|
c:\mingw\lib\gcc\mingw32\8.2.0\include\c++\iostream|74|undefined reference to `__ZNSt8ios_base4InitC1Ev'|
c:\mingw\lib\gcc\mingw32\8.2.0\include\c++\iostream|74|undefined reference to `_atexit'|
C:\SDL_Dev\SDL2-2.0.12\x86_64-w64-mingw32\lib\libSDL2main.a(SDL_windows_main.o)||In function `main_getcmdline':|
\Users\valve\release\SDL\SDL2-2.0.12-source\foo-x64\..\src\main\windows\SDL_windows_main.c|71|undefined reference to `SDL_main'|
||error: ld returned 1 exit status|
||=== Build failed: 8 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

Command CodeBlocks may be executing for compilation, in separate log window:

x86_64-w64-mingw32-g++.exe -LC:\SDL_Dev\SDL2-2.0.12\x86_64-w64-mingw32\lib -LC:\SDL_Dev\SDL2-2.0.12\x86_64-w64-mingw32\lib -LC:\SDL_Dev\SDL_Img\SDL2_image-2.0.5\x86_64-w64-mingw32\lib -LC:\SDL_Dev\SDL_Mixer\SDL2_mixer-2.0.4\x86_64-w64-mingw32\lib -L"C:\Program Files\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\lib" -o bin\Debug\Initialization_Test.exe obj\Debug\main.o  -lmingw32 -lSDL2main -lSDL2  -lmingw32 -lSDL2main -lSDL2.dll -luser32 -lgdi32 -lwinmm -ldxguid
C:/MinGW/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: i386 architecture of input file `obj\Debug\main.o' is incompatible with i386:x86-64 output
1
Can you please post the full error output? Every detail may be important.rubenvb
"they seem to be due to CodeBlocks using a 32-bit compiler, but I'm using the 64-bit SDL2 library" Yes, that's probably it. "My first thought was to then change -lmingw32 to -lmingw64, but this doesn't work." You don't need to change anything, use -lmingw32.HolyBlackCat
@HolyBlackCat Thanks for the response. I changed back to -lmingw32, and while it seems to find the compiler now, I'm just back to the original undefined reference errors to the SDL functions. There must be something else that I'm missing.Rowan
@Rowan Please post the exact error messages. Does it still complain about WinMain@16 or not?HolyBlackCat
@HolyBlackCat No, there is no error for WinMain@16 now. I'll edit the original post and add the full output the end now.Rowan

1 Answers

2
votes

UPDATE Your last edit shows the most important bit of the output (it's incidentally also the first part of the output):

C:/MinGW/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: i386 architecture of input file `obj\Debug\main.o' is incompatible with i386:x86-64 output

This is the linker telling you you are mixing 32 and 64-bit binaries. It seems you compiled your source file main.cpp into a 32-bit binary object obj\Debug\main.o. You'll need to provide the commands leading to the creation of that file.


Some general remarks:

  1. The last symbol you're missing, WinMain@16 is a Windows-specific entry point that you "request" by compiling/linking with -mwindows and is typical/necessary for a native Win32 GUI application. It also seems linking SDL2main "causes" this.

  2. The "32"s you see in various system libraries and compiler prefixes reflects the API you're targeting, which is called "Win32", even on 64-bit Windows.

On to the error information you posted:

The undefined references to C++ symbols imply you are linking with gcc but instead should be linking with g++ which automagically links in the C++ bits you need. These missing symbols are needed because you included <iostream> which causes some global initialization to happen.

I cannot reproduce your linker error with MSYS2's build of SDL2. Your test code gives me the following output:

g++ main.cpp -o sdl_test -lSDL2main -lSDL2
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.3.0/../../../../x86_64-w64-mingw32/lib/../lib/libmingw32.a(lib64_libmingw32_a-crt0_c.o): in function `main':
D:/mingwbuild/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crt0_c.c:18: undefined reference to `WinMain'
collect2.exe: error: ld returned 1 exit status

For which I can refer back to my point 1 above. But that is not your issue as it's first complaining about the SDL symbols.