Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[date] Add tz recipe as a dependency #22294

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions recipes/date/all/conandata.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,18 @@ patches:
- patch_file: "patches/cmake-3.0.1.patch"
patch_description: "Disable string view to workaround clang 5 not having it"
patch_type: "portability"
- patch_file: "patches/load-tzdb-from-envvar-3.0.x.patch"
patch_description: "Allow TZDB to be loaded from the TZDATA environment variable"
patch_type: "portability"
patch_source: "https://github.com/HowardHinnant/date/pull/807"
"3.0.0":
- patch_file: "patches/cmake-3.0.0.patch"
patch_description: "Disable string view to workaround clang 5 not having it"
patch_type: "portability"
- patch_file: "patches/load-tzdb-from-envvar-3.0.x.patch"
patch_description: "Allow TZDB to be loaded from the TZDATA environment variable"
patch_type: "portability"
patch_source: "https://github.com/HowardHinnant/date/pull/807"
"2.4.1":
- patch_file: "patches/0001-fix-uwp.patch"
patch_description: "Fix Universal Windows Platform (UWP) unhandled exception support. See https://github.com/microsoft/vcpkg/pull/8151#issuecomment-531175393."
Expand All @@ -27,3 +35,7 @@ patches:
- patch_file: "patches/string_view.patch"
patch_description: "Disable string view to workaround clang 5 not having it"
patch_type: "portability"
- patch_file: "patches/load-tzdb-from-envvar-2.4.1.patch"
patch_description: "Allow TZDB to be loaded from the TZDATA environment variable"
patch_type: "portability"
patch_source: "https://github.com/HowardHinnant/date/pull/807"
26 changes: 21 additions & 5 deletions recipes/date/all/conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from conan.tools.cmake import CMake, CMakeToolchain, CMakeDeps, cmake_layout
from conan.tools.files import get, rmdir, apply_conandata_patches, export_conandata_patches, copy
from conan.tools.scm import Version
from conan.errors import ConanInvalidConfiguration

import os

Expand All @@ -22,14 +23,18 @@ class DateConan(ConanFile):
"shared": [True, False],
"fPIC": [True, False],
"header_only": [True, False],
"use_system_tz_db": [True, False],
"use_system_tz_db": [True, False, "deprecated"],
"with_tzdb": [False, "system", "download", "manual", "tz"],
"with_db_format": ["source", "binary"],
"use_tz_db_in_dot": [True, False],
}
default_options = {
"shared": False,
"fPIC": True,
"header_only": False,
"use_system_tz_db": False,
"with_tzdb": "tz",
"with_db_format": "source",
"use_tz_db_in_dot": False,
}

Expand All @@ -53,8 +58,10 @@ def layout(self):
cmake_layout(self, src_folder="src")

def requirements(self):
if not self.options.header_only and not self.options.use_system_tz_db:
if not self.options.header_only and not self.options.use_system_tz_db and self.options.with_tzdb == "download":
self.requires("libcurl/[>=7.78 <9]")
if self.options.with_tzdb == "tz":
self.requires("tz/2023c", options={"with_binary_db": self.options.with_db_format == "binary"})

def package_id(self):
if self.info.options.header_only:
Expand All @@ -63,16 +70,25 @@ def package_id(self):
def validate(self):
if self.settings.compiler.get_safe("cppstd"):
check_min_cppstd(self, 11)
if self.options.with_tzdb != "download" and self.options.use_tz_db_in_dot:
raise ConanInvalidConfiguration("'use_tz_db_in_dot=True' is only valid when 'with_tzdb=\"download\"'")
if self.options.use_system_tz_db and (self.options.with_tzdb not in [False, "system"]):
raise ConanInvalidConfiguration("'use_system_tz_db' is deprecated. You must set 'with_tzdb=system'")
if (self.options.use_system_tz_db or self.options.with_tzdb == "system") and not self.options.with_db_format == "binary":
raise ConanInvalidConfiguration("date only supports using the operating system database in a binary format. You must set 'with_db_format=binary'")
if self.settings.os == "Windows" and self.options.with_db_format == "binary":
raise ConanInvalidConfiguration("date does not currently support parsing the binary tzdb on Windows. An attempt has been made to introduce this in https://github.com/HowardHinnant/date/pull/611, so if this is functionality you would like please feel free to adapt this to a conan patch.")

def source(self):
get(self, **self.conan_data["sources"][self.version], strip_root=True)

def generate(self):
tc = CMakeToolchain(self)
tc.variables["ENABLE_DATE_TESTING"] = False
tc.variables["USE_SYSTEM_TZ_DB"] = self.options.use_system_tz_db
tc.variables["USE_SYSTEM_TZ_DB"] = (self.options.use_system_tz_db or self.options.with_tzdb in ["system", "tz"]) and self.options.with_db_format == "binary"
tc.variables["USE_TZ_DB_IN_DOT"] = self.options.use_tz_db_in_dot
tc.variables["BUILD_TZ_LIB"] = not self.options.header_only
tc.variables["MANUAL_TZ_DB"] = self.options.with_tzdb in ["manual", "tz"] and not self.options.with_db_format == "binary"
# workaround for clang 5 not having string_view
if Version(self.version) >= "3.0.0" and self.settings.compiler == "clang" \
and Version(self.settings.compiler.version) <= "5.0":
Expand Down Expand Up @@ -123,10 +139,10 @@ def package_info(self):
self.cpp_info.components["date-tz"].system_libs.append("pthread")
self.cpp_info.components["date-tz"].system_libs.append("m")

