Statically linked OpenGL library on Windows - c++

I want to get ( or build from source) OpenGL library that is statically linked to the crt on Windows.
I don't want my executable to require OPENGL32.dll.
My compiler is Visual C++ 9.
Where do I begin? The OpenGL website directs me to this wiki http://www.opengl.org/wiki/Getting_started
But that wiki tells me "In all three major desktop platforms (Linux, MacOS X, and Windows), OpenGL more or less comes with the system".
I am on Windows. Is this statement true. How do I verify this?

Statically linked OpenGL library on Windows
I don't want my executable to require OPENGL32.dll.
Impossible. End of story. opengl32.dll is provided by microsoft and may be changed after each system update. So you can't static-link it - it is a system component.
You can only static link with mesa3d which emulates OpenGL on CPU. However, it is not fully compliant to OpenGL, so you can get unexpected problems, and you'll still require several system dlls. (my bet is gdi32.dll) for your application. Also, performance will be very bad compared to normal OpenGL.

I believe what you are saying is that you don't want to be forced to make your application link with the C Runtime libraries dynamically (i.e. Multithreaded DLL or Multithreaded Debug DLL in the Properties/C++/Code Generation/Runtime Library setting).
Since OpenGL is a system provided .DLL, you are still free to choose Multithreaded or Multithreaded Debug (both choices statically link to the C Runtime) for your Runtime Library when using OpenGL.

Related

Distributing Qt/C++ application cross-platform

I'm struggling to deploy my Qt/C++ application, probably because I have not found a good introduction about this online. In brief my question is how do I setup an installation framework which requires only minimal, or preferably no, compilation before shipping to users.
I want to deploy the GUI to users on different platforms, who may or may not have admin rights on their machines. I have found different options:
Statically compile Qt -> statically compile an executable -> distribute the executable. With this setup I have encountered a Windows security warning, which requires admin privileges (I have not yet tried on Linux / macOS). And frankly this approach seems sub-optimal, as my compiler has no idea about how to compile optimally for my users.
Create an installer. But there I start to be confused... Do I need to provide a statically compiled executable of my GUI, or just of the installer, or neither? Or can I avoid pre-compiling on my side all together by using an installer from Qt with built-in compiler/libraries?
With this setup I have encountered a Windows security warning
You didn't sign the binaries. This issue has nothing to do with Qt. You'd face it even when distributing a trivial "Hello World".
Ensure that you sign all of the following:
The executables.
All DLLs that you redistribute and are not signed (verify each one).
The installer.
my compiler has no idea about how to compile optimally for my users.
Since C++ doesn't use just-in-time compilation, this statement is a truism. When you dynamically link your compiler will also have "no idea" how to compile "optimally for your users" if you imply that you need CPU-specific variants of your code. This has to be addressed by having multiple executables, each compiled for a particular CPU, and selecting them on installation. I don't think you meant that, though. But then I have no idea what you mean by "compile optimally for my users".
Do I need to provide a statically compiled executable of my GUI
It's up to you. If you don't provide a statically compiled executable, you will need to provide all of the dependencies: the C++ runtime of your compiler, and all the libraries and plugins needed by Qt.
The procedure for producing a statically linked executable on Windows, Linux and OS X is identical. You start with a statically configured copy of Qt (configure -static -static-runtime), then build it, and then use that to build your application. The end product will be statically linked against C++ runtime and Qt libraries.
Do I need to provide a statically compiled executable of [...] the installer
Only if you compile the installer program yourself using a C++ compiler. Most installer generator packages take care of creating an installer that has no additional dependencies, i.e. you can run it on a bare Windows system.
can I avoid pre-compiling on my side all together by using an installer from Qt
Qt provides no pre-built installers for re-use.
You can use e.g. NSIS to deploy the compiler runtime, Qt libraries and plugins, and your application and any data files it needs.
Or you can statically compile your application so that it has no dependencies and is a single .exe file, and have it as a portable application. It could also self-install, i.e. you could bundle the installer within the application, and on startup the application could detect whether it's already installed, and if not it'd relaunch itself in administrative mode and perform the installation.
Obviously you need to build your application on each platform you want to distribute it to. Easiest way is to link all the QT libraries dynamically to your application. After that all you need to do is provide your application (as in exe file on windows, or executable on linux etc) and the QT libraries you used (DLLs on windows, SO file I think on linux etc)
For example (on windows) if your app is called MyApp and uses QTGui, QTWidgets and QTNetwork, then you have the following files to distribute:
MyApp.exe
QTCore.dll and few other DLLs needed called icu*.dll something, can't remember)
QTGui.dll
QTWidgets.dll
QTNetwork.dll
and you can zip them all in one zip, create an installer etc.
EDIT Few notes after the follow up in the comment.
The standard library (what you called default library that has vector class) is part of the c/c++ runtime (on windows) or installed on linux systems etc, so no, you don't have to worry about this. I can't say for all compilers but for some you can specify a flag/parameter to link this runtime statically (rarely there is a need to do this).
On windows there is a tool called dependency walker, which gives you the list of all DLLs needed for the application to run. On linux systems I don't know, never needed one really. But for your own application, you do know which libraries you need, since you wrote it :)

