Howto: Visual Studio, Libraries and Environment Variables
There are a few typical scenarios that I see come up in classes every year for programming students who are trying to use APIs and libraries that are not included by default in Microsoft’s Visual Studio installation;
- Trying to “install” OpenGL
- Trying to link external libraries to their project.
- Running programs that use external libraries.
- Understanding what IDE, API, libraries, DLL and environment variables even mean.
This post aims to try and help people to understand a few differences between different these concepts and generally make it simpler to manage your code stuff. If anyone has any questions, post it in the comments section so that I can try and modify this to make more sense. This might seem simplistic at times to a degree that makes certain concepts almost sound inaccurate in their description; but the point is that a range of people can understand the basic concepts and get things up and running as soon as possible. First off, a couple of explanations of terminologies:
- IDE: Integrated Developer/Development Environment. When you code, you write a load of text. When you compile, you run a program to convert that text into something else (usually a binary executable file on Windows, a .exe file). These are two separate things you would do and, along with debugging and a range of other things you might want to do, thankfully there are programs out there that wrap it all up together in one program. This is what an IDE is. Visual Studio and Eclipse are a couple of examples of this.
- API: Basically just a way to access (in other words, an interface to) various libraries. You would download a library and access it through an API. If you installed Visual Studio, you already have access to the Win32 libraries through the Win32 API. To use it, you would just include the relevant headers (.h files) and call the different functions. So an API provides a way for someone to use already-developed code (libraries) in their own code. APIs you might commonly use will often come with some sort of documentation somewhere that describes each of the functions and some example usage. The scripting that you can do in Unity, and any programming you do with OGRE, use the Unity and OGRE APIs.
- Middleware, in the context of software development, is some software that bridges various gaps in development. So, for example, you might have a system that implements graphics APIs, or handles all the audio for you or focuses on different inputs you might have from various game controllers and interface devices. Middleware can often be cross-platform, so you don’t have to worry about underlying implementations for different systems. It is usually used to describe a complete software package, so you could consider things like OGRE and Unity to be middleware as you can run your game on top of these engines.
e.g. GLFW, GLEW and so on
So you have Visual Studio set up and you want to use some obscure OpenGL library. But you haven’t installed OpenGL and when you have downloaded any libraries, it isn’t really clear how to install them.
For the sake of simplicity, the first thing to make sure you do is that, when downloading libraries, you find the binary rather than the source. A binary has been pre-compiled already – which means that you can use it straight away so long as you are using the right binary. For example, if you download the Mac version of a library, it won’t work on Windows. This is what the source is useful for – compilation yourself on a specific system.
But, luckily, Visual Studio 2013 binaries for 64 bit (and 32 bit) Windows are fairly standard, so you can go ahead and probably just download the binary with no issue. However, from there you have to move a few files around.
Headers, Libraries and DLL files
The three files you’ll be interested in, in the binary packages, are:
- DLL (dynamically linked library) files which contain, basically, code that has already been written which does certain stuff. This is a runtime file and is used by your executables that you have already built.
- Headers – contains function definitions for use when you are programming. A header file (.h) will contain references to functions that are included in..
- Libraries (.lib) files. This is essentially a big load of code packed into a single file. Hence it being called a library. You can’t really see this code yourself, so you have to use a header to access it. You’ll get errors during compile time if it can’t find the right library associated with the functions you have written that are referenced in the header. You might be using a 64 bit library, for example, on a 32 bit compilation or vice versa. Or you might not have linked your program to that library.
So essentially you use your .h and your .lib files when developing a program and your .dll file when distributing it. Lets see how you actually “install” these on your system.
- Download your library you want from wherever. For example GLFW (http://www.glfw.org/download.html and click either the 32 bit or 64 bit binaries buttons. You only need one but it will kind of make some difference later. Go for 32 bit maybe).
- I will go ahead and assume you are using Visual Studio 2013 (which is called Visual Studio 12 – just go with this. If you are using 2012, use Visual Studio 11) and you are running a 64 bit windows. The first thing to do is to navigate to your Visual C folder, which would be located in this example here:
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\
- Inside this folder are two other folders; lib and include. Using the example of GLFW, you would put glfw3.h into include and glfw3.lib into lib
- Next you want to find your system folder. On 64 bit windows, this is C:/Windows/SysWOW64. Inside here, you want to put your dll files – this can actually go into a number of places, but system files here are a good place to put your dll files that can be used by numerous other applications.
- Finally, boot up your program and either add a reference to your library (eg glfw3.lib) to your project properties (Project -> <application name> Properties -> Configuration Properties -> Linker -> Input) under the “Additional Dependencies” section or do it inline in your code. I prefer the code way, because this is much more visible to the user. Do that through doing:
#pragma lib (lib, "glfw3.lib")
Now you will be linking against this library when you compile your code. Just make sure you also do an #include glfw3.h for the above example and you’re done!
Some issues you might run into with those three parts:
- Coding: If you don’t include the #include glfw3.h, you will get errors when you are, such as undefined functions.
- Compiling: If you don’t include #pragma comment (lib, “glfw3.lib”), you will get errors such as unresolved external symbol errors (note: this also occurs when you are using a 32/64 bit binary on a different target build, e.g. a 64 bit binary for a 32 bit build. This is easiest fixed by just redownloading the other binary that you didn’t download)
- Runtime: If you don’t include your glfw3.dll in your system folder, or you are distributing your application to someone else later and they don’t have the DLL themselves, you will get an error when the application runs. The application will just not run and you will get an error saying that the DLL can’t be found. Just make sure the DLL is in your system and, if distributing your application, include this in the same directory as your executable file.
I’ll probably update this post and tidy it a bit later, but if anyone has a question, just leave it in the comments section!