From a62e533123ac5693b3c7bd5e99cafcfce7465a8c Mon Sep 17 00:00:00 2001
From: ck <qt-info@nokia.com>
Date: Wed, 7 Apr 2010 17:10:00 +0200
Subject: [PATCH] Maemo: Implement basic packaging.

---
 .../qt-maemo/maemopackagecreationfactory.cpp  |  45 +++--
 .../qt-maemo/maemopackagecreationfactory.h    |   4 +
 .../qt-maemo/maemopackagecreationstep.cpp     | 163 +++++++++++++++++-
 .../qt-maemo/maemopackagecreationstep.h       |  17 ++
 .../qt-maemo/maemoruncontrol.cpp              | 107 ------------
 .../qt-maemo/maemoruncontrol.h                |   3 -
 6 files changed, 204 insertions(+), 135 deletions(-)

diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationfactory.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationfactory.cpp
index 544d6342148..ab031f1b3f2 100644
--- a/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationfactory.cpp
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationfactory.cpp
@@ -60,43 +60,34 @@ MaemoPackageCreationFactory::MaemoPackageCreationFactory(QObject *parent)
 
 }
 
-QStringList MaemoPackageCreationFactory::availableCreationIds(BuildConfiguration *parent,
-                StepType type) const
+QStringList MaemoPackageCreationFactory::availableCreationIds(BuildConfiguration *,
+                StepType) const
 {
-    QStringList ids;
-    if (type == ProjectExplorer::Build
-        && parent->target()->id() == Constants::MAEMO_DEVICE_TARGET_ID)
-        ids << MaemoPackageCreationStep::CreatePackageId;
-    return ids;
+    return QStringList();
 }
 
-QString MaemoPackageCreationFactory::displayNameForId(const QString &id) const
+QString MaemoPackageCreationFactory::displayNameForId(const QString &) const
 {
-    return id == MaemoPackageCreationStep::CreatePackageId
-        ? tr("Maemo Package Creation")
-        : QString();
+    return QString();
 }
 
-bool MaemoPackageCreationFactory::canCreate(BuildConfiguration *parent,
-         StepType type, const QString &id) const
+bool MaemoPackageCreationFactory::canCreate(BuildConfiguration *,
+         StepType, const QString &) const
 {
-    return type == ProjectExplorer::Build
-        && id == MaemoPackageCreationStep::CreatePackageId
-        && parent->target()->id() == Constants::MAEMO_DEVICE_TARGET_ID;
+    return false;
 }
 
-BuildStep *MaemoPackageCreationFactory::create(BuildConfiguration *parent,
-               ProjectExplorer::StepType type, const QString &id)
+BuildStep *MaemoPackageCreationFactory::create(BuildConfiguration *,
+               StepType, const QString &)
 {
-    Q_ASSERT(canCreate(parent, type, id));
-    return new MaemoPackageCreationStep(parent);
+    Q_ASSERT(false);
+    return 0;
 }
 
 bool MaemoPackageCreationFactory::canRestore(BuildConfiguration *parent,
          StepType type, const QVariantMap &map) const
 {
-    qDebug("%s: %d", Q_FUNC_INFO, canCreate(parent, type, ProjectExplorer::idFromMap(map)));
-    return canCreate(parent, type, ProjectExplorer::idFromMap(map));
+    return canCreateInternally(parent, type, ProjectExplorer::idFromMap(map));
 }
 
 BuildStep *MaemoPackageCreationFactory::restore(BuildConfiguration *parent,
@@ -109,7 +100,7 @@ BuildStep *MaemoPackageCreationFactory::restore(BuildConfiguration *parent,
 bool MaemoPackageCreationFactory::canClone(BuildConfiguration *parent,
          StepType type, BuildStep *product) const
 {
-    return canCreate(parent, type, product->id());
+    return canCreateInternally(parent, type, product->id());
 }
 
 BuildStep *MaemoPackageCreationFactory::clone(BuildConfiguration *parent,
@@ -119,5 +110,13 @@ BuildStep *MaemoPackageCreationFactory::clone(BuildConfiguration *parent,
     return new MaemoPackageCreationStep(parent, static_cast<MaemoPackageCreationStep *>(product));
 }
 
+bool MaemoPackageCreationFactory::canCreateInternally(BuildConfiguration *parent,
+         StepType type, const QString &id) const
+{
+    return type == ProjectExplorer::Build
+        && id == MaemoPackageCreationStep::CreatePackageId
+        && parent->target()->id() == Constants::MAEMO_DEVICE_TARGET_ID;
+}
+
 } // namespace Internal
 } // namespace Qt4ProjectManager
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationfactory.h b/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationfactory.h
index 88157e8654b..da80af2fae5 100644
--- a/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationfactory.h
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationfactory.h
@@ -78,6 +78,10 @@ public:
                   ProjectExplorer::StepType type,
                   ProjectExplorer::BuildStep *product);
 
