Why do I have to call my library explicitly? - c++

I'm following an OpenGL tutorial and I'm at the last step, using GLEW to setup the FPS counter. I had a problem where I had to use #pragma comment(lib, "glew32sd.lib") to successfully link my library. Whereas with freeglut, I didn't have to explicitly reference it.
My structure is simple,
library\
dll\
freeglut.dll
glew32d.dll
include\
GL\
freeglut.h
freeglut_ext.h
freeglut_std.h
glew.h
glut.h
glxew.h
wglew.h
lib\
freeglut.lib
glew32d.lib
glew32sd.lib
I have set Visual Studio to include the include\ dir and to look for additional libraries in lib. The dll folder is set to copy to the output via a post-build job. I'm pretty sure it works because up to this point everything was fine with freeglut. Only glew isn't working.
How is Visual Studio not able to link glew but it is working with freeglut ? They are in the same directory. I see that freeglut is being linked because I see it in the linker's output 1> Processed /DEFAULTLIB:freeglut.lib. Both libraries are compiled from my computer.
I tried to compile GLEW as a static library so I'm assuming the compiler does not load the .dll so I might as well remove it. But in both cases it wouldn't work. I tried using #define GLEW_STATIC and #define GLEW_BUILD, would not link either.
Then I stumbled on an answer on SO and found that if I did #pragma comment(lib, "glew32sd.lib") it would correctly load my library. Now I'm assuming that by explicitly telling the linker to use this .lib it makes it work. But why then does freeglut gets loaded automatically ? I'm not referencing directly it anywhere.
Right now my code is working but I'm just curious. I'm a new C++ developer and the concept of static libraries and dynamic libraries is still too fresh in my mind.

You need to tell the linker which libraries you use either via the pragma or in the Project->Linker->Input->Additional Dependencies area of the project properties.
In the case of freeglut the pragmas are supplied for you in freeglut_std.h unless you explicitly define FREEGLUT_LIB_PRAGMAS to 0. If you did that you would need to add the dependency manually either via your own pragmas or in the Additional Dependencies area.
In general it is up to you to add the dependencies you need. In my experience it is rare for a library to attempt to do it automatically.

Related

how to make my executable not rely on sfml dll files [c++] [minGW] [g++]

Perhaps I can "create" these necessary files by having them linked to the exe, and store them in a temp folder when the program launches, and if that's possible how please? I've tried messing around with compiler options but nothing seems to work.
In order your executable to not rely on DLL files, you should link them statically. SFML gives you that option by using their "sfml-xxx-s-d.lib" (for Debug) and "sfml-xxx-s.lib" (for Release) libraries, as stated in the documentation.
If you want to get rid of these DLLs and have SFML directly integrated
into your executable, you must link to the static version. Static SFML
libraries have the "-s" suffix: "sfml-xxx-s-d.lib" for Debug, and
"sfml-xxx-s.lib" for Release. In this case, you'll also need to define
the SFML_STATIC macro in the preprocessor options of your project.
NOTE: "xxx" stands for the name of the file you are trying to include into your project
Full documentation on how to set up SFML in VisualStudio: https://www.sfml-dev.org/tutorials/2.5/start-vc.php
Hope this answered your question! :)

SFML library can't find .dll

I implemented the SFML library nightly build to my Visual Studio 2013, because the original one is not compatibile with this VS version. I done everything what is needed (added directory to include folder in both Debug and Release, added directory to .dll files), but it can't find the files in program. What else should be done to make this library work? Or should i consider changing Visual Studio to 2010?
You haven't given really to much information so I am just really guessing as to what the problem is.
added directory to .dll files
But that sounds like your problem right there. You don't add the directory that the .dll files are in to your project. The only directories you need to add to the project are the include directory and the library directory.
But anyways I am assuming you are using dynamic linking since otherwise you wouldn't be dealing with .dlls. Now different IDE's require that you place the .dlls in different spots but since you are dealing with VS2013 you need to copy whatever .dlls that you are using into the same folder where your program's compiled executable is (The .exe file).
Another option is to link statically instead of dynamically which I generally prefer to do on small projects but it is really up to the developer which he prefers.
When you link statically you don't need to include any .dlls. What you will need to do is recompile SFML's sources and make sure to build the library so it produces the static library files (They should be named something like sfml-graphics-s-d.lib for debug and sfml-graphics-s-d.lib for release).
Add that library directory which contains the static library files to your project and then link to them .lib files in VS's input window (Remember that -d is for the debug build).
Next you will need to add SFML_STATIC to your preprocessor options on both the release and debug build.
After that you are good to go and don't need to include the .dll files with your project. And again whether you choose to link dynamically or statically is really up to you and the project you are working on but for small projects I would suggest linking statically.

