I can't really recommend any books... but I suppose I can try to explain what's happening.
I assume you understand the difference between a header file and a source file. When you build (compile+link) an EXE, each source file is compiled independently forming an intermediate "object" file. This object file is compiled code, but can't be executed because it's somewhat incomplete.
For example, given the below program:
1 2 3
|
// header.h
void func();
|
1 2 3 4 5 6 7 8
|
// func.cpp
#include <iostream>
#include "header.h"
void func()
{
std::cout << "hello world";
}
|
1 2 3 4 5 6 7 8
|
// main.cpp
#include "header.h"
int main()
{
func();
}
|
When this program is compiled, 2 object files are formed (either with the .obj extension, or the .o, or something else -- it depends on what compiler you're using). One for each source file.
main.obj would contain the compiled code for the main() function. However it cannot be executed because it tries to call the 'func' function, and the code for that is not in main.obj. The compiled code for the 'func' function is over in func.obj.
The next step is the linker, which takes all those .obj files and links them to form the final executable. In this case, the references main.obj makes to the func function will be filled in by linking it to func.obj.
So what does this have to do with libraries? Well libraries are built the exact same way. The only difference is they form a static lib or dll instead of an exe. But the concept is the same.
Something like OpenGL is a massive library with a ton of compiled code. Including the header will define the functions for the compiler, but those functions will remain 'unresolved' to the linker because they have no body. The body for those functions are in the library itself.
So that's why you need to add a linker reference to a library when you use it. That tells the linker to use that library to fill in the bodies for those functions.