Is my application loading a dll to use std::string?

I'm working on an application that needs to be compatible up to Windows XP (yea... I know...), my colleagues are arguing that they don't want to use std::string because it might load some dlls that might change the code behavior.
I'm not sure either if they are right or wrong here. At some point, there has to be some common grounds where the application can be loaded.
And so given the context where an application have to be self contained as much as possible, would this application be required to load a dll in order to use the stl or string or else coming from the standard libraries?
Also, assuming I use the -static-libstdc++ flag, by which order of magnitude will the executable be bigger?
In windows, STL is supported using CRT libraries. These libraries require the run time DLLs to be deployed before you running the application. Compiling code with different version of visual studio will create dependency on a particular version of CRT. Compiling code with vs2013 will need a version of CRT much different than the vs2010. So you cannot use/pass STL objects from one version of CRT to another dll consuming a different version. Please go through microsoft articles before consuming the CRT libraries. Below article is for vs2013:
http://msdn.microsoft.com/en-us/library/abx4dbyh.aspx
I would suggest you to use ATL:CString which is much easier to implement & the static version library also much compact than CRT libraries.

How is Linux CRunTime library handled compared to Microsoft

I've been having a lot of conceptual issues with Microsoft's CRT. For any project you have to compile all required libraries to link against the same version of the CRT.
The first problem is when your project statically links against the CRT (/MT). Then all the dependant libraries must also link their own CRT statically. So each library has its own version of - for example - malloc(). If you compiled one of the libraries last year on system A, that CRT version may be different than the one you're currently using on another system B with service pack 3+. So if you're freeing objects allocated by the library you may run into problems.
So it seems dynamically linked CRT is the way to go (/MD). With dlls all the libraries would get the current implementation of the CRT on the system. Except that with Microsoft's Side by Side mechanism that's not what happens. Instead you get the CRT version that's stamped on the library you compiled and that version of the DLL is supplied to that library. So exactly the same problem I described before can occur. You compile a library on system A a year ago against one CRT. A year later there's a new version with upgrade. Your main program gets the DLL with one version of the CRT, the library gets the DLL with another version of CRT, same problem can occur.
So what do you do? I realize cross library memory allocation is frowned upon. But you can ignore the malloc example and come up with another one. Do you have every developer recompile every dependant library on their machine to make sure everything does use the same CRT? Then for the release you recompile every library again?
How does this work on Linux? That's my main interest. Is there a CRT supplied with GCC or the Linux system itself comes with CRT libraries? I've never seen the CRT linked explicitly in Makefils.
On Linux, what CRT do dynamic libraries link against? The most current one on the machine, or is it more "side by side" mechanism.
On the Linux side I think there are two basic parts of the standard library that are at issue: We have the C-runtime part, which should pretty much be ABI compatible forever. Effectively whichever version links at final link time should be fine, and you can redistribute any needed shared library with your binary if it's an older version needed for compatibility. Usually the libraries just sit side-by-side on *NIX systems.
Secondly, you have the C++ libraries. These are pretty much guaranteed to not be ABI compatible in any way, so you must rebuild every single component of a final binary against the same version of the C++ library. There's just no way around it unfortunately because otherwise you could wind up with a variety of mismatches. This is why many open source libraries don't even bother with premade library binaries: Everyone needs to build their own copy to make sure that it will properly link into their final application code.

