aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build2/cc/link-rule.cxx3
-rw-r--r--build2/depdb.cxx47
-rw-r--r--build2/depdb.hxx2
3 files changed, 37 insertions, 15 deletions
diff --git a/build2/cc/link-rule.cxx b/build2/cc/link-rule.cxx
index 981358e..2581d6f 100644
--- a/build2/cc/link-rule.cxx
+++ b/build2/cc/link-rule.cxx
@@ -2076,7 +2076,7 @@ namespace build2
timestamp dd_tt (system_clock::now ());
#endif
- dd.close ();
+ timestamp dd_cl (dd.close ());
// If nothing changed, then we are done.
//
@@ -2569,6 +2569,7 @@ namespace build2
if (dd_mt > tp_mt)
fail << "backwards modification times:\n"
<< dd_tt << " window start\n"
+ << dd_cl << " write mtime\n"
<< dd.mtime << " close mtime\n"
<< dd_mt << " " << dd.path.string () << '\n'
<< tp_mt << " " << tp.string () << '\n'
diff --git a/build2/depdb.cxx b/build2/depdb.cxx
index f0b0d21..088b355 100644
--- a/build2/depdb.cxx
+++ b/build2/depdb.cxx
@@ -6,6 +6,10 @@
#include <libbutl/filesystem.mxx> // file_mtime()
+#ifdef _WIN32
+# include <libbutl/win32-utility.hxx>
+#endif
+
#include <build2/diagnostics.hxx>
using namespace std;
@@ -201,7 +205,7 @@ namespace build2
fs_.put ('\n');
}
- void depdb::
+ timestamp depdb::
close ()
{
// If we are at eof, then it means all lines are good, there is the "end
@@ -259,34 +263,51 @@ namespace build2
// getting the old mtime if we ask for it too soon. For such cases we are
// going to just set it ourselves.
//
-#if defined(_WIN32) || defined(__FreeBSD__)
-# define BUILD2_NEED_MTIME_FIX
-#endif
-
-#ifdef BUILD2_NEED_MTIME_FIX
- timestamp mt;
+#ifdef _WIN32
+ timestamp mt (timestamp_unknown);
#endif
if (state_ == state::write)
{
-#ifdef BUILD2_NEED_MTIME_FIX
- mt = system_clock::now ();
+#ifdef _WIN32
+ FILETIME ft;
+ GetSystemTimeAsFileTime (&ft);
+
+ // See libbutl/filesystem.cxx for details.
+ //
+ uint64_t nsec ((static_cast<uint64_t> (ft.dwHighDateTime) << 32) |
+ ft.dwLowDateTime);
+ nsec -= 11644473600ULL * 10000000;
+ nsec *= 100;
+
+ mt = timestamp (
+ chrono::duration_cast<duration> (chrono::nanoseconds (nsec)));
#endif
+
fs_.put ('\0'); // The "end marker".
}
fs_.close ();
-#ifdef BUILD2_NEED_MTIME_FIX
+#if defined(_WIN32) || defined(__FreeBSD__)
if (state_ == state::write)
{
- // Save the original returned time for debugging.
- //
- mtime = file_mtime (path);
+ mtime = file_mtime (path); // Save for debugging.
+#ifdef _WIN32
if (mtime < mt)
+ {
file_mtime (path, mt);
+ assert (file_mtime (path) == mt);
+ }
+#endif
}
#endif
+
+#ifdef _WIN32
+ return mt;
+#else
+ return timestamp_unknown;
+#endif
}
}
diff --git a/build2/depdb.hxx b/build2/depdb.hxx
index 7c9e464..ffb3b89 100644
--- a/build2/depdb.hxx
+++ b/build2/depdb.hxx
@@ -90,7 +90,7 @@ namespace build2
// may be left in the old/currupt state. Note that in the read mode this
// function will "chop off" lines that haven't been read.
//
- void
+ timestamp
close ();
// Read the next line. If the result is not NULL, then it is a pointer to