TLDR:
When you use a library in your project,
- Compiling needs header filenames (
#include <*.h>
) and include directories containing them
- Linking needs lib filenames (
*.lib
, what you're missing) and library directories containing them
- Running needs dynamic libraries (
*.dll
), commonly using the same name as the .lib
in the current or system directory (VS has binary directories too but I've never needed to know what they're for exactly)
When you compile code and add #include <SDL.h>
, the compiler runs through a list of possible directories its been given to find that file. There are some default directories already set up, but so you don't have a mess of all your libraries in one place it's possible to add more. For example, Setting Global C++ Include Paths in Visual Studio 2012 (and 2011, and 2010). If your SDL.h is in a subdirectory in an include directory it won't be found - eg. just check this shouldn't be <SDL/SDL.h>
or something similar.
With the include path set and the correct #include
your code can compile. Now it's the linking stage. You've got some code that says I need the these functions and the linker has to either find the actual code for those functions and link them statically (all the code can be found in the .lib
) or set up the program to link at runtime, dynamically (in which case the program needs to be able to find the .dll
, and I think on windows you need a .lib
file that goes with it).
So in addition to the include directory you need a library directory. Also, just like you said to the compiler #include <SDL.h>
you need to tell the linker to look for the code for those functions defined in SDL.h
in SDL.lib
(which may end up actually providing the code at runtime when loading SDL.dll
). I think specifying libraries could even be done through #pragma
calls, but it's more common to see the library files specified as arguments to the linker program. As @ScottMcP-MVP said, append SDL.lib
to the Project Properties->Configuration Properties->Linker->Input->Additional Dependencies
list. If it still says unresolved external
that generally means the linker still can't find the file, so check for typos and double check the directories. Worst case is a mismatch between SDL.h and SDL.lib or SDL.lib was compiled with different options or a different compiler.
The error you're receiving is the linker saying the compiler says I need an "external" function, SDL_Init
, to make your code work but I haven't found/resolved-the-reference-to one in the list of libraries I've been given.
Just as an example/recap all these GUI options end up going to the compiler/linker. So for example a full compile line might look like this:
./compiler -I/path/to/my/includes -L/path/to/my/lib -lmylibrary.lib mycode.cpp -o myexecutable.exe
Where mycode.cpp
contains #include <mylibrary.h>
. Note that here the ./compiler
is operating as both compiler and linker. The process could be split into:
./compiler -I/path/to/my/includes mycode.cpp -o mycompiledcode.o
./linker -L/path/to/my/lib -lmylibrary.lib mycompiledcode.o -o myexecutable.exe
Once you have your executable it needs to be able to find SDL.dll
when you run it. Exactly as you've done, the executable should search the windows system directory. It should also search its current directory. On linux you can set an rpath
(not sure on windows). If you keep getting application configuration incorrect
and the dll is definitely there it's time to grab dependency walker and see what dll name the program is actually trying to load. Worst case is the application finds a different version of the dll or something else with the same name before the desired one.
Good luck. OpenGL is great fun!!
[EDIT]
You can use either x32 or x64 lib files, but all your code must be the same. It'll probably be easier to start with x32, and if you need fast double
computation and more ram then change. OpenGL doesn't have great support for x64 yet so it probably won't make much difference to you.
Additional Dependencies
is where you put just "SDL.lib
". This file then needs to exist in one of visual studio's library directories. If you don't get unresolved externals from SDL anymore then that part is fixed.
Your _main
error is probably to do with a disgusting hack *spit* SDL uses. Straight after #include <SDL.h>
put #undef main
(may want to surround in #ifdef
s in case it changes):
#include <SDL.h> //my include is <SDL2/SDL.h>, as I have both an SDL and SDL2 dir in my include path
#ifdef main
#undef main //remove SDL's main() hook if it exists
#endif
An important thing to note: generally use </>
to include external libraries and "/"
to include headers within your project - What is the difference between #include <filename> and #include "filename"?