How to create a Standalone Executable program in C++?

I want to create a program that could work on any computer without the source code, How is that possible? and does it make any difference if I used OpenGL in the Program?
You cannot code a program in C++ that would work on any computer without giving your source code to be compiled.
For example, you could perhaps code in C++ a program, and compile it and build an executable which works on Windows x86-64, but that executable won't work on Linux (or MacOSX), and it won't work on ARM (e.g. Android phones) unless you consider using emulators
If you are developing your code with Visual C++ you may need to consider two options:
Make sure you link all libraries statically.
Install on the target computers along with your program Microsoft Visual C++ Redistributable Package corresponding to the Visual C++ version you use like the one at http://www.microsoft.com/download/en/details.aspx?id=5555. Some installer generating software will make it for you automatically.
Normally you would link your object file with some sort of a platform dependent loader. This loader loads your object and does all the stuff to start it from memory. Normally you can tell your compiler to link your object file and compile a blob. OpenGL is a powerful API and is usually distributed as a.dynamic linked library and is linked at runtime to your program. If I remember you just have to make sure the dll is where you want it and load the dll in your program from start.
Your C++ program is compiled and linked into an executable before it is run. You should be able to find that executable in a Debug or Release subfolder of the folder containing your project.
OpenGL, if you're not using GLUT or similar libraries, should just come with Windows and pose no additional problems. If you do use GLUT, it's enough to bundle the .dll file with your application.
In any case, the source code won't be necessary.
I want to create a program that could work on any computer without the source code, How is that possible? and does it make any difference if I used OpenGL in the Program?
By compiling and linking it into an executable. As long as you're not using some interpreted language (like Python, Ruby or such) you're presented with an executable inevitably. The biggest problem you may/will run into is dependencies on libraries. However those are linked into a binary as well. So what you're going to ship will be just a .exe; and some .dll maybe. Usually you'd wrap this in a installer package for deployment to the end user. Installers are created with something like the "NullSoft Installer System" (NSIS).
OpenGL itself is just a API, provided by a system library. So you don't ship OpenGL with your program, but expect the user to have it installed on the system (which will be the case if he installed the graphics drivers).

Why does intel compiler produce output that requires libiomp5mt.dll, even though I ask for static linking?

I'm compiling an openmp project with the /MT switch (or equivalently in visual studio settings, "C++: Code Generation: Runtime Library: Multi Threaded".
Visual Studio still, however, reports that my output requires libiomp5mt.dll (multi threading dll) when I thought the above setting was asking for static linking.
Is there another option somewhere I missed?
Alternatively, if the dll is a requirement, I presume I'm allowed to redistribute Intel's dll alongside my own application?
The Intel website says:
You are strongly encouraged to dynamically link in the compatibility OpenMP* run-time library libiomp (i.e libiomp5md.lib and libiomp5md.dll , located in the [Compiler Dir]\lib directory), even if other libraries are linked statically. Linking to static OpenMP* run-time library (i.e libiomp5mt.lib) is not recommended. Because multiple OpenMP libraries in one appliation causes performance problems (too many threads) and may cause correctness problems if more than one copy is initialized.
So although you can configure OpenMP to link statically, and this configuration is independent of the C runtime, you are recommended not to.
Intel's OpenMP licence allows for royalty free redistribution as far as I can tell. You should check the licence that came with your OpenMP just to be on the safe side.
The above switch is for C++ runtime only, OpenMP is an external library which is not a part of the C++ runtime. Hence the switch doesn't have any effect on it.
As per the redistribution of the DLL, look at the license of the product the DLL was shipped with. You're probably allowed to redistribute it.
There are two ways of creating code libraries. As static Libs and as Dlls (Extentsions: *.lib and * dll).
If there is only a Dll available, you can only link to it dynamically, not statically. What may be confusing you is that a Dll usually has a lib file you link to which has all the entry points into the Dll.