qmake: Use utimensat on macOS when propagating mtime during install

macOS only claims to conform to POSIX.1-2001, but has had utimensat
since macOS 10.13.

By enabling the utimensat code path, using stat.st_mtimespec as input,
we get nanosecond precision when qmake installs files.

Without this the tst_qmake::install_files tests fails due to the source
file having a sub second timestamp -- 2023-07-31 15:58:12.468 -- while the
installed does not: 2023-07-31 15:58:12.000.

The reason this test passes in the CI right now is probably because
the source file archive we use to pass test sources to the test
machines does not support the same level of precision.

Change-Id: I6ca7a2a2f9e71981814cbf496aa55717b3a3f74f
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit a2779192eec649a15b909cd9becade7eb0bda34e)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Tor Arne Vestbø 2024-07-07 23:53:54 +02:00 committed by Qt Cherry-pick Bot
parent 9cc291fe94
commit 1407e54f34

View File

@ -221,15 +221,21 @@ bool IoUtils::touchFile(const QString &targetFileName, const QString &referenceF
*errorString = fL1S("Cannot stat() reference file %1: %2.").arg(referenceFileName, fL1S(strerror(errno)));
return false;
}
# if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L
const struct timespec times[2] = { { 0, UTIME_NOW }, st.st_mtim };
# if (defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L) || defined(Q_OS_DARWIN)
const struct timespec times[2] = { { 0, UTIME_NOW },
# if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L
st.st_mtim // POSIX.1-2008
# else
st.st_mtimespec // Darwin
# endif
};
const bool utimeError = utimensat(AT_FDCWD, targetFileName.toLocal8Bit().constData(), times, 0) < 0;
# else
struct utimbuf utb;
utb.actime = time(0);
utb.modtime = st.st_mtime;
const bool utimeError= utime(targetFileName.toLocal8Bit().constData(), &utb) < 0;
# endif
# endif // (defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L) || defined(Q_OS_DARWIN)
if (utimeError) {
*errorString = fL1S("Cannot touch %1: %2.").arg(targetFileName, fL1S(strerror(errno)));
return false;
@ -256,7 +262,7 @@ bool IoUtils::touchFile(const QString &targetFileName, const QString &referenceF
}
SetFileTime(wHand, NULL, NULL, &ft);
CloseHandle(wHand);
# endif
# endif // Q_OS_UNIX
return true;
}