diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2021-01-08 10:24:42 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2021-01-08 10:24:42 +0200 |
commit | 834876c5fb13dfaa102000e816e9052af139048c (patch) | |
tree | b07b7670ce555ad50415d811885ea46ae89a533f /libbuild2 | |
parent | a8017ff4b661305a71fe98813d0118b6c3876c52 (diff) |
Initial attempt (gzip -n and preserve post-processed manifest timestamp)reproducible-dist
Turns our this is not enough since tar saves timestamps (as well as owner
information, file order, etc) including for directories and getting rid of
that in a portable way is not going to be easy. Looks like the most plausible
way would be to switch to embedded libarchive (provided it's possible to
achieve everything we need).
Diffstat (limited to 'libbuild2')
-rw-r--r-- | libbuild2/dist/module.hxx | 4 | ||||
-rw-r--r-- | libbuild2/dist/operation.cxx | 21 | ||||
-rw-r--r-- | libbuild2/version/init.cxx | 19 |
3 files changed, 34 insertions, 10 deletions
diff --git a/libbuild2/dist/module.hxx b/libbuild2/dist/module.hxx index 314dc96..e1af9fc 100644 --- a/libbuild2/dist/module.hxx +++ b/libbuild2/dist/module.hxx @@ -59,6 +59,10 @@ namespace build2 // Note also that in the bootstrap distribution mode only callbacks // registered during bootstrap will be called. // + // If the callback is doing some sort of post-processing, then you may + // want to consider preserving the timestamps of the files being + // modified in order produce the same archive for the same distribution. + // using callback_func = void (const path&, const scope&, void*); void diff --git a/libbuild2/dist/operation.cxx b/libbuild2/dist/operation.cxx index 2fa953d..402f34b 100644 --- a/libbuild2/dist/operation.cxx +++ b/libbuild2/dist/operation.cxx @@ -719,13 +719,16 @@ namespace build2 // On Windows we use libarchive's bsdtar with auto-compression (tar // itself and quite a few compressors are MSYS executables). // - const char* l (nullptr); // Compression level (option). + // For gzip we also suppress the timestamp with -n to produce the + // same archive for the same distribution. + // + const char* o (nullptr); // Option (compression level, etc). #ifdef _WIN32 const char* tar = "bsdtar"; if (e == "tar.gz") - l = "--options=compression-level=9"; + o = "--options=compression-level=9,!timestamp"; #else const char* tar = "tar"; @@ -739,9 +742,9 @@ namespace build2 // const char* c (nullptr); - if (e == "tar.gz") { c = "gzip"; l = "-9"; } - else if (e == "tar.xz") { c = "xz"; } - else if (e == "tar.bz2") { c = "bzip2"; } + if (e == "tar.gz") { c = "gzip"; o = "-9n"; } + else if (e == "tar.xz") { c = "xz"; } + else if (e == "tar.bz2") { c = "bzip2"; } if (c != nullptr) { @@ -753,8 +756,8 @@ namespace build2 i = args.size (); args.push_back (c); - if (l != nullptr) - args.push_back (l); + if (o != nullptr) + args.push_back (o); args.push_back (nullptr); args.push_back (nullptr); // Pipe end. @@ -784,8 +787,8 @@ namespace build2 "--format", "ustar", "-a"}; - if (l != nullptr) - args.push_back (l); + if (o != nullptr) + args.push_back (o); args.push_back ("-cf"); args.push_back (ap.string ().c_str ()); diff --git a/libbuild2/version/init.cxx b/libbuild2/version/init.cxx index ced9c68..88f1080 100644 --- a/libbuild2/version/init.cxx +++ b/libbuild2/version/init.cxx @@ -374,7 +374,24 @@ namespace build2 path::temp_path ("manifest"), m.version)); - mvfile (t.path, f, verb_never); + + + // Copy the original timestamps in order produce the same archive for + // the same distribution. + // + try + { + entry_time et (file_time (f)); + + mvfile (t.path, f, verb_never); + + file_time (f, et); + } + catch (const system_error& e) + { + fail << "unable to get/set timestamp for " << f << ": " << e; + } + t.cancel (); } |