1
\$\begingroup\$

I've been a software developer for a while, but I haven't done C++ in a long time and I thought I'd try it out with some game developement. I'm following the tutorial on youtube for Remaking Cavestory in C++ (great tutorial so far). I'm on Episode 4. I liked the sound of doing some 64 bit dev, so after a bunch of struggling I got SDL2 to work, scouring the internet and some trial & error I got it set up using the x86_64 libraries with a MinGW-w64 installation. I opted not to copy lib and include files into mingw as suggested by some guides. Instead, I figured I could "point" eclipse at the proper folders and everything should work. This was true up until trying to integrate the SDL_Image library. I have everything set up such that SDL.h is found by the compiler, and SDL_image.h is found by the compiler. That is, the SDL.h and SDL_image.h as referenced by my project code are fine. The problem is the compiler fails on SDL_image.h because IT references SDL.h and that reference is apparently bad.

Windows 10 64 bit (pro I think, though I doubt it matters)
eclipse Neon.2 (4.6.2)
MinGW-w64 (I think 4.3.0)
SDL2 (2.0.5)
SDL_image (2.0.1)

Here's where all of my files are:

C:\MinGW-w64\mingw64
C:\MinGW-w64\mingw64\bin
C:\MinGW-w64\mingw64\include
C:\MinGW-w64\mingw64\lib
C:\MinGW-w64\mingw64\x86_64-w64-mingw32
C:\MinGW-w64\mingw64\x86_64-w64-mingw32\bin
C:\MinGW-w64\mingw64\x86_64-w64-mingw32\include
C:\MinGW-w64\mingw64\x86_64-w64-mingw32\lib

F:\Dev\SDL2-2.0.5\x86_64-w64-mingw32
F:\Dev\SDL2-2.0.5\x86_64-w64-mingw32\bin
F:\Dev\SDL2-2.0.5\x86_64-w64-mingw32\include
F:\Dev\SDL2-2.0.5\x86_64-w64-mingw32\lib

F:\Dev\SDL2_image-2.0.1\x86_64-w64-mingw32
F:\Dev\SDL2_image-2.0.1\x86_64-w64-mingw32\bin
F:\Dev\SDL2_image-2.0.1\x86_64-w64-mingw32\include
F:\Dev\SDL2_image-2.0.1\x86_64-w64-mingw32\lib

In eclipse I have the following configured:

Project -> Properties -> C/C++ Build -> Settings -> Tool Settings -> GCC C++ Compiler -> Includes:

"${workspace_loc:/cavestory-development/source/headers}"
"F:\Dev\SDL2-2.0.5\x86_64-w64-mingw32\include"
"F:\Dev\SDL2_image-2.0.1\x86_64-w64-mingw32\include"

Project -> Properties -> C/C++ Build -> Settings -> Tool Settings -> MinGW C++ Linker -> Libraries:

(top box: Libraries (-l))

SDL2
SDL2main
SDL2_image

