How to build an standalone shared library in C++ using qmake? - c++

I have written a shared library in C++ using qt creator and QMake
When I compile my project with MinGW compiler, I need the libraries libgcc_s_dw2-1.dll, libstdc++-6.dll and libwinpthread-1.dll to be copied next to my DLL in order to work. Which has about 1.5 megabytes size.
When I compile my project with MSVC 2015 compiler, I need to install the Visual C++ Redistributable 2015 x86 on the deployment system. Which has about 13 megabytes size.
My project has less than 100 kiloobytes size so these dependencies are so big.
How can I embed them into my library? or How can I have fewer dependencies to be installed or copied next to my project in Windows 7 or upper?
PS 1: I have read this, but the MinGW method was the same as before. And I encountered errors in Microsoft Tools method.
PS 2: Maybe .Net Framework 2.0 is a better option because it is preinstalled on Windows 7 and we can force .Net 4.5 to run it in Windows 8/8.1/10. Don't you agee?

Just link standard libraries statically. Your DLL size will increase obviously (I hope it isn't a problem) but not that much (<1 MB).
To do that:
If you use MSVC add /MT to command line (you can find it in project properties window too).
If you use g++ add '--static' .

I think you can't do that, your project must be set on static or dynamic link, not both of them together.

Related

Compiling a C++ program with all libs it needs

When I compile C++ code that uses openmp libs with visual studio, the program is very portable - because it runs in other machines with Windows without problems.
When I compile the C++ code with Eclipse CDT (oxygen and g++ cygwin) for Windows, in general, I need to install the correct runtime libs in the other machines to be able to run the program. I don't find it practical.
Based on this:
1) What is the right way to compile the code including all libs (g++ and openmp) to run in another Windows system?
2) How can do this in Eclipse CDT for Windows?
The problem is not in compiling, but in distributing. Windows and windows toolchains intend to use dynamic linking. Now, if created software are dependent on particular version of runtime, which includes side-by-side build, they can be run only if exactly that build is installed. Several builds of same library version may exist, they are fetched using side-by-side (SxS) mechanics.
On Linux platform this problem is solved through package manager and dependencies. On Windows you have to create an installer, which would contain or have ability to download proper version of libraries. Also installer may do proper changes to OS settings, and register them , for future rollback.
Note, that runtime libraries have debug variants which cannot be distributed and debug build of software must be run on developer system only.
"Portable" apps that appear here and there and can be run without installation, have special status not to be dependant on SxS run-time library. To my knowledge cygwin and mingw32 allowed to create such, the 64bit project of mingw had problems with that. But they are still dependant on particular versions of system .dll and may break or malfunction in case of mismatch.
Even in that case you still need some .dll, from mingw, cygwin, Qt, whatever you use and what is not a part of OS, to place them where program can reach them. Which can be folder comtaining the executable. Static linking became a gimmick of past for desktops, because of code bloat - dynamic library size easily can be dozens of megabytes.
And last: you don't compile anything with Visual Studio or with Eclipse CDT. Both designed to use various compilers, it's juse environments. You have to specify normal;y, what compiler your IDE uses, not what IDE you use to run ot.

VS2017 and missing "api-ms-win-core-rtlsupport-l1-2-0.dll" on Win7/XP

