Preserve last modification timestamps of installed directories
Similar to the two parent commits, this patchs preserves the time stamps of files we install as a result of recursive directory copying. Change-Id: Id5931a467196d5cd67acfa0deffc2488af8a3669 Task-number: QTBUG-59004 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@qt.io>
This commit is contained in:
parent
7eae7e8103
commit
c12b96daf2
@ -1283,14 +1283,12 @@ MakefileGenerator::writeInstalls(QTextStream &t, bool noBuild)
|
|||||||
if(is_target || exists(wild)) { //real file or target
|
if(is_target || exists(wild)) { //real file or target
|
||||||
QFileInfo fi(fileInfo(wild));
|
QFileInfo fi(fileInfo(wild));
|
||||||
QString dst_file = filePrefixRoot(root, dst_dir);
|
QString dst_file = filePrefixRoot(root, dst_dir);
|
||||||
if (!fi.isDir() || project->isActiveConfig("copy_dir_files")) {
|
if (!dst_file.endsWith(Option::dir_sep))
|
||||||
if(!dst_file.endsWith(Option::dir_sep))
|
|
||||||
dst_file += Option::dir_sep;
|
dst_file += Option::dir_sep;
|
||||||
dst_file += fi.fileName();
|
dst_file += fi.fileName();
|
||||||
}
|
|
||||||
QString cmd;
|
QString cmd;
|
||||||
if (fi.isDir())
|
if (fi.isDir())
|
||||||
cmd = "-$(INSTALL_DIR)";
|
cmd = "-$(QINSTALL_DIR)";
|
||||||
else if (is_target || fi.isExecutable())
|
else if (is_target || fi.isExecutable())
|
||||||
cmd = "-$(QINSTALL_PROGRAM)";
|
cmd = "-$(QINSTALL_PROGRAM)";
|
||||||
else
|
else
|
||||||
@ -1310,23 +1308,16 @@ MakefileGenerator::writeInstalls(QTextStream &t, bool noBuild)
|
|||||||
if (installConfigValues.contains("no_check_exist") && files.isEmpty()) {
|
if (installConfigValues.contains("no_check_exist") && files.isEmpty()) {
|
||||||
QString dst_file = filePrefixRoot(root, dst_dir);
|
QString dst_file = filePrefixRoot(root, dst_dir);
|
||||||
QString cmd;
|
QString cmd;
|
||||||
if (installConfigValues.contains("directory")) {
|
|
||||||
cmd = QLatin1String("-$(INSTALL_DIR)");
|
|
||||||
if (project->isActiveConfig("copy_dir_files")) {
|
|
||||||
if (!dst_file.endsWith(Option::dir_sep))
|
if (!dst_file.endsWith(Option::dir_sep))
|
||||||
dst_file += Option::dir_sep;
|
dst_file += Option::dir_sep;
|
||||||
dst_file += filestr;
|
dst_file += filestr;
|
||||||
}
|
if (installConfigValues.contains("directory")) {
|
||||||
} else {
|
cmd = QLatin1String("-$(QINSTALL_DIR)");
|
||||||
if (installConfigValues.contains("executable")) {
|
} else if (installConfigValues.contains("executable")) {
|
||||||
cmd = QLatin1String("-$(QINSTALL_PROGRAM)");
|
cmd = QLatin1String("-$(QINSTALL_PROGRAM)");
|
||||||
} else {
|
} else {
|
||||||
cmd = QLatin1String("-$(QINSTALL_FILE)");
|
cmd = QLatin1String("-$(QINSTALL_FILE)");
|
||||||
}
|
}
|
||||||
if (!dst_file.endsWith(Option::dir_sep))
|
|
||||||
dst_file += Option::dir_sep;
|
|
||||||
dst_file += filestr;
|
|
||||||
}
|
|
||||||
cmd += " " + escapeFilePath(wild) + " " + escapeFilePath(dst_file);
|
cmd += " " + escapeFilePath(wild) + " " + escapeFilePath(dst_file);
|
||||||
inst << cmd;
|
inst << cmd;
|
||||||
uninst.append(rm_dir_contents + " " + escapeFilePath(filePrefixRoot(root, fileFixify(dst_dir + filestr, FileFixifyAbsolute, false))));
|
uninst.append(rm_dir_contents + " " + escapeFilePath(filePrefixRoot(root, fileFixify(dst_dir + filestr, FileFixifyAbsolute, false))));
|
||||||
@ -1336,12 +1327,10 @@ MakefileGenerator::writeInstalls(QTextStream &t, bool noBuild)
|
|||||||
uninst.append(rm_dir_contents + " " + escapeFilePath(filePrefixRoot(root, fileFixify(dst_dir + file, FileFixifyAbsolute, false))));
|
uninst.append(rm_dir_contents + " " + escapeFilePath(filePrefixRoot(root, fileFixify(dst_dir + file, FileFixifyAbsolute, false))));
|
||||||
QFileInfo fi(fileInfo(dirstr + file));
|
QFileInfo fi(fileInfo(dirstr + file));
|
||||||
QString dst_file = filePrefixRoot(root, fileFixify(dst_dir, FileFixifyAbsolute, false));
|
QString dst_file = filePrefixRoot(root, fileFixify(dst_dir, FileFixifyAbsolute, false));
|
||||||
if (!fi.isDir() || project->isActiveConfig("copy_dir_files")) {
|
if (!dst_file.endsWith(Option::dir_sep))
|
||||||
if(!dst_file.endsWith(Option::dir_sep))
|
|
||||||
dst_file += Option::dir_sep;
|
dst_file += Option::dir_sep;
|
||||||
dst_file += fi.fileName();
|
dst_file += fi.fileName();
|
||||||
}
|
QString cmd = QString(fi.isDir() ? "-$(QINSTALL_DIR)" : "-$(QINSTALL_FILE)") + " " +
|
||||||
QString cmd = QString(fi.isDir() ? "-$(INSTALL_DIR)" : "-$(QINSTALL_FILE)") + " " +
|
|
||||||
escapeFilePath(dirstr + file) + " " + escapeFilePath(dst_file);
|
escapeFilePath(dirstr + file) + " " + escapeFilePath(dst_file);
|
||||||
inst << cmd;
|
inst << cmd;
|
||||||
if (!project->isActiveConfig("debug_info") && !project->isActiveConfig("nostrip") &&
|
if (!project->isActiveConfig("debug_info") && !project->isActiveConfig("nostrip") &&
|
||||||
@ -2255,6 +2244,7 @@ MakefileGenerator::writeDefaultVariables(QTextStream &t)
|
|||||||
t << "INSTALL_DIR = " << var("QMAKE_INSTALL_DIR") << endl;
|
t << "INSTALL_DIR = " << var("QMAKE_INSTALL_DIR") << endl;
|
||||||
t << "QINSTALL_FILE = " << var("QMAKE_QMAKE") << " -install qinstall file" << endl;
|
t << "QINSTALL_FILE = " << var("QMAKE_QMAKE") << " -install qinstall file" << endl;
|
||||||
t << "QINSTALL_PROGRAM = " << var("QMAKE_QMAKE") << " -install qinstall program" << endl;
|
t << "QINSTALL_PROGRAM = " << var("QMAKE_QMAKE") << " -install qinstall program" << endl;
|
||||||
|
t << "QINSTALL_DIR = " << var("QMAKE_QMAKE") << " -install qinstall directory" << endl;
|
||||||
t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl;
|
t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl;
|
||||||
t << "SYMLINK = " << var("QMAKE_SYMBOLIC_LINK") << endl;
|
t << "SYMLINK = " << var("QMAKE_SYMBOLIC_LINK") << endl;
|
||||||
t << "DEL_DIR = " << var("QMAKE_DEL_DIR") << endl;
|
t << "DEL_DIR = " << var("QMAKE_DEL_DIR") << endl;
|
||||||
|
@ -636,7 +636,7 @@ UnixMakefileGenerator::defaultInstall(const QString &t)
|
|||||||
|
|
||||||
QString copy_cmd;
|
QString copy_cmd;
|
||||||
if (bundle == SolidBundle) {
|
if (bundle == SolidBundle) {
|
||||||
copy_cmd += "-$(INSTALL_DIR) " + src_targ + ' ' + plain_targ;
|
copy_cmd += "-$(QINSTALL_DIR) " + src_targ + ' ' + plain_targ;
|
||||||
} else if (project->first("TEMPLATE") == "lib" && project->isActiveConfig("staticlib")) {
|
} else if (project->first("TEMPLATE") == "lib" && project->isActiveConfig("staticlib")) {
|
||||||
copy_cmd += "-$(QINSTALL_FILE) " + src_targ + ' ' + dst_targ;
|
copy_cmd += "-$(QINSTALL_FILE) " + src_targ + ' ' + dst_targ;
|
||||||
} else if (!isAux) {
|
} else if (!isAux) {
|
||||||
@ -698,7 +698,7 @@ UnixMakefileGenerator::defaultInstall(const QString &t)
|
|||||||
ret += "\n\t";
|
ret += "\n\t";
|
||||||
ret += mkdir_p_asstring("\"`dirname " + dst + "`\"", false) + "\n\t";
|
ret += mkdir_p_asstring("\"`dirname " + dst + "`\"", false) + "\n\t";
|
||||||
ret += "-$(DEL_FILE) " + dst + "\n\t"; // Can't overwrite symlinks to directories
|
ret += "-$(DEL_FILE) " + dst + "\n\t"; // Can't overwrite symlinks to directories
|
||||||
ret += "-$(INSTALL_DIR) " + escapeFilePath(src) + " " + dst; // Use cp -R to copy symlinks
|
ret += "-$(QINSTALL_DIR) " + escapeFilePath(src) + " " + dst;
|
||||||
if (!uninst.isEmpty())
|
if (!uninst.isEmpty())
|
||||||
uninst.append("\n\t");
|
uninst.append("\n\t");
|
||||||
uninst.append("-$(DEL_FILE) " + dst);
|
uninst.append("-$(DEL_FILE) " + dst);
|
||||||
|
@ -532,6 +532,7 @@ void Win32MakefileGenerator::writeStandardParts(QTextStream &t)
|
|||||||
t << "INSTALL_DIR = " << var("QMAKE_INSTALL_DIR") << endl;
|
t << "INSTALL_DIR = " << var("QMAKE_INSTALL_DIR") << endl;
|
||||||
t << "QINSTALL_FILE = " << var("QMAKE_QMAKE") << " -install qinstall file" << endl;
|
t << "QINSTALL_FILE = " << var("QMAKE_QMAKE") << " -install qinstall file" << endl;
|
||||||
t << "QINSTALL_PROGRAM = " << var("QMAKE_QMAKE") << " -install qinstall program" << endl;
|
t << "QINSTALL_PROGRAM = " << var("QMAKE_QMAKE") << " -install qinstall program" << endl;
|
||||||
|
t << "QINSTALL_DIR = " << var("QMAKE_QMAKE") << " -install qinstall directory" << endl;
|
||||||
t << endl;
|
t << endl;
|
||||||
|
|
||||||
t << "####### Output directory\n\n";
|
t << "####### Output directory\n\n";
|
||||||
|
@ -253,4 +253,39 @@ bool IoUtils::touchFile(const QString &targetFileName, const QString &referenceF
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef Q_OS_UNIX
|
||||||
|
bool IoUtils::readLinkTarget(const QString &symlinkPath, QString *target)
|
||||||
|
{
|
||||||
|
const QByteArray localSymlinkPath = QFile::encodeName(symlinkPath);
|
||||||
|
# if defined(__GLIBC__) && !defined(PATH_MAX)
|
||||||
|
# define PATH_CHUNK_SIZE 256
|
||||||
|
char *s = 0;
|
||||||
|
int len = -1;
|
||||||
|
int size = PATH_CHUNK_SIZE;
|
||||||
|
|
||||||
|
forever {
|
||||||
|
s = (char *)::realloc(s, size);
|
||||||
|
len = ::readlink(localSymlinkPath.constData(), s, size);
|
||||||
|
if (len < 0) {
|
||||||
|
::free(s);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (len < size)
|
||||||
|
break;
|
||||||
|
size *= 2;
|
||||||
|
}
|
||||||
|
# else
|
||||||
|
char s[PATH_MAX+1];
|
||||||
|
int len = readlink(localSymlinkPath.constData(), s, PATH_MAX);
|
||||||
|
# endif
|
||||||
|
if (len <= 0)
|
||||||
|
return false;
|
||||||
|
*target = QFile::decodeName(QByteArray(s, len));
|
||||||
|
# if defined(__GLIBC__) && !defined(PATH_MAX)
|
||||||
|
::free(s);
|
||||||
|
# endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -65,6 +65,9 @@ public:
|
|||||||
#if defined(PROEVALUATOR_FULL)
|
#if defined(PROEVALUATOR_FULL)
|
||||||
static bool touchFile(const QString &targetFileName, const QString &referenceFileName, QString *errorString);
|
static bool touchFile(const QString &targetFileName, const QString &referenceFileName, QString *errorString);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef Q_OS_UNIX
|
||||||
|
static bool readLinkTarget(const QString &symlinkPath, QString *target);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ProFileEvaluatorInternal
|
} // namespace ProFileEvaluatorInternal
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include <qdebug.h>
|
#include <qdebug.h>
|
||||||
#include <qregexp.h>
|
#include <qregexp.h>
|
||||||
#include <qdir.h>
|
#include <qdir.h>
|
||||||
|
#include <qdiriterator.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -43,6 +44,11 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#if defined(Q_OS_UNIX)
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
# include <qt_windows.h>
|
# include <qt_windows.h>
|
||||||
#endif
|
#endif
|
||||||
@ -267,6 +273,44 @@ static int installFile(const QString &source, const QString &target, bool exe =
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int installDirectory(const QString &source, const QString &target)
|
||||||
|
{
|
||||||
|
QFileInfo fi(source);
|
||||||
|
if (false) {
|
||||||
|
#if defined(Q_OS_UNIX)
|
||||||
|
} else if (fi.isSymLink()) {
|
||||||
|
QString linkTarget;
|
||||||
|
if (!IoUtils::readLinkTarget(fi.absoluteFilePath(), &linkTarget)) {
|
||||||
|
fprintf(stderr, "Could not read link %s: %s\n", qPrintable(fi.absoluteFilePath()), strerror(errno));
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
QFile::remove(target);
|
||||||
|
if (::symlink(linkTarget.toLocal8Bit().constData(), target.toLocal8Bit().constData()) < 0) {
|
||||||
|
fprintf(stderr, "Could not create link: %s\n", strerror(errno));
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} else if (fi.isDir()) {
|
||||||
|
QDir::current().mkpath(target);
|
||||||
|
|
||||||
|
QDirIterator it(source, QDir::AllEntries | QDir::NoDotAndDotDot);
|
||||||
|
while (it.hasNext()) {
|
||||||
|
it.next();
|
||||||
|
const QFileInfo &entry = it.fileInfo();
|
||||||
|
const QString &entryTarget = target + QDir::separator() + entry.fileName();
|
||||||
|
|
||||||
|
const int recursionResult = installDirectory(entry.filePath(), entryTarget);
|
||||||
|
if (recursionResult != 0)
|
||||||
|
return recursionResult;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const int fileCopyResult = installFile(source, target);
|
||||||
|
if (fileCopyResult != 0)
|
||||||
|
return fileCopyResult;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int doQInstall(int argc, char **argv)
|
static int doQInstall(int argc, char **argv)
|
||||||
{
|
{
|
||||||
if (argc != 3) {
|
if (argc != 3) {
|
||||||
@ -281,6 +325,8 @@ static int doQInstall(int argc, char **argv)
|
|||||||
return installFile(source, target);
|
return installFile(source, target);
|
||||||
if (!strcmp(argv[0], "program"))
|
if (!strcmp(argv[0], "program"))
|
||||||
return installFile(source, target, /*exe=*/true);
|
return installFile(source, target, /*exe=*/true);
|
||||||
|
if (!strcmp(argv[0], "directory"))
|
||||||
|
return installDirectory(source, target);
|
||||||
|
|
||||||
fprintf(stderr, "Error: Unsupported qinstall command type %s\n", argv[0]);
|
fprintf(stderr, "Error: Unsupported qinstall command type %s\n", argv[0]);
|
||||||
return 3;
|
return 3;
|
||||||
|
Loading…
Reference in New Issue
Block a user