How to build Qt 6.x.x for Windows with -MT compiler flag?
-
I try to build Qt 6.5.3 for Windows with -MT compiler flag.
For example to do that for Qt 5.x.x need maker a changes to this file:
qtbase\mkspecs\common\msvc-desktop.conf
Replace -MD, -MDd to -MT, -MTd before configuration and then build the Qt library.
But this trick is not working for Qt 6.x.x
To ensure that I even make some non-compilable changes in any cpp file. It allows me to see the full command line and it contains -MD, -MDd flags.
It looks like "msvc-desktop.conf" is not used for configuration.
I use this command for configuration:
configure.bat -prefix %CD%\qtbase -opensource -debug-and-release -nomake examples -skip qtquick -skip qtvirtualkeyboard -nomake tests -opengl desktop -optimize-size -platform win32-msvc
-
If you want to expirement, you could try creating a simple proxy dll with DllMain with say a printf() so that it has dependencies to MS runtime dlls.
Build that proxy dll with -MT so that it adds the MS dlls to its .lib file, and link that .lib with your Qt app.
Most likely you'll get lots of warnings and complaints about missing _strdup(), _time64() etc. at the link stage.
To fix those link your proxy dll also with msvcrt.lib.
You'll still get warnings that you should link with /NODEFAULTLIB but if you ignore that the app might run anyway. But with 2 separate MSVC runtimes, kind of a FrankenExe :-) -
Building with -MT, you mean you're trying building a static (no DLLs) version of Qt?
Been awhile but I remember using "-static -static-runtime" in configure.bat, maybe those work in Qt6 as well.@hskoglund No, I want to use -MT option to avoid dll-mess for example dependency from CRT modules.
From MSDN:
*/MT Defines _MT so that multithread-specific versions of the run-time routines are selected from the standard header (.h) files.
This option also causes the compiler to place the library name LIBCMT.lib into the .obj file so that the
linker will use LIBCMT.lib to resolve external symbols. Either /MT or /MD (or their debug equivalents /MTd or /MDd)
is required to create multithreaded programs./MD Defines _MT and _DLL so that both multithread- and DLL-specific versions of the run-time routines are selected from the standard .h files.
This option also causes the compiler to place the library name MSVCRT.lib into the .obj file.Applications compiled with this option are statically linked to MSVCRT.lib.
This library provides a layer of code that allows the linker to resolve external references.
The actual working code is contained in MSVCR71.DLL, which must be available at run time to applications linked with MSVCRT.lib.When /MD is used with _STATIC_CPPLIB defined (/D_STATIC_CPPLIB) it will cause the application to link with
the static multithread Standard C++ Library (libcpmt.lib) instead of the dynamic version (msvcprt.lib) while still dynamically linking to
the main CRT via msvcrt.lib.* -
@hskoglund No, I want to use -MT option to avoid dll-mess for example dependency from CRT modules.
From MSDN:
*/MT Defines _MT so that multithread-specific versions of the run-time routines are selected from the standard header (.h) files.
This option also causes the compiler to place the library name LIBCMT.lib into the .obj file so that the
linker will use LIBCMT.lib to resolve external symbols. Either /MT or /MD (or their debug equivalents /MTd or /MDd)
is required to create multithreaded programs./MD Defines _MT and _DLL so that both multithread- and DLL-specific versions of the run-time routines are selected from the standard .h files.
This option also causes the compiler to place the library name MSVCRT.lib into the .obj file.Applications compiled with this option are statically linked to MSVCRT.lib.
This library provides a layer of code that allows the linker to resolve external references.
The actual working code is contained in MSVCR71.DLL, which must be available at run time to applications linked with MSVCRT.lib.When /MD is used with _STATIC_CPPLIB defined (/D_STATIC_CPPLIB) it will cause the application to link with
the static multithread Standard C++ Library (libcpmt.lib) instead of the dynamic version (msvcprt.lib) while still dynamically linking to
the main CRT via msvcrt.lib.*@nen777w then use '-static-runtime' as @hskoglund suggested. Configure has also a '--help' switch BTW...
-
@nen777w then use '-static-runtime' as @hskoglund suggested. Configure has also a '--help' switch BTW...
@Christian-Ehrlicher
The configuration with -static-runtime option like this:configure.bat -prefix %CD%\qtbase -opensource -static-runtime -debug-and-release -nomake examples -skip qtquick -skip qtvirtualkeyboard -nomake tests -opengl desktop -optimize-size -platform win32-msvc
leads to:
ERROR: Feature "static_runtime": Forcing to "ON" breaks its condition: NOT QT_FEATURE_shared Condition values dump: QT_FEATURE_shared = "ON"
I don't know whether the error is, but -static-runtime implies that you will use -static also.
That will lead to building Qt as the static libraries for the static linking (i.e. without dll-s files).But I need to build Qt with a dynamic library but with the -MT option not -MD.
-
@Christian-Ehrlicher
The configuration with -static-runtime option like this:configure.bat -prefix %CD%\qtbase -opensource -static-runtime -debug-and-release -nomake examples -skip qtquick -skip qtvirtualkeyboard -nomake tests -opengl desktop -optimize-size -platform win32-msvc
leads to:
ERROR: Feature "static_runtime": Forcing to "ON" breaks its condition: NOT QT_FEATURE_shared Condition values dump: QT_FEATURE_shared = "ON"
I don't know whether the error is, but -static-runtime implies that you will use -static also.
That will lead to building Qt as the static libraries for the static linking (i.e. without dll-s files).But I need to build Qt with a dynamic library but with the -MT option not -MD.
@nen777w said in How to build Qt 6.x.x for Windows with -MT compiler flag?:
But I need to build Qt with a dynamic library but with the -MT option not -MD.
As the error message tells you, this is not supported. You might open a bug report but I doubt this will be implemented.
-
If you want to expirement, you could try creating a simple proxy dll with DllMain with say a printf() so that it has dependencies to MS runtime dlls.
Build that proxy dll with -MT so that it adds the MS dlls to its .lib file, and link that .lib with your Qt app.
Most likely you'll get lots of warnings and complaints about missing _strdup(), _time64() etc. at the link stage.
To fix those link your proxy dll also with msvcrt.lib.
You'll still get warnings that you should link with /NODEFAULTLIB but if you ignore that the app might run anyway. But with 2 separate MSVC runtimes, kind of a FrankenExe :-) -
I try to build Qt 6.5.3 for Windows with -MT compiler flag.
For example to do that for Qt 5.x.x need maker a changes to this file:
qtbase\mkspecs\common\msvc-desktop.conf
Replace -MD, -MDd to -MT, -MTd before configuration and then build the Qt library.
But this trick is not working for Qt 6.x.x
To ensure that I even make some non-compilable changes in any cpp file. It allows me to see the full command line and it contains -MD, -MDd flags.
It looks like "msvc-desktop.conf" is not used for configuration.
I use this command for configuration:
configure.bat -prefix %CD%\qtbase -opensource -debug-and-release -nomake examples -skip qtquick -skip qtvirtualkeyboard -nomake tests -opengl desktop -optimize-size -platform win32-msvc
I solved this problem.
A Ilittle bit rube, but works.
Here are the patches if anybody needs them. :-)--- qttools/src/assistant/CMakeLists.txt 2023-09-24 09:45:36.000000000 +0100 +++ qttools/src/assistant/CMakeLists.txt 2024-08-13 18:50:42.744407900 +0100 @@ -17,21 +17,22 @@ return() endif() add_subdirectory(help) add_subdirectory(assistant) add_subdirectory(qhelpgenerator) set(QLITEHTML_BIN_PATH ${INSTALL_BINDIR}) set(QLITEHTML_LIBRARY_PATH ${INSTALL_LIBDIR}) set(QLITEHTML_LIBRARY_TYPE STATIC) set(BUILD_SHARED_LIBS OFF) -if(QT_FEATURE_static_runtime AND MSVC) +#if(QT_FEATURE_static_runtime AND MSVC) +if(MSVC) set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>") endif() add_subdirectory(qlitehtml/src EXCLUDE_FROM_ALL) if(TARGET qlitehtml) qt_autogen_tools_initial_setup(qlitehtml) # The litehtml and gumbo targets will not be available here if they are not built by Qt # but found in the system, because they are imported only to the subdirectory scope # where find_package was called. But that's fine, we wouldn't be able to set compiler flags # on them anyway. if(TARGET litehtml)
--- qtmultimedia/src/3rdparty/resonance-audio/CMakeLists.txt 2023-09-24 11:12:48.000000000 +0100 +++ qtmultimedia/src/3rdparty/resonance-audio/CMakeLists.txt 2024-08-13 19:08:11.046330800 +0100 @@ -11,25 +11,25 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # Static/dynamic runtime can be selected via -DSTATIC_MSVC_RUNTIME=ON|OFF macro(configure_msvc_runtime) if (NOT BUILD_WWISE_AUTHORING_PLUGIN) option(STATIC_MSVC_RUNTIME "Static linkage of MSVC runtime" ON) SET(MSVC_RUNTIME_FLAG "/MT" CACHE STRING "MSVC Runtime flag") - if (STATIC_MSVC_RUNTIME) + #if (STATIC_MSVC_RUNTIME) SET(MSVC_RUNTIME_FLAG "/MT") - else () - SET(MSVC_RUNTIME_FLAG "/MD") - endif () + #else () + # SET(MSVC_RUNTIME_FLAG "/MD") + #endif () message(STATUS "MSVC Runtime flag: ${MSVC_RUNTIME_FLAG}") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${MSVC_RUNTIME_FLAG}" CACHE INTERNAL "" FORCE) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${MSVC_RUNTIME_FLAG}d" CACHE INTERNAL "" FORCE) set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${MSVC_RUNTIME_FLAG}" CACHE INTERNAL "" FORCE) set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${MSVC_RUNTIME_FLAG}d" CACHE INTERNAL "" FORCE) endif (NOT BUILD_WWISE_AUTHORING_PLUGIN) endmacro() macro(use_cxx11) set(CMAKE_CXX_STANDARD 11)
--- qtbase/cmake/QtPublicTargetHelpers.cmake 2023-09-21 19:24:26.000000000 +0100 +++ qtbase/cmake/QtPublicTargetHelpers.cmake 2024-08-13 18:39:43.681027000 +0100 @@ -312,12 +312,17 @@ set(link_option PRIVATE) else() set(link_option INTERFACE) endif() if(CLANG) target_link_options(${target} ${link_option} "LINKER:-Bstatic") else() target_link_options(${target} ${link_option} "-static") endif() endif() + else() + if(MSVC) + set_property(TARGET ${target} PROPERTY + MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>") + endif() endif() endfunction()
-