After porting some of my programs from VS2015 to VS2017 in noticed that the binaries no longer run on Windows 7 or Windows XP - even though they have been compiled with v141_xp toolset. The program fails to start with missing DLL api-ms-win-core-rtlsupport-l1-2-0.dll (note the 2).
I'm well aware that those api-ms-win-* DLL's belong to the UCRT and that, starting with VS2015, I have to redistribute the UCRT DLL's from the Windows 10 SDK (to be found at Redist\ucrt\DLLs in the Windows 10 SDK directory), along with my application - just redistributing the vcruntime140.dll and msvcp140.dll is not sufficient. But there is only api-ms-win-core-rtlsupport-l1-1-0.dll in my Windows SDK directory, but not api-ms-win-core-rtlsupport-l1-2-0.dll. I just downloaded and re-installed the latest Windows SDK (10.0.15063), just to be sure. Still the DLL in question is absent!
I also tried installing the VS2017 Redistributable package on the Windows 7 (or XP) machine via VC_redist.x86.exe - latest version downloaded from Visual Studio web-site (14.11.25325). Obviously that copies the api-ms-win-* DLL's into the "System32" directory. But, again, only api-ms-win-core-rtlsupport-l1-1-0.dll, but not api-ms-win-core-rtlsupport-l1-2-0.dll. App still won't start.
[EDIT]
This of course only applies if I link against the DLL runtime (/MD). If I link against the "static" runtime (/MT) I get a binary that has no DLL dependencies on UCRT and runs fine on Windows 7 and XP.
[EDIT #2]
Please refer to my other post (including EDIT) for the resolution of the mess:
https://stackoverflow.com/a/45773325/1766377
Okay, this is quite interesting: Just now my VS2017 found a new update. Apparently that updated my VS2017 from v15.2 to v15.3.1. The runtime libraries were updated as well, it seems!
There are now two directories, VC\Redist\MSVC\14.11.25325 and VC\Redist\MSVC\14.11.25415, inside my VS2017 install directory. The vcruntime140.dll exists in both directories. But the newer version (25415, right) has quite different dependencies, compared to the older one (25325, left):
 
Only the "new" version has dependencies that are missing on Windows 7. So, I should be fine going with the "old" version. But it means I'm locked to the "old" version. Is this normal / intended ???
(BTW: Both DLL versions from VS2017 v15.3.1 are newer than the one I originally took from v15.2)
[EDIT]
So, it was just brought to my attention that there is a subtle difference between the VC\Redist\MSVC\14.11.25325 and VC\Redist\MSVC\14.11.25415 directories: The 25415 directory has all DLL files inside another sub-folder called onecore, the other one doesn't. Apparently, this means that the "newer" DLL versions (the one with onecore sub-folder) are not supposed to be redistributed with normal Desktop applications; they are strictly for the "OneCore" Mobile/IoT platform.
Conclusion:
M$ did a great job to design the Redist directory structure as confusing as possible. Putting the version numbers of the "normal" and the "onecore" redistributables on the same level of the directory hierarchy (rather than having separate onecore and desktop directories on that level) indicates that those directories represent different versions of the same thing - which isn't the case at all :-/
Do *not* redistribute any */onecore/* DLL's with normal Desktop applications!
In the property pages for the project, try changing the Windows SDK version from 10.0.15063.0 to 10.0.10240.0. I think that will fix it, provided that the older SDK is installed on your build machine. Something else to try is to change the platform toolset to v140_xp. VS 2017 then builds with the VS 2015 tool chain, provided that VS 2015 is installed.
My personal preference is to avoid any 'DLL hell' by linking with the static runtime, although this won't work if an exe and a dll need to share a heap and incurs some space penalty if you are building several binaries (I just have two).

Building GSL (GNU Scientific Library) in Windows for use with VS2015

I am trying to build GSL as a library(DLL,lib) to use with my application. I have tested both GSL ports(gladman) to VS and CMake route and I do not want to go that path due to various reasons.
Currently I am using nuget version and I am not too happy about it as some functions are missing. I want to build it myself to be absolutely sure about what I am getting. The objective is to build four set of dll and libs---win32, win32d, win64 and win64d.
I know that from a MinGW library I can build lib file(for VS2015) and thereafter dll using Microsoft LIB tool if I have DEF file available.
My open source experience is very limited. Till now I have successfully built gsl for MinGW using ./config, make, make install. But I am not finding any DEF file generated and I do not know how to utilize this build to generate required DEF and dll to be used with Microsoft Visual Studio 2015.
Thank you
Building and linking has always been a pain for me as well. For mac, I use Homebrew, which downloads frameworks and libraries through a simple one-line-command in the terminal. I would then simply add the library into my program by adding the directory of the libs necessary. In XCode, there was an "add framework/library"-button where I added the directories, but I'm sure there's an analogue in VS.
However, you seem to be using Windows (so Homebrew will not work). I searched the web for Windows versions of Homebrew, and it seems that Scoop is pretty similar. You might want to check that out.
Hope this helped, despite me using different tools :)

Building log4cplus for Windows x64

I am supposed to build existing Windows 32bit project for Windows 64bit. (and probably linux 64bit too).
The project uses log4cplus library. That one only contains 32bit .lib files at the moment and is shining example of why I hate using libraries in C++ - there's just a bunch of source files and linux bash scripts. The INSTALL help file is entirely about the configure bash script which doesn't work on Windows. The configure probably just passes some arguments to GCC, but I don't known which ones.
I downloaded MinGW in hope I'll be able to use mingw32-make on the project and it will work, but no such thing happened.
So does anyone have any experience making those Linux projects on Windows? This is not the first time I tackle this problem - my third most viewed question is about broken Boost build. Judging from the view count, I'm not the only one who has problems building Linux project on widnows.
log4cplus maintainer here.
The master branch of log4cplug GIT repository is C++11 only. Because of this, it requires Visual Studio 2015 and thus the msvc14 directory is there.
Branch 1.2.x and its releases come with Visual Studio project files for version 2010. However, you might be able to build it using CMake for even older Visual Studio.
However, both of them, in any configuration, should have no problem building for AMD64 platform.
I also suggest that you read the README.md file. It documents many things, some of which might be useful to you, too.

Running C++ binaries without the runtime redistributable (Server2k3, XPSP3)

Having written a CGI application in Visual Studio 2008 and debigged it locally, I uploaded it to a Windows Server 2003 OS where it promptly failed to run.
I am guessing I need to install the wretched Runtime distributable, but after reading this:
http://kobyk.wordpress.com/2007/07/20/dynamically-linking-with-msvcrtdll-using-visual-c-2005/
I am wondering if it makes more sense to ignore this side by side stuff and just re-write the app.
I am guessing Windows Server 2003 does not have MSCRVT version I need?
Does Windows Server 2003 have it?
When it comes to deploying thick clients, I would like to distribute the required dlls with my app.
What are they assuming I just INCLUDE iostream, sstream, string?
Does it change significantly if I add windows.h?
Added:
Using the /MT switch recommended below
C / C++ -> Code Generation -> Runtime Library -> Multi-threaded(/MT)
(You will probably need to do a clean:
Build -> Clean
in order to avoid the error message
"Failed to save the updated manifest to the file")
bloated my app from 38k to 573k. Thats what I call Significant (imagine if that were your salary). Since many instances of this app will be loaded and unloaded constantly (requiring precious memory and processor resources) I would like to find a better (smaller) solution.
I understand this is not important for many situations today and not the focus of many developers, hence the trend to .NOT and 60MB runtimes, but this is what I want to do.
Added:
After removing the debugging to get the project to compile:
Project -> Propeties -> c/c++ -> Preprocessor -> Preprocessor Definitions (remove DEBUG;)
the size was reduced to 300k, and it will run.
Added:
As suggested by Chris Becke below, copying:
msvcm90.dll
msvcp90.dll
msvcr90.dll
Microsoft.VC90.CRT.manifest
To the directory of the application will provide all the runtime needed.
Using Visual Studio 6 has been suggested a few times, but it does not support Vista (or Windows 7 we assume) Other solutions that do not require a runtime distributable would probably me MASM or even a flavor of Basic. Unfortunately that defeats the purpose of using a high level OOP language like C++.
So long as I do need to require the C++ redistributable be installed, the trade off is an additional 260k. Thats acceptable
Let me revise my answer:
You have a few options:
1) Install the VC++2008 runtime. You can download and installer for them. Merge modules for them are also available.
2) Link against the runtime statically (/MT or C/C++ -> Code Generation -> Runtime Library: Multi-threaded). This will increase the size of your executable, but it won't depend on any Dlls. If you are worried about size, only use the C standard library or only use the Windows API directly.
3) Use an older version of VC++. 2005 and earlier did not require the runtime to be installed. The Dlls could be placed in the same directory as the executable. If you use VC++6.0 the runtimes will be installed on all versions of windows, otherwise you need to install it yourself.
A fuller list of options:
Rewrite the app so that theres no C/C++ usage at all.
Switch to Visual Studio 6 or a mingw based toolset like Code::Blocks - these use the already distributed msvcrt.dll as their runtime.
Build using the /MT switch. This builds the necessary runtime functions into your exe. Which will bloat it. But that bloat (frankly) is less overhead than loading separate dll's.
Distribute the VS9 runtime as a 'private sxs' install. This entails copying the contents of C:\Program Files\Microsoft Visual Studio 9.0\VC\redist\x86\Microsoft.VC90.CRT into the same folder as your application's exe. If you have applied SP1, then this folder will contain the SP1 runtime, but your application will be asking for the RTM runtime (go figure). Add _BIND_TO_CURRENT_CRT_VERSION to your projects defines, rebuild and that should sort itself out.
There is apparently a vc_redist.exe that can be obtained for VS9. Find that or figure out the MSI or installer mojo required to actually install the above assembly (being the contents of Microsoft.VC90.CRT) into the shared sxs store.