I can't make SDL + OpenGL work in Visual Studio 2012

I just started a tutorial to learn C++ OpenGL using SDL. The steps shown in the videotutorial were done by using the IDE called Code Blocks, but I thought it was going to work also for Visual Studio 2012.
I downloaded the SDL2 developer which is for Windows x64 (my Windows 7 is 64 bits, but the Visual Studio 2012 I have is an x86 version)
To install the SDL2 in Visual Studio 2012, I put:
the .h files in the include folder (D:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\SDL).
the .lib files in the lib folder (D:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\lib\SDL).
the .dll file in C:/Windows/system folder.
After that, I opened the IDE, made a new project and while I was writting the code, autocompletion popped up for specific SDL features, meaning success... until I tried to run it.
This is the code I wrote according to the videotutorial:
#include "SDL.h"
int main(int argc, char* args[]){
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Quit();
return 0;
}
When I click on "Start Debugging" or "Start without debugging", after pressing yes to build it, the output comes with errors.
Here's a screenshot of the code I wrote, plus the output:
After that, I tried an older version of the SDL the tutorial was already using, which was the 1.2 (I overwrote few files of the newer version) but still no good results.
How do I fix it so I can practice with OpenGL + SDL features?
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 #ifdefs 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"?
You have to link the lib file into your exe. See Project, Properties, Link, Additional Dependencies. Put the name of the lib file there.

setting up sfml

I'm following the sfml getting started guide for version 2 and codeblocks and did everything the tutorial told me to do :
downloaded and unzipped the sdk
added the path to the sfml headers and libraries
linked the libraries graphics, window and system
but the sample code doesnt work. I'm getting the error message that sfml-graphics-d-2.dll is missing. Compilation works, the window opens but remains black and this error pops up.
Here's the link to the tutorial
http://www.sfml-dev.org/tutorials/2.0/start-cb.php
Since Im new to c++ and codeblocks, I would be grateful for a detailed answer.
UPDATE:
I have copied the SFML dlls to the executable. Now my program just crashes. I don't know why. It's the exact same code as used in the tutorial.
UPDATE:
I have changed the linked libraries to the -s version and added the #define SFML_STATIC. The program still builds and then crashes
If you're using the latest Code::Blocks version, which includes GCC 4.7.1, then you have to recompile SFML on your own (or use my Nightly Builds), because the ones provided are only for GCC versions < 4.7.x.
It seems you aren't setting up your static libraries to be built inside the project, and instead using dynamic linking with your SFML. I had a similar problem when setting up SFML a couple months ago, recall this quote:
The settings shown here will result in your application being linked to the dynamic version of SFML, the one that needs the DLL files. If you want to get rid of these DLLs and have SFML directly integrated to your executable, you must link to the static version. Static SFML libraries have the "-s" suffix: "sfml-xxx-s-d" for Debug, and "sfml-xxx-s" for Release.
In this case, you'll also need to define the SFML_STATIC macro in the preprocessor options of your project.
make sure you include the static files in your project
sfml-graphics-s-d //for debug
sfml-window-s-d //d for debug!
sfml-system-s-d
for release, omit the d (sfml-graphics-s)
Next go to Compiler settings -> #Defines and type
SFML_STATIC
Regarding Visual Studio 2017 and SFML-2.5.1, I suggest this tutorial. Setting up SFML is similar to setting up SDL, GLFW, freeGLUT, and GLEW, with two peculiarities: .lib files are 29, and .dll are 11. Briefly I suggest:
1. Upload SFML and select first "Download". Copy downloaded folder and paste in a folder you created in C:.
2. Create Empty Project.
3. Configure "Additional Include Directories" with C:...\SFML-2.5.1\include.
4. Configure "Additional Library Directories" with C:...\SFML-2.5.1\lib.
5. In "Additional Dependencies" window copy and paste: flac.lib; freetype.lib; ogg.lib; openal32.lib; sfml-audio.lib; sfml-audio-d.lib; sfml-audio-s.lib; sfml-audio-s-d.lib; sfml-graphics.lib; sfml-graphics-d.lib; sfml-graphics-s.lib; sfml-graphics-s-d.lib; sfml-main.lib; sfml-main-d.lib; sfml-network.lib; sfml-network-d.lib; sfml-network-s.lib; sfml-network-s-d.lib; sfml-system.lib; sfml-system-d.lib; sfml-system-s.lib; sfml-system-s-d.lib; sfml-window.lib; sfml-window-d.lib; sfml-window-s.lib; sfml-window-s-d.lib; vorbis.lib; vorbisenc.lib; vorbisfile.lib
6. Navigate to C: > ... > SFML2.5.1 > bin. Copy all 11 dll files and paste in project-folder.
Good job. Regards.

