How to link MS runtime into Qt core libraries
-
When building Qt as shared, I see that the MS run-time is a dependency that must reside on the target machine. Can one rebuild the core libraries (4.8.4 in this case) to static link the run-time?
-
If you're using Visual Studio right click on the project, go to Properties -> Configuration Properties -> C/C++ -> Code generation ->Runtime Library and select "Multi-threaded DLL" for dynamic and "Multi-threaded" for static linking.
If you're talking about compiling Qt itself this way you can provide the relevant switch (/MT) to the configure.
-
Before you build Qt from the sources, edit this file:
mkspecs\win32-msvc2010\qmake.confSearch this line:
QMAKE_CFLAGS_RELEASE = -O2 -MDAnd change to:
QMAKE_CFLAGS_RELEASE = -O2 -MT--
However be aware that it is highly recommended to use the shared C++ runtime when using DLL's. With the static runtime, each DLL as well as the main EXE file get their own separate copy/instance of the C++ runtime linked in, which can lead to problems. There is no such problem when you link everything (e.g. the Qt libraries) statically into the EXE file...
-
[quote author="Krzysztof Kawa" date="1363300272"]If you're using Visual Studio right click on the project, go to Properties -> Configuration Properties -> C/C++ -> Code generation ->Runtime Library and select "Multi-threaded DLL" for dynamic and "Multi-threaded" for static linking.
If you're talking about compiling Qt itself this way you can provide the relevant switch (/MT) to the configure.[/quote]
Maybe I failed to explain myself. If you look at the dependencies for example QtCore4.dll, it shows MSVCP100.DLL and MSVCR100.DLL as being required for the system on which it will run.
Another "posting":http://qt-project.org/forums/viewthread/15666 shows a similar issue. I want to keep the core libraries as shared, but link the run-time to them.
I hope that is clearer
-
[quote author="MuldeR" date="1363305632"]Before you build Qt from the sources, edit this file:
mkspecs\win32-msvc2010\qmake.confSearch this line:
QMAKE_CFLAGS_RELEASE = -O2 -MDAnd change to:
QMAKE_CFLAGS_RELEASE = -O2 -MT--
However be aware that it is highly recommended to use the shared C++ runtime when using DLL's. With the static runtime, each DLL as well as the main EXE file get their own separate copy/instance of the C++ runtime linked in, which can lead to problems. There is no such problem when you link everything (e.g. the Qt libraries) statically into the EXE file...[/quote]
Isn't the mkspecs files related to building projects? I want to link the runtime to the core libs. Doing this prevents a requirement of having to to install the runtime on the target machine.
-
The original (pre-compiled) Qt DLL's link against the shared C++ runtime. If you want these DLL's to link against the static C++ runtime (i.e. no dependency from the Qt DLL's to MSVC runtime DLL's), then you have to re-build the Qt DLL's from the sources. And you have to change the project settings for each DLL to built with the static runtime. The easiest way to do that, in my opinion, is to adjust the mkspecs, before running configure! Not that you will still have to configure/build Qt as "shared" to get Qt DLL's. No guarantee these DLL's work correctly though.
Building Qt as static libs and with the static MSVC runtime definitely works. But needs adjusted mkspecs too!
[quote author="astodolski" date="1363309409"]
[quote author="MuldeR" date="1363305632"]Before you build Qt from the sources, edit this file:
mkspecs\win32-msvc2010\qmake.confSearch this line:
QMAKE_CFLAGS_RELEASE = -O2 -MDAnd change to:
QMAKE_CFLAGS_RELEASE = -O2 -MT--
However be aware that it is highly recommended to use the shared C++ runtime when using DLL's. With the static runtime, each DLL as well as the main EXE file get their own separate copy/instance of the C++ runtime linked in, which can lead to problems. There is no such problem when you link everything (e.g. the Qt libraries) statically into the EXE file...[/quote]
Isn't the mkspecs files related to building projects? I want to link the runtime to the core libs. Doing this prevents a requirement of having to to install the runtime on the target machine.[/quote]
-
[quote author="MuldeR" date="1363350300"]The original (pre-compiled) Qt DLL's link against the shared C++ runtime. If you want these DLL's to link against the static C++ runtime (i.e. no dependency from the Qt DLL's to MSVC runtime DLL's), then you have to re-build the Qt DLL's from the sources. And you have to change the project settings for each DLL to built with the static runtime. The easiest way to do that, in my opinion, is to adjust the mkspecs, before running configure! Not that you will still have to configure/build Qt as "shared" to get Qt DLL's. No guarantee these DLL's work correctly though.
Building Qt as static libs and with the static MSVC runtime definitely works. But needs adjusted mkspecs too!
[quote author="astodolski" date="1363309409"]
[quote author="MuldeR" date="1363305632"]Before you build Qt from the sources, edit this file:
mkspecs\win32-msvc2010\qmake.confSearch this line:
QMAKE_CFLAGS_RELEASE = -O2 -MDAnd change to:
QMAKE_CFLAGS_RELEASE = -O2 -MT--
However be aware that it is highly recommended to use the shared C++ runtime when using DLL's. With the static runtime, each DLL as well as the main EXE file get their own separate copy/instance of the C++ runtime linked in, which can lead to problems. There is no such problem when you link everything (e.g. the Qt libraries) statically into the EXE file...[/quote]
Isn't the mkspecs files related to building projects? I want to link the runtime to the core libs. Doing this prevents a requirement of having to to install the runtime on the target machine.[/quote]
[/quote]
Thanks for responding.
I still am unclear as to the changing of the mkspecs files. Isn't the changing of these going to affect the build globally? You wrote that:
[quote]
And you have to change the project settings for each DLL to built with the static runtime. The easiest way to do that, in my opinion, is to adjust the mkspecs, before running configure!
[/quote]Unless I am mistaken as to the build process for the core libraries, changing mkspecs are global to the entire build. Are you suggesting that this can be done to only QtCore4.DLL and QtGui4.DLL for example? That would be great as those are usually the only two being distributed with my app.
-
Yes, it's "global". In the sense that it effects everything built with the Qt build system (qmake). And you want it to be global! If you build Qt, by running "configure" and then "nmake", a large number of projects are being built. And, you want them all to use the "static" MSVC runtime, don't you? Same for your main program, right? Otherwise, you can change it back after Qt has been built. Or you can keep your mkspec unchanged. But then you have to change MD to MT "by hand" in all the various projects (Makefiles) you need for building Qt. And you'd have to do that after "configure" but before "nmake". It's big pain, so I prefer the mkspecs method ;-)
-
[quote author="MuldeR" date="1363351963"]Yes, it's "global". In the sense that it effects everything built with the Qt build system (qmake). And you want it to be global! If you build Qt, by running "configure" and then "nmake", a large number of projects are being built. And, you want them all to use the "static" MSVC runtime, don't you? Same for your main program, right? Otherwise, you can change it back after Qt has been built. Or you can keep your mkspec unchanged. But then you have to change MD to MT "by hand" in all the various projects (Makefiles) you need for building Qt. And you'd have to do that after "configure" but before "nmake". It's big pain, so I prefer the mkspecs method ;-)[/quote]
Ok, so to be clear, it IS possible then to build Qt core as shared DLLs but with out the need to distribute the C run-time separately by rebuilding the libraries with the changes mentioned.
-
Possible, yes. Will it work perfectly? I can't say for sure.
If you want to avoid troubles, build Qt as static libraries (not DLL's) and make it use the static C++ Runtime.
BTW: If you use Qt as DLL's, what is so bad about shipping the C++ runtime too? Starting with VS2010 it is sufficient to put the MSVCR100.DLL or MSVCR110.DLL into the same folder as your EXE and Qt DLL's.
-
[quote author="MuldeR" date="1363352844"]Possible, yes. Will it work perfectly? I can't say for sure.
If you want to avoid troubles, build Qt as static libraries (not DLL's) and make it use the static C++ Runtime.
BTW: If you use Qt as DLL's, what is so bad about shipping the C++ runtime too? Starting with VS2010 it is sufficient to put the MSVCR100.DLL or MSVCR110.DLL into the same folder as your EXE and Qt DLL's.[/quote]
Thanks, I am aware of that. It's just a matter of another merge module for the installer for that particular platform and I want to retain shared DLLs for LGPL reasons.
Thanks again.
-
I found an entry in the FAQ that seems to shoot down what I want to do
"linked here":http://qt-project.org/faq/answer/why_does_a_statically_built_qt_use_the_dynamic_visual_studio_runtime_librar
-
From my own experience I can say, it is perfectly safe to use the static C++ runtime, as long as you link everything statically. As soon as DLL's are involved, that then would get their own separate copy/instance of the static C++ runtime, some unexpected problems can occur. It's because the DLL calls to a different C++ runtime than the main EXE...
-
@MuldeR: Your posts were really helpful. Thank you.