From 76dd632ec5403574d7b6211f62bff02c4ff444d5 Mon Sep 17 00:00:00 2001
From: Osyotr <Osyotr@users.noreply.github.com>
Date: Sun, 7 Apr 2024 01:50:34 +0300
Subject: [PATCH] Devendor some thridparty deps (#7836)

* Link with Qt6::Network on windows
* Make find_program(BASH) REQUIRED to prevent build-time errors
* Link more targets explicitly to pickup transitive dependencies
* Don't add unsupported flags on MSVC
  Drive-by: use add_compile_options instead of add_definitions to set -fno-omit-frame-pointer
* Move find_package(gflags) out of 3party
  GLOBAL flag for find_package has been added in CMake 3.24
* Don't hardcode paths to 3party/utfcpp
* Use system expat explicitly if needed
* Use system jansson explicitly if needed
* Use find_package(ZLIB) to find zlib
* Don't use vendored Freetype, ICU and HarfBuzz when WITH_SYSTEM_PROVIDED_3PARTY is set
* Find pugixml explicitly
* Fix typo in target name
* Update utfcpp include path
* Let CMake handle /DEBUG flag for MSVC

Signed-off-by: Osyotr <Osyotr@users.noreply.github.com>
---
 3party/CMakeLists.txt                         | 24 +++++++------
 3party/utf8cpp/include/utf8cpp                |  1 -
 CMakeLists.txt                                | 35 ++++++++++++++-----
 base/CMakeLists.txt                           |  1 +
 base/internal/message.cpp                     |  2 +-
 base/string_utils.hpp                         |  2 +-
 cmake/OmimConfig.cmake                        |  2 +-
 coding/CMakeLists.txt                         |  4 +--
 .../string_utf8_multilang_tests.cpp           |  2 +-
 coding/internal/xmlparser.hpp                 |  2 ++
 cppjansson/CMakeLists.txt                     |  4 ++-
 drape/CMakeLists.txt                          |  2 +-
 ge0/CMakeLists.txt                            |  8 +++++
 generator/CMakeLists.txt                      |  2 +-
 generator/pygen/CMakeLists.txt                |  4 +--
 indexer/search_string_utils.cpp               |  2 +-
 kml/pykmlib/CMakeLists.txt                    |  2 +-
 platform/CMakeLists.txt                       |  5 +--
 routing/CMakeLists.txt                        |  1 +
 routing/routing_quality/api/CMakeLists.txt    |  5 ++-
 routing_common/CMakeLists.txt                 |  6 ++++
 search/pysearch/CMakeLists.txt                |  2 +-
 shaders/CMakeLists.txt                        |  2 +-
 track_generator/CMakeLists.txt                |  2 +-
 tracking/CMakeLists.txt                       | 11 ++++++
 traffic/pytraffic/CMakeLists.txt              |  2 +-
 transit/CMakeLists.txt                        |  9 ++++-
 xcode/common.xcconfig                         |  2 +-
 28 files changed, 103 insertions(+), 43 deletions(-)
 delete mode 120000 3party/utf8cpp/include/utf8cpp

diff --git a/3party/CMakeLists.txt b/3party/CMakeLists.txt
index 7007dcf323..d4996e302d 100644
--- a/3party/CMakeLists.txt
+++ b/3party/CMakeLists.txt
@@ -2,10 +2,7 @@
 # Compatibility with CMake < 3.5 will be removed from a future version of CMake.
 set(CMAKE_WARN_DEPRECATED OFF CACHE BOOL "" FORCE)
 
-if (WITH_SYSTEM_PROVIDED_3PARTY)
-  set(GFLAGS_USE_TARGET_NAMESPACE ON)
-  find_package(gflags REQUIRED GLOBAL)
-else()
+if (NOT WITH_SYSTEM_PROVIDED_3PARTY)
   # Suppress "Policy CMP0077 is not set: option() honors normal variables"
   # for the freetype, expat and jansson options.
   set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
@@ -25,6 +22,7 @@ else()
   set(EXPAT_DTD OFF)
   set(EXPAT_NS ON)
   add_subdirectory(expat/expat)
+  add_library(expat::expat ALIAS expat)
 
   # Configure Jansson library.
   set(JANSSON_BUILD_DOCS OFF)
@@ -34,6 +32,7 @@ else()
   set(JANSSON_WITHOUT_TESTS ON)
   add_subdirectory(jansson/jansson/)
   target_include_directories(jansson INTERFACE "${PROJECT_BINARY_DIR}/3party/jansson/jansson/include")
+  add_library(jansson::jansson ALIAS jansson)
 
   # Add gflags library.
   add_subdirectory(gflags)
@@ -44,17 +43,20 @@ else()
 
   # Add protobuf library.
   add_subdirectory(protobuf)
+
+  if (NOT PLATFORM_LINUX)
+    add_subdirectory(freetype)
+    add_subdirectory(icu)
+    add_subdirectory(harfbuzz)
+  endif()
+
+  add_library(utf8cpp INTERFACE)
+  add_library(utf8cpp::utf8cpp ALIAS utf8cpp)
+  target_include_directories(utf8cpp INTERFACE "${OMIM_ROOT}/3party/utfcpp/source")
 endif()
 
 add_subdirectory(agg)
 add_subdirectory(bsdiff-courgette)
-
-if (NOT PLATFORM_LINUX)
-  add_subdirectory(freetype)
-  add_subdirectory(icu)
-  add_subdirectory(harfbuzz)
-endif()
-
 add_subdirectory(liboauthcpp)
 add_subdirectory(minizip)
 add_subdirectory(open-location-code)
diff --git a/3party/utf8cpp/include/utf8cpp b/3party/utf8cpp/include/utf8cpp
deleted file mode 120000
index 43119b90b3..0000000000
--- a/3party/utf8cpp/include/utf8cpp
+++ /dev/null
@@ -1 +0,0 @@
-../../utfcpp/source
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 71ecbe2e28..602c0d81a3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -103,7 +103,12 @@ if (NOT CMAKE_BUILD_TYPE)
 endif()
 
 # Global compile options for all configurations.
-add_compile_options(-ffast-math)
+if (MSVC)
+  add_compile_options(/utf-8)
+  add_link_options(/INCREMENTAL:NO)
+else()
+  add_compile_options(-ffast-math)
+endif()
 
 if (PLATFORM_WIN)
   add_definitions(
@@ -114,10 +119,15 @@ endif()
 
 # Built-in CMake configurations: Debug, Release, RelWithDebInfo, MinSizeRel
 if (${CMAKE_BUILD_TYPE} STREQUAL "Debug")
-  add_definitions(-DDEBUG -fno-omit-frame-pointer)
+  add_definitions(-DDEBUG)
+  if (NOT MSVC)
+    add_compile_options(-fno-omit-frame-pointer)
+  endif()
 elseif (${CMAKE_BUILD_TYPE} MATCHES "Rel")
   add_definitions(-DRELEASE)
-  add_compile_options(-Ofast)  # Also enables -ffast-math
+  if (NOT MSVC)
+    add_compile_options(-Ofast)  # Also enables -ffast-math
+  endif()
 else()
   message(FATAL_ERROR "Unknown build type: " ${CMAKE_BUILD_TYPE})
 endif()
@@ -262,11 +272,6 @@ if (NOT PLATFORM_IPHONE AND NOT PLATFORM_ANDROID)
   find_package(Qt6 COMPONENTS REQUIRED ${qt_components} PATHS $ENV{QT_PATH} /opt/homebrew/opt/qt@6 /usr/local/opt/qt@6 /usr/lib/x86_64-linux-gnu/qt6)
 endif()
 
-find_library(LIBZ NAMES z)
-if (LIBZ STREQUAL "LIBZ-NOTFOUND")
-  message(FATAL_ERROR "Failed to find libz library.")
-endif()
-
 # To allow #include "base/file_name.hpp" in all sources.
 include_directories(${CMAKE_HOME_DIRECTORY})
 
@@ -302,12 +307,24 @@ if (USE_PCH)
 endif()
 
 # Should be on the root level, not in 3party, so tests can get these dependencies.
-if (PLATFORM_LINUX)
+if (PLATFORM_LINUX OR PLATFORM_WIN)
   find_package(ICU COMPONENTS uc i18n data REQUIRED)
   find_package(Freetype REQUIRED)
   find_package(harfbuzz REQUIRED)
 endif()
 
+if (WITH_SYSTEM_PROVIDED_3PARTY)
+  set(GFLAGS_USE_TARGET_NAMESPACE ON)
+  find_package(gflags REQUIRED)
+
+  find_package(expat CONFIG REQUIRED)
+  find_package(jansson CONFIG REQUIRED)
+  find_package(pugixml REQUIRED)
+  find_package(utf8cpp REQUIRED)
+endif()
+
+find_package(ZLIB REQUIRED)
+
 # Include 3party dependencies.
 add_subdirectory(3party)
 
diff --git a/base/CMakeLists.txt b/base/CMakeLists.txt
index 69e16cc18c..b2c0f07ed8 100644
--- a/base/CMakeLists.txt
+++ b/base/CMakeLists.txt
@@ -109,6 +109,7 @@ omim_add_library(${PROJECT_NAME} ${SRC})
 set(THREADS_PREFER_PTHREAD_FLAG ON)
 find_package(Threads REQUIRED)
 target_link_libraries(${PROJECT_NAME} INTERFACE Threads::Threads)
+target_link_libraries(${PROJECT_NAME} PUBLIC utf8cpp::utf8cpp)
 
 if (NOT WITH_SYSTEM_PROVIDED_3PARTY)
   target_include_directories(${PROJECT_NAME} PRIVATE "${OMIM_ROOT}/3party/fast_double_parser/include")
diff --git a/base/internal/message.cpp b/base/internal/message.cpp
index 5b656e1b73..d58cfe62c7 100644
--- a/base/internal/message.cpp
+++ b/base/internal/message.cpp
@@ -2,7 +2,7 @@
 
 #include "std/target_os.hpp"
 
-#include <utf8cpp/utf8/unchecked.h>
+#include <utf8/unchecked.h>
 
 std::string DebugPrint(std::string const & t)
 {
diff --git a/base/string_utils.hpp b/base/string_utils.hpp
index 211fd930c5..178576a0f1 100644
--- a/base/string_utils.hpp
+++ b/base/string_utils.hpp
@@ -18,7 +18,7 @@
 #include <string_view>
 #include <type_traits>
 
-#include <utf8cpp/utf8/unchecked.h>
+#include <utf8/unchecked.h>
 
 /// All methods work with strings in utf-8 format
 namespace strings
diff --git a/cmake/OmimConfig.cmake b/cmake/OmimConfig.cmake
index d0aac124ed..a8e04c1de9 100644
--- a/cmake/OmimConfig.cmake
+++ b/cmake/OmimConfig.cmake
@@ -3,6 +3,6 @@ set(OMIM_WARNING_FLAGS
   $<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wall -Wextra -Wpedantic>
   $<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wno-unused-parameter>  # We have a lot of functions with unused parameters
 )
-set(3PARTY_INCLUDE_DIRS "${OMIM_ROOT}/3party/boost" "${OMIM_ROOT}/3party/utf8cpp/include")
+set(3PARTY_INCLUDE_DIRS "${OMIM_ROOT}/3party/boost")
 set(OMIM_DATA_DIR "${OMIM_ROOT}/data")
 set(OMIM_USER_RESOURCES_DIR "${OMIM_ROOT}/data")
diff --git a/coding/CMakeLists.txt b/coding/CMakeLists.txt
index b4d945351e..b9972aa0a5 100644
--- a/coding/CMakeLists.txt
+++ b/coding/CMakeLists.txt
@@ -95,14 +95,14 @@ omim_add_library(${PROJECT_NAME} ${SRC})
 
 target_link_libraries(${PROJECT_NAME}
   base
-  expat
+  expat::expat
   cppjansson
   succinct
   ICU::uc
   ICU::i18n # For transliteration.
   oauthcpp  # For base64_encode and base64_decode
   minizip
-  ${LIBZ}
+  ZLIB::ZLIB
 )
 
 omim_add_test_subdirectory(coding_tests)
diff --git a/coding/coding_tests/string_utf8_multilang_tests.cpp b/coding/coding_tests/string_utf8_multilang_tests.cpp
index a1d963f258..12d1945a94 100644
--- a/coding/coding_tests/string_utf8_multilang_tests.cpp
+++ b/coding/coding_tests/string_utf8_multilang_tests.cpp
@@ -4,7 +4,7 @@
 
 #include "base/control_flow.hpp"
 
-#include <utf8cpp/utf8.h>
+#include <utf8.h>
 
 #include <cstddef>
 #include <string>
diff --git a/coding/internal/xmlparser.hpp b/coding/internal/xmlparser.hpp
index f270cd6de1..0d8ca68b05 100644
--- a/coding/internal/xmlparser.hpp
+++ b/coding/internal/xmlparser.hpp
@@ -12,7 +12,9 @@
 #include <sstream>
 #include <string>
 
+#ifndef XML_STATIC
 #define XML_STATIC
+#endif
 #include <expat.h>
 
 #if defined(__clang__)
diff --git a/cppjansson/CMakeLists.txt b/cppjansson/CMakeLists.txt
index 7fc9b37fa0..3996d3c657 100644
--- a/cppjansson/CMakeLists.txt
+++ b/cppjansson/CMakeLists.txt
@@ -7,5 +7,7 @@ set(SRC
 )
 omim_add_library(${PROJECT_NAME} ${SRC})
 target_link_libraries(${PROJECT_NAME}
-  jansson
+  PUBLIC
+    base
+    jansson::jansson
 )
diff --git a/drape/CMakeLists.txt b/drape/CMakeLists.txt
index 061decbaed..9720c8d5eb 100644
--- a/drape/CMakeLists.txt
+++ b/drape/CMakeLists.txt
@@ -175,7 +175,7 @@ target_link_libraries(${PROJECT_NAME}
   sdf_image
   harfbuzz
   ICU::i18n
-  expat
+  expat::expat
   $<$<BOOL:${PLATFORM_MAC}>:-framework\ OpenGL>
   $<$<BOOL:${PLATFORM_LINUX}>:OpenGL::GL>
 )
diff --git a/ge0/CMakeLists.txt b/ge0/CMakeLists.txt
index a652851899..c8c996004e 100644
--- a/ge0/CMakeLists.txt
+++ b/ge0/CMakeLists.txt
@@ -10,5 +10,13 @@ set(SRC
 )
 
 omim_add_library(${PROJECT_NAME} ${SRC})
+target_link_libraries(${PROJECT_NAME}
+  PUBLIC
+    coding
+
+  PRIVATE
+    base
+    geometry
+)
 
 omim_add_test_subdirectory(ge0_tests)
diff --git a/generator/CMakeLists.txt b/generator/CMakeLists.txt
index a669096cd0..5beba476f9 100644
--- a/generator/CMakeLists.txt
+++ b/generator/CMakeLists.txt
@@ -248,7 +248,7 @@ target_link_libraries(${PROJECT_NAME}
   descriptions
   indexer
   cppjansson
-  expat
+  expat::expat
   tess2
   $<$<BOOL:CMAKE_DL_LIBS>:${CMAKE_DL_LIBS}>  # dladdr from boost::stacktrace
 )
diff --git a/generator/pygen/CMakeLists.txt b/generator/pygen/CMakeLists.txt
index d8142a7fc9..3583d44913 100644
--- a/generator/pygen/CMakeLists.txt
+++ b/generator/pygen/CMakeLists.txt
@@ -28,7 +28,7 @@ omim_link_libraries(
   base
   opening_hours
   freetype
-  expat
+  expat::expat
   ICU::i18n
   cppjansson
   protobuf
@@ -40,7 +40,7 @@ omim_link_libraries(
   oauthcpp
   sqlite3
   ${CMAKE_DL_LIBS}
-  ${LIBZ}
+  ZLIB::ZLIB
   ${Boost_LIBRARIES}
 )
 
diff --git a/indexer/search_string_utils.cpp b/indexer/search_string_utils.cpp
index 9cbc306ab1..09835ae800 100644
--- a/indexer/search_string_utils.cpp
+++ b/indexer/search_string_utils.cpp
@@ -12,7 +12,7 @@
 #include <queue>
 #include <vector>
 
-#include <utf8cpp/utf8/unchecked.h>
+#include <utf8/unchecked.h>
 
 namespace search
 {
diff --git a/kml/pykmlib/CMakeLists.txt b/kml/pykmlib/CMakeLists.txt
index b9dc934b5f..52f2bfb193 100644
--- a/kml/pykmlib/CMakeLists.txt
+++ b/kml/pykmlib/CMakeLists.txt
@@ -24,7 +24,7 @@ omim_link_libraries(
   oauthcpp
   protobuf
   pugixml
-  expat
+  expat::expat
   succinct
 )
 
diff --git a/platform/CMakeLists.txt b/platform/CMakeLists.txt
index 374d916871..44ef48e9fa 100644
--- a/platform/CMakeLists.txt
+++ b/platform/CMakeLists.txt
@@ -101,7 +101,7 @@ elseif(${PLATFORM_ANDROID})
   )
 else() # neither iPhone nor Android
   # Find bash first, on Windows it can be either in Git or in WSL
-  find_program(BASH bash)
+  find_program(BASH bash REQUIRED)
   # Generate version header file.
   execute_process(COMMAND "${BASH}" tools/unix/version.sh qt_version
     WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
@@ -183,7 +183,7 @@ if (APPLE)
   target_compile_options(${PROJECT_NAME} PRIVATE "-fobjc-arc")
 endif()
 
-if (PLATFORM_LINUX)
+if (PLATFORM_LINUX OR PLATFORM_WIN)
   set_target_properties(${PROJECT_NAME} PROPERTIES AUTOMOC ON)
 endif()
 
@@ -192,6 +192,7 @@ target_link_libraries(${PROJECT_NAME}
   coding
   $<$<BOOL:${PLATFORM_DESKTOP}>:Qt6::Core>
   $<$<BOOL:${PLATFORM_LINUX}>:Qt6::Network>
+  $<$<BOOL:${PLATFORM_WIN}>:Qt6::Network>
   $<$<BOOL:${QT_POSITIONING}>:Qt6::Positioning>
   $<$<BOOL:${PLATFORM_MAC}>:
     -framework\ Foundation
diff --git a/routing/CMakeLists.txt b/routing/CMakeLists.txt
index 5dd2df78d0..8954ec70f9 100644
--- a/routing/CMakeLists.txt
+++ b/routing/CMakeLists.txt
@@ -185,6 +185,7 @@ set(SRC
 omim_add_library(${PROJECT_NAME} ${SRC})
 
 target_link_libraries(${PROJECT_NAME}
+  base
   routing_common
   platform
   traffic
diff --git a/routing/routing_quality/api/CMakeLists.txt b/routing/routing_quality/api/CMakeLists.txt
index 79b9b473bb..772ca00f60 100644
--- a/routing/routing_quality/api/CMakeLists.txt
+++ b/routing/routing_quality/api/CMakeLists.txt
@@ -15,5 +15,8 @@ set(SRC
 omim_add_library(${PROJECT_NAME} ${SRC})
 
 target_link_libraries(${PROJECT_NAME}
-  jansson  # serdes_json.hpp is in coding
+  PUBLIC
+    coding
+    geometry
+    routing
 )
diff --git a/routing_common/CMakeLists.txt b/routing_common/CMakeLists.txt
index 5d11fdb427..f03636b2d7 100644
--- a/routing_common/CMakeLists.txt
+++ b/routing_common/CMakeLists.txt
@@ -16,5 +16,11 @@ set(SRC
 )
 
 omim_add_library(${PROJECT_NAME} ${SRC})
+target_link_libraries(${PROJECT_NAME}
+  PUBLIC
+    base
+    indexer
+    platform
+)
 
 omim_add_test_subdirectory(routing_common_tests)
diff --git a/search/pysearch/CMakeLists.txt b/search/pysearch/CMakeLists.txt
index afa2e0d0f7..38badf2900 100644
--- a/search/pysearch/CMakeLists.txt
+++ b/search/pysearch/CMakeLists.txt
@@ -32,7 +32,7 @@ omim_link_libraries(
   pugixml
   succinct
   ${Boost_LIBRARIES}
-  ${LIBZ}
+  ZLIB::ZLIB
 )
 
 link_qt5_core(${PROJECT_NAME})
diff --git a/shaders/CMakeLists.txt b/shaders/CMakeLists.txt
index 24680dfef3..11da795e91 100644
--- a/shaders/CMakeLists.txt
+++ b/shaders/CMakeLists.txt
@@ -143,7 +143,7 @@ if (PLATFORM_IPHONE)
 endif()
 
 # Do not include glm's CMakeLists.txt, because it's outdated and not necessary.
-target_include_directories(${PROJECT_NAME} PUBLIC ${OMIM_ROOT}/3party/glm ${OMIM_ROOT}/3party/utf8cpp/include)
+target_include_directories(${PROJECT_NAME} PUBLIC "${OMIM_ROOT}/3party/glm")
 
 target_link_libraries(${PROJECT_NAME} drape)
 
diff --git a/track_generator/CMakeLists.txt b/track_generator/CMakeLists.txt
index e0d2af7f33..8b387b0520 100644
--- a/track_generator/CMakeLists.txt
+++ b/track_generator/CMakeLists.txt
@@ -13,6 +13,6 @@ target_link_libraries(${PROJECT_NAME}
   routing
   kml
   coding
-  expat
+  expat::expat
   gflags::gflags
 )
diff --git a/tracking/CMakeLists.txt b/tracking/CMakeLists.txt
index 75b2fd859b..335f6d899b 100644
--- a/tracking/CMakeLists.txt
+++ b/tracking/CMakeLists.txt
@@ -19,6 +19,17 @@ set(
 )
 
 omim_add_library(${PROJECT_NAME} ${SRC})
+target_link_libraries(${PROJECT_NAME}
+  PUBLIC
+    routing
+    traffic
+
+  PRIVATE
+    base
+    coding
+    geometry
+    platform
+)
 
 omim_add_test_subdirectory(tracking_tests)
 
diff --git a/traffic/pytraffic/CMakeLists.txt b/traffic/pytraffic/CMakeLists.txt
index c51e2d52aa..0dd0c16d96 100644
--- a/traffic/pytraffic/CMakeLists.txt
+++ b/traffic/pytraffic/CMakeLists.txt
@@ -44,7 +44,7 @@ omim_link_libraries(
   succinct
   ICU::i18n
   ${Boost_LIBRARIES}
-  ${LIBZ}
+  ZLIB::ZLIB
 )
 
 set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "")
diff --git a/transit/CMakeLists.txt b/transit/CMakeLists.txt
index 8eebc2b7b2..2a7067ddcf 100644
--- a/transit/CMakeLists.txt
+++ b/transit/CMakeLists.txt
@@ -20,7 +20,14 @@ set(SRC
 
 omim_add_library(${PROJECT_NAME} ${SRC})
 
-target_link_libraries(${PROJECT_NAME} PUBLIC jansson)
+target_link_libraries(${PROJECT_NAME}
+  PUBLIC
+    base
+    coding
+    cppjansson
+    geometry
+    indexer
+)
 
 if (PLATFORM_DESKTOP)
     add_subdirectory(world_feed)
diff --git a/xcode/common.xcconfig b/xcode/common.xcconfig
index 722a8b6337..95ba151e16 100644
--- a/xcode/common.xcconfig
+++ b/xcode/common.xcconfig
@@ -5,7 +5,7 @@ QT_PATH[arch=arm64] = /opt/homebrew/opt/qt@6
 BOOST_ROOT = $(OMIM_ROOT)/3party/boost
 
 // jansson is included in many libs, and is also used in headers (leaks to other libs)
-HEADER_SEARCH_PATHS = $(inherited) $(OMIM_ROOT) $(BOOST_ROOT) $(OMIM_ROOT)/3party/jansson $(OMIM_ROOT)/3party/jansson/jansson/src $(OMIM_ROOT)/3party/utf8cpp/include
+HEADER_SEARCH_PATHS = $(inherited) $(OMIM_ROOT) $(BOOST_ROOT) $(OMIM_ROOT)/3party/jansson $(OMIM_ROOT)/3party/jansson/jansson/src $(OMIM_ROOT)/3party/utfcpp/source
 FRAMEWORK_SEARCH_PATHS[sdk=macosx*] = $(QT_PATH)/lib
 
 // Deployment target