+private:
+    bool canCreateInternally(ProjectExplorer::BuildConfiguration *parent,
+                             ProjectExplorer::StepType type,
+                             const QString &id) const;
 };
 
 } // namespace Internal
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationstep.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationstep.cpp
index 1e585b2499c..715b806f9a6 100644
--- a/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationstep.cpp
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationstep.cpp
@@ -41,6 +41,16 @@
 
 #include "maemopackagecreationstep.h"
 
+#include "maemotoolchain.h"
+#include <qt4buildconfiguration.h>
+#include <qt4project.h>
+#include <qt4target.h>
+
+#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
+#include <QtCore/QProcess>
+#include <QtCore/QProcessEnvironment>
+#include <QtCore/QStringBuilder>
 #include <QtGui/QWidget>
 
 using ProjectExplorer::BuildConfiguration;
@@ -81,8 +91,7 @@ bool MaemoPackageCreationStep::init()
 
 void MaemoPackageCreationStep::run(QFutureInterface<bool> &fi)
 {
-    qDebug("%s", Q_FUNC_INFO);
-    fi.reportResult(true);
+    fi.reportResult(createPackage());
 }
 
 BuildStepConfigWidget *MaemoPackageCreationStep::createConfigWidget()
@@ -90,6 +99,156 @@ BuildStepConfigWidget *MaemoPackageCreationStep::createConfigWidget()
     return new MaemoPackageCreationWidget(this);
 }
 
