From 8259932f86c8c557088b1e5c3b7e1b0b17f107b2 Mon Sep 17 00:00:00 2001 From: Kenneth Geisshirt Date: Fri, 5 Jul 2024 11:08:48 +0200 Subject: [PATCH] Building for Windows using C++20 (#7841) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Building using C++20 on Windows * Building and testing on Linux with C++20 --------- Co-authored-by: Jørgen Edelbo --- CHANGELOG.md | 1 + CMakeLists.txt | 3 +++ evergreen/config.yml | 27 +++++++++++++++++++-------- src/external/bson/bson-decimal128.c | 4 ++-- src/external/bson/bson-iter.c | 2 +- src/realm/util/file.cpp | 25 ++++++++++++++++++++----- test/benchmark-common-tasks/main.cpp | 16 ++++++++-------- test/util/test_path.cpp | 2 +- 8 files changed, 55 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 35684661d9b..fee31ebeefe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ * Fixed `Table::remove_object_recursive` which wouldn't recursively follow links through a single `Mixed` property. This feature is exposed publicly on `Table` but no SDK currently uses it, so this is considered internal. ([#7829](https://github.com/realm/realm-core/issues/7829), likely since the introduction of Mixed) * Upload completion is now tracked in a multiprocess-compatible manner ([PR #7796](https://github.com/realm/realm-core/pull/7796)). * The local realm will assume the the client file ident of the fresh realm during a client reset. ([PR #7850](https://github.com/realm/realm-core/pull/7850)) +* Building using C++20 on Windows. ---------------------------------------------- diff --git a/CMakeLists.txt b/CMakeLists.txt index e2401e4d5ab..a693f1c8542 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -129,6 +129,9 @@ if(MSVC) # We use these in our AtomicSharedPtr implementation and it can't move # to atomic> because NotificationToken relies on movability. add_compile_options(/D_SILENCE_CXX20_OLD_SHARED_PTR_ATOMIC_SUPPORT_DEPRECATION_WARNING) + + # Enable __cplusplus macro + add_compile_options(/Zc:__cplusplus) else() add_compile_options(-Wall -Wextra -Wempty-body -Wparentheses -Wunknown-pragmas -Wunreachable-code -Wunused-parameter -Wno-missing-field-initializers) # TODO: Remove this when fixed diff --git a/evergreen/config.yml b/evergreen/config.yml index 62436af36ad..6022e4e5518 100644 --- a/evergreen/config.yml +++ b/evergreen/config.yml @@ -430,7 +430,7 @@ functions: script: |- if ls crash-*> /dev/null 2>&1; then echo "Found crash file" - #Rename the crash file and the realm file. + #Rename the crash file and the realm file. #If there is a crash, this will signal that something needs to be uploaded. mv crash-* realm-fuzzer-crash.txt mv fuzz-realm.realm fuzzer_realm.realm @@ -459,7 +459,7 @@ functions: bucket: mciuploads permissions: public-read content_type: application/x-binary - display_name: Realm File + display_name: Realm File optional: true - command: shell.exec @@ -515,7 +515,7 @@ functions: set -o verbose TOP_DIR=$(pwd) - + HANG_ANALYZER_PATH=$TOP_DIR/evergreen/hang_analyzer REQUIREMENTS_PATH=$HANG_ANALYZER_PATH/requirements.txt @@ -1166,7 +1166,7 @@ tasks: ./build/test/${cmake_build_type|Debug}-iphonesimulator/realm-combined-tests.app \ 'io.realm.CombinedTests' \ $TEST_RESULTS_FILE - + - name: generate-sync-corpus tags: [ "for_nightly_tests" ] exec_timeout_secs: 1800 @@ -1393,6 +1393,19 @@ buildvariants: - name: compile_test - name: lint +- name: ubuntu-cpp20 + display_name: "Ubuntu C++20" + run_on: ubuntu2404-arm64-large + expansions: + fetch_missing_dependencies: On + c_compiler: "/opt/clang+llvm/bin/clang" + cxx_compiler: "/opt/clang+llvm/bin/clang++" + clang_format: "/opt/clang+llvm/bin/clang-format" + extra_flags: -DCMAKE_CXX_STANDARD=20 + tasks: + - name: compile_test + - name: lint + - name: ubuntu-no-session-multiplexing display_name: "Ubuntu (Sync Multiplexing Disabled)" run_on: ubuntu2204-arm64-large @@ -1469,7 +1482,7 @@ buildvariants: fetch_missing_dependencies: On c_compiler: "/opt/clang+llvm/bin/clang" cxx_compiler: "/opt/clang+llvm/bin/clang++" - run_with_encryption: 1 + run_with_encryption: 1 enable_asan: On cmake_build_type: RelWithDebInfo tasks: @@ -1492,7 +1505,7 @@ buildvariants: cxx_compiler: "./clang_binaries/bin/clang++" python3: /opt/mongodbtoolchain/v3/bin/python3 tasks: - - name: compile_test_and_package + - name: compile_test_and_package - name: benchmarks - name: generate-sync-corpus @@ -1979,5 +1992,3 @@ buildvariants: # no_tests: On # tasks: # - name: compile_only - - diff --git a/src/external/bson/bson-decimal128.c b/src/external/bson/bson-decimal128.c index 827d1165ed7..5642e045ecf 100644 --- a/src/external/bson/bson-decimal128.c +++ b/src/external/bson/bson-decimal128.c @@ -374,7 +374,7 @@ _mul_64x64 (uint64_t left, /* IN */ * Returns: * The lowercased character. */ -char +static char _dec128_tolower (char c) { if (isupper (c)) { @@ -395,7 +395,7 @@ _dec128_tolower (char c) * Returns: * true if the strings are equal, false otherwise. */ -bool +static bool _dec128_istreq (const char *a, /* IN */ const char *b /* IN */) { diff --git a/src/external/bson/bson-iter.c b/src/external/bson/bson-iter.c index a71b2b59ee5..535dedefef2 100644 --- a/src/external/bson/bson-iter.c +++ b/src/external/bson/bson-iter.c @@ -631,7 +631,7 @@ _bson_iter_next_internal (bson_iter_t *iter, /* INOUT */ subtype = *(iter->raw + iter->d2); if (subtype == BSON_SUBTYPE_BINARY_DEPRECATED) { - int32_t binary_len; + uint32_t binary_len; if (l < 4) { iter->err_off = o; diff --git a/src/realm/util/file.cpp b/src/realm/util/file.cpp index fc3e823734f..3f059a0a9dd 100644 --- a/src/realm/util/file.cpp +++ b/src/realm/util/file.cpp @@ -128,7 +128,22 @@ struct WindowsFileHandleHolder { #endif #if REALM_HAVE_STD_FILESYSTEM +#if __cplusplus < 202002L using std::filesystem::u8path; +inline std::string path_to_string(const std::filesystem::path& path) +{ + return path.u8string(); +} +#else +inline std::string path_to_string(const std::filesystem::path& path) +{ + return reinterpret_cast(path.u8string().c_str()); +} +inline auto u8path(const std::string& str) +{ + return std::filesystem::path(reinterpret_cast(str.c_str())); +}; +#endif void throwIfCreateDirectoryError(std::error_code error, const std::string& path) { @@ -340,7 +355,7 @@ std::string make_temp_dir() } break; } - return path.u8string(); + return path_to_string(path); #else // POSIX.1-2008 version @@ -374,7 +389,7 @@ std::string make_temp_file(const char* prefix) throw SystemError(error, get_last_error_msg("GetTempFileName() failed: ", error)); } - return std::filesystem::path(buffer).u8string(); + return path_to_string(std::filesystem::path(buffer)); #else // POSIX.1-2008 version @@ -1573,7 +1588,7 @@ std::string File::get_path() const std::string File::resolve(const std::string& path, const std::string& base_dir) { #if REALM_HAVE_STD_FILESYSTEM - return (u8path(base_dir) / u8path(path)).lexically_normal().u8string(); + return path_to_string((u8path(base_dir) / u8path(path)).lexically_normal()); #else char dir_sep = '/'; std::string path_2 = path; @@ -1615,7 +1630,7 @@ std::string File::resolve(const std::string& path, const std::string& base_dir) std::string File::parent_dir(const std::string& path) { #if REALM_HAVE_STD_FILESYSTEM - return u8path(path).parent_path().u8string(); // Throws + return path_to_string(u8path(path).parent_path()); // Throws #else auto is_sep = [](char c) -> bool { return c == '/' || c == '\\'; @@ -1864,7 +1879,7 @@ bool DirScanner::next(std::string& name) const std::filesystem::directory_iterator end; if (m_iterator == end) return false; - name = m_iterator->path().filename().u8string(); + name = path_to_string(m_iterator->path().filename()); m_iterator++; return true; } diff --git a/test/benchmark-common-tasks/main.cpp b/test/benchmark-common-tasks/main.cpp index 53e82d56276..1218d509e89 100644 --- a/test/benchmark-common-tasks/main.cpp +++ b/test/benchmark-common-tasks/main.cpp @@ -581,7 +581,7 @@ template struct BenchmarkMixedCaseInsensitiveEqual : public BenchmarkWithType { using Base = BenchmarkWithType; using underlying_type = typename Type::underlying_type; - BenchmarkMixedCaseInsensitiveEqual() + BenchmarkMixedCaseInsensitiveEqual() : BenchmarkWithType() { BenchmarkWithType::set_name_with_prefix("QueryInsensitiveEqual"); @@ -610,7 +610,7 @@ template struct BenchmarkRangeForType : public BenchmarkWithType { using Base = BenchmarkWithType; using underlying_type = typename Type::underlying_type; - BenchmarkRangeForType() + BenchmarkRangeForType() : BenchmarkWithType() { BenchmarkWithType::set_name_with_prefix("QueryRange"); @@ -647,7 +647,7 @@ template struct BenchmarkCreateIndexForType : public BenchmarkWithType { using Base = BenchmarkWithType; using underlying_type = typename Type::underlying_type; - BenchmarkCreateIndexForType() + BenchmarkCreateIndexForType() : BenchmarkWithType() { BenchmarkWithType::set_name_with_prefix("CreateIndexFor"); @@ -669,7 +669,7 @@ template struct BenchmarkInsertToIndexForType : public BenchmarkWithType { using Base = BenchmarkWithType; using underlying_type = typename Type::underlying_type; - BenchmarkInsertToIndexForType() + BenchmarkInsertToIndexForType() : BenchmarkWithType() { BenchmarkWithType::set_name_with_prefix("InsertWithIndex"); @@ -706,7 +706,7 @@ template struct BenchmarkInsertPKToIndexForType : public BenchmarkWithType { using Base = BenchmarkWithType; using underlying_type = typename Type::underlying_type; - BenchmarkInsertPKToIndexForType() + BenchmarkInsertPKToIndexForType() : BenchmarkWithType() { BenchmarkWithType::set_name_with_prefix("InsertPK"); @@ -739,7 +739,7 @@ template struct BenchmarkEraseObjectForType : public BenchmarkWithType { using Base = BenchmarkWithType; using underlying_type = typename Type::underlying_type; - BenchmarkEraseObjectForType() + BenchmarkEraseObjectForType() : BenchmarkWithType() { BenchmarkWithType::set_name_with_prefix("EraseObject"); @@ -760,7 +760,7 @@ template struct BenchmarkParsedChainedOrEquality : public BenchmarkWithType { using Base = BenchmarkWithType; using underlying_type = typename Type::underlying_type; - BenchmarkParsedChainedOrEquality() + BenchmarkParsedChainedOrEquality() : BenchmarkWithType() { BenchmarkWithType::set_name_with_prefix(util::format("QueryChainedOrEquality_%1", NUM_CONDITIONS)); @@ -803,7 +803,7 @@ template struct BenchmarkParsedIn : public BenchmarkWithType { using Base = BenchmarkWithType; using underlying_type = typename Type::underlying_type; - BenchmarkParsedIn() + BenchmarkParsedIn() : BenchmarkWithType() { BenchmarkWithType::set_name_with_prefix(util::format("QueryParsedIN_%1", NUM_CONDITIONS)); diff --git a/test/util/test_path.cpp b/test/util/test_path.cpp index c7cfd26115b..24104ef7e79 100644 --- a/test/util/test_path.cpp +++ b/test/util/test_path.cpp @@ -134,7 +134,7 @@ bool initialize_test_path(int argc, const char* argv[]) } PathCchRemoveFileSpec(path, MAX_PATH); SetCurrentDirectory(path); - g_path_prefix = std::filesystem::path(path).u8string(); + g_path_prefix = std::string(reinterpret_cast(std::filesystem::path(path).u8string().c_str())); g_resource_path = g_path_prefix + "\\resources\\"; #else char executable[PATH_MAX];