BIG-95 BIG-95 - 1 month ago 20
C++ Question

SDL2 undefined reference to several functions with MinGW

I have the following project directory structure:

/program1
/bin
/include
/SDL2
/lib
/resources
/source
makefile


I read a lot Q&A here about this problem. But I really don't understand what's going on. I followed all the steps in the articles. I'm using Windows 7 64 bits and I got the include and lib files from
i686-w64-mingw32
paste. I put those files in my directories as I mentioned above.

My simple main.cpp code in
source
directory is:

#include <iostream>
#include "SDL.h"

int main( int argc, char* argv[ ] ) {
if( SDL_Init( SDL_INIT_VIDEO ) != 0 ) {
std::cout << "SDL_Init Error: " << SDL_GetError( ) << std::endl;
return 1;
}

SDL_Quit( );
return 0;
}


At the
source
directory I have a makefile too, that I'm using with MSYS, and this is the compile command that the makefile is yielding:

g++ -Wall -c -std=c++11 -I../include -I../include/SDL2 main.cpp -o ../bin/main.o
g++ ../bin/main.o -L../lib -lmingw32 -lSDL2main -lSDL2 -mwindows -o ../bin/program1.exe


After these two commands, I have this big error :(

../lib/libSDL2.a(SDL_windows.o): In function `WIN_CoInitialize':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/core/windows/SDL_windows.c:73: undefined reference to `_imp__CoInitializeEx@8'
../lib/libSDL2.a(SDL_windows.o): In function `WIN_CoUninitialize':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/core/windows/SDL_windows.c:92: undefined reference to `_imp__CoUninitialize@0'
../lib/libSDL2.a(SDL_windowskeyboard.o): In function `IME_SetupAPI':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:617: undefined reference to `ImmGetIMEFileNameA@12'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:630: undefined reference to `ImmGetContext@4'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:633: undefined reference to `ImmReleaseContext@8'
../lib/libSDL2.a(SDL_windowskeyboard.o): In function `IME_GetId':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:551: undefined reference to `ImmGetIMEFileNameA@12'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:566: undefined reference to `GetFileVersionInfoSizeA@8'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:570: undefined reference to `GetFileVersionInfoA@16'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:571: undefined reference to `VerQueryValueA@16'
../lib/libSDL2.a(SDL_windowskeyboard.o): In function `UILess_GetCandidateList':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:984: undefined reference to `_imp__SysFreeString@4'
../lib/libSDL2.a(SDL_windowskeyboard.o): In function `IME_ClearComposition':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:683: undefined reference to `ImmGetContext@4'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:687: undefined reference to `ImmNotifyIME@16'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:691: undefined reference to `ImmNotifyIME@16'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:692: undefined reference to `ImmReleaseContext@8'
../lib/libSDL2.a(SDL_windowskeyboard.o): In function `IME_Disable':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:364: undefined reference to `ImmAssociateContext@8'
../lib/libSDL2.a(SDL_windowskeyboard.o): In function `IME_ClearComposition':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:689: undefined reference to `ImmSetCompositionStringW@24'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:683: undefined reference to `ImmGetContext@4'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:687: undefined reference to `ImmNotifyIME@16'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:691: undefined reference to `ImmNotifyIME@16'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:692: undefined reference to `ImmReleaseContext@8'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:689: undefined reference to `ImmSetCompositionStringW@24'
../lib/libSDL2.a(SDL_windowskeyboard.o): In function `UIElementSink_BeginUIElement@12':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:1051: undefined reference to `_imp__SysFreeString@4'
../lib/libSDL2.a(SDL_windowskeyboard.o): In function `UIElementSink_UpdateUIElement@8':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:1078: undefined reference to `_imp__SysFreeString@4'
../lib/libSDL2.a(SDL_windowskeyboard.o): In function `IME_Init':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:309: undefined reference to `_imp__CoCreateInstance@20'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:323: undefined reference to `ImmGetContext@4'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:324: undefined reference to `ImmReleaseContext@8'
../lib/libSDL2.a(SDL_windowskeyboard.o): In function `UILess_SetupSinks':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:1192: undefined reference to `_imp__CoCreateInstance@20'
../lib/libSDL2.a(SDL_windowskeyboard.o): In function `IME_GetId':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:551: undefined reference to `ImmGetIMEFileNameA@12'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:566: undefined reference to `GetFileVersionInfoSizeA@8'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:570: undefined reference to `GetFileVersionInfoA@16'
../lib/libSDL2.a(SDL_windowskeyboard.o): In function `IME_GetReadingString':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:423: undefined reference to `ImmGetContext@4'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:498: undefined reference to `ImmReleaseContext@8'
../lib/libSDL2.a(SDL_windowskeyboard.o): In function `IME_GetId':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:571: undefined reference to `VerQueryValueA@16'
../lib/libSDL2.a(SDL_windowskeyboard.o): In function `IME_Quit':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:378: undefined reference to `ImmAssociateContext@8'
../lib/libSDL2.a(SDL_windowskeyboard.o): In function `IME_Enable':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:349: undefined reference to `ImmAssociateContext@8'
../lib/libSDL2.a(SDL_windowskeyboard.o): In function `IME_ClearComposition':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:683: undefined reference to `ImmGetContext@4'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:687: undefined reference to `ImmNotifyIME@16'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:691: undefined reference to `ImmNotifyIME@16'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:692: undefined reference to `ImmReleaseContext@8'
../lib/libSDL2.a(SDL_windowskeyboard.o): In function `IME_Disable':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:364: undefined reference to `ImmAssociateContext@8'
../lib/libSDL2.a(SDL_windowskeyboard.o): In function `IME_ClearComposition':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:689: undefined reference to `ImmSetCompositionStringW@24'
../lib/libSDL2.a(SDL_windowskeyboard.o): In function `WIN_SetTextInputRect':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:202: undefined reference to `ImmGetContext@4'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:209: undefined reference to `ImmSetCompositionWindow@8'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:210: undefined reference to `ImmReleaseContext@8'
../lib/libSDL2.a(SDL_windowskeyboard.o): In function `IME_HandleMessage':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:852: undefined reference to `ImmGetContext@4'
../lib/libSDL2.a(SDL_windowskeyboard.o): In function `IME_GetCompositionString':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:699: undefined reference to `ImmGetCompositionStringW@16'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:704: undefined reference to `ImmGetCompositionStringW@16'
../lib/libSDL2.a(SDL_windowskeyboard.o): In function `IME_HandleMessage':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:890: undefined reference to `ImmReleaseContext@8'
../lib/libSDL2.a(SDL_windowskeyboard.o): In function `IME_ClearComposition':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:683: undefined reference to `ImmGetContext@4'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:687: undefined reference to `ImmNotifyIME@16'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:691: undefined reference to `ImmNotifyIME@16'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:692: undefined reference to `ImmReleaseContext@8'
../lib/libSDL2.a(SDL_windowskeyboard.o): In function `IME_HandleMessage':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:885: undefined reference to `ImmGetContext@4'
../lib/libSDL2.a(SDL_windowskeyboard.o): In function `IME_GetCandidateList':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:767: undefined reference to `ImmGetCandidateListW@16'
../lib/libSDL2.a(SDL_windowskeyboard.o): In function `IME_GetCompositionString':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:699: undefined reference to `ImmGetCompositionStringW@16'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:704: undefined reference to `ImmGetCompositionStringW@16'
../lib/libSDL2.a(SDL_windowskeyboard.o): In function `IME_ClearComposition':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:689: undefined reference to `ImmSetCompositionStringW@24'
../lib/libSDL2.a(SDL_windowskeyboard.o): In function `IME_GetCandidateList':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/video/windows/SDL_windowskeyboard.c:771: undefined reference to `ImmGetCandidateListW@16'
../lib/libSDL2.a(SDL_xaudio2.o): In function `XAudio2Create':
/usr/local/cross-tools/i686-w64-mingw32/include/xaudio2.h:1273: undefined reference to `_imp__CoCreateInstance@20'
/usr/local/cross-tools/i686-w64-mingw32/include/xaudio2.h:1273: undefined reference to `_imp__CoCreateInstance@20'
/usr/local/cross-tools/i686-w64-mingw32/include/xaudio2.h:1273: undefined reference to `_imp__CoCreateInstance@20'
/usr/local/cross-tools/i686-w64-mingw32/include/xaudio2.h:1273: undefined reference to `_imp__CoCreateInstance@20'
../lib/libSDL2.a(SDL_dinputhaptic.o): In function `SDL_DINPUT_HapticInit':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/haptic/windows/SDL_dinputhaptic.c:98: undefined reference to `_imp__CoCreateInstance@20'
../lib/libSDL2.a(SDL_systimer.o): In function `SDL_SetSystemTimerResolution':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/timer/windows/SDL_systimer.c:57: undefined reference to `_imp__timeBeginPeriod@4'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/timer/windows/SDL_systimer.c:51: undefined reference to `_imp__timeEndPeriod@4'
../lib/libSDL2.a(SDL_systimer.o): In function `SDL_TicksInit':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/timer/windows/SDL_systimer.c:102: undefined reference to `_imp__timeGetTime@0'
../lib/libSDL2.a(SDL_systimer.o): In function `SDL_SetSystemTimerResolution':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/timer/windows/SDL_systimer.c:51: undefined reference to `_imp__timeEndPeriod@4'
../lib/libSDL2.a(SDL_systimer.o): In function `SDL_GetTicks_REAL':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/timer/windows/SDL_systimer.c:141: undefined reference to `_imp__timeGetTime@0'
../lib/libSDL2.a(SDL_systimer.o): In function `SDL_TicksInit':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/timer/windows/SDL_systimer.c:102: undefined reference to `_imp__timeGetTime@0'
../lib/libSDL2.a(SDL_winmm.o): In function `WINMM_CloseDevice':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/audio/winmm/SDL_winmm.c:170: undefined reference to `_imp__waveOutUnprepareHeader@12'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/audio/winmm/SDL_winmm.c:170: undefined reference to `_imp__waveOutUnprepareHeader@12'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/audio/winmm/SDL_winmm.c:182: undefined reference to `_imp__waveInClose@4'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/audio/winmm/SDL_winmm.c:187: undefined reference to `_imp__waveOutClose@4'
../lib/libSDL2.a(SDL_winmm.o): In function `WINMM_PlayDevice':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/audio/winmm/SDL_winmm.c:131: undefined reference to `_imp__waveOutWrite@12'
../lib/libSDL2.a(SDL_winmm.o): In function `SetMMerror':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/audio/winmm/SDL_winmm.c:106: undefined reference to `_imp__waveOutGetErrorTextW@12'
../lib/libSDL2.a(SDL_winmm.o): In function `WINMM_OpenDevice':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/audio/winmm/SDL_winmm.c:285: undefined reference to `_imp__waveOutOpen@24'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/audio/winmm/SDL_winmm.c:331: undefined reference to `_imp__waveOutPrepareHeader@12'
../lib/libSDL2.a(SDL_winmm.o): In function `PrepWaveFormat':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/audio/winmm/SDL_winmm.c:216: undefined reference to `_imp__waveOutOpen@24'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/audio/winmm/SDL_winmm.c:214: undefined reference to `_imp__waveInOpen@24'
../lib/libSDL2.a(SDL_winmm.o): In function `WINMM_OpenDevice':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/audio/winmm/SDL_winmm.c:281: undefined reference to `_imp__waveInOpen@24'
../lib/libSDL2.a(SDL_winmm.o): In function `DetectWaveInDevs':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/audio/winmm/SDL_winmm.c:57: undefined reference to `_imp__waveInGetNumDevs@0'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/audio/winmm/SDL_winmm.c:57: undefined reference to `_imp__waveInGetDevCapsW@12'
../lib/libSDL2.a(SDL_winmm.o): In function `DetectWaveOutDevs':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/audio/winmm/SDL_winmm.c:56: undefined reference to `_imp__waveOutGetNumDevs@0'
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/audio/winmm/SDL_winmm.c:56: undefined reference to `_imp__waveOutGetDevCapsW@12'
../lib/libSDL2.a(SDL_dinputjoystick.o): In function `SDL_DINPUT_JoystickInit':
/Users/slouken/release/SDL/SDL2-2.0.4-source/foo-x86/../src/joystick/windows/SDL_dinputjoystick.c:317: undefined reference to `_imp__CoCreateInstance@20'
collect2.exe: error: ld returned 1 exit status
make: *** [program1.exe] Error 1


I already tried to switch my include to "SDL2/SDL.h" and tried to put the include and lib files inside mingw folder and the same error is produced. Is my compilation command wrong?

EDIT: The strange thing is: if I modify my compilation command to an absolute path as an example F:/APIs/SDL2/include and lib, the program compiles. Why?

Answer

Linker used libSDL2.a, which is static library. Static library lacks dependenciy information so all additional dependencies have to be specified manually. To use dynamic library, you need libSDL2.dll.a in your libs paths (newer gcc/mingw should accept SDL2.dll as well, even without .dll.a, although I never used that). Also of course with dynamic linking you'll need SDL2.dll either bundled with your resulting .exe or in system directory to actually launch resulting program.

You could put both of these libraries into the same directory, like it is in SDL2 distribution. By default, linker should prefer dynamic library if it can find one, or it could be controlled manually with -Wl,-Bstatic and -Wl,-Bdynamic switches (if you want that, read documentation first - these flags affect all libraries specified after it).

(it only covers mingw; msvc have different library format, and SDL2 have separate download file for it)