+bool MaemoPackageCreationStep::createPackage()
+{
+    qDebug("%s", Q_FUNC_INFO);
+    if (!packagingNeeded())
+        return true;
+
+    const QString projectDir = QFileInfo(executable()).absolutePath();
+
+    QFile configFile(targetRoot() % QLatin1String("/config.sh"));
+    if (!configFile.open(QIODevice::ReadOnly)) {
+        qDebug("Cannot open config file '%s'", qPrintable(configFile.fileName()));
+        return false;
+    }
+    QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
+    const QLatin1String pathKey("PATH");
+    env.insert(pathKey, maddeRoot() % QLatin1String("/madbin:")
+                        % env.value(pathKey));
+    env.insert(QLatin1String("PERL5LIB"),
+               maddeRoot() % QLatin1String("/madlib/perl5"));
+    const QRegExp envPattern(QLatin1String("([^=]+)=[\"']?([^;\"']+)[\"']? ;.*"));
+    env.insert(QLatin1String("PWD"), projectDir);
+    QByteArray line;
+    do {
+        line = configFile.readLine(200);
+        if (envPattern.exactMatch(line))
+            env.insert(envPattern.cap(1), envPattern.cap(2));
+    } while (!line.isEmpty());
+    qDebug("Process environment: %s",
+           qPrintable(env.toStringList().join(QLatin1String(":"))));
+    qDebug("sysroot: '%s'", qPrintable(env.value(QLatin1String("SYSROOT_DIR"))));
+    QProcess buildProc;
+    buildProc.setProcessEnvironment(env);
+    buildProc.setWorkingDirectory(projectDir);
+
+    if (!QFileInfo(projectDir + QLatin1String("/debian")).exists()) {
+        const QString command = QLatin1String("dh_make -s -n -p ")
+                                % executableFileName() % QLatin1String("_0.1");
+        if (!runCommand(buildProc, command))
+            return false;
+        QFile rulesFile(projectDir + QLatin1String("/debian/rules"));
+        if (!rulesFile.open(QIODevice::ReadWrite)) {
+            qDebug("Error: Could not open debian/rules.");
+            return false;
+        }
+
+        QByteArray rulesContents = rulesFile.readAll();
+        rulesContents.replace("DESTDIR", "INSTALL_ROOT");
+        rulesFile.resize(0);
+        rulesFile.write(rulesContents);
+        if (rulesFile.error() != QFile::NoError) {
+            qDebug("Error: could not access debian/rules");
+            return false;
+        }
+    }
+
+    if (!runCommand(buildProc, QLatin1String("dh_installdirs")))
+        return false;
+    const QString targetFile(projectDir % QLatin1String("/debian/")
+                             % executableFileName().toLower() % QLatin1String("/usr/bin/")
+                             % executableFileName());
+    if (QFile::exists(targetFile)) {
+        if (!QFile::remove(targetFile)) {
+            qDebug("Error: Could not remove '%s'", qPrintable(targetFile));
+            return false;
+        }
+    }
+    if (!QFile::copy(executable(), targetFile)) {
+        qDebug("Error: Could not copy '%s' to '%s'",
+               qPrintable(executable()), qPrintable(targetFile));
+        return false;
+    }
+
+    const QStringList commands = QStringList() << QLatin1String("dh_link")
+        << QLatin1String("dh_fixperms") << QLatin1String("dh_installdeb")
+        << QLatin1String("dh_shlibdeps") << QLatin1String("dh_gencontrol")
+        << QLatin1String("dh_md5sums") << QLatin1String("dh_builddeb --destdir=.");
+    foreach (const QString &command, commands) {
+        if (!runCommand(buildProc, command))
+            return false;
+    }
+
+    return true;
+}
+
+bool MaemoPackageCreationStep::runCommand(QProcess &proc,
+                                          const QString &command)
+{
+    qDebug("Running command '%s'", qPrintable(command));
+    proc.start(maddeRoot() % QLatin1String("/madbin/") % command);
+    proc.write("\n"); // For dh_make
+    if (!proc.waitForFinished(10000) && proc.error() == QProcess::Timedout) {
+        qDebug("command '%s' hangs", qPrintable(command));
+        return false;
+    }
+    if (proc.exitCode() != 0) {
+        qDebug("command '%s' failed with return value %d and output '%s'",
+               qPrintable(command),  proc.exitCode(),
+               (proc.readAllStandardOutput() + "\n" + proc.readAllStandardError()).data());
+        return false;
+    }
+    qDebug("Command finished, output was '%s'",
+           (proc.readAllStandardOutput() + "\n" + proc.readAllStandardError()).data());
+    return true;
+}
+
+const Qt4BuildConfiguration *MaemoPackageCreationStep::qt4BuildConfiguration() const
+{
+    return static_cast<Qt4BuildConfiguration *>(buildConfiguration());
+}
+
+QString MaemoPackageCreationStep::executable() const
+{
+    return qt4BuildConfiguration()->qt4Target()->qt4Project()->rootProjectNode()
+        ->targetInformation().executable;
+}
+
+QString MaemoPackageCreationStep::executableFileName() const
+{
+    return QFileInfo(executable()).fileName();
+}
+
+const MaemoToolChain *MaemoPackageCreationStep::maemoToolChain() const
+{
+    return static_cast<MaemoToolChain *>(qt4BuildConfiguration()->toolChain());
+}
+
+QString MaemoPackageCreationStep::maddeRoot() const
+{
+    return maemoToolChain()->maddeRoot();
+}
+
+QString MaemoPackageCreationStep::targetRoot() const
+{
+    return maemoToolChain()->targetRoot();
+}
+
+bool MaemoPackageCreationStep::packagingNeeded() const
+{
+#if 0
+    QFileInfo execInfo(executable());
+    const QString packageFile = execInfo.absolutePath() % QLatin1Char('/')
+        % executableFileName() % QLatin1String("_0.1_armel.deb");
+    QFileInfo packageInfo(packageFile);
+    return !packageInfo.exists()
+        || packageInfo.lastModified() <= execInfo.lastModified();
+#else
+    return false;
+#endif
+}
+
 const QLatin1String MaemoPackageCreationStep::CreatePackageId("Qt4ProjectManager.MaemoPackageCreationStep");
 
 } // namespace Internal
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationstep.h b/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationstep.h
index 072e2a202bb..b80ce7db881 100644
--- a/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationstep.h
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationstep.h
@@ -44,9 +44,16 @@
 
 #include <projectexplorer/buildstep.h>
 