if not self.options.use_system_tz_db:
if self.options.with_tzdb == "download":
self.cpp_info.components["date-tz"].requires.append("libcurl::libcurl")

if self.options.use_system_tz_db and not self.settings.os == "Windows":
if (self.options.use_system_tz_db or self.options.with_tzdb in ["system", "tz"]) and self.options.with_db_format == "binary":
use_os_tzdb = 1
else:
use_os_tzdb = 0
Expand Down
117 changes: 117 additions & 0 deletions recipes/date/all/patches/load-tzdb-from-envvar-2.4.1.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
From 73ed8608827b3256e4f97415c9e2014fd31da2be Mon Sep 17 00:00:00 2001
From: Samuel Dowling <samuel.dowling@protonmail.com>
Date: Sat, 13 Jan 2024 19:57:49 +1030
Subject: [PATCH] Add ability to specify timezone database location via
environment variable

This adds the ability for a user to populate the TZDATA environment
variable to specify the location in which to look for the timezone
database, which allows for a runtime query of this location. Without
this, date currently only supports compile time determination of the
database location.

This facilitates the ability to:
* Use a timezone database provided by a package manager
* Keep the timezone database up to date without re-compilation
* Be flexible about where the timezone database is stored

Closes #788
---
CMakeLists.txt | 23 +++++++++++++++--------
src/tz.cpp | 19 +++++++++++++++++++
2 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7bc93df..ac989c8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -23,6 +23,7 @@ function( print_option OPT )
endfunction( )

print_option( USE_SYSTEM_TZ_DB )
+print_option( MANUAL_TZ_DB )
print_option( USE_TZ_DB_IN_DOT )
print_option( BUILD_SHARED_LIBS )
print_option( ENABLE_DATE_TESTING )
@@ -45,20 +46,26 @@ set( HEADER_FILES

add_library( tz ${HEADER_FILES} ${SOURCE_FOLDER}/tz.cpp )

-if( USE_SYSTEM_TZ_DB )
+if( USE_SYSTEM_TZ_DB OR MANUAL_TZ_DB )
target_compile_definitions( tz PRIVATE -DUSE_AUTOLOAD=0 )
target_compile_definitions( tz PRIVATE -DHAS_REMOTE_API=0 )
- # cannot set USE_OS_TZDB to 1 on Windows
- if( NOT WIN32 )
- target_compile_definitions( tz PUBLIC -DUSE_OS_TZDB=1 )
- endif( )
else( )
target_compile_definitions( tz PRIVATE -DUSE_AUTOLOAD=1 )
target_compile_definitions( tz PRIVATE -DHAS_REMOTE_API=1 )
- target_compile_definitions( tz PUBLIC -DUSE_OS_TZDB=0 )
- find_package( CURL REQUIRED )
+endif( )
+
+if ( USE_SYSTEM_TZ_DB AND NOT MANUAL_TZ_DB )
+ target_compile_definitions( tz PRIVATE -DINSTALL=. )
+ target_compile_definitions( tz PUBLIC -DUSE_OS_TZDB=1 )
+else( )
+ target_compile_definitions( tz PUBLIC USE_OS_TZDB=0 )
+endif( )
+
+if( NOT USE_SYSTEM_TZ_DB AND NOT MANUAL_TZ_DB )
+ find_package( CURL REQUIRED )
+ include_directories( SYSTEM ${CURL_INCLUDE_DIRS} )
set( OPTIONAL_LIBRARIES CURL::libcurl )
-endif()
+endif( )

if( BUILD_SHARED_LIBS )
target_compile_definitions( tz PRIVATE -DDATE_BUILD_DLL=1 )
diff --git a/src/tz.cpp b/src/tz.cpp
index f4a819b..fd7cd9f 100644
--- a/src/tz.cpp
+++ b/src/tz.cpp
@@ -81,6 +81,9 @@
# endif // __MINGW32__

# include <windows.h>
+# if !defined(S_ISDIR) && defined(S_IFMT) && defined(_S_IFDIR)
+# define S_ISDIR(m) (((m) & S_IFMT) == _S_IFDIR)
+# endif
#endif // _WIN32

#include "date/tz_private.h"
@@ -276,6 +279,14 @@ access_install()
#undef STRINGIZE
#endif // !INSTALL

+ {
+ static char* tz_local_env = getenv("TZDATA");
+ if (tz_local_env != nullptr) {
+ static std::string tz_local_env_s = tz_local_env;
+ return tz_local_env_s;
+ }
+ }
+
return install;
}

