diff --git a/.gitignore b/.gitignore
index f90d5ba5389c95021ac38cf737b7d32493a679db..8cfcb49b84b4ee0548da301001095035bab41d74 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,7 +11,6 @@ x86/
 debug/
 release/
 beta/
-qrencode-win32/
 *.dll
 *.qm
 build/
diff --git a/.gitmodules b/.gitmodules
index 3648ccab9d34c4ab29cd6d1c55447205f12be238..971ddabe0c0aa4f3b6bbbb6e39b2c88e9bf49c4a 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,4 +1,4 @@
-[submodule "libqrencode"]
-    path = libqrencode
-    url = https://github.com/fukuchi/libqrencode.git
-    ignore = dirty
+[submodule "3rdparty/qrencode-win32"]
+	path = 3rdparty/qrencode-win32
+	url = https://github.com/BlueDragon747/qrencode-win32.git
+	ignore = dirty
diff --git a/3rdparty/qrencode-win32 b/3rdparty/qrencode-win32
new file mode 160000
index 0000000000000000000000000000000000000000..d6495a2aa74d058d54ae0f1b9e9e545698de66ce
--- /dev/null
+++ b/3rdparty/qrencode-win32
@@ -0,0 +1 @@
+Subproject commit d6495a2aa74d058d54ae0f1b9e9e545698de66ce
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 489d9bd54e371a542add33157cd8e384024a652b..39245b5bf7856ab4e9cb54001d8d64ab87f0528d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -20,6 +20,38 @@ set(CMAKE_AUTORCC ON)
 set(CMAKE_AUTOUIC ON)
 set(CMAKE_INCLUDE_CURRENT_DIR ON)
 
+# Here we let find_package(<PackageName>...) try to find Qt 6,
+# If it is found, find_package will succeed, and the CMake variable
+# QT_VERSION_MAJOR will be defined 6.
+find_package(QT NAMES Qt6 REQUIRED)
+if (${QT_VERSION_MAJOR} STRLESS 6)
+    if (${QT_VERSION_MINOR} STRLESS 2)
+        message(FATAL_ERROR "Qt 6.2 or higher is required." )
+    endif()
+endif()
+set(QT_MODULES
+    Quick
+    Network
+    NetworkAuth
+    Svg
+    Gui
+    Qml
+    QmlModels
+    Positioning
+    Sql
+    Concurrent
+    Core
+    Core5Compat
+    WebEngineCore
+    WebEngineQuick
+    WebChannel
+    WebEngineWidgets
+)
+find_package(Qt6 COMPONENTS ${QT_MODULES} REQUIRED)
+foreach(MODULE ${QT_MODULES})
+  list(APPEND QT_LIBS "Qt::${MODULE}")
+endforeach()
+
 set(SRC_DIR ${PROJECT_SOURCE_DIR}/src)
 set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS})
 set(CMAKE_INSTALL_RPATH_USE_LINK_PATH true)
@@ -108,7 +140,8 @@ set(COMMON_SOURCES
     ${SRC_DIR}/currentconversation.cpp
     ${SRC_DIR}/currentaccount.cpp
     ${SRC_DIR}/videodevices.cpp
-    ${SRC_DIR}/previewengine.cpp)
+    ${SRC_DIR}/previewengine.cpp
+)
 
 set(COMMON_HEADERS
     ${SRC_DIR}/avatarimageprovider.h
@@ -165,62 +198,21 @@ set(COMMON_HEADERS
     ${SRC_DIR}/currentconversation.h
     ${SRC_DIR}/currentaccount.h
     ${SRC_DIR}/videodevices.h
-    ${SRC_DIR}/previewengine.h)
-
-set(QML_LIBS
-    Qt::Quick
-    Qt::Network
-    Qt::NetworkAuth
-    Qt::Svg
-    Qt::Gui
-    Qt::Qml
-    Qt::QmlModels
-    Qt::Positioning
-    Qt::Sql
-    Qt::Concurrent
-    Qt::Core
-    Qt::Core5Compat
-    Qt::WebEngineCore
-    Qt::WebEngineQuick
-    Qt::WebChannel
-    Qt::WebEngineWidgets)
-
-set(QML_LIBS_LIST
-    Quick
-    Network
-    NetworkAuth
-    Svg
-    Gui
-    Qml
-    QmlModels
-    Positioning
-    Sql
-    Concurrent
-    Core
-    Core5Compat
-    WebEngineCore
-    WebEngineQuick
-    WebChannel
-    WebEngineWidgets)
-
-set(WINDOWS_SYS_LIBS Shell32.lib
-                     Ole32.lib
-                     Advapi32.lib
-                     Shlwapi.lib
-                     User32.lib
-                     Gdi32.lib
-                     Crypt32.lib
-                     Strmiids.lib)
-
-# Here we let find_package(<PackageName>...) try to find Qt 6,
-# If it is found, find_package will succeed, and the CMake variable
-# QT_VERSION_MAJOR will be defined 6.
-find_package(QT NAMES Qt6 COMPONENTS ${QML_LIBS_LIST} REQUIRED)
-if (${QT_VERSION_MAJOR} STRLESS 6)
-   message(FATAL_ERROR "We currently only support Qt6" )
-endif()
+    ${SRC_DIR}/previewengine.h
+)
 
 if(MSVC)