+QT_BEGIN_NAMESPACE
+class QProcess;
+QT_END_NAMESPACE
+
 namespace Qt4ProjectManager {
 namespace Internal {
 
+class MaemoToolChain;
+class Qt4BuildConfiguration;
+
 class MaemoPackageCreationStep : public ProjectExplorer::BuildStep
 {
     friend class MaemoPackageCreationFactory;
@@ -61,6 +68,16 @@ private:
     virtual ProjectExplorer::BuildStepConfigWidget *createConfigWidget();
     virtual bool immutable() const { return true; }
 
+    bool createPackage();
+    bool runCommand(QProcess &proc, const QString &command);
+    const Qt4BuildConfiguration *qt4BuildConfiguration() const;
+    const MaemoToolChain *maemoToolChain() const;
+    QString executable() const;
+    QString executableFileName() const;
+    QString maddeRoot() const;
+    QString targetRoot() const;
+    bool packagingNeeded() const;
+
     static const QLatin1String CreatePackageId;
 };
 
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.cpp
index 288044ea7b2..60906fb95c7 100644
--- a/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.cpp
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.cpp
@@ -76,13 +76,6 @@ void AbstractMaemoRunControl::startDeployment(bool forDebugging)
             deployables.append(Deployable(executableFileName(),
                 QFileInfo(executableOnHost()).canonicalPath(),
                 &MaemoRunConfiguration::wasDeployed));
-            if (false) {
-                if (!buildPackage()) {
-                    qDebug("Error: Could not build package");
-                    handleDeploymentFinished(false);
-                    return;
-                }
-            }
         }
         if (forDebugging
             && runConfig->debuggingHelpersNeedDeployment(devConfig.host)) {
@@ -97,106 +90,6 @@ void AbstractMaemoRunControl::startDeployment(bool forDebugging)
     }
 }
 
