cmake: Teach "-E tar" command a "--mtime=" option
Add an option to set the mtime of entries in a tarball so that one can create a tarball with a consistent content hash (e.g. MD5) for a given set of files regardless of their current timestamps on disk. This will be useful for submission of tarballs to CDash, which tracks content hashes to avoid duplication. Inspired-by: Bill Hoffman <bill.hoffman@kitware.com>
This commit is contained in:
parent
90f9c42732
commit
3a60c899fc
|
@ -0,0 +1,6 @@
|
|||
cmake-E-tar-mtime
|
||||
-----------------
|
||||
|
||||
* The :manual:`cmake(1)` ``-E tar`` command learned a new
|
||||
``--mtime=<date>`` option to specify the modification time
|
||||
recorded in tarball entries.
|
|
@ -335,6 +335,8 @@ set(SRCS
|
|||
cmake.cxx
|
||||
cmake.h
|
||||
|
||||
cm_get_date.h
|
||||
cm_get_date.c
|
||||
cm_sha2.h
|
||||
cm_sha2.c
|
||||
cm_utf8.h
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <cmsys/Directory.hxx>
|
||||
#include <cmsys/FStream.hxx>
|
||||
#include <cm_libarchive.h>
|
||||
#include "cm_get_date.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static std::string cm_archive_error_string(struct archive* a)
|
||||
|
@ -277,6 +278,20 @@ bool cmArchiveWrite::AddFile(const char* file,
|
|||
this->Error += cm_archive_error_string(this->Disk);
|
||||
return false;
|
||||
}
|
||||
if (!this->MTime.empty())
|
||||
{
|
||||
time_t now;
|
||||
time(&now);
|
||||
time_t t = cm_get_date(now, this->MTime.c_str());
|
||||
if (t == -1)
|
||||
{
|
||||
this->Error = "unable to parse mtime '";
|
||||
this->Error += this->MTime;
|
||||
this->Error += "'";
|
||||
return false;
|
||||
}
|
||||
archive_entry_set_mtime(e, t, 0);
|
||||
}
|
||||
// Clear acl and xattr fields not useful for distribution.
|
||||
archive_entry_acl_clear(e);
|
||||
archive_entry_xattr_clear(e);
|
||||
|
|
|
@ -74,6 +74,7 @@ public:
|
|||
// std::cout.
|
||||
void SetVerbose(bool v) { this->Verbose = v; }
|
||||
|
||||
void SetMTime(std::string const& t) { this->MTime = t; }
|
||||
private:
|
||||
bool Okay() const { return this->Error.empty(); }
|
||||
bool AddPath(const char* path, size_t skip, const char* prefix);
|
||||
|
@ -90,6 +91,7 @@ private:
|
|||
struct archive* Disk;
|
||||
bool Verbose;
|
||||
std::string Error;
|
||||
std::string MTime;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1469,7 +1469,7 @@ bool cmSystemTools::IsPathToFramework(const char* path)
|
|||
bool cmSystemTools::CreateTar(const char* outFileName,
|
||||
const std::vector<std::string>& files,
|
||||
cmTarCompression compressType,
|
||||
bool verbose)
|
||||
bool verbose, std::string const& mtime)
|
||||
{
|
||||
#if defined(CMAKE_BUILD_WITH_CMAKE)
|
||||
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
|
||||
|
@ -1501,6 +1501,7 @@ bool cmSystemTools::CreateTar(const char* outFileName,
|
|||
}
|
||||
cmArchiveWrite a(fout, compress,
|
||||
cmArchiveWrite::TypeTAR);
|
||||
a.SetMTime(mtime);
|
||||
a.SetVerbose(verbose);
|
||||
for(std::vector<std::string>::const_iterator i = files.begin();
|
||||
i != files.end(); ++i)
|
||||
|
|
|
@ -394,9 +394,9 @@ public:
|
|||
bool verbose);
|
||||
static bool CreateTar(const char* outFileName,
|
||||
const std::vector<std::string>& files,
|
||||
cmTarCompression compressType, bool verbose);
|
||||
static bool ExtractTar(const char* inFileName,
|
||||
bool verbose);
|
||||
cmTarCompression compressType, bool verbose,
|
||||
std::string const& mtime = std::string());
|
||||
static bool ExtractTar(const char* inFileName, bool verbose);
|
||||
// This should be called first thing in main
|
||||
// it will keep child processes from inheriting the
|
||||
// stdin and stdout of this process. This is important
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
/*============================================================================
|
||||
CMake - Cross Platform Makefile Generator
|
||||
Copyright 2000-2015 Kitware, Inc.
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
#include "cm_get_date.h"
|
||||
|
||||
#define __archive_get_date cm_get_date
|
||||
|
||||
#include "../Utilities/cmlibarchive/libarchive/archive_getdate.c"
|
|
@ -0,0 +1,28 @@
|
|||
/*============================================================================
|
||||
CMake - Cross Platform Makefile Generator
|
||||
Copyright 2000-2015 Kitware, Inc.
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
#ifndef cm_get_date_h
|
||||
#define cm_get_date_h
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Parse a date/time string. Treat relative times with respect to 'now'. */
|
||||
time_t cm_get_date(time_t now, const char *str);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -729,9 +729,31 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
|
|||
std::string flags = args[2];
|
||||
std::string outFile = args[3];
|
||||
std::vector<std::string> files;
|
||||
std::string mtime;
|
||||
bool doing_options = true;
|
||||
for (std::string::size_type cc = 4; cc < args.size(); cc ++)
|
||||
{
|
||||
files.push_back(args[cc]);
|
||||
std::string const& arg = args[cc];
|
||||
if (doing_options && cmHasLiteralPrefix(arg, "--"))
|
||||
{
|
||||
if (arg == "--")
|
||||
{
|
||||
doing_options = false;
|
||||
}
|
||||
else if (cmHasLiteralPrefix(arg, "--mtime="))
|
||||
{
|
||||
mtime = arg.substr(8);
|
||||
}
|
||||
else
|
||||
{
|
||||
cmSystemTools::Error("Unknown option to -E tar: ", arg.c_str());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
files.push_back(arg);
|
||||
}
|
||||
}
|
||||
cmSystemTools::cmTarCompression compress =
|
||||
cmSystemTools::TarCompressNone;
|
||||
|
@ -774,7 +796,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
|
|||
else if ( flags.find_first_of('c') != flags.npos )
|
||||
{
|
||||
if ( !cmSystemTools::CreateTar(
|
||||
outFile.c_str(), files, compress, verbose) )
|
||||
outFile.c_str(), files, compress, verbose, mtime) )
|
||||
{
|
||||
cmSystemTools::Error("Problem creating tar: ", outFile.c_str());
|
||||
return 1;
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,2 @@
|
|||
^CMake Error: unable to parse mtime 'bad'
|
||||
CMake Error: Problem creating tar: bad.tar$
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1 @@
|
|||
^CMake Error: Unknown option to -E tar: --bad$
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,2 @@
|
|||
^CMake Error: archive_read_disk_entry_from_file '--bad':.*
|
||||
CMake Error: Problem creating tar: bad.tar$
|
|
@ -1,5 +1,11 @@
|
|||
include(RunCMake)
|
||||
|
||||
run_cmake_command(E_tar-bad-opt1 ${CMAKE_COMMAND} -E tar cvf bad.tar --bad)
|
||||
run_cmake_command(E_tar-bad-mtime1 ${CMAKE_COMMAND} -E tar cvf bad.tar --mtime=bad .)
|
||||
run_cmake_command(E_tar-end-opt1 ${CMAKE_COMMAND} -E tar cvf bad.tar -- --bad)
|
||||
run_cmake_command(E_tar-end-opt2 ${CMAKE_COMMAND} -E tar cvf bad.tar --)
|
||||
run_cmake_command(E_tar-mtime ${CMAKE_COMMAND} -E tar cvf bad.tar "--mtime=1970-01-01 00:00:00 UTC")
|
||||
|
||||
run_cmake_command(build-no-cache
|
||||
${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR})
|
||||
run_cmake_command(build-no-generator
|
||||
|
|
Loading…
Reference in New Issue