+    set(WINDOWS_SYS_LIBS
+        Shell32.lib
+        Ole32.lib
+        Advapi32.lib
+        Shlwapi.lib
+        User32.lib
+        Gdi32.lib
+        Crypt32.lib
+        Strmiids.lib
+    )
+
     list(APPEND COMMON_SOURCES
                 ${SRC_DIR}/connectivitymonitor.cpp)
     # preprocessor defines
@@ -229,18 +221,25 @@ if(MSVC)
     # dependencies
     set(LRC ${PROJECT_SOURCE_DIR}/../lrc)
     set(DRING ${PROJECT_SOURCE_DIR}/../daemon)
-    set(QRENCODE ${PROJECT_SOURCE_DIR}/qrencode-win32/qrencode-win32)
+    set(QRENCODE_DIR ${PROJECT_SOURCE_DIR}/3rdparty/qrencode-win32/qrencode-win32)
 
     # compiler options
     add_compile_options(/wd4068 /wd4099 /wd4189 /wd4267 /wd4577 /wd4467 /wd4715 /wd4828)
-    add_compile_options(/MP /GS /W3 /Gy /Zc:wchar_t /Zi /Gm- /O2 /Zc:inline /fp:precise /errorReport:prompt)
-    add_compile_options(/Gd /Oi /MD /std:c++17 /FC /EHsc /nologo /sdl)
+    add_compile_options(/MP /GS /W3 /Gy /Zc:wchar_t /Zi /Gm- /O2 /Zc:inline /fp:precise)
+    add_compile_options(/Gd /Oi /MD /FC /EHsc /nologo /sdl)
 
     # linker options
-    add_link_options("/IGNORE:4006,4049,4078,4098" "/FORCE:MULTIPLE" "/INCREMENTAL:NO" "/DEBUG" "/LTCG" "/NODEFAULTLIB:LIBCMT")
+    add_link_options(
+        "/IGNORE:4006,4049,4078,4098"
+        "/FORCE:MULTIPLE"
+        "/INCREMENTAL:NO"
+        "/DEBUG"
+        "/LTCG"
+        "/NODEFAULTLIB:LIBCMT"
+    )
 
     # client deps
-    set(QRENCODE_LIB ${QRENCODE}/vc8/qrcodelib/x64/Release-Lib/qrcodelib.lib)
+    set(QRENCODE_LIB ${QRENCODE_DIR}/vc8/qrcodelib/x64/Release-Lib/qrcodelib.lib)
 
     # lrc
     set(LRC_SRC_PATH ${LRC}/src)
@@ -252,24 +251,20 @@ if(MSVC)
     set(DRING_LIB ${DRING}/build/x64/ReleaseLib_win32/bin/jami.lib)
     set(GNUTLS_LIB ${DRING}/contrib/msvc/lib/x64/libgnutls.lib)
 
-    # ReleaseCompile config
-    if(ReleaseCompile)
-        message("ReleaseCompile config enabled")
-        add_definitions(-DCOMPILE_ONLY)
+    # Beta config
+    if(BETA)
+        message(STATUS "Beta config enabled")
+        add_definitions(-DBETA)
+        set(JAMI_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/x64/Beta)
     else()
-        # Beta config
-        if(BETA)
-            message("Beta config enabled")
-            add_definitions(-DBETA)
-            set(JAMI_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/x64/Beta)
-        else()
-            set(JAMI_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/x64/Release)
-        endif()
+        set(JAMI_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/x64/Release)
     endif()
 
-    include_directories(${DRING_SRC_PATH}
-                        ${LRC_SRC_PATH}
-                        ${QRENCODE})
+    include_directories(
+        ${DRING_SRC_PATH}
+        ${LRC_SRC_PATH}
+        ${QRENCODE_DIR}
+    )
 elseif (NOT APPLE)
     list(APPEND COMMON_SOURCES
                 ${SRC_DIR}/xrectsel.c
@@ -278,8 +273,8 @@ elseif (NOT APPLE)
     list(APPEND COMMON_HEADERS
                 ${SRC_DIR}/dbuserrorhandler.h
                 ${SRC_DIR}/xrectsel.h)
-    list(APPEND QML_LIBS Qt::DBus)
-    list(APPEND QML_LIBS_LIST DBus)
+    list(APPEND QT_LIBS Qt::DBus)
+    list(APPEND QT_MODULES DBus)
 
     find_package(PkgConfig REQUIRED)
 
@@ -401,13 +396,13 @@ endif()
 # Qt find package
 if(QT6_VER AND QT6_PATH)
     message(STATUS "Using custom Qt version")
-    find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS ${QML_LIBS_LIST}
+    find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS ${QT_MODULES}
                  PATHS ${QT6_PATH} NO_DEFAULT_PATH)
     # Linguist tools is not required.
     find_package(Qt${QT_VERSION_MAJOR} COMPONENTS LinguistTools
                  PATHS ${QT6_PATH} NO_DEFAULT_PATH)
 else()
-    find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS ${QML_LIBS_LIST})
+    find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS ${QT_MODULES})
     find_package(Qt${QT_VERSION_MAJOR}LinguistTools)
 endif()
 
