diff --git a/CMakeLists.txt b/CMakeLists.txt
index d9a0829d8..a6a93e4a5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.15)
+cmake_minimum_required(VERSION 3.16)
 cmake_policy(SET CMP0076 NEW)
 cmake_policy(SET CMP0091 NEW)
 
@@ -12,7 +12,7 @@ project(Telegram
 )
 
 include(cmake/paths.cmake)
-include(cmake/force_include.cmake)
+include(cmake/options.cmake)
 include(cmake/init_target.cmake)
 include(cmake/generate_target.cmake)
 include(cmake/nice_target_sources.cmake)
diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt
index 10dd973c5..bfd5f4e13 100644
--- a/Telegram/CMakeLists.txt
+++ b/Telegram/CMakeLists.txt
@@ -1,6 +1,9 @@
 add_executable(Telegram WIN32 MACOSX_BUNDLE)
 init_target(Telegram)
 
+add_executable(Updater WIN32)
+init_target(Updater)
+
 add_subdirectory(lib_rpl)
 add_subdirectory(lib_crl)
 add_subdirectory(lib_base)
@@ -939,7 +942,7 @@ PRIVATE
 )
 nice_target_sources(Telegram ${res_loc} "${telegram_resources}")
 
-force_include(Telegram stdafx.h)
+target_precompile_headers(Telegram PRIVATE ${src_loc}/stdafx.h)
 
 if (WIN32)
     # message(${CMAKE_GENERATOR})
@@ -980,3 +983,14 @@ PRIVATE
     AL_LIBTYPE_STATIC
     AL_ALEXT_PROTOTYPES
 )
+
+add_dependencies(Telegram Updater)
+
+set(updater_sources
+PRIVATE
+    _other/updater.cpp
+    _other/updater.h
+    _other/updater_linux.cpp
+    _other/updater_osx.m
+)
+nice_target_sources(Updater ${src_loc} "${updater_sources}")
diff --git a/Telegram/cmake/lib_export.cmake b/Telegram/cmake/lib_export.cmake
index 293043392..6f9c3ebb1 100644
--- a/Telegram/cmake/lib_export.cmake
+++ b/Telegram/cmake/lib_export.cmake
@@ -27,7 +27,7 @@ PRIVATE
 )
 nice_target_sources(lib_export ${src_loc} "${lib_export_sources}")
 
-force_include(lib_export export/export_pch.h)
+target_precompile_headers(lib_export PRIVATE ${src_loc}/export/export_pch.h)
 
 target_include_directories(lib_export
 PUBLIC
diff --git a/Telegram/cmake/lib_mtproto.cmake b/Telegram/cmake/lib_mtproto.cmake
index 74878a42f..6ce8926ba 100644
--- a/Telegram/cmake/lib_mtproto.cmake
+++ b/Telegram/cmake/lib_mtproto.cmake
@@ -12,7 +12,7 @@ PRIVATE
 )
 nice_target_sources(lib_mtproto ${src_loc} "${lib_mtproto_sources}")
 
