File indexing completed on 2024-05-05 04:40:21
0001 /* 0002 SPDX-FileCopyrightText: 2010 Milian Wolff <mail@milianw.de> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "qmakejob.h" 0008 #include <QDir> 0009 #include <QProcess> 0010 #include <KLocalizedString> 0011 #include <KShell> 0012 #include <util/processlinemaker.h> 0013 #include <outputview/outputmodel.h> 0014 #include <outputview/ioutputview.h> 0015 #include <debug.h> 0016 0017 using namespace KDevelop; 0018 0019 QMakeJob::QMakeJob(QString srcDir, QString buildDir, QObject* parent) 0020 : OutputJob(parent) 0021 , m_srcDir(std::move(srcDir)) 0022 , m_buildDir(std::move(buildDir)) 0023 , m_qmakePath(QStringLiteral("qmake")) 0024 , m_buildType(0) 0025 , m_process(nullptr) 0026 , m_model(nullptr) 0027 0028 { 0029 setCapabilities(Killable); 0030 setStandardToolView(IOutputView::RunView); 0031 setBehaviours(IOutputView::AllowUserClose | IOutputView::AutoScroll); 0032 0033 setObjectName(i18n("Run QMake in %1", m_buildDir)); 0034 } 0035 0036 QMakeJob::~QMakeJob() 0037 { 0038 } 0039 0040 void QMakeJob::setQMakePath(const QString& path) 0041 { 0042 m_qmakePath = path; 0043 } 0044 0045 void QMakeJob::setInstallPrefix(const QString& prefix) 0046 { 0047 m_installPrefix = prefix; 0048 } 0049 0050 void QMakeJob::setBuildType(int comboboxSelectedIndex) 0051 { 0052 m_buildType = comboboxSelectedIndex; 0053 } 0054 0055 void QMakeJob::setExtraArguments(const QString& args) 0056 { 0057 m_extraArguments = args; 0058 } 0059 0060 void QMakeJob::start() 0061 { 0062 static const char* const BUILD_TYPES[] = { "debug", "build", "(don't specify)" }; 0063 0064 m_model = new OutputModel; 0065 setModel(m_model); 0066 0067 startOutput(); 0068 0069 QStringList args; 0070 if (m_buildType < 2) 0071 args << QLatin1String("CONFIG+=") + QLatin1String(BUILD_TYPES[m_buildType]); 0072 if (!m_installPrefix.isEmpty()) 0073 args << QLatin1String("target.path=") + m_installPrefix; 0074 if (!m_extraArguments.isEmpty()) { 0075 KShell::Errors err; 0076 QStringList tmp = KShell::splitArgs(m_extraArguments, KShell::TildeExpand | KShell::AbortOnMeta, &err); 0077 if (err == KShell::NoError) { 0078 args += tmp; 0079 } else { 0080 qCWarning(KDEV_QMAKE) << "Ignoring qmake Extra arguments"; 0081 if (err == KShell::BadQuoting) { 0082 qCWarning(KDEV_QMAKE) << "QMake arguments badly quoted:" << m_extraArguments; 0083 } else { 0084 qCWarning(KDEV_QMAKE) << "QMake arguments had meta character:" << m_extraArguments; 0085 } 0086 } 0087 } 0088 args << QStringLiteral("-r") << m_srcDir; 0089 0090 m_model->appendLine(m_buildDir + QLatin1String(": ") + args.join(QLatin1Char(' '))); 0091 0092 QDir build(m_buildDir); 0093 if (!build.exists()) { 0094 build.mkpath(build.absolutePath()); 0095 } 0096 0097 m_process = new QProcess(this); 0098 m_process->setWorkingDirectory(m_buildDir); 0099 m_process->setProgram(m_qmakePath); 0100 m_process->setArguments(args); 0101 m_process->setProcessChannelMode(QProcess::MergedChannels); 0102 auto lineMaker = new KDevelop::ProcessLineMaker(m_process, this); 0103 0104 connect(lineMaker, &ProcessLineMaker::receivedStdoutLines, m_model, &OutputModel::appendLines); 0105 connect(lineMaker, &ProcessLineMaker::receivedStderrLines, m_model, &OutputModel::appendLines); 0106 connect(m_process, SIGNAL(error(QProcess::ProcessError)), SLOT(processError(QProcess::ProcessError))); 0107 connect(m_process, SIGNAL(finished(int,QProcess::ExitStatus)), SLOT(processFinished(int,QProcess::ExitStatus))); 0108 0109 m_process->start(); 0110 } 0111 0112 bool QMakeJob::doKill() 0113 { 0114 if (!m_process) { 0115 return true; 0116 } 0117 0118 m_process->kill(); 0119 return m_process->state() == m_process->NotRunning; 0120 } 0121 0122 QString QMakeJob::errorString() const 0123 { 0124 return m_process->errorString(); 0125 } 0126 0127 void QMakeJob::processError(QProcess::ProcessError error) 0128 { 0129 m_model->appendLine(errorString()); 0130 setError(error); 0131 emitResult(); 0132 } 0133 0134 void QMakeJob::processFinished(int exitCode, QProcess::ExitStatus status) 0135 { 0136 if (status == QProcess::NormalExit) { 0137 m_model->appendLine(i18n("*** Exited with return code: %1 ***", exitCode)); 0138 } else if (error() == KJob::KilledJobError) { 0139 m_model->appendLine(i18n("*** Process aborted ***")); 0140 } else { 0141 m_model->appendLine(i18n("*** Crashed with return code: %1 ***", exitCode)); 0142 } 0143 0144 emitResult(); 0145 } 0146 0147 #include "moc_qmakejob.cpp"