[Bug]: Compile break for chrono timepoint formatting for macOS target < 13.3 and Xcode 15.3
wAuner opened this issue · comments
Describe the issue
Problem:
With the latest version of Xcode 15.3 it is no longer possible to use chrono timpoints in a test assertion, if the build target is lower than macOS 13.3. With Xcode 15.0.1 (and possibly later) this worked.
The macOS SDK made the std::to_chars
function available with macOS 13.3, which seems to be involved when formatting the timepoints for printing.
Before that, Google Test maybe used a workaround for formatting that's no longer necessary for newer targets? This workaround is still needed for older deployment targets.
Steps to reproduce the problem
I've created an example project here. The build breaks with Xcode 15.3 when the deployment target is set below 13.3, which wasn't a problem with Xcode 15.0.1.
CMakeLists.txt
cmake_minimum_required(VERSION 3.14)
# build fails if deployment target is set below 13.3
set(CMAKE_OSX_DEPLOYMENT_TARGET "14.0")
set(CMAKE_CXX_STANDARD 20)
project(gtest_issue)
include(FetchContent)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/5197b1a8e6a1ef9f214f4aa537b0be17cbf91946.zip # latest commit
# URL https://github.com/google/googletest/archive/f8d7d77c06936315286eb55f8de22cd23c188571.zip # 1.14 release
)
FetchContent_MakeAvailable(googletest)
enable_testing()
add_executable(gtest_issue macostest.cpp)
target_link_libraries(gtest_issue gtest_main)
include(GoogleTest)
gtest_discover_tests(gtest_issue)
#include <gtest/gtest.h>
#include <chrono>
TEST(ChronoTest, CompileBreakBelowMacOS133) {
auto t1 = std::chrono::system_clock::now();
ASSERT_EQ(t1, t1);
}
TEST(ChronoTest, Success) {
auto t1 = std::chrono::system_clock::now();
ASSERT_EQ(t1.time_since_epoch().count(), t1.time_since_epoch().count());
}
The deployment target of the mach-o can be verified via otool -l gtest_issue | grep -A 4 LC_BUILD_VERSION
What version of GoogleTest are you using?
latest commit 5197b1a8e6a1ef9f214f4aa537b0be17cbf91946
What operating system and version are you using?
macOS 14.4.1
Xcode 15.3 (macOS SDK 14.4)
What compiler and version are you using?
clang --version
Apple clang version 15.0.0 (clang-1500.3.9.4)
Target: arm64-apple-darwin23.4.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
What build system are you using?
Xcode / cmake
Additional context
No response
I am encountering the same issue and have not found any fix apart from raising the deployment target for our test executor to 13.3.
While looking into this, I added @wAuner's CompileBreakBelowMacOS133
test to /googletest/test/googletest-printers-test.cc
to try to reproduce the issue in the repository itself. Interestingly, I am not able to reproduce it here. Neither with cmake/ninja, nor with bazel:
Ninja:
cmake .. -G Ninja -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 && ninja
Successfully compiles, the tests succeed, and otool
also shows the correct deployment target:
otool -l googletest/googletest-printers-test
...
cmd LC_BUILD_VERSION
cmdsize 32
platform 1
minos 11.0
sdk 14.5
ntools 1
tool 3
version 1053.12
...
Bazel:
bazelisk test '//googletest/test:gtest_all_test' --macos_minimum_os=11.0
Successfully compiles, the tests succeed, and otool
also shows the correct deployment target:
otool -l bazel-out/darwin_arm64-fastbuild/bin/googletest/test/gtest_all_test
...
cmd LC_BUILD_VERSION
cmdsize 32
platform 1
minos 11.0
sdk 14.5
ntools 1
tool 3
version 1053.12
...
I found a good workaround in case anybody else is running into this, too.
googletest provide a customization point test/internal/custom.
Adding the following googletest/include/gtest/internal/custom/gtest-printers.h
resolves the error for my use case and brings back the old behavior before the introduction of std::to_chars
:
#include "gtest/gtest-printers.h"
#ifdef _LIBCPP_AVAILABILITY_HAS_NO_TO_CHARS_FLOATING_POINT
namespace std {
inline void PrintTo(const ::std::chrono::time_point<std::chrono::system_clock>& value, ::std::ostream* os) {
::testing::internal::RawBytesPrinter::PrintValue(value, os);
}
} // namespace std
#endif
In case anyone else runs into this, I had to use
#include <Availability.h>
#if defined(MACOS) && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_13_3
instead of
#ifdef _LIBCPP_AVAILABILITY_HAS_NO_TO_CHARS_FLOATING_POINT
on Xcode 16 beta 6 in the solution suggested by @mjburghard above.