@@ -330,6 +341,14 @@ discover_tz_dir()
CONSTDATA auto tz_dir_default = "/usr/share/zoneinfo";
CONSTDATA auto tz_dir_buildroot = "/usr/share/zoneinfo/uclibc";

+ {
+ static char* tz_local_env = getenv("TZDATA");
+ if (tz_local_env != nullptr) {
+ static std::string tz_local_env_s = tz_local_env;
+ return tz_local_env_s;
+ }
+ }
+
// Check special path which is valid for buildroot with uclibc builds
if(stat(tz_dir_buildroot, &sb) == 0 && S_ISDIR(sb.st_mode))
return tz_dir_buildroot;
--
2.43.0.windows.1

69 changes: 69 additions & 0 deletions recipes/date/all/patches/load-tzdb-from-envvar-3.0.x.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
From 8b2cceb71f65f6aa6bdb3ffa63a63400214d5f1b Mon Sep 17 00:00:00 2001
From: Samuel Dowling <samuel.dowling@protonmail.com>
Date: Sat, 13 Jan 2024 19:57:49 +1030
Subject: [PATCH] Add ability to specify timezone database location via
environment variable

This adds the ability for a user to populate the TZDATA environment
variable to specify the location in which to look for the timezone
database, which allows for a runtime query of this location. Without
this, date currently only supports compile time determination of the
database location.

This facilitates the ability to:
* Use a timezone database provided by a package manager
* Keep the timezone database up to date without re-compilation
* Be flexible about where the timezone database is stored

Closes #788
---
src/tz.cpp | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)

diff --git a/src/tz.cpp b/src/tz.cpp
index 26babbd..6d010b8 100644
--- a/src/tz.cpp
+++ b/src/tz.cpp
@@ -81,6 +81,9 @@
# endif // __MINGW32__

# include <windows.h>
+# if !defined(S_ISDIR) && defined(S_IFMT) && defined(_S_IFDIR)
+# define S_ISDIR(m) (((m) & S_IFMT) == _S_IFDIR)
+# endif
#endif // _WIN32

#include "date/tz_private.h"
@@ -299,6 +302,14 @@ access_install()
#undef STRINGIZE
#endif // !INSTALL

+ {
+ static char* tz_local_env = getenv("TZDATA");
+ if (tz_local_env != nullptr) {
+ static std::string tz_local_env_s = tz_local_env;
+ return tz_local_env_s;
+ }
+ }
+
return install;
}

@@ -353,6 +364,14 @@ discover_tz_dir()
CONSTDATA auto tz_dir_default = "/usr/share/zoneinfo";
CONSTDATA auto tz_dir_buildroot = "/usr/share/zoneinfo/uclibc";

+ {
+ static char* tz_local_env = getenv("TZDATA");
+ if (tz_local_env != nullptr) {
+ static std::string tz_local_env_s = tz_local_env;
+ return tz_local_env_s;
+ }
+ }
+
// Check special path which is valid for buildroot with uclibc builds
if(stat(tz_dir_buildroot, &sb) == 0 && S_ISDIR(sb.st_mode))
return tz_dir_buildroot;
--
2.43.0.windows.1

11 changes: 4 additions & 7 deletions recipes/date/all/test_package/test_package.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,15 @@ class ZoneOffset {
auto to_local(date::sys_time<Duration> tp) const
-> date::local_time<typename std::common_type<Duration, std::chrono::minutes>::type> {
using namespace date;
using namespace std::chrono;
using LT = local_time<typename std::common_type<Duration, minutes>::type>;
using LT = local_time<typename std::common_type<Duration, std::chrono::minutes>::type>;
return LT{(tp + _offset).time_since_epoch()};
}

template <class Duration>
auto to_sys(date::local_time<Duration> tp) const
-> date::sys_time<typename std::common_type<Duration, std::chrono::minutes>::type> {
using namespace date;
using namespace std::chrono;
using ST = sys_time<typename std::common_type<Duration, minutes>::type>;
using ST = sys_time<typename std::common_type<Duration, std::chrono::minutes>::type>;
return ST{(tp - _offset).time_since_epoch()};
}

Expand All @@ -34,7 +32,6 @@ class ZoneOffset {
};

int main() {
using namespace std::chrono;
using namespace date;

auto date1 = 2015_y/March/22;
Expand All @@ -44,8 +41,8 @@ int main() {
auto date3 = 22_d/March/2015;
std::cout << date3 << '\n';

ZoneOffset p3_45{hours{3} + minutes{45}};
zoned_time<milliseconds, ZoneOffset*> zt{&p3_45, floor<milliseconds>(system_clock::now())};
ZoneOffset p3_45{std::chrono::hours{3} + std::chrono::minutes{45}};
zoned_time<std::chrono::milliseconds, ZoneOffset*> zt{&p3_45, floor<std::chrono::milliseconds>(std::chrono::system_clock::now())};
std::cout << zt.get_sys_time() << " (sys time)\n";
std::cout << zt.get_local_time() << " (local time)\n";

Expand Down