cmake: update nanosecond selection

For consistency, specify the nanosecond option in the same way as other
options, and identify it as such. Split the detection of platform
support (`FindStatNsec`) and its selection (`SelectNsec`).
This commit is contained in:
Edward Thomson
2024-12-31 11:29:41 +00:00
parent 8bbd2f406e
commit 890d70856c
15 changed files with 97 additions and 63 deletions

View File

@@ -27,9 +27,8 @@ option(BUILD_FUZZERS "Build the fuzz targets"
# Suggested functionality that may not be available on a per-platform basis
option(USE_THREADS "Use threads for parallel processing when possible" ON)
option(USE_NSEC "Support nanosecond precision file mtimes and ctimes" ON)
# Backend selection
# Feature enablement and backend selection
set(USE_SSH "" CACHE STRING "Enables SSH support and optionally selects provider. One of ON, OFF, or a specific provider: libssh2 or exec. (Defaults to OFF.)")
set(USE_HTTPS "" CACHE STRING "Enable HTTPS support and optionally selects the provider. One of ON, OFF, or a specific provider: OpenSSL, OpenSSL-FIPS, OpenSSL-Dynamic, mbedTLS, SecureTransport, Schannel, or WinHTTP. (Defaults to ON.)")
set(USE_SHA1 "" CACHE STRING "Selects SHA1 provider. One of builtin, HTTPS, or a specific provider. (Defaults to builtin.)")
@@ -40,6 +39,7 @@ option(USE_NSEC "Support nanosecond precision file mtimes and cti
# set(USE_XDIFF "" CACHE STRING "Specifies the xdiff implementation; either system or builtin.")
set(USE_REGEX "" CACHE STRING "Selects regex provider. One of regcomp_l, pcre2, pcre, regcomp, or builtin.")
set(USE_COMPRESSION "" CACHE STRING "Selects compression backend. Either builtin or zlib.")
set(USE_NSEC "" CACHE STRING "Enable nanosecond precision timestamps. One of ON, OFF, or a specific provider: mtimespec, mtim, mtime, or win32. (Defaults to ON).")
if(APPLE)
# Currently only available on macOS for `precomposeUnicode` support

View File

@@ -1,20 +1,6 @@
include(FeatureSummary)
check_struct_has_member("struct stat" st_mtim "sys/types.h;sys/stat.h"
HAVE_STRUCT_STAT_ST_MTIM LANGUAGE C)
check_struct_has_member("struct stat" st_mtimespec "sys/types.h;sys/stat.h"
HAVE_STRUCT_STAT_ST_MTIMESPEC LANGUAGE C)
check_struct_has_member("struct stat" st_mtime_nsec sys/stat.h
HAVE_STRUCT_STAT_MTIME_NSEC LANGUAGE C)
if(HAVE_STRUCT_STAT_ST_MTIM)
check_struct_has_member("struct stat" st_mtim.tv_nsec sys/stat.h
HAVE_STRUCT_STAT_NSEC LANGUAGE C)
elseif(HAVE_STRUCT_STAT_ST_MTIMESPEC)
check_struct_has_member("struct stat" st_mtimespec.tv_nsec sys/stat.h
HAVE_STRUCT_STAT_NSEC LANGUAGE C)
else()
set(HAVE_STRUCT_STAT_NSEC ON )
endif()
add_feature_info(nanoseconds USE_NSEC "support nanosecond precision file mtimes and ctimes")

58
cmake/SelectNsec.cmake Normal file
View File

@@ -0,0 +1,58 @@
include(SanitizeBool)
include(FeatureSummary)
sanitizebool(USE_NSEC)
if((USE_NSEC STREQUAL ON OR USE_NSEC STREQUAL "") AND HAVE_STRUCT_STAT_ST_MTIM)
set(USE_NSEC "mtim")
elseif((USE_NSEC STREQUAL ON OR USE_NSEC STREQUAL "") AND HAVE_STRUCT_STAT_ST_MTIMESPEC)
set(USE_NSEC "mtimespec")
elseif((USE_NSEC STREQUAL ON OR USE_NSEC STREQUAL "") AND HAVE_STRUCT_STAT_MTIME_NSEC)
set(USE_NSEC "mtime_nsec")
elseif((USE_NSEC STREQUAL ON OR USE_NSEC STREQUAL "") AND WIN32)
set(USE_NSEC "win32")
elseif(USE_NSEC STREQUAL "")
message(WARNING "nanosecond timestamp precision was not detected")
set(USE_NSEC OFF)
elseif(USE_NSEC STREQUAL ON)
message(FATAL_ERROR "nanosecond support was requested but no platform support is available")
endif()
if(USE_NSEC STREQUAL "mtim")
if(NOT HAVE_STRUCT_STAT_ST_MTIM)
message(FATAL_ERROR "stat mtim could not be found")
endif()
set(GIT_NSEC 1)
set(GIT_NSEC_MTIM 1)
add_feature_info("Nanosecond support" ON "using mtim")
elseif(USE_NSEC STREQUAL "mtimespec")
if(NOT HAVE_STRUCT_STAT_ST_MTIMESPEC)
message(FATAL_ERROR "mtimespec could not be found")
endif()
set(GIT_NSEC 1)
set(GIT_NSEC_MTIMESPEC 1)
add_feature_info("Nanosecond support" ON "using mtimespec")
elseif(USE_NSEC STREQUAL "mtime_nsec")
if(NOT HAVE_STRUCT_STAT_MTIME_NSEC)
message(FATAL_ERROR "mtime_nsec could not be found")
endif()
set(GIT_NSEC 1)
set(GIT_NSEC_MTIME_NSEC 1)
add_feature_info("Nanosecond support" ON "using mtime_nsec")
elseif(USE_NSEC STREQUAL "win32")
if(NOT WIN32)
message(FATAL_ERROR "Win32 API support is not available on this platform")
endif()
set(GIT_NSEC 1)
set(GIT_NSEC_WIN32 1)
add_feature_info("Nanosecond support" ON "using Win32 APIs")
elseif(USE_NSEC STREQUAL OFF)
set(GIT_NSEC 0)
add_feature_info("Nanosecond support" OFF "Nanosecond timestamp resolution is disabled")
else()
message(FATAL_ERROR "unknown nanosecond option: ${USE_NSEC}")
endif()

View File

@@ -36,6 +36,7 @@ add_feature_info(debugopen GIT_DEBUG_STRICT_OPEN "path validation in open")
# Optional feature enablement
#
include(SelectNsec)
include(SelectHTTPSBackend)
include(SelectHashes)
include(SelectHTTPParser)
@@ -110,22 +111,6 @@ else()
message(FATAL_ERROR "Unsupported architecture (CMAKE_SIZEOF_VOID_P is unset)")
endif()
# nanosecond mtime/ctime support
if(USE_NSEC)
set(GIT_USE_NSEC 1)
endif()
# high-resolution stat support
if(HAVE_STRUCT_STAT_ST_MTIM)
set(GIT_USE_STAT_MTIM 1)
elseif(HAVE_STRUCT_STAT_ST_MTIMESPEC)
set(GIT_USE_STAT_MTIMESPEC 1)
elseif(HAVE_STRUCT_STAT_ST_MTIME_NSEC)
set(GIT_USE_STAT_MTIME_NSEC 1)
endif()
# realtime support
check_library_exists(rt clock_gettime "time.h" NEED_LIBRT)

View File

@@ -902,7 +902,7 @@ void git_index_entry__init_from_stat(
{
entry->ctime.seconds = (int32_t)st->st_ctime;
entry->mtime.seconds = (int32_t)st->st_mtime;
#if defined(GIT_USE_NSEC)
#if defined(GIT_NSEC)
entry->mtime.nanoseconds = st->st_mtime_nsec;
entry->ctime.nanoseconds = st->st_ctime_nsec;
#endif

View File

@@ -85,7 +85,7 @@ GIT_INLINE(bool) git_index_time_eq(const git_index_time *one, const git_index_ti
if (one->seconds != two->seconds)
return false;
#ifdef GIT_USE_NSEC
#ifdef GIT_NSEC
if (one->nanoseconds != two->nanoseconds)
return false;
#endif
@@ -106,7 +106,7 @@ GIT_INLINE(bool) git_index_entry_newer_than_index(
return false;
/* If the timestamp is the same or newer than the index, it's racy */
#if defined(GIT_USE_NSEC)
#if defined(GIT_NSEC)
if ((int32_t)index->stamp.mtime.tv_sec < entry->mtime.seconds)
return true;
else if ((int32_t)index->stamp.mtime.tv_sec > entry->mtime.seconds)

View File

@@ -1520,7 +1520,7 @@ static void filesystem_iterator_set_current(
iter->entry.ctime.seconds = (int32_t)entry->st.st_ctime;
iter->entry.mtime.seconds = (int32_t)entry->st.st_mtime;
#if defined(GIT_USE_NSEC)
#if defined(GIT_NSEC)
iter->entry.ctime.nanoseconds = entry->st.st_ctime_nsec;
iter->entry.mtime.nanoseconds = entry->st.st_mtime_nsec;
#else

View File

@@ -90,7 +90,7 @@ int git_libgit2_features(void)
#ifdef GIT_SSH
| GIT_FEATURE_SSH
#endif
#ifdef GIT_USE_NSEC
#ifdef GIT_NSEC
| GIT_FEATURE_NSEC
#endif
| GIT_FEATURE_HTTP_PARSER
@@ -152,15 +152,15 @@ const char *git_libgit2_feature_backend(git_feature_t feature)
break;
case GIT_FEATURE_NSEC:
#if defined(GIT_USE_NSEC) && defined(GIT_USE_STAT_MTIMESPEC)
#if defined(GIT_NSEC_MTIMESPEC)
return "mtimespec";
#elif defined(GIT_USE_NSEC) && defined(GIT_USE_STAT_MTIM)
#elif defined(GIT_NSEC_MTIM)
return "mtim";
#elif defined(GIT_USE_NSEC) && defined(GIT_USE_STAT_MTIME_NSEC)
return "mtime";
#elif defined(GIT_USE_NSEC) && defined(GIT_WIN32)
#elif defined(GIT_NSEC_MTIME_NSEC)
return "mtime_nsec";
#elif defined(GIT_NSEC_WIN32)
return "win32";
#elif defined(GIT_USE_NSEC)
#elif defined(GIT_NSEC)
GIT_ASSERT_WITH_RETVAL(!"Unknown high-resolution time backend", NULL);
#endif
break;

View File

@@ -1158,7 +1158,7 @@ int git_futils_filestamp_check(
return GIT_ENOTFOUND;
if (stamp->mtime.tv_sec == st.st_mtime &&
#if defined(GIT_USE_NSEC)
#if defined(GIT_NSEC)
stamp->mtime.tv_nsec == st.st_mtime_nsec &&
#endif
stamp->size == (uint64_t)st.st_size &&
@@ -1166,7 +1166,7 @@ int git_futils_filestamp_check(
return 0;
stamp->mtime.tv_sec = st.st_mtime;
#if defined(GIT_USE_NSEC)
#if defined(GIT_NSEC)
stamp->mtime.tv_nsec = st.st_mtime_nsec;
#endif
stamp->size = (uint64_t)st.st_size;
@@ -1190,7 +1190,7 @@ void git_futils_filestamp_set_from_stat(
{
if (st) {
stamp->mtime.tv_sec = st->st_mtime;
#if defined(GIT_USE_NSEC)
#if defined(GIT_NSEC)
stamp->mtime.tv_nsec = st->st_mtime_nsec;
#else
stamp->mtime.tv_nsec = 0;

View File

@@ -14,10 +14,12 @@
#cmakedefine GIT_I18N 1
#cmakedefine GIT_I18N_ICONV 1
#cmakedefine GIT_USE_NSEC 1
#cmakedefine GIT_USE_STAT_MTIM 1
#cmakedefine GIT_USE_STAT_MTIMESPEC 1
#cmakedefine GIT_USE_STAT_MTIME_NSEC 1
#cmakedefine GIT_NSEC 1
#cmakedefine GIT_NSEC_MTIM 1
#cmakedefine GIT_NSEC_MTIMESPEC 1
#cmakedefine GIT_NSEC_MTIME_NSEC 1
#cmakedefine GIT_NSEC_WIN32 1
#cmakedefine GIT_USE_FUTIMENS 1
#cmakedefine GIT_REGEX_REGCOMP_L 1

View File

@@ -23,16 +23,16 @@ typedef int GIT_SOCKET;
#define p_lstat(p,b) lstat(p,b)
#define p_stat(p,b) stat(p, b)
#if defined(GIT_USE_STAT_MTIMESPEC)
#if defined(GIT_NSEC_MTIMESPEC)
# define st_atime_nsec st_atimespec.tv_nsec
# define st_mtime_nsec st_mtimespec.tv_nsec
# define st_ctime_nsec st_ctimespec.tv_nsec
#elif defined(GIT_USE_STAT_MTIM)
#elif defined(GIT_NSEC_MTIM)
# define st_atime_nsec st_atim.tv_nsec
# define st_mtime_nsec st_mtim.tv_nsec
# define st_ctime_nsec st_ctim.tv_nsec
#elif !defined(GIT_USE_STAT_MTIME_NSEC) && defined(GIT_USE_NSEC)
# error GIT_USE_NSEC defined but unknown struct stat nanosecond type
#elif !defined(GIT_NSEC_MTIME_NSEC) && defined(GIT_NSEC)
# error GIT_NSEC defined but unknown struct stat nanosecond type
#endif
#define p_utimes(f, t) utimes(f, t)

View File

@@ -77,8 +77,10 @@ GIT_INLINE(void) git_win32__filetime_to_timespec(
int64_t winTime = ((int64_t)ft->dwHighDateTime << 32) + ft->dwLowDateTime;
winTime -= INT64_C(116444736000000000); /* Windows to Unix Epoch conversion */
ts->tv_sec = (time_t)(winTime / 10000000);
#ifdef GIT_USE_NSEC
#ifdef GIT_NSEC_WIN32
ts->tv_nsec = (winTime % 10000000) * 100;
#elif GIT_NSEC
# error GIT_NSEC defined but GIT_NSEC_WIN32 not defined
#else
ts->tv_nsec = 0;
#endif

View File

@@ -1,5 +1,6 @@
#include "git2/object.h"
#include "git2/repository.h"
#include "git2_features.h"
extern void assert_on_branch(git_repository *repo, const char *branch);
extern void reset_index_to_treeish(git_object *treeish);

View File

@@ -20,7 +20,7 @@ void test_core_features__basic(void)
cl_assert((caps & GIT_FEATURE_SSH) == 0);
#endif
#if defined(GIT_USE_NSEC)
#if defined(GIT_NSEC)
cl_assert((caps & GIT_FEATURE_NSEC) != 0);
#else
cl_assert((caps & GIT_FEATURE_NSEC) == 0);
@@ -118,15 +118,15 @@ void test_core_features__backends(void)
cl_assert(ssh == NULL);
#endif
#if defined(GIT_USE_NSEC) && defined(GIT_USE_STAT_MTIMESPEC)
#if defined(GIT_NSEC_MTIMESPEC)
cl_assert_equal_s("mtimespec", nsec);
#elif defined(GIT_USE_NSEC) && defined(GIT_USE_STAT_MTIM)
#elif defined(GIT_NSEC_MTIM)
cl_assert_equal_s("mtim", nsec);
#elif defined(GIT_USE_NSEC) && defined(GIT_USE_STAT_MTIME_NSEC)
cl_assert_equal_s("mtime", nsec);
#elif defined(GIT_USE_NSEC) && defined(GIT_WIN32)
#elif defined(GIT_NSEC_MTIME_NSEC)
cl_assert_equal_s("mtime_nsec", nsec);
#elif defined(GIT_NSEC_WIN32)
cl_assert_equal_s("win32", nsec);
#elif defined(GIT_USE_NSEC)
#elif defined(GIT_NSEC)
cl_assert(0);
#else
cl_assert(nsec == NULL);

View File

@@ -162,7 +162,7 @@ static void hack_index(char *files[])
entry->ctime.seconds = (int32_t)statbuf.st_ctime;
entry->mtime.seconds = (int32_t)statbuf.st_mtime;
#if defined(GIT_USE_NSEC)
#if defined(GIT_NSEC)
entry->ctime.nanoseconds = statbuf.st_ctime_nsec;
entry->mtime.nanoseconds = statbuf.st_mtime_nsec;
#else