11#include <QtCore/QDateTime>
12#include <QtCore/QJsonArray>
13#include <QtCore/QJsonObject>
14#include <QtCore/QJsonDocument>
20struct PeHeaderInfoStruct {
21 unsigned wordSize = 0;
23 unsigned short machineArch = 0;
47Q_DECLARE_FLAGS(Platform, PlatformFlag)
49Q_DECLARE_OPERATORS_FOR_FLAGS(Platform)
51inline bool platformHasDebugSuffix(Platform p)
53 return p.testFlag(Msvc) || p.testFlag(ClangMsvc);
67 str <<
reinterpret_cast<
const wchar_t *>(s.utf16());
69 str << s.toStdWString();
81 void addFile(
const QString &source,
const QString &target)
83 m_files.append(SourceTargetMapping(source, target));
88 for (
int i = m_files.size() - 1; i >= 0; --i) {
89 if (m_files.at(i).second == targetDirectory)
98 for (
const SourceTargetMapping &mapping : m_files) {
100 object.insert(QStringLiteral(
"source"), QDir::toNativeSeparators(mapping.first));
101 object.insert(QStringLiteral(
"target"), QDir::toNativeSeparators(mapping.second));
102 files.append(object);
104 document.insert(QStringLiteral(
"files"), files);
105 return QJsonDocument(document).toJson();
110 for (
const SourceTargetMapping &mapping : m_files) {
111 const QString source = QDir::toNativeSeparators(mapping.first);
112 const QString fileName = QFileInfo(mapping.first).fileName();
113 const QString target = QDir::toNativeSeparators(mapping.second) + QDir::separator() + fileName;
118 list += source.toUtf8() +
'\n';
121 list += target.toUtf8() +
'\n';
124 list += QDir::toNativeSeparators(base.relativeFilePath(target)).toUtf8() +
'\n';
127 list +=
'"' + source.toUtf8() +
"\" \"" + QDir::toNativeSeparators(base.relativeFilePath(target)).toUtf8() +
"\"\n";
134 SourceTargetMappings m_files;
138QString normalizeFileName(
const QString &name);
139QString winErrorMessage(
unsigned long error);
140QString findSdkTool(
const QString &tool);
150bool createSymbolicLink(
const QFileInfo &source,
const QString &target, QString *errorMessage);
151bool createDirectory(
const QString &directory, QString *errorMessage,
bool dryRun);
166 const QString &prefix = QString());
168bool updateFile(
const QString &sourceFileName,
const QStringList &nameFilters,
169 const QString &targetDirectory,
unsigned flags,
JsonOutput *json, QString *errorMessage);
170bool runProcess(
const QString &binary,
const QStringList &args,
171 const QString &workingDirectory = QString(),
172 unsigned long *exitCode = 0, QByteArray *stdOut = 0, QByteArray *stdErr = 0,
173 QString *errorMessage = 0,
int timeout = 30000);
176 PeHeaderInfoStruct *headerInfo);
179 QStringList *dependentLibraries = 0);
182# if !defined(IMAGE_FILE_MACHINE_ARM64)
183# define IMAGE_FILE_MACHINE_ARM64 0xAA64
185QString getArchString (
unsigned short machineArch);
193 readPeExecutableDependencies(executableFileName, errorMessage, &result);
200bool patchQtCore(
const QString &path, QString *errorMessage);
213template <
class DirectoryFileEntryFunction>
215 DirectoryFileEntryFunction directoryFileEntryFunction,
216 const QString &targetDirectory,
219 QString *errorMessage)
221 const QFileInfo sourceFileInfo(sourceFileName);
222 const QString targetFileName = targetDirectory + u'/' + sourceFileInfo.fileName();
224 std::wcout <<
"Checking " << sourceFileName <<
", " << targetFileName <<
'\n';
226 if (!sourceFileInfo.exists()) {
227 *errorMessage = QString::fromLatin1(
"%1 does not exist.").arg(QDir::toNativeSeparators(sourceFileName));
231 const QFileInfo targetFileInfo(targetFileName);
233 if (sourceFileInfo.isSymLink()) {
234 const QString sourcePath = sourceFileInfo.symLinkTarget();
235 const QString relativeSource = QDir(sourceFileInfo.absolutePath()).relativeFilePath(sourcePath);
236 if (relativeSource.contains(u'/')) {
237 *errorMessage = QString::fromLatin1(
"Symbolic links across directories are not supported (%1).")
238 .arg(QDir::toNativeSeparators(sourceFileName));
243 if (!updateFile(sourcePath, directoryFileEntryFunction, targetDirectory, flags, json, errorMessage))
246 if (targetFileInfo.exists()) {
247 if (!targetFileInfo.isSymLink()) {
248 *errorMessage = QString::fromLatin1(
"%1 already exists and is not a symbolic link.")
249 .arg(QDir::toNativeSeparators(targetFileName));
252 const QString relativeTarget = QDir(targetFileInfo.absolutePath()).relativeFilePath(targetFileInfo.symLinkTarget());
253 if (relativeSource == relativeTarget)
255 QFile existingTargetFile(targetFileName);
257 *errorMessage = QString::fromLatin1(
"Cannot remove existing symbolic link %1: %2")
258 .arg(QDir::toNativeSeparators(targetFileName), existingTargetFile.errorString());
262 return createSymbolicLink(QFileInfo(targetDirectory + u'/' + relativeSource), sourceFileInfo.fileName(), errorMessage);
265 if (sourceFileInfo.isDir()) {
268 std::wcout <<
"Skipping " << QDir::toNativeSeparators(sourceFileName) <<
".\n";
271 bool created =
false;
272 if (targetFileInfo.exists()) {
273 if (!targetFileInfo.isDir()) {
274 *errorMessage = QString::fromLatin1(
"%1 already exists and is not a directory.")
275 .arg(QDir::toNativeSeparators(targetFileName));
279 QDir d(targetDirectory);
281 std::wcout <<
"Creating " << targetFileName <<
".\n";
283 created = d.mkdir(sourceFileInfo.fileName());
285 *errorMessage = QString::fromLatin1(
"Cannot create directory %1 under %2.")
286 .arg(sourceFileInfo.fileName(), QDir::toNativeSeparators(targetDirectory));
292 QDir dir(sourceFileName);
294 const QStringList allEntries = directoryFileEntryFunction(dir) + dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
295 for (
const QString &entry : allEntries)
296 if (!updateFile(sourceFileName + u'/' + entry, directoryFileEntryFunction, targetFileName, flags, json, errorMessage))
300 QDir d(targetFileName);
301 const QStringList entries = d.entryList(QStringList(), QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
302 if (entries.isEmpty() || (entries.size() == 1 && entries.first() == QLatin1StringView(
"qmldir"))) {
303 if (!d.removeRecursively()) {
304 *errorMessage = QString::fromLatin1(
"Cannot remove empty directory %1.")
305 .arg(QDir::toNativeSeparators(targetFileName));
309 json->removeTargetDirectory(targetFileName);
315 if (targetFileInfo.exists()) {
317 && targetFileInfo.lastModified() >= sourceFileInfo.lastModified()) {
319 std::wcout << sourceFileInfo.fileName() <<
" is up to date.\n";
321 json->addFile(sourceFileName, targetDirectory);
324 QFile targetFile(targetFileName);
326 *errorMessage = QString::fromLatin1(
"Cannot remove existing file %1: %2")
327 .arg(QDir::toNativeSeparators(targetFileName), targetFile.errorString());
331 QFile file(sourceFileName);
333 std::wcout <<
"Updating " << sourceFileInfo.fileName() <<
".\n";
335 if (!file.copy(targetFileName)) {
336 *errorMessage = QString::fromLatin1(
"Cannot copy %1 to %2: %3")
337 .arg(QDir::toNativeSeparators(sourceFileName),
338 QDir::toNativeSeparators(targetFileName),
342 if (!(file.permissions() & QFile::WriteUser)) {
343 QFile targetFile(targetFileName);
344 if (!targetFile.setPermissions(targetFile.permissions() | QFile::WriteUser)) {
345 *errorMessage = QString::fromLatin1(
"Cannot set write permission on %1: %2")
346 .arg(QDir::toNativeSeparators(targetFileName), file.errorString());
352 json->addFile(sourceFileName, targetDirectory);
363 const QStringList m_nameFilters;
367inline bool updateFile(
const QString &sourceFileName,
const QString &targetDirectory,
unsigned flags,
JsonOutput *json, QString *errorMessage)
369 return updateFile(sourceFileName, NameFilterFileEntryFunction(QStringList()), targetDirectory, flags, json, errorMessage);
QStringList operator()(const QDir &dir) const
DllDirectoryFileEntryFunction(Platform platform, DebugMatchMode debugMatchMode, const QString &prefix=QString())
void addFile(const QString &source, const QString &target)
void removeTargetDirectory(const QString &targetDirectory)
QByteArray toJson() const
QByteArray toList(ListOption option, const QDir &base) const
QStringList operator()(const QDir &dir) const
NameFilterFileEntryFunction(const QStringList &nameFilters)
QStringList operator()(const QDir &dir) const
QmlDirectoryFileEntryFunction(const QString &moduleSourcePath, Platform platform, DebugMatchMode debugMatchMode, unsigned flags)
static Platform platformFromMkSpec(const QString &xSpec)
static bool isQtModule(const QString &libName)
static QString libraryPath(const QString &libraryLocation, const char *name, const QString &infix, Platform platform, bool debug)
static QString lineBreak(QString s)
static QString msgFileDoesNotExist(const QString &file)
static QStringList compilerRunTimeLibs(const QString &qtBinDir, Platform platform, bool isDebug, unsigned short machineArch)
static bool updateLibrary(const QString &sourceFileName, const QString &targetDirectory, const Options &options, QString *errorMessage)
static bool findDependentQtLibraries(const QString &qtBinDir, const QString &binary, Platform platform, QString *errorMessage, QStringList *qtDependencies, QStringList *nonQtDependencies)
static void assignKnownModuleIds()
static QCommandLineOption createVerboseOption()
static int parseArguments(const QStringList &arguments, QCommandLineParser *parser, Options *options, QString *errorMessage)
static ExlusiveOptionValue parseExclusiveOptions(const QCommandLineParser *parser, const QCommandLineOption &enableOption, const QCommandLineOption &disableOption)
static int qtVersion(const QMap< QString, QString > &qtpathsVariables)
static QStringList translationNameFilters(const ModuleBitset &modules, const QString &prefix)
static QString findBinary(const QString &directory, Platform platform)
static DeployResult deploy(const Options &options, const QMap< QString, QString > &qtpathsVariables, const PluginInformation &pluginInfo, QString *errorMessage)
static int parseEarlyArguments(const QStringList &arguments, Options *options, QString *errorMessage)
static QCommandLineOption createQMakeOption()
static bool deployWebEngineCore(const QMap< QString, QString > &qtpathsVariables, const PluginInformation &pluginInfo, const Options &options, bool isDebug, QString *errorMessage)
static QStringList qmlCacheFileFilters()
static QString pdbFileName(QString libraryFileName)
@ CommandLineVersionRequested
@ CommandLineParseHelpRequested
static QString moduleNameToOptionName(const QString &moduleName, bool internal)
static QString formatQtPlugins(const PluginInformation &pluginInfo)
#define DECLARE_KNOWN_MODULE(name)
static QCommandLineOption createQtPathsOption()
static bool needsPluginType(const QString &subDirName, const PluginInformation &pluginInfo, const PluginSelections &pluginSelections)
static qint64 qtModule(QString module, const QString &infix)
static QString vcRedistDir()
static QString webProcessBinary(const char *binaryName, Platform p)
static QStringList findFFmpegLibs(const QString &qtBinDir, Platform platform)
static const char webEngineProcessC[]
static QString deployPlugin(const QString &plugin, const QDir &subDir, const bool dueToModule, const DebugMatchMode &debugMatchMode, ModuleBitset *pluginNeededQtModules, const ModuleBitset &disabledQtModules, const PluginSelections &pluginSelections, const QString &libraryLocation, const QString &infix, Platform platform, bool deployInsightTrackerPlugin, bool deployOpenSslPlugin)
static QString helpText(const QCommandLineParser &p, const PluginInformation &pluginInfo)
static bool deployWebProcess(const QMap< QString, QString > &qtpathsVariables, const char *binaryName, const PluginInformation &pluginInfo, const Options &sourceOptions, QString *errorMessage)
static QStringList findMinGWRuntimePaths(const QString &qtBinDir, Platform platform, const QStringList &runtimeFilters)
#define DEFINE_KNOWN_MODULE(name)
#define IMAGE_FILE_MACHINE_ARM64
static QString getIcuVersion(const QString &libName)
static bool deployTranslations(const QString &sourcePath, const ModuleBitset &usedQtModules, const QString &target, const Options &options, QString *errorMessage)
static QtModuleInfoStore qtModuleEntries
QStringList findQtPlugins(ModuleBitset *usedQtModules, const ModuleBitset &disabledQtModules, const PluginInformation &pluginInfo, const PluginSelections &pluginSelections, const QString &qtPluginsDirName, const QString &libraryLocation, const QString &infix, DebugMatchMode debugMatchModeIn, Platform platform, QString *platformPlugin, bool deployInsightTrackerPlugin, bool deployOpenSslPlugin)
static QStringList findOpenSslLibraries(const QString &openSslRootDir, Platform platform)
static QString vcDebugRedistDir()
static QByteArray formatQtModules(const ModuleBitset &mask, bool option=false)
int main(int argc, char *argv[])
[ctor_close]
QDataStream & operator<<(QDataStream &stream, const QImage &image)
[0]
ModuleBitset usedQtLibraries
ModuleBitset directlyUsedQtLibraries
ModuleBitset deployedQtLibraries
DebugDetection debugDetection
QStringList qmlImportPaths
PluginSelections pluginSelections
QStringList qmlDirectories
QString translationsDirectory
ModuleBitset additionalLibraries
QString openSslRootDirectory
ModuleBitset disabledLibraries
bool deployInsightTrackerPlugin
QString appxCertificatePath
@ DebugDetectionForceRelease
@ DebugDetectionForceDebug
QString findD3dCompiler(Platform platform, const QString &qtBinDir, unsigned wordSize)
bool runProcess(const QString &binary, const QStringList &args, const QString &workingDirectory=QString(), unsigned long *exitCode=0, QByteArray *stdOut=0, QByteArray *stdErr=0, QString *errorMessage=0, int timeout=30000)
@ WindowsDesktopMsvcIntel
@ WindowsDesktopClangMinGW
@ WindowsDesktopClangMsvc
QStringList findDxc(Platform platform, const QString &qtBinDir, unsigned wordSize)
QStringList findSharedLibraries(const QDir &directory, Platform platform, DebugMatchMode debugMatchMode, const QString &prefix=QString())
const char * qmakeInfixKey
QString findInPath(const QString &file)
bool createSymbolicLink(const QFileInfo &source, const QString &target, QString *errorMessage)
bool readPeExecutableDependencies(const QString &peExecutableFileName, QString *errorMessage, QStringList *dependentLibraries=0)
@ RemoveEmptyQmlDirectories
@ SkipQmlDesignerSpecificsDirectories
bool updateFile(const QString &sourceFileName, DirectoryFileEntryFunction directoryFileEntryFunction, const QString &targetDirectory, unsigned flags, JsonOutput *json, QString *errorMessage)
bool createDirectory(const QString &directory, QString *errorMessage, bool dryRun)
static const char windowsSharedLibrarySuffix[]
bool updateFile(const QString &sourceFileName, const QStringList &nameFilters, const QString &targetDirectory, unsigned flags, JsonOutput *json, QString *errorMessage)
QStringList findDependentLibraries(const QString &executableFileName, QString *errorMessage)
bool updateFile(const QString &sourceFileName, const QString &targetDirectory, unsigned flags, JsonOutput *json, QString *errorMessage)
bool isBuildDirectory(Platform platform, const QString &dirName)
bool patchQtCore(const QString &path, QString *errorMessage)
QMap< QString, QString > queryQtPaths(const QString &qmakeBinary, QString *errorMessage)
bool readPeExecutableInfo(const QString &peExecutableFileName, QString *errorMessage, PeHeaderInfoStruct *headerInfo)
QString sharedLibrarySuffix()
QString normalizeFileName(const QString &name)