(bottom box: Library search path (-L)

"F:\Dev\SDL2-2.0.5\x86_64-w64-mingw32\lib"
"F:\Dev\SDL2_image-2.0.1\x86_64-w64-mingw32\lib"

Project -> Properties -> C/C++ General -> Paths and Symbols -> Includes -> GNU C++:

/cavestorye-development/source/headers
F:\Dev\SDL2-2.0.5\x86_64-w64-mingw32\include
F:\Dev\SDL2_image-2.0.1\x86_64-w64-mingw32\include

Project -> Properties -> C/C++ General -> Paths and Symbols -> Libraries:

SDL2
SDL2main
SDL2_image

Project -> Properties -> C/C++ General -> Paths and Symbols -> Library Paths:

F:\Dev\SDL2-2.0.5\x86_64-w64-mingw32\lib
F:\Dev\SDL2_image-2.0.1\x86_64-w64-mingw32\lib

I've also copied all of the DLLs from these two folders into my Debug (where my .exe is created)

F:\Dev\SDL2-2.0.5\x86_64-w64-mingw32\bin
F:\Dev\SDL2_image-2.0.1\x86_64-w64-mingw32\bin

When I build the project, I get the following error:

F:\Dev\SDL2_image-2.0.1\x86_64-w64-mingw32\include/SDL2/SDL_image.h:27:17: fatal error: SDL.h: No such file or directory

It seems that when the compiler looks at SDL_image.h, it sees that THAT file includes SDL.h, which it can't find. Again, this worked when I was only including SDL2, and broke when I tried to include SDL2_image because the image library references the normal library in a way that can't be reconciled.

Has anyone dealt with this before? Let me know if I've left out any pertinent information.

\$\endgroup\$
  • \$\begingroup\$ switch the order of SDL2 and SDL2main in your linking phase, it may not fix the problem, but it does matter. Also, I believe your problem stems from including the /include folders and not the /include/SDL2 folders, in your code, do you use #include <SDL2/SDL.h> or do you use <SDL.h> directly? \$\endgroup\$ – Joshua Hedges Jan 12 '17 at 8:31
  • \$\begingroup\$ switching the order didn't help. My includes are <SDL2/SDL.h> and <SDL2/SDL_image.h>.I did try pointing to the include/SDL2 folders earlier which did not help. \$\endgroup\$ – vecima Jan 12 '17 at 19:57
  • \$\begingroup\$ The compiler finds both SDL.h and SDL_image.h, but when it's looking at SDL_image.h THAT file has #include "SDL.h", and that's the line that fails. \$\endgroup\$ – vecima Jan 12 '17 at 19:58
  • \$\begingroup\$ Edit SDL_image.h to have SDL2/SDL.h then. It's easier than changing all of your build settings. Also I believe because this change does not affect the output binary, you don't have to mark the change and release the source code. \$\endgroup\$ – Joshua Hedges Jan 12 '17 at 20:50
  • \$\begingroup\$ If you'd like to avoid such licensing questions by making any such edits however, the typical method would be to remove the include paths and library search parhs for SDL_image and directly install (copy) the sdl header into your sdl2 directory and do the same with it's libraries. That is the reason sdl_image says "sdl.h" it's expecting it to be in the same local directory. There is no downside to this method, if you ever don't need sdl_image but need sdl2 simply don't link SDL_image. Let me know whichmethod you prefer and I can explain it better in an answer so you can mark it for success. \$\endgroup\$ – Joshua Hedges Jan 12 '17 at 21:02
0
\$\begingroup\$

The problem is SDL_image.h has #include "sdl.h" is because it's expecting two things, it's expecting it to be in the local directory because "" instead of <>, the latter would suggest it's expecting it's directory to be added -Ilike/this at compile time. The second thing it's expecting is that SDL.h shares a directory with SDL_image.h, because #include "sdl.h" says search right where we are, for the file named such.

To remedy the problem the appropriate solution for SDL is to add the link and include SDL paths into your project, and with the SDL_extension libraries, to copy the files directly into the matching directories of the SDL path. With SDL_image this means copying SDL_image.h into SDL-version-number/include(/SDL2 whether this is present depends on download, but the idea is it needs to be in the same folder as SDL.h). Then copy the SDL_image .so/.a/.dll/etc. into the matching SDL-version-number/lib(/x86 or /x64 may be present depending on your download, but it needs to be in the same directory as sdlmain.a and sdl.a).

Any used functionalities that are additional sub-extensions of an SDL_extension library are generally linked on their own, or linked directly by the SDL_extension library, and you must determine their usage yourself, such as using PNG images. PNG images will be linked automatically because the PNG library was linked at the time of compiling SDL_image, however libpng-some-version.dll and zlib-some-version.dll must be copied into your project binary folder yourself, and you simply determine which ones you need by what sort of image you're using (if you need jpegs, copy the jpeg.dll no additional linking or compilation flags required it's already done)

Main Signature The required main signature for SDL/SDL2 is:

int main( int argc, char *argv[])

char **argv is equivalent to char *argv[], either may be used.

This issue is discussed here and other places, the fact that the tutorial writer's compiler allowed this usage is probably just a decision made by the compiler writers knowing that C++ SHOULD allow this usage, but doesn't.

For why the main signature has a macro making it be defined differently check here. It's not generally good practice, so don't copy this behavior ever, but SDL did it because it was written in C, and not too recently either.

\$\endgroup\$
  • \$\begingroup\$ Thank you for the detailed answer. You are correct about the SDL file path issue. I was able to resolve that an move on. I understood that SDL implements WinMain and "expects" a main implementation as you laid out above, I just didn't know why the "const" caused a problem in my case. At any rate I appreciate your help, and I'll accept your answer in the hopes that it helps someone in the future. \$\endgroup\$ – vecima Jan 16 '17 at 5:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.