-bool AbstractMaemoRunControl::buildPackage()
-{
-    qDebug("%s", Q_FUNC_INFO);
-    const QString projectDir = QFileInfo(executableOnHost()).absolutePath();
-
-    QFile configFile(runConfig->targetRoot() % QLatin1String("/config.sh"));
-    if (!configFile.open(QIODevice::ReadOnly)) {
-        qDebug("Cannot open config file '%s'", qPrintable(configFile.fileName()));
-        return false;
-    }
-    const QString &maddeRoot = runConfig->maddeRoot();
-    QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
-    const QLatin1String pathKey("PATH");
-    env.insert(pathKey,  maddeRoot % QLatin1String("/madbin:")
-                                        % env.value(pathKey));
-    env.insert(QLatin1String("PERL5LIB"),
-           maddeRoot % QLatin1String("/madlib/perl5"));
-    const QRegExp envPattern(QLatin1String("([^=]+)=[\"']?([^;\"']+)[\"']? ;.*"));
-    env.insert(QLatin1String("PWD"), projectDir);
-    QByteArray line;
-    do {
-        line = configFile.readLine(200);
-        if (envPattern.exactMatch(line))
-            env.insert(envPattern.cap(1), envPattern.cap(2));
-    } while (!line.isEmpty());
-    qDebug("Process environment: %s",
-        qPrintable(env.toStringList().join(QLatin1String(":"))));
-    qDebug("sysroot: '%s'", qPrintable(env.value(QLatin1String("SYSROOT_DIR"))));
-    QProcess buildProc;
-    buildProc.setProcessEnvironment(env);
-    buildProc.setWorkingDirectory(projectDir);
-
-    if (!QFileInfo(projectDir + QLatin1String("/debian")).exists()) {
-        if (!runCommand(buildProc, QLatin1String("dh_make -s -n")))
-            return false;
-        QFile rulesFile(projectDir + QLatin1String("/debian/rules"));
-        if (!rulesFile.open(QIODevice::ReadWrite)) {
-            qDebug("Error: Could not open debian/rules.");
-            return false;
-        }
-
-        QByteArray rulesContents = rulesFile.readAll();
-        rulesContents.replace("DESTDIR", "INSTALL_ROOT");
-        rulesFile.resize(0);
-        rulesFile.write(rulesContents);
-        if (rulesFile.error() != QFile::NoError) {
-            qDebug("Error: could not access debian/rules");
-            return false;
-        }
-    }
-
-    if (!runCommand(buildProc, QLatin1String("dh_installdirs")))
-        return false;
-    const QString targetFile(projectDir % QLatin1String("/debian/")
-                  % executableFileName().toLower() % QLatin1String("/usr/bin/")
-                  % executableFileName());
-    if (QFile::exists(targetFile)) {
-        if (!QFile::remove(targetFile)) {
-            qDebug("Error: Could not remove '%s'", qPrintable(targetFile));
-            return false;
-        }
-    }
-    if (!QFile::copy(executableOnHost(), targetFile)) {
-        qDebug("Error: Could not copy '%s' to '%s'",
-            qPrintable(executableOnHost()), qPrintable(targetFile));
-        return false;
-    }
-
-    const QStringList commands = QStringList() << QLatin1String("dh_link")
-        << QLatin1String("dh_fixperms") << QLatin1String("dh_installdeb")
-        << QLatin1String("dh_shlibdeps") << QLatin1String("dh_gencontrol")
-        << QLatin1String("dh_md5sums") << QLatin1String("dh_builddeb --destdir=.");
-    foreach (const QString &command, commands) {
-        if (!runCommand(buildProc, command))
-            return false;
-    }
-
-    return true;
-}
-
-bool AbstractMaemoRunControl::runCommand(QProcess &proc,
-             const QString &command)
-{
-    qDebug("Running command '%s'", qPrintable(command));
-    proc.start(runConfig->maddeRoot() % QLatin1String("/madbin/") % command);
-    proc.write("\n"); // For dh_make
-    if (!proc.waitForFinished(5000) && proc.error() == QProcess::Timedout) {
-        qDebug("command '%s' hangs", qPrintable(command));
-        return false;
-    }
-    if (proc.exitCode() != 0) {
-        qDebug("command '%s' failed with return value %d and output '%s'",
-               qPrintable(command),  proc.exitCode(),
-               (proc.readAllStandardOutput() + "\n" + proc.readAllStandardError()).data());
-        return false;
-    }
-    qDebug("Command finished, output was '%s'",
-        (proc.readAllStandardOutput() + "\n" + proc.readAllStandardError()).data());
-    return true;
-}
 
 void AbstractMaemoRunControl::deploy()
 {
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.h b/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.h
index 6f925dc8532..bcc9de92abe 100644
--- a/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.h
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.h
@@ -89,9 +89,6 @@ protected:
 private:
     virtual void handleDeploymentFinished(bool success)=0;
 
-    bool buildPackage();
-    bool runCommand(QProcess &proc, const QString &command);
-
     QFutureInterface<void> m_progress;
     QScopedPointer<MaemoSshDeployer> sshDeployer;
 
-- 
GitLab