-force_include(lib_mtproto mtproto/mtp_pch.h)
+target_precompile_headers(lib_mtproto PRIVATE ${src_loc}/mtproto/mtp_pch.h)
 
 target_include_directories(lib_mtproto
 PUBLIC
diff --git a/Telegram/cmake/lib_tgvoip.cmake b/Telegram/cmake/lib_tgvoip.cmake
index d5fba61fa..16ff4853a 100644
--- a/Telegram/cmake/lib_tgvoip.cmake
+++ b/Telegram/cmake/lib_tgvoip.cmake
@@ -1,5 +1,5 @@
 add_library(lib_tgvoip OBJECT)
-init_target_no_ranges(lib_tgvoip)
+init_target(lib_tgvoip)
 
 set(tgvoip_loc ${third_party_loc}/libtgvoip)
 
diff --git a/Telegram/codegen b/Telegram/codegen
index 8e8d1de1a..dc530a1ce 160000
--- a/Telegram/codegen
+++ b/Telegram/codegen
@@ -1 +1 @@
-Subproject commit 8e8d1de1a1ad5fbc9db0ec797880b5c754be8be7
+Subproject commit dc530a1cecddf8291b7b67e71e455cef6b963e06
diff --git a/Telegram/lib_base b/Telegram/lib_base
index eae957873..c156e8eaf 160000
--- a/Telegram/lib_base
+++ b/Telegram/lib_base
@@ -1 +1 @@
-Subproject commit eae95787375e0dd399641abb5e94e40f5ef154e7
+Subproject commit c156e8eaf7600545024625ce182995e9305ef6ff
diff --git a/Telegram/lib_crl b/Telegram/lib_crl
index 5ea1a6d44..48bfce822 160000
--- a/Telegram/lib_crl
+++ b/Telegram/lib_crl
@@ -1 +1 @@
-Subproject commit 5ea1a6d4469ff6292f4a563958830d3104b42aef
+Subproject commit 48bfce822d5a3262e9b0643517a2a996125e1026
diff --git a/Telegram/lib_spellcheck b/Telegram/lib_spellcheck
index 01f028516..e4ac96670 160000
--- a/Telegram/lib_spellcheck
+++ b/Telegram/lib_spellcheck
@@ -1 +1 @@
-Subproject commit 01f028516bcb2041b6ad2aaba1bcd4d62bc32e90
+Subproject commit e4ac966708205159a696435021a7c1a6ccd71dae
diff --git a/Telegram/lib_storage b/Telegram/lib_storage
index 3f375807e..ffdc9cc7b 160000
--- a/Telegram/lib_storage
+++ b/Telegram/lib_storage
@@ -1 +1 @@
-Subproject commit 3f375807eacd3411dfe8644df7b0dc494536d3de
+Subproject commit ffdc9cc7b64e3d9502ae416cc362f3f2d327b8a8
diff --git a/Telegram/lib_ui b/Telegram/lib_ui
index 110a17089..b7af3b71a 160000
--- a/Telegram/lib_ui
+++ b/Telegram/lib_ui
@@ -1 +1 @@
-Subproject commit 110a17089a2b18e93edf77a0adf596df92e9def0
+Subproject commit b7af3b71a3f7ee93cb2ea70cdeb16a8a3ff06bce
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
index d3e9e057e..126657d2a 100644
--- a/cmake/CMakeLists.txt
+++ b/cmake/CMakeLists.txt
@@ -1,95 +1 @@
 add_subdirectory(external)
-
-add_library(with_ranges INTERFACE)
-
-if (WIN32)
-    target_compile_options(with_ranges
-    INTERFACE
-        /experimental:preprocessor # need for range-v3 see https://github.com/ericniebler/range-v3#supported-compilers
-        /wd5105 # needed for `/experimental:preprocessor`, suppressing C5105 "macro expansion producing 'defined' has undefined behavior"
-    )
-endif()
-
-add_library(common_no_ranges INTERFACE)
-
-target_compile_features(common_no_ranges
-INTERFACE
-    cxx_std_17
-)
-
-target_compile_definitions(common_no_ranges
-INTERFACE
-    UNICODE
-)
-
-if (WIN32)
-    target_compile_definitions(common_no_ranges
-    INTERFACE
-        WIN32
-        _WINDOWS
-        _UNICODE
-        UNICODE
-        _SCL_SECURE_NO_WARNINGS
-        _USING_V110_SDK71_
-        NOMINMAX
-    )
-    target_compile_options(common_no_ranges
-    INTERFACE
-        /permissive-
-        # /Qspectre
-        /W1
-        /WX
-        /MP     # Enable multi process build.
-        /EHsc   # Catch C++ exceptions only, extern C functions never throw a C++ exception.
-        /w14834 # [[nodiscard]]
-        /w15038 # wrong initialization order
-        /w14265 # class has virtual functions, but destructor is not virtual
-        /wd4068 # Disable "warning C4068: unknown pragma"
-        /wd5105 # needed for `/experimental:preprocessor`, suppressing C5105 "macro expansion producing 'defined' has undefined behavior"
-        /Zc:wchar_t- # don't tread wchar_t as builtin type
-    )
-    target_link_options(common_no_ranges
-    INTERFACE
-        /NODEFAULTLIB:LIBCMT
-    )
-    target_link_libraries(common_no_ranges
-    INTERFACE
-        winmm
-        imm32
-        ws2_32
-        kernel32
-        user32
-        gdi32
-        winspool
-        comdlg32
-        advapi32
-        shell32
-        ole32
-        oleaut32
-        uuid
-        odbc32
-        odbccp32
-        Shlwapi
-        Iphlpapi
-        Gdiplus
-        Strmiids
-        Netapi32
-        Userenv
-        Version
-        Dwmapi
-        Wtsapi32
-        UxTheme
-        DbgHelp
-        Rstrtmgr
-        Crypt32
-    )
-else()
-endif()
-
-add_library(common INTERFACE)
-
-target_link_libraries(common
-INTERFACE
-    common_no_ranges
-    with_ranges
-)
\ No newline at end of file
diff --git a/cmake/external/ranges/CMakeLists.txt b/cmake/external/ranges/CMakeLists.txt
index e2fcdf603..f6b3c8590 100644
--- a/cmake/external/ranges/CMakeLists.txt
+++ b/cmake/external/ranges/CMakeLists.txt
@@ -4,3 +4,11 @@ target_include_directories(external_ranges SYSTEM
 INTERFACE
     ${libs_loc}/range-v3/include
 )
+
+if (WIN32)
+    target_compile_options(external_ranges
+    INTERFACE
+        /experimental:preprocessor # need for range-v3 see https://github.com/ericniebler/range-v3#supported-compilers
+        /wd5105 # needed for `/experimental:preprocessor`, suppressing C5105 "macro expansion producing 'defined' has undefined behavior"
+    )
+endif()
\ No newline at end of file
diff --git a/cmake/init_target.cmake b/cmake/init_target.cmake
index 5753dee6a..08ae1e35c 100644
--- a/cmake/init_target.cmake
+++ b/cmake/init_target.cmake
@@ -4,22 +4,12 @@ function(init_target_folder target_name folder_name)
     endif()
 endfunction()
 
-function(init_target_no_ranges target_name) # init_target(my_target folder_name)
-    init_target_folder(${target_name} "${ARGV1}")
-    set_property(TARGET ${target_name} PROPERTY
-        MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
-    if (WIN32)
-        target_compile_options(${target_name}
-        INTERFACE
-            /W1
-        )
-    endif()
-    target_link_libraries(${target_name} PUBLIC common_no_ranges)
-endfunction()
-
 function(init_target target_name) # init_target(my_target folder_name)
     init_target_folder(${target_name} "${ARGV1}")
-    init_target_no_ranges(${target_name})
-    target_link_libraries(${target_name} PUBLIC common)
+    if (WIN32)
+        set_property(TARGET ${target_name} PROPERTY
+            MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
+    endif()
+    target_link_libraries(${target_name} PUBLIC common_options)
 endfunction()
 
diff --git a/cmake/nice_target_sources.cmake b/cmake/nice_target_sources.cmake
index 85166bc46..3026b0d7f 100644
--- a/cmake/nice_target_sources.cmake
+++ b/cmake/nice_target_sources.cmake
@@ -14,7 +14,7 @@ function(nice_target_sources target_name src_loc list)
             if (${file} MATCHES "(^|/)win/" OR ${file} MATCHES "(^|/)winrc/" OR ${file} MATCHES "(^|/)windows/" OR ${file} MATCHES "[_\\/]win\\.")
                 list(APPEND not_mac_sources ${full_name})
                 list(APPEND not_linux_sources ${full_name})
-            elseif (${file} MATCHES "(^|/)mac/" OR ${file} MATCHES "(^|/)darwin/" OR ${file} MATCHES "[_\\/]mac\\.")
+            elseif (${file} MATCHES "(^|/)mac/" OR ${file} MATCHES "(^|/)darwin/" OR ${file} MATCHES "(^|/)osx/" OR ${file} MATCHES "[_\\/]mac\\." OR ${file} MATCHES "[_\\/]darwin\\." OR ${file} MATCHES "[_\\/]osx\\.")
                 list(APPEND not_win_sources ${full_name})
                 list(APPEND not_linux_sources ${full_name})
             elseif (${file} MATCHES "(^|/)linux/" OR ${file} MATCHES "[_\\/]linux\\.")
diff --git a/cmake/options.cmake b/cmake/options.cmake
new file mode 100644
index 000000000..aab86150d
--- /dev/null
+++ b/cmake/options.cmake
@@ -0,0 +1,16 @@
+add_library(common_options INTERFACE)
+
+target_compile_features(common_options
+INTERFACE
+    cxx_std_17
+)
+
+target_compile_definitions(common_options
+INTERFACE
+    UNICODE
+)
+
+if (WIN32)
+    include(cmake/options_win.cmake)
+else()
+endif()
diff --git a/cmake/options_win.cmake b/cmake/options_win.cmake
new file mode 100644
index 000000000..570e9e644
--- /dev/null
+++ b/cmake/options_win.cmake
@@ -0,0 +1,61 @@
+target_compile_definitions(common_options
+INTERFACE
+    WIN32
+    _WINDOWS
+    _UNICODE
+    UNICODE
+    _SCL_SECURE_NO_WARNINGS
+    _USING_V110_SDK71_
+    NOMINMAX
+)
+target_compile_options(common_options
+INTERFACE
+    /permissive-
+    # /Qspectre
+    /W1
+    /WX
+    /MP     # Enable multi process build.
+    /EHsc   # Catch C++ exceptions only, extern C functions never throw a C++ exception.
+    /w14834 # [[nodiscard]]
+    /w15038 # wrong initialization order
+    /w14265 # class has virtual functions, but destructor is not virtual
+    /wd4068 # Disable "warning C4068: unknown pragma"
+    /Zc:wchar_t- # don't tread wchar_t as builtin type
+)
+
+target_link_options(common_options
+INTERFACE
+    /NODEFAULTLIB:LIBCMT
+)
+
+target_link_libraries(common_options
+INTERFACE
+    winmm
+    imm32
+    ws2_32
+    kernel32
+    user32
+    gdi32
+    winspool
+    comdlg32
+    advapi32
+    shell32
+    ole32
+    oleaut32
+    uuid
+    odbc32
+    odbccp32
+    Shlwapi
+    Iphlpapi
+    Gdiplus
+    Strmiids
+    Netapi32
+    Userenv
+    Version
+    Dwmapi
+    Wtsapi32
+    UxTheme
+    DbgHelp
+    Rstrtmgr
+    Crypt32
+)