C++ - Can you build one static library into another?

I ran into a strange problem with a Visual Studio 2008 project I was working with recently.
I am trying to compile a new static library that uses functions from another static library. (Let's say Lib1 is my static library project, and Lib2 is the lib file that Lib1 depends on).
I am able to build lib1 without issue; It includes the header files for lib2 and calls its functions, and there are no problems.
The problem is when I build a separate test project that has Lib1 as a dependency; it won't build and I get linker errors. The unresolved externals are the functions I am trying to call within Lib1 that are from Lib2.
This is all fixed when I include Lib2 in my test project as well.
This all makes sense to me of course; I can test that Lib2 is not being built into Lib1..
My question is: is there a way to do this? I would ideally like to be able to deploy Lib1 as a standalone lib without requiring Lib2. (Lib2 is actually just a Lib from the Windows Platform SDK, so it's not really a big deal...)
Is this not allowed because it would allow people to "hide" third party libraries in their own, or something?
What would be a professional approach to this problem?
Thanks!
--R
I would not advise using a librarian to take Windows' library contents into your own library -- it's likely that that's against the license.
I see two possibilities
Documenting the dependency
Using a #pragma in your .h file that requests the .lib to be linked against. If VS can find it, it's the same as including it on your link line.
http://msdn.microsoft.com/en-us/library/7f0aews7(VS.80).aspx
#pragma comment(lib, "libname.lib")
You need to use a tool called a librarian to do this. A librarian allows you to create and modify library (.lib) files. In visual studio check under the Librarian section of your project properties. A command line version also comes with visual studio (lib.exe).
Just document the dependencies of your lib.
As long as the library you depend on is available to anyone that could use your library, this is the preferred solution. Especially considering that the library user could also depend on this platform SDK lib - if you had it embedded then he'd get funny linker errors with multiply defined symbols.
This is a fairly normal problem - you wouldn't normally attempt to include 'lib2' into 'lib1' but simply document that it's required to be linked against in order to work. There is nothing wrong with declaring the use of other libraries (apart from any licensing issues of course) so you are already doing the right thing.
If you really want to do this, you can extract the .obj files from Lib2 and add them to Lib1.
See How to Extract .OBJ Routines from .LIB Files Using LIB.EXE -- I hope it is still relevant for VS2008.
Instead of simply documenting your dependencies, use #pragma comment(lib, 'lib2name') in your code to make the linker pull in the other library automatically. Since you said you're using a standard library that comes with the SDK, this should eliminate all burden on the application.