@@ -429,7 +424,7 @@ if(MSVC)
     set_target_properties(${PROJECT_NAME} PROPERTIES WIN32_EXECUTABLE TRUE)
 
     target_link_libraries(${PROJECT_NAME} PRIVATE
-                          ${QML_LIBS}
+                          ${QT_LIBS}
                           ${QRENCODE_LIB}
                           ${WINDOWS_SYS_LIBS})
 
@@ -439,72 +434,70 @@ if(MSVC)
         RUNTIME_OUTPUT_DIRECTORY_RELEASE "${JAMI_OUTPUT_DIRECTORY_RELEASE}"
     )
 
-    if(NOT DEFINED ReleaseCompile)
-        # executable icon
-        target_sources(${PROJECT_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/ico.rc)
-
-        target_link_libraries(${PROJECT_NAME} PRIVATE
-                              ${RINGCLIENT_STATIC_LIB}
-                              ${QTWRAPPER_LIB}
-                              ${DRING_LIB}
-                              ${GNUTLS_LIB})
-
-        # translations
-        if(Qt${QT_VERSION_MAJOR}LinguistTools_FOUND)
-            message("Releasing and copying translation files")
-            file(MAKE_DIRECTORY "${JAMI_OUTPUT_DIRECTORY_RELEASE}/share/ring/translations/")
-            file(MAKE_DIRECTORY "${JAMI_OUTPUT_DIRECTORY_RELEASE}/share/libringclient/translations/")
-            file(GLOB TS_CLIENT_FILES ${PROJECT_SOURCE_DIR}/translations/*.ts)
-            file(GLOB TS_LRC_FILES ${LRC}/translations/*.ts)
-            set_source_files_properties(${TS_CLIENT_FILES} PROPERTIES OUTPUT_LOCATION
-                                        "${JAMI_OUTPUT_DIRECTORY_RELEASE}/share/ring/translations")
-            set_source_files_properties(${TS_LRC_FILES} PROPERTIES OUTPUT_LOCATION
-                                        "${JAMI_OUTPUT_DIRECTORY_RELEASE}/share/libringclient/translations")
-
-            qt_add_translation(QM_CLIENT_FILES ${TS_CLIENT_FILES})
-            qt_add_translation(QM_LRC_FILES ${TS_LRC_FILES})
-            target_sources(${PROJECT_NAME} PRIVATE ${QM_CLIENT_FILES})
-            target_sources(${PROJECT_NAME} PRIVATE ${QM_LRC_FILES})
-        endif()
+    # executable icon
+    target_sources(${PROJECT_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/ico.rc)
+
+    target_link_libraries(${PROJECT_NAME} PRIVATE
+                          ${RINGCLIENT_STATIC_LIB}
+                          ${QTWRAPPER_LIB}
+                          ${DRING_LIB}
+                          ${GNUTLS_LIB})
 
-        # POST_BUILD steps
-
-        # check time stamp
-        set(TIME_STAMP_FILE ".deploy.stamp")
-        add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
-                           WORKING_DIRECTORY "$<TARGET_FILE_DIR:${PROJECT_NAME}>"
-                           COMMAND ${CMAKE_COMMAND} -DTIME_STAMP_FILE=${TIME_STAMP_FILE}
-                                   -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/time_stamp_check.cmake)
-
-        # copy runtime files and run windeployqt on target and deploy Qt libs
-        add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
-                           WORKING_DIRECTORY "$<TARGET_FILE_DIR:${PROJECT_NAME}>"
-                           COMMAND ${CMAKE_COMMAND} -DTIME_STAMP_FILE=${TIME_STAMP_FILE}
-                                   -DCOPY_TO_PATH=$<TARGET_FILE_DIR:${PROJECT_NAME}>
-                                   -DDRING_PATH=${DRING}
-                                   -DPROJECT_ROOT_DIR=${PROJECT_SOURCE_DIR}
-                                   -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/windows_daemon_deploy.cmake)
-
-        add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
-                           WORKING_DIRECTORY "$<TARGET_FILE_DIR:${PROJECT_NAME}>"
-                           COMMAND ${CMAKE_COMMAND} -DTIME_STAMP_FILE=${TIME_STAMP_FILE}
-                                   -DWIN_DEPLOY_QT_PATH=${CMAKE_PREFIX_PATH}/bin
-                                   -DQML_SRC_DIR=${SRC_DIR}
-                                   -DEXE_NAME=$<TARGET_FILE:${PROJECT_NAME}>
-                                   -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/windows_qt_deploy.cmake)
-
-        # create time stamp
-        add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
-                           WORKING_DIRECTORY "$<TARGET_FILE_DIR:${PROJECT_NAME}>"
-                           COMMAND ${CMAKE_COMMAND} -DTIME_STAMP_FILE=${TIME_STAMP_FILE}
-                                   -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/time_stamp_create.cmake)
+    # translations
+    if(Qt${QT_VERSION_MAJOR}LinguistTools_FOUND)
+        message("Releasing and copying translation files")
+        file(MAKE_DIRECTORY "${JAMI_OUTPUT_DIRECTORY_RELEASE}/share/ring/translations/")
+        file(MAKE_DIRECTORY "${JAMI_OUTPUT_DIRECTORY_RELEASE}/share/libringclient/translations/")
+        file(GLOB TS_CLIENT_FILES ${PROJECT_SOURCE_DIR}/translations/*.ts)
+        file(GLOB TS_LRC_FILES ${LRC}/translations/*.ts)
+        set_source_files_properties(${TS_CLIENT_FILES} PROPERTIES OUTPUT_LOCATION
+                                    "${JAMI_OUTPUT_DIRECTORY_RELEASE}/share/ring/translations")
+        set_source_files_properties(${TS_LRC_FILES} PROPERTIES OUTPUT_LOCATION
+                                    "${JAMI_OUTPUT_DIRECTORY_RELEASE}/share/libringclient/translations")
+
+        qt_add_translation(QM_CLIENT_FILES ${TS_CLIENT_FILES})
+        qt_add_translation(QM_LRC_FILES ${TS_LRC_FILES})
+        target_sources(${PROJECT_NAME} PRIVATE ${QM_CLIENT_FILES})
+        target_sources(${PROJECT_NAME} PRIVATE ${QM_LRC_FILES})
     endif()
 
+    # POST_BUILD steps
+
+    # check time stamp
+    set(TIME_STAMP_FILE ".deploy.stamp")
+    add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
+                       WORKING_DIRECTORY "$<TARGET_FILE_DIR:${PROJECT_NAME}>"
+                       COMMAND ${CMAKE_COMMAND} -DTIME_STAMP_FILE=${TIME_STAMP_FILE}
+                               -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/time_stamp_check.cmake)
+
+    # copy runtime files and run windeployqt on target and deploy Qt libs
+    add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
+                       WORKING_DIRECTORY "$<TARGET_FILE_DIR:${PROJECT_NAME}>"
+                       COMMAND ${CMAKE_COMMAND} -DTIME_STAMP_FILE=${TIME_STAMP_FILE}
+                               -DCOPY_TO_PATH=$<TARGET_FILE_DIR:${PROJECT_NAME}>
+                               -DDRING_PATH=${DRING}
+                               -DPROJECT_ROOT_DIR=${PROJECT_SOURCE_DIR}
+                               -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/windows_daemon_deploy.cmake)
+
+    add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
+                       WORKING_DIRECTORY "$<TARGET_FILE_DIR:${PROJECT_NAME}>"
+                       COMMAND ${CMAKE_COMMAND} -DTIME_STAMP_FILE=${TIME_STAMP_FILE}
+                               -DWIN_DEPLOY_QT_PATH=${CMAKE_PREFIX_PATH}/bin
+                               -DQML_SRC_DIR=${SRC_DIR}
+                               -DEXE_NAME=$<TARGET_FILE:${PROJECT_NAME}>
+                               -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/windows_qt_deploy.cmake)
+
+    # create time stamp
+    add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
+                       WORKING_DIRECTORY "$<TARGET_FILE_DIR:${PROJECT_NAME}>"
+                       COMMAND ${CMAKE_COMMAND} -DTIME_STAMP_FILE=${TIME_STAMP_FILE}
+                               -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/time_stamp_create.cmake)
+
     # executable name
     set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "Jami")
 elseif (NOT APPLE)
     target_link_libraries(${PROJECT_NAME} PRIVATE
-                          ${QML_LIBS}
+                          ${QT_LIBS}
                           ${LRC_LIB_NAME}
                           ${qrencode}
                           ${X11}
@@ -616,7 +609,7 @@ elseif (NOT APPLE)
 else()
     target_sources(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/resources/images/jami.icns)
     target_link_libraries(${PROJECT_NAME} PRIVATE
-                          ${QML_LIBS}
+                          ${QT_LIBS}
                           ${LRC_LIB_NAME}
                           ${SYSTEM_CONFIGURATUION}
                           qrencode)
diff --git a/make-client.py b/make-client.py
index 181a26f92f79dcd175d19d556608a31cea82ff5e..b7a931ea5fe1187c47eb5601869aee52743b99be 100644
--- a/make-client.py
+++ b/make-client.py
@@ -1,3 +1,5 @@
+#!/usr/bin/env python3
+
 import tempfile
 import re
 import sys
@@ -9,9 +11,6 @@ import multiprocessing
 import fileinput
 from enum import Enum
 
-# vs help
-win_sdk_default = '10.0.16299.0'
-win_toolset_default = '142'
 qt_version_default = '6.2.0'
 
 vs_where_path = os.path.join(
@@ -21,36 +20,30 @@ vs_where_path = os.path.join(
 host_is_64bit = (False, True)[platform.machine().endswith('64')]
 this_dir = os.path.dirname(os.path.realpath(__file__))
 build_dir = os.path.join(this_dir, 'build')
+
 temp_path = os.environ['TEMP']
 openssl_include_dir = 'C:\\Qt\\Tools\\OpenSSL\\Win_x64\\include\\openssl'
 
+qt_path = os.path.join('c:', os.sep, 'Qt')
+qt_kit_path = 'msvc2019_64'
+qt_root_path = os.getenv('QT_ROOT_DIRECTORY', qt_path)
+
 # project path
-jami_qt_project = os.path.join(build_dir, 'jami-qt.vcxproj')
 unit_test_project = os.path.join(build_dir, 'tests', 'unittests.vcxproj')
 qml_test_project = os.path.join(build_dir, 'tests', 'qml_tests.vcxproj')
 
 # test executable command
 qml_test_exe = os.path.join(this_dir, 'x64', 'test', 'qml_tests.exe -input ') + \
-               os.path.join(this_dir, 'tests', 'qml')
+    os.path.join(this_dir, 'tests', 'qml')
 unit_test_exe = os.path.join(this_dir, 'x64', 'test', 'unittests.exe')
 
-class TestBuilding(Enum):
-    NoTests = 0
-    WithTests = 1
-    OnlyTests = 2
-
-class QtVerison(Enum):
-    Major = 0
-    Minor = 1
-    Micro = 2
-
-def execute_cmd(cmd, with_shell=False, env_vars={}):
-    if(bool(env_vars)):
-        p = subprocess.Popen(cmd, shell=with_shell,
-                             stdout=sys.stdout,
-                             env=env_vars)
-    else:
-        p = subprocess.Popen(cmd, shell=with_shell)
+
+def execute_cmd(cmd, with_shell=False, env_vars=None, cmd_dir=os.getcwd()):
+    p = subprocess.Popen(cmd,
+                         shell=with_shell,
+                         stdout=sys.stdout,
+                         env=env_vars,
+                         cwd=cmd_dir)
     _, _ = p.communicate()
     return p.returncode
 
@@ -69,11 +62,6 @@ def getLatestVSVersion():
     else:
         return
 
-def getCMakeGenerator(vs_version):
-    if vs_version == '15':
-        return 'Visual Studio 15 2017 Win64'
-    else:
-        return 'Visual Studio ' + vs_version + ' 2019'
 
 def findVSLatestDir():
     args = [
@@ -90,17 +78,20 @@ def findVSLatestDir():
     else:
         return
 
+
 def getQtVersionNumber(qt_version, version_type):
     version_list = qt_version.split('.')
     return version_list[version_type.value]
 
+
 def findMSBuild():
     filename = 'MSBuild.exe'
     for root, _, files in os.walk(findVSLatestDir() + r'\\MSBuild'):
         if filename in files:
             return os.path.join(root, filename)
 
-def getMSBuildArgs(arch, config_str, toolset, configuration_type=''):
+
+def getMSBuildArgs(arch, config_str, configuration_type=''):
     msbuild_args = [
         '/nologo',
         '/verbosity:minimal',
@@ -108,12 +99,11 @@ def getMSBuildArgs(arch, config_str, toolset, configuration_type=''):
         '/p:Platform=' + arch,
         '/p:Configuration=' + config_str,
         '/p:useenv=true']
-    if (toolset != ''):
-        msbuild_args.append('/p:PlatformToolset=' + toolset)
     if (configuration_type != ''):
         msbuild_args.append('/p:ConfigurationType=' + configuration_type)
     return msbuild_args
 
+
 def getVSEnv(arch='x64', platform='', version=''):
     env_cmd = 'set path=%path:"=% && ' + \
         getVSEnvCmd(arch, platform, version) + ' && set'
@@ -151,6 +141,7 @@ def replace_necessary_vs_prop(project_path, toolset, sdk_version):
                     'WindowsTargetPlatformVersion',
                     sdk_version)
 
+
 def build_project(msbuild, msbuild_args, proj, env_vars):
     args = []
     args.extend(msbuild_args)
@@ -170,24 +161,33 @@ def replace_vs_prop(filename, prop, val):
             print(re.sub(p, val, line), end='')
 
 
-def deps(arch, toolset, qtver):
-    print('Deps Qt Client Release|' + arch)
-
-    # Fetch QRencode
-    print('Generate QRencode')
-    apply_cmd = "git apply --reject --ignore-whitespace --whitespace=fix"
-    qrencode_path = 'qrencode-win32'
-    if (os.path.isdir(qrencode_path)):
-        os.system('rmdir qrencode-win32 /s /q')
-    if (execute_cmd("git clone https://github.com/BlueDragon747/qrencode-win32.git", True)):
-        print("Git clone failed when cloning from https://github.com/BlueDragon747/qrencode-win32.git")
-        sys.exit(1)
-    if(execute_cmd("cd qrencode-win32 && git checkout d6495a2aa74d058d54ae0f1b9e9e545698de66ce && "
-                    + apply_cmd + os.path.join(' ..', 'qrencode-win32.patch'), True)):
-        print("qrencode-win32 set up error")
-        sys.exit(1)
+def init_submodules():
+    print('Initializing submodules...')
 
-    print('Building qrcodelib')
+    if (execute_cmd(['git', 'submodule', 'update', '--init'], False)):
+        print('Submodule initialization error.')
+    else:
+        if (execute_cmd(['git', 'submodule', 'update', '--recursive'], False)):
+            print('Submodule recursive checkout error.')
+        else:
+            print('Submodule recursive checkout finished.')
+
+
+def build_deps(arch):
+    print('Patching and building qrencode')
+    apply_cmd = [
+        'git',
+        'apply',
+        '--reject',
+        '--ignore-whitespace',
+        '--whitespace=fix'
+    ]
+    qrencode_dir = os.path.join(this_dir, '3rdparty', 'qrencode-win32')
+    patch_file = os.path.join(this_dir, 'qrencode-win32.patch')
+    apply_cmd.append(patch_file)
+    print(apply_cmd)
+    if(execute_cmd(apply_cmd, False, None, qrencode_dir)):
+        print("Couldn't patch qrencode-win32.")
 
     vs_env_vars = {}
     vs_env_vars.update(getVSEnv())
@@ -195,112 +195,48 @@ def deps(arch, toolset, qtver):
     msbuild = findMSBuild()
     if not os.path.isfile(msbuild):
         raise IOError('msbuild.exe not found. path=' + msbuild)
-    msbuild_args = getMSBuildArgs(arch, 'Release-Lib', toolset)
-
-    this_dir = os.path.dirname(os.path.realpath(__file__))
-    proj_path = os.path.join(this_dir, 'qrencode-win32' ,'qrencode-win32',
+    msbuild_args = getMSBuildArgs(arch, 'Release-Lib')
+    proj_path = os.path.join(qrencode_dir, 'qrencode-win32',
                              'vc8', 'qrcodelib', 'qrcodelib.vcxproj')
 
     build_project(msbuild, msbuild_args, proj_path, vs_env_vars)
 
 
-def build(arch, toolset, sdk_version, config_str, project_path_under_current_path, qtver,
-          test_building_type, force_option=True):
+def build(arch, config_str, qtver, tests=False):
     print("Building with Qt " + qtver)
 
-    configuration_type = 'StaticLibrary'
-
     vs_env_vars = {}
     vs_env_vars.update(getVSEnv())
 
-    qt_dir = os.path.join("C:\\", 'Qt', qtver)
-    cmake_gen = getCMakeGenerator(getLatestVSVersion())
-    qt_major_version = getQtVersionNumber(qtver, QtVerison.Major)
-    qt_general_macro = 'Qt' + qt_major_version
-    msvc_folder = '\\msvc2019_64'
-
-    qt_cmake_dir = qt_dir + msvc_folder + '\\lib\\cmake\\'
-    cmake_prefix_path = qt_dir + msvc_folder
+    qt_dir = os.path.join(qt_root_path, qtver, qt_kit_path)
 
-    qt_cmake_dir = os.path.join(qt_dir, msvc_folder, 'lib', 'cmake')
-    cmake_prefix_path = os.path.join(qt_dir, msvc_folder)
     cmake_options = [
-        '-DCMAKE_PREFIX_PATH=' + cmake_prefix_path,
-        '-DOPENSSL_INCLUDE_DIR=' + openssl_include_dir,
-        '-DQT_DIR=' + qt_dir + msvc_folder,
-        '-D' + qt_general_macro + '_DIR=' + qt_cmake_dir + qt_general_macro,
-        '-D' + qt_general_macro + 'Core_DIR=' + qt_cmake_dir + qt_general_macro + 'Core',
-        '-D' + qt_general_macro + 'Core5Compat_DIR=' + qt_cmake_dir + qt_general_macro + 'Core5Compat',
-        '-D' + qt_general_macro + 'WebEngineCore_DIR=' + qt_cmake_dir + qt_general_macro + 'WebEngineCore',
-        '-D' + qt_general_macro + 'WebEngineQuick_DIR=' + qt_cmake_dir + qt_general_macro + 'WebEngineQuick',
-        '-D' + qt_general_macro + 'WebChannel_DIR=' + qt_cmake_dir + qt_general_macro + 'WebChannel',
-        '-D' + qt_general_macro + 'WebEngineWidgets_DIR=' + qt_cmake_dir + qt_general_macro + 'WebEngineWidgets',
-        '-D' + qt_general_macro + 'Sql_DIR=' + qt_cmake_dir + qt_general_macro + 'Sql',
-        '-D' + qt_general_macro + 'LinguistTools_DIR=' + qt_cmake_dir + qt_general_macro + 'LinguistTools',
-        '-D' + qt_general_macro + 'Concurrent_DIR=' + qt_cmake_dir + qt_general_macro + 'Concurrent',
-        '-D' + qt_general_macro + 'Network_DIR=' + qt_cmake_dir + qt_general_macro + 'Network',
-        '-D' + qt_general_macro + 'NetworkAuth_DIR=' + qt_cmake_dir + qt_general_macro + 'NetworkAuth',
-        '-D' + qt_general_macro + 'Gui_DIR=' + qt_cmake_dir + qt_general_macro + 'Gui',
-        '-D' + qt_general_macro + 'Qml_DIR=' + qt_cmake_dir + qt_general_macro + 'Qml',
-        '-D' + qt_general_macro + 'QmlModels_DIR=' + qt_cmake_dir + qt_general_macro + 'QmlModels',
-        '-D' + qt_general_macro + 'Positioning_DIR=' + qt_cmake_dir + qt_general_macro + 'Positioning',
-        '-D' + qt_general_macro + 'Test_DIR=' + qt_cmake_dir + qt_general_macro + 'Test',
-        '-D' + qt_general_macro + 'QuickTest_DIR=' + qt_cmake_dir + qt_general_macro + 'QuickTest',
-        '-DENABLE_TESTS=' + (str("ENABLE_TESTS") if test_building_type != TestBuilding.NoTests else ''),
-        '-DCMAKE_SYSTEM_VERSION=' + sdk_version
+        '-DCMAKE_PREFIX_PATH=' + qt_dir,
+        '-DCMAKE_BUILD_TYPE=' + config_str
     ]
+    if tests:
+        cmake_options.append('-DENABLE_TESTS=true')
+
     if not os.path.exists(build_dir):
         os.makedirs(build_dir)
-    os.chdir(build_dir)
-
-    if (config_str == 'Release'):
-        print('Generating project using cmake ' + config_str + '|' + arch)
-        cmd = ['cmake', '..', '-G', cmake_gen]
-        cmd.extend(cmake_options)
-        if(execute_cmd(cmd, False, vs_env_vars)):
-            print("Cmake vcxproj file generate error")
-            sys.exit(1)
-        configuration_type = 'Application'
-    elif (config_str == 'Beta'):
-        print('Generating project using cmake ' + config_str + '|' + arch)
-        cmake_options.append('-DBETA=1')
-        cmd = ['cmake', '..', '-G', cmake_gen]
-        cmd.extend(cmake_options)
-        if(execute_cmd(cmd, False, vs_env_vars)):
-            print("Beta: Cmake vcxproj file generate error")
-            sys.exit(1)
-        config_str = 'Release'
-        configuration_type = 'Application'
-    elif (config_str == 'ReleaseCompile'):
-        print('Generating project using qmake ' + config_str + '|' + arch)
-        cmake_options.append('-DReleaseCompile=1')
-        cmd = ['cmake', '..', '-G', cmake_gen]
-        cmd.extend(cmake_options)
-        if(execute_cmd(cmd, False, vs_env_vars)):
-            print("ReleaseCompile: Cmake vcxproj file generate error")
-            sys.exit(1)
-        config_str = 'Release'
-
-    # Note: If project is configured to Beta or ReleaseCompile, the configuration name is still release,
-    # but will be outputted into x64/Beta folder (for Beta Only)
-
-    print('Building projects in ' + config_str + '|' + arch)
 
-    msbuild = findMSBuild()
-    if not os.path.isfile(msbuild):
-        raise IOError('msbuild.exe not found. path=' + msbuild)
-    msbuild_args = getMSBuildArgs(arch, config_str, toolset, configuration_type)
+    config_str = 'Release'
+    cmd = ['cmake', '..']
+    if (config_str == 'Beta'):
+        cmake_options.append('-DBETA=1')
 
-    if (force_option):
-        replace_necessary_vs_prop(project_path_under_current_path, toolset, sdk_version)
+    print('Generating project using cmake ' + config_str + '|' + arch)
+    cmd.extend(cmake_options)
+    if(execute_cmd(cmd, False, vs_env_vars, build_dir)):
+        print("Cmake generate error")
+        sys.exit(1)
 
-    if (test_building_type != TestBuilding.OnlyTests):
-        build_project(msbuild, msbuild_args, project_path_under_current_path, vs_env_vars)
+    print('Building projects in ' + config_str + '|' + arch)
+    cmd = ['cmake', '--build', '.', '--config', config_str]
+    if(execute_cmd(cmd, False, vs_env_vars, build_dir)):
+        print("Cmake build error")
+        sys.exit(1)
 
-    # build test projects
-    if (test_building_type != TestBuilding.NoTests):
-        build_tests_projects(arch, config_str, msbuild, vs_env_vars,
-                             toolset, sdk_version, force_option)
 
 def build_tests_projects(arch, config_str, msbuild, vs_env_vars, toolset,
                          sdk_version, force_option=True):
@@ -316,6 +252,7 @@ def build_tests_projects(arch, config_str, msbuild, vs_env_vars, toolset,
         msbuild_args = getMSBuildArgs(arch, config_str, toolset)
         build_project(msbuild, msbuild_args, project, vs_env_vars)
 
+
 def run_tests(mute_jamid, output_to_files):
     print('Running client tests')
 
@@ -325,8 +262,10 @@ def run_tests(mute_jamid, output_to_files):
         test_exe_command_list[0] += ' -mutejamid'
         test_exe_command_list[1] += ' -mutejamid'
     if output_to_files:
-        test_exe_command_list[0] += ' -o ' + os.path.join(this_dir, 'x64', 'test', 'qml_tests.txt')
-        test_exe_command_list[1] += ' > ' + os.path.join(this_dir, 'x64', 'test', 'unittests.txt')
+        test_exe_command_list[0] += ' -o ' + \
+            os.path.join(this_dir, 'x64', 'test', 'qml_tests.txt')
+        test_exe_command_list[1] += ' > ' + \
+            os.path.join(this_dir, 'x64', 'test', 'unittests.txt')
 
     test_result_code = 0
 
@@ -339,55 +278,37 @@ def run_tests(mute_jamid, output_to_files):
             test_result_code = 1
     sys.exit(test_result_code)
 
+
 def parse_args():
     ap = argparse.ArgumentParser(description="Client qt build tool")
     subparser = ap.add_subparsers(dest="subparser_name")
 
-    ap.add_argument(
-        '-b', '--build', action='store_true',
-        help='Build Qt Client')
     ap.add_argument(
         '-a', '--arch', default='x64',
         help='Sets the build architecture')
     ap.add_argument(
-        '-wt', '--withtest', action='store_true',
-        help='Build Qt Client Test')
+        '-t', '--runtests', action='store_true',
+        help='Build and run tests')
     ap.add_argument(
-        '-ot', '--onlytest', action='store_true',
-        help='Build Only Qt Client Test')
-    ap.add_argument(
-        '-d', '--deps', action='store_true',
-        help='Build Deps for Qt Client')
-    ap.add_argument(
-        '-bt', '--beta', action='store_true',
+        '-b', '--beta', action='store_true',
         help='Build Qt Client in Beta Config')
-    ap.add_argument(
-        '-c', '--releasecompile', action='store_true',
-        help='Build Qt Client in ReleaseCompile Config')
-    ap.add_argument(
-        '-s', '--sdk', default=win_sdk_default, type=str,
-        help='Use specified windows sdk version')
-    ap.add_argument(
-        '-t', '--toolset', default=win_toolset_default, type=str,
-        help='Use specified platform toolset version')
     ap.add_argument(
         '-q', '--qtver', default=qt_version_default,
         help='Sets the version of Qmake')
+    ap.add_argument(
+        '-m', '--mute', action='store_true', default=False,
+        help='Mute jamid logs')
+
+    subparser.add_parser('init')
+    subparser.add_parser('pack')
 
     run_test = subparser.add_parser('runtests')
     run_test.add_argument(
-        '-md', '--mutejamid', action='store_true', default=False,
-        help='Avoid jamid logs')
-    run_test.add_argument(
-        '-o', '--outputtofiles', action='store_true', default=False,
-        help='Output tests log into files')
+        '-l', '--logtests', action='store_true', default=False,
+        help='Output tests log to files')
 
     parsed_args = ap.parse_args()
 
-    if parsed_args.toolset:
-        if parsed_args.toolset[0] != 'v':
-            parsed_args.toolset = 'v' + parsed_args.toolset
-
     return parsed_args
 
 
@@ -402,35 +323,18 @@ def main():
 
     parsed_args = parse_args()
 
-    if int(getQtVersionNumber(parsed_args.qtver, QtVerison.Major)) < 6:
-        print('We currently only support Qt6')
+    if parsed_args.subparser_name == 'init':
+        init_submodules()
+        build_deps(parsed_args.arch)
+    elif parsed_args.subparser_name == 'pack':
+        print('Package generation is not yet implemented.')
         sys.exit(1)
-
-    test_building_type = TestBuilding.NoTests
-
-    if parsed_args.withtest:
-        test_building_type = TestBuilding.WithTests
-
-    if parsed_args.onlytest:
-        test_building_type = TestBuilding.OnlyTests
-
-    if parsed_args.subparser_name == 'runtests':
-        run_tests(parsed_args.mutejamid, parsed_args.outputtofiles)
-
-    if parsed_args.deps:
-        deps(parsed_args.arch, parsed_args.toolset, parsed_args.qtver)
-
-    if parsed_args.build:
-        build(parsed_args.arch, parsed_args.toolset, parsed_args.sdk,
-              'Release', jami_qt_project, parsed_args.qtver, test_building_type)
-
-    if parsed_args.beta:
-        build(parsed_args.arch, parsed_args.toolset, parsed_args.sdk,
-              'Beta', jami_qt_project, parsed_args.qtver, test_building_type)
-
-    if parsed_args.releasecompile:
-        build(parsed_args.arch, parsed_args.toolset, parsed_args.sdk,
-              'ReleaseCompile', jami_qt_project, parsed_args.qtver, test_building_type)
+    else:
+        config = ('Release', 'Beta')[parsed_args.beta]
+        build(parsed_args.arch, config,
+              qt_version_default, parsed_args.runtests)
+        if parsed_args.runtests:
+            run_tests(parsed_args.mutejamid, parsed_args.outputtofiles)
 
 
 if __name__ == '__main__':
diff --git a/src/mainapplication.cpp b/src/mainapplication.cpp
index c6b7ede9ac8c4e4f411c4e9c574b85aaf3642a48..076a824f0989eb6d11d4b99d553b87e9c3c52b83 100644
--- a/src/mainapplication.cpp
+++ b/src/mainapplication.cpp
@@ -49,7 +49,7 @@
 #include "dbuserrorhandler.h"
 #endif
 
-#if defined _MSC_VER && !COMPILE_ONLY
+#if defined _MSC_VER
 #include <gnutls/gnutls.h>
 #endif
 
@@ -181,7 +181,7 @@ MainApplication::init()
     loadTranslations();
     setApplicationFont();
 
-#if defined _MSC_VER && !COMPILE_ONLY
+#if defined _MSC_VER
     gnutls_global_init();
 #endif
 
diff --git a/tests/unittests/globaltestenvironment.h b/tests/unittests/globaltestenvironment.h
index 07fe0c33b223c202b52423eb217fdd7df34498b8..c1637c6ac6dd65e389cab0565db4d28d72378464 100644
--- a/tests/unittests/globaltestenvironment.h
+++ b/tests/unittests/globaltestenvironment.h
@@ -49,7 +49,7 @@ public:
         settingsManager.reset(new AppSettingsManager(nullptr));
         systemTray.reset(new SystemTray(settingsManager.get(), nullptr));
 
-#if defined _MSC_VER && !COMPILE_ONLY
+#if defined _MSC_VER
         gnutls_global_init();
 #endif