/tools/qtestlib/wince/cetest/deployment.cpp

https://bitbucket.org/ultra_iter/qt-vtl · C++ · 293 lines · 219 code · 25 blank · 49 comment · 64 complexity · 70eb9e2978fed150804df5ed3314aeed MD5 · raw file

  1. /****************************************************************************
  2. **
  3. ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
  4. ** All rights reserved.
  5. ** Contact: Nokia Corporation (qt-info@nokia.com)
  6. **
  7. ** This file is part of the tools applications of the Qt Toolkit.
  8. **
  9. ** $QT_BEGIN_LICENSE:LGPL$
  10. ** GNU Lesser General Public License Usage
  11. ** This file may be used under the terms of the GNU Lesser General Public
  12. ** License version 2.1 as published by the Free Software Foundation and
  13. ** appearing in the file LICENSE.LGPL included in the packaging of this
  14. ** file. Please review the following information to ensure the GNU Lesser
  15. ** General Public License version 2.1 requirements will be met:
  16. ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  17. **
  18. ** In addition, as a special exception, Nokia gives you certain additional
  19. ** rights. These rights are described in the Nokia Qt LGPL Exception
  20. ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
  21. **
  22. ** GNU General Public License Usage
  23. ** Alternatively, this file may be used under the terms of the GNU General
  24. ** Public License version 3.0 as published by the Free Software Foundation
  25. ** and appearing in the file LICENSE.GPL included in the packaging of this
  26. ** file. Please review the following information to ensure the GNU General
  27. ** Public License version 3.0 requirements will be met:
  28. ** http://www.gnu.org/copyleft/gpl.html.
  29. **
  30. ** Other Usage
  31. ** Alternatively, this file may be used in accordance with the terms and
  32. ** conditions contained in a signed written agreement between you and Nokia.
  33. **
  34. **
  35. **
  36. **
  37. **
  38. ** $QT_END_LICENSE$
  39. **
  40. ****************************************************************************/
  41. #include "deployment.h"
  42. #include "remoteconnection.h"
  43. #include <option.h>
  44. #include <qdir.h>
  45. #include <qfile.h>
  46. #include <qstring.h>
  47. extern void debugOutput(const QString& text, int level);
  48. bool DeploymentHandler::deviceCopy(const DeploymentList &deploymentList)
  49. {
  50. for (int i=0; i<deploymentList.size(); ++i) {
  51. CopyItem item = deploymentList.at(i);
  52. m_connection->createDirectory(item.to.left(item.to.lastIndexOf(QLatin1Char('\\'))));
  53. if (!m_connection->copyFileToDevice(item.from , item.to)) {
  54. debugOutput(QString::fromLatin1("Error while copy: %1 -> %2").arg(item.from).arg(item.to),0);
  55. return false;
  56. }
  57. }
  58. return true;
  59. }
  60. bool DeploymentHandler::deviceDeploy(const DeploymentList &deploymentList)
  61. {
  62. DeploymentList copyList;
  63. for (int i=0; i<deploymentList.size(); ++i) {
  64. #if defined(Q_OS_WIN)
  65. HANDLE localHandle = CreateFile(deploymentList.at(i).from.utf16(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
  66. if (localHandle == INVALID_HANDLE_VALUE) {
  67. copyList.append(deploymentList.at(i));
  68. continue;
  69. }
  70. FILETIME localCreationTime;
  71. if (!GetFileTime(localHandle, NULL, NULL, &localCreationTime) || !m_connection->timeStampForLocalFileTime(&localCreationTime)) {
  72. copyList.append(deploymentList.at(i));
  73. CloseHandle(localHandle);
  74. continue;
  75. }
  76. CloseHandle(localHandle);
  77. FILETIME deviceCreationTime;
  78. if (!m_connection->fileCreationTime(deploymentList.at(i).to , &deviceCreationTime)) {
  79. copyList.append(deploymentList.at(i));
  80. continue;
  81. }
  82. int res = CompareFileTime(&localCreationTime, &deviceCreationTime);
  83. if (res != 0)
  84. copyList.append(deploymentList.at(i));
  85. else
  86. debugOutput(QString::fromLatin1("Skipping File %1, already latest version").arg(deploymentList.at(i).from),0);
  87. #else
  88. copyList.append(deploymentList.at(i));
  89. #endif
  90. }
  91. return deviceCopy(copyList);
  92. }
  93. void DeploymentHandler::cleanup(const DeploymentList &deploymentList)
  94. {
  95. for (int i=0; i<deploymentList.size(); ++i) {
  96. m_connection->deleteFile(deploymentList.at(i).to);
  97. #ifdef Q_OS_WIN
  98. QString path = deploymentList.at(i).to;
  99. int pos;
  100. while ( (pos = path.lastIndexOf(QLatin1Char('\\'))) > 0) {
  101. path = path.left(pos);
  102. if (!m_connection->deleteDirectory(path, false, true))
  103. break;
  104. }
  105. #endif
  106. }
  107. }
  108. void DeploymentHandler::initQtDeploy(QMakeProject *project, DeploymentList &deploymentList, const QString &testPath)
  109. {
  110. QString targetPath = project->values("deploy.path").join(" ");
  111. if (targetPath.isEmpty())
  112. targetPath = testPath;
  113. if (targetPath.endsWith("/") || targetPath.endsWith("\\"))
  114. targetPath = targetPath.mid(0,targetPath.size()-1);
  115. // Only deploy Qt libs for shared build
  116. if (!project->values("QMAKE_QT_DLL").isEmpty() && !project->values("QMAKE_LIBDIR").isEmpty()) {
  117. QStringList libs = project->values("LIBS");
  118. QStringList qtLibs;
  119. QStringList libPaths;
  120. foreach (QString item, libs) {
  121. if (item.startsWith("-L")) {
  122. // -L -> a directory containing DLLs
  123. libPaths << item.mid(2);
  124. continue;
  125. }
  126. QStringList libCandidates;
  127. if (item.startsWith("-l")) {
  128. // -l -> a library located within one of the standard library paths
  129. QString lib = item.mid(2);
  130. // Check if it's a Qt library first, then check in all paths given with -L.
  131. // Note Qt libraries get a `4' appended to them, others don't.
  132. libCandidates << project->values("QMAKE_LIBDIR").at(0) + QDir::separator() + lib + QLatin1String("4.dll");
  133. foreach (QString const& libPath, libPaths) {
  134. libCandidates << libPath + QDir::separator() + lib + QLatin1String(".dll");
  135. }
  136. } else {
  137. libCandidates << item.replace(".lib",".dll");
  138. }
  139. foreach (QString const& file, libCandidates) {
  140. QFileInfo info(file);
  141. if (info.exists()) {
  142. qtLibs += info.dir().absoluteFilePath(info.fileName());
  143. break;
  144. }
  145. }
  146. }
  147. for (QStringList::ConstIterator it = qtLibs.constBegin(); it != qtLibs.constEnd(); ++it) {
  148. QString dllName = *it;
  149. QFileInfo info(dllName);
  150. if (!info.exists())
  151. continue;
  152. deploymentList.append(CopyItem(Option::fixPathToLocalOS(info.absoluteFilePath()) ,
  153. Option::fixPathToLocalOS(targetPath + "/" + info.fileName())));
  154. }
  155. }
  156. #ifndef QT_CETEST_NO_ACTIVESYNC
  157. // QtRemote deployment. We always deploy to \Windows
  158. if (!project->values("QMAKE_LIBDIR").isEmpty()) {
  159. QString remoteLibName = QLatin1String("QtRemote.dll");
  160. QString remoteLib = Option::fixPathToLocalOS(project->values("QMAKE_LIBDIR").at(0) + QDir::separator() + remoteLibName);
  161. if (QFile::exists(remoteLib))
  162. deploymentList.append(CopyItem(remoteLib, QString::fromLatin1("\\Windows\\") + remoteLibName));
  163. else
  164. debugOutput(QString::fromLatin1("Could not find QtRemote. Might not be able to launch target executable"),0);
  165. }
  166. #endif
  167. // C-runtime deployment
  168. QString runtime = project->values("QT_CE_C_RUNTIME").join(QLatin1String(" "));
  169. debugOutput(QString::fromLatin1("Runtime:%1").arg(runtime), 2);
  170. if (!runtime.isEmpty() && (runtime != QLatin1String("no"))) {
  171. QString runtimeVersion = QLatin1String("msvcr");
  172. const QString mkspec = project->values("QMAKESPEC").first();
  173. if (mkspec.endsWith("2008"))
  174. runtimeVersion.append("90");
  175. else
  176. runtimeVersion.append("80");
  177. if (project->isActiveConfig("debug"))
  178. runtimeVersion.append("d");
  179. runtimeVersion.append(".dll");
  180. if (runtime == "yes") {
  181. // Auto-find C-runtime
  182. QString vcInstallDir = qgetenv("VCINSTALLDIR");
  183. if (!vcInstallDir.isEmpty()) {
  184. vcInstallDir += "\\ce\\dll\\";
  185. vcInstallDir += project->values("CE_ARCH").join(QLatin1String(" "));
  186. if (!QFileInfo(vcInstallDir + QDir::separator() + runtimeVersion).exists())
  187. runtime.clear();
  188. else
  189. runtime = vcInstallDir;
  190. }
  191. }
  192. if (!runtime.isEmpty()) {
  193. deploymentList.append(CopyItem(Option::fixPathToLocalOS(runtime + "/" + runtimeVersion ) ,
  194. Option::fixPathToLocalOS(targetPath + "/" + runtimeVersion)));
  195. }
  196. }
  197. }
  198. void DeploymentHandler::initProjectDeploy(QMakeProject* project, DeploymentList &deploymentList, const QString &testPath)
  199. {
  200. QString targetPath = project->values("deploy.path").join(" ");
  201. if (targetPath.isEmpty())
  202. targetPath = testPath;
  203. if (targetPath.endsWith("/") || targetPath.endsWith("\\"))
  204. targetPath = targetPath.mid(0,targetPath.size()-1);
  205. QStringList& list = project->values("DEPLOYMENT");
  206. if (list.isEmpty())
  207. return;
  208. for (int it = 0; it < list.size(); ++it) {
  209. QString argSource = list.at(it);
  210. QString argPath = list.at(it) + QString(".path");
  211. if (((project->values(argSource + QString(".files")).isEmpty() && project->values(argSource + QString(".sources")).isEmpty()) || project->values(argPath).isEmpty()) && list.at(it) != "deploy") {
  212. debugOutput(QString::fromLatin1("cannot deploy \"%1\" because of missing data.").arg(list.at(it)), 0);
  213. continue;
  214. }
  215. QString addPath = project->values(argPath).join(QLatin1String(" "));
  216. if (addPath == QLatin1String("."))
  217. addPath.clear();
  218. if (!addPath.startsWith("/") && !addPath.startsWith(QLatin1String("\\")))
  219. addPath = targetPath + "/" + addPath;
  220. QStringList addSources = project->values(argSource + QString(".files")) + project->values(argSource + QString(".sources"));
  221. addSources.replaceInStrings(QLatin1String("/"), QLatin1String("\\"));
  222. for(int index=0; index < addSources.size(); ++index) {
  223. QString dirstr = qmake_getpwd();
  224. QString filestr = Option::fixPathToLocalOS(addSources.at(index), false, false);
  225. int slsh = filestr.lastIndexOf(Option::dir_sep);
  226. if(slsh != -1) {
  227. dirstr = filestr.left(slsh+1);
  228. filestr = filestr.right(filestr.length() - slsh - 1);
  229. }
  230. if(dirstr.right(Option::dir_sep.length()) != Option::dir_sep)
  231. dirstr += Option::dir_sep;
  232. QFileInfo info(dirstr + filestr);
  233. static int addQMakeDeployCounter = 0;
  234. QStringList entryList = info.absoluteDir().entryList(QStringList() << info.fileName());
  235. if (entryList.size() > 1) {
  236. foreach(QString s, entryList) {
  237. // We do not include directories when using wildcards
  238. QFileInfo wildInfo(info.absolutePath() + "/" + s);
  239. if (wildInfo.isDir()) {
  240. continue;
  241. }
  242. QString appendedQmakeDeploy = QString::fromLatin1("_q_make_additional_deploy_%1").arg(addQMakeDeployCounter++);
  243. project->parse(appendedQmakeDeploy + QLatin1String(".files = \"") + wildInfo.absoluteFilePath());
  244. project->parse(appendedQmakeDeploy + QLatin1String(".path = \"") + addPath);
  245. list.append(appendedQmakeDeploy);
  246. }
  247. continue;
  248. }
  249. if (info.isDir()) {
  250. QDir additionalDir(dirstr + filestr);
  251. QStringList additionalEntries = additionalDir.entryList(QDir::NoDotAndDotDot | QDir::AllEntries | QDir::NoSymLinks);
  252. foreach(QString item, additionalEntries) {
  253. QString appendedDeploy = QString::fromLatin1("_q_make_additional_deploy_%1").arg(addQMakeDeployCounter++);
  254. project->parse(appendedDeploy + QLatin1String(".files = \"") + Option::fixPathToLocalOS(additionalDir.absoluteFilePath(item)) + QLatin1String("\""));
  255. QString appendTargetPath = project->values(argPath).join(QLatin1String(" "));
  256. if (appendTargetPath == QLatin1String("."))
  257. appendTargetPath = filestr;
  258. else
  259. appendTargetPath.append(QLatin1String("\\") + filestr);
  260. project->parse(appendedDeploy + QLatin1String(".path = ") + appendTargetPath);
  261. list.append(appendedDeploy);
  262. }
  263. } else if (entryList.size() == 1)
  264. deploymentList.append(CopyItem(Option::fixPathToLocalOS(info.absolutePath() + "/" + entryList.at(0)) ,
  265. Option::fixPathToLocalOS(addPath + "/" + entryList.at(0))));
  266. }
  267. }
  268. }