File indexing completed on 2024-04-28 04:38:57

0001 /*
0002     SPDX-FileCopyrightText: 2004 Roberto Raggi <roberto@kdevelop.org>
0003     SPDX-FileCopyrightText: 2007 Andreas Pakulat <apaku@gmx.de>
0004     SPDX-FileCopyrightText: 2007 Dukju Ahn <dukjuahn@gmail.com>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #include "makebuilder.h"
0010 #include "debug.h"
0011 #include "makebuilderpreferences.h"
0012 
0013 #include <project/projectmodel.h>
0014 #include <project/builderjob.h>
0015 
0016 #include <interfaces/iproject.h>
0017 
0018 #include <KPluginFactory>
0019 #include <KConfigGroup>
0020 
0021 K_PLUGIN_FACTORY_WITH_JSON(MakeBuilderFactory, "kdevmakebuilder.json", registerPlugin<MakeBuilder>(); )
0022 
0023 MakeBuilder::MakeBuilder(QObject *parent, const QVariantList &)
0024     : KDevelop::IPlugin(QStringLiteral("kdevmakebuilder"), parent)
0025 {
0026 }
0027 
0028 MakeBuilder::~MakeBuilder()
0029 {
0030 }
0031 
0032 KJob* MakeBuilder::build( KDevelop::ProjectBaseItem *dom )
0033 {
0034     return runMake( dom, MakeJob::BuildCommand );
0035 }
0036 
0037 KJob* MakeBuilder::clean( KDevelop::ProjectBaseItem *dom )
0038 {
0039     return runMake( dom, MakeJob::CleanCommand, QStringList(QStringLiteral("clean")) );
0040 }
0041 
0042 KJob* MakeBuilder::install(KDevelop::ProjectBaseItem *dom, const QUrl &installPath)
0043 {
0044     KSharedConfigPtr configPtr = dom->project()->projectConfiguration();
0045     KConfigGroup builderGroup( configPtr, "MakeBuilder" );
0046     bool installAsRoot = builderGroup.readEntry("Install As Root", false);
0047 
0048     QStringList args(QStringLiteral("install"));
0049     if (!installPath.isEmpty())
0050         args << QLatin1String("DESTDIR=") + installPath.toLocalFile();
0051 
0052     if(installAsRoot) {
0053         auto* job = new KDevelop::BuilderJob;
0054         job->addCustomJob( KDevelop::BuilderJob::Build, build(dom), dom );
0055         job->addCustomJob( KDevelop::BuilderJob::Install, runMake( dom, MakeJob::InstallCommand, args ), dom );
0056         job->updateJobName();
0057         return job;
0058     } else
0059         return runMake( dom, MakeJob::InstallCommand, args );
0060 }
0061 
0062 void MakeBuilder::jobFinished(KJob* job)
0063 {
0064     auto* mj = qobject_cast<MakeJob*>(job);
0065 
0066     if( !mj )
0067         return;
0068 
0069     if (mj->error())
0070     {
0071         emit failed( mj->item() );
0072 
0073     } else
0074     {
0075         switch( mj->commandType() )
0076         {
0077             case MakeJob::BuildCommand:
0078                 emit built( mj->item() );
0079                 break;
0080             case MakeJob::InstallCommand:
0081                 emit installed( mj->item() );
0082                 break;
0083             case MakeJob::CleanCommand:
0084                 emit cleaned( mj->item() );
0085                 break;
0086             case MakeJob::CustomTargetCommand: {
0087                 const auto targets = mj->customTargets();
0088                 for (const QString& target : targets) {
0089                     emit makeTargetBuilt( mj->item(), target );
0090                 }
0091                 break;
0092             }
0093         }
0094     }
0095 }
0096 
0097 KJob* MakeBuilder::executeMakeTarget(KDevelop::ProjectBaseItem* item,
0098                                     const QString& targetname )
0099 {
0100     return executeMakeTargets( item, QStringList(targetname) );
0101 }
0102 
0103 KJob* MakeBuilder::executeMakeTargets(KDevelop::ProjectBaseItem* item,
0104                                     const QStringList& targetnames,
0105                                     const MakeVariables& variables )
0106 {
0107     return runMake( item, MakeJob::CustomTargetCommand, targetnames, variables );
0108 }
0109 
0110 KJob* MakeBuilder::runMake( KDevelop::ProjectBaseItem* item, MakeJob::CommandType c,
0111                             const QStringList& overrideTargets,
0112                             const MakeVariables& variables )
0113 {
0114     ///Running the same builder twice may result in serious problems,
0115     ///so kill jobs already running on the same project
0116     const auto makeJobs = m_activeMakeJobs.data();
0117     for (MakeJob* makeJob : makeJobs) {
0118         if(item && makeJob->item() && makeJob->item()->project() == item->project() && makeJob->commandType() == c) {
0119             qCDebug(KDEV_MAKEBUILDER) << "killing running make job, due to new started build on same project:" << makeJob;
0120             makeJob->kill();
0121         }
0122     }
0123 
0124     auto* job = new MakeJob(this, item, c, overrideTargets, variables);
0125     m_activeMakeJobs.append(job);
0126 
0127     connect(job, &MakeJob::finished, this, &MakeBuilder::jobFinished);
0128     return job;
0129 }
0130 
0131 int MakeBuilder::perProjectConfigPages() const
0132 {
0133     return 1;
0134 }
0135 
0136 KDevelop::ConfigPage* MakeBuilder::perProjectConfigPage(int number, const KDevelop::ProjectConfigOptions& options, QWidget* parent)
0137 {
0138     if (number == 0) {
0139         return new MakeBuilderPreferences(this, options, parent);
0140     }
0141     return nullptr;
0142 }
0143 
0144 #include "makebuilder.moc"
0145 #include "moc_makebuilder.cpp"