File: cmakejob.cpp

package info (click to toggle)
kdevelop 4%3A24.12.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 71,888 kB
  • sloc: cpp: 290,869; python: 3,626; javascript: 3,518; sh: 1,316; ansic: 703; xml: 401; php: 95; lisp: 66; makefile: 31; sed: 12
file content (142 lines) | stat: -rw-r--r-- 4,532 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*
    SPDX-FileCopyrightText: 2006-2007 Andreas Pakulat <apaku@gmx.de>
    SPDX-FileCopyrightText: 2008 Hamish Rodda <rodda@kde.org>

    SPDX-License-Identifier: GPL-2.0-or-later
*/


#include "cmakejob.h"

#include <cmakebuilderconfig.h>
#include <cmakebuilder.h>

#include <QDir>

#include <project/projectmodel.h>

#include <interfaces/iproject.h>
#include <interfaces/icore.h>
#include <interfaces/iruntime.h>
#include <interfaces/iruntimecontroller.h>

#include <cmakeutils.h>
#include <cmakefileapi.h>
#include "debug.h"

#include <KShell>
#include <KLocalizedString>

using namespace KDevelop;

CMakeJob::CMakeJob(QObject* parent)
    : OutputExecuteJob(parent)
{
    setCapabilities( Killable );
    setFilteringStrategy( OutputModel::CompilerFilter );
    setProperties( NeedWorkingDirectory | PortableMessages | DisplayStderr | IsBuilderHint );
    setToolTitle( i18n("CMake") );
    setStandardToolView( KDevelop::IOutputView::BuildView );
    setBehaviours(KDevelop::IOutputView::AllowUserClose | KDevelop::IOutputView::AutoScroll );
}

void CMakeJob::start()
{
    qCDebug(KDEV_CMAKEBUILDER) << "Configuring cmake" << workingDirectory();

    auto error = [this](ErrorTypes error, const QString &message)
    {
        qCWarning(KDEV_CMAKEBUILDER) << "failed" << error << message;
        setError(error);
        setErrorText(message);
        emitResult();
    };

    if( !m_project ) {
        error(NoProjectError, i18n("Internal error: no project specified to configure."));
        return;
    }

    const auto workingDir = workingDirectory().toLocalFile();
    QDir dir;
    if (!dir.mkpath(workingDir)) {
        error(FailedError, i18n("Failed to create build directory %1.", workingDir));
        return;
    }
    CMake::FileApi::writeClientQueryFile(workingDir);
    CMake::updateConfig( m_project, CMake::currentBuildDirIndex(m_project) );

    OutputExecuteJob::start();
}

QUrl CMakeJob::workingDirectory() const
{
    KDevelop::Path path = CMake::currentBuildDir( m_project );
    qCDebug(KDEV_CMAKEBUILDER) << "builddir: " << path;
    Q_ASSERT(path.isValid()); //We cannot get the project folder as a build directory!
    return path.toUrl();
}

QStringList CMakeJob::commandLine() const
{
    QStringList args;
    args << CMake::currentCMakeExecutable( m_project ).toLocalFile();

    args << QStringLiteral("-DCMAKE_EXPORT_COMPILE_COMMANDS=ON");

    QString installDir = CMake::currentInstallDir( m_project ).toLocalFile();
    if( !installDir.isEmpty() )
    {
        args << QStringLiteral("-DCMAKE_INSTALL_PREFIX=%1").arg(installDir);
    }
    QString buildType = CMake::currentBuildType( m_project );
    if( !buildType.isEmpty() )
    {
        args << QStringLiteral("-DCMAKE_BUILD_TYPE=%1").arg(buildType);
    }
    QVariantMap cacheArgs = property("extraCMakeCacheValues").toMap();
    for( auto it = cacheArgs.constBegin(), itEnd = cacheArgs.constEnd(); it!=itEnd; ++it) {
        args << QStringLiteral("-D%1=%2").arg(it.key(), it.value().toString());
    }

    auto rt = ICore::self()->runtimeController()->currentRuntime();
    //if we are creating a new build directory, we'll want to specify the generator
    QDir builddir(rt->pathInRuntime(CMake::currentBuildDir( m_project )).toLocalFile());
    if(!builddir.exists() || !builddir.exists(QStringLiteral("CMakeCache.txt"))) {
        CMakeBuilderSettings::self()->load();
        args << QStringLiteral("-G") << CMake::defaultGenerator();
    }
    QString cmakeargs = CMake::currentExtraArguments( m_project );
    if( !cmakeargs.isEmpty() ) {
        KShell::Errors err;
        QStringList tmp = KShell::splitArgs( cmakeargs, KShell::TildeExpand | KShell::AbortOnMeta, &err );
        if( err == KShell::NoError ) {
            args += tmp;
        } else {
            qCWarning(KDEV_CMAKEBUILDER) << "Ignoring cmake Extra arguments";
            if( err == KShell::BadQuoting ) {
                qCWarning(KDEV_CMAKEBUILDER) << "CMake arguments badly quoted:" << cmakeargs;
            } else {
                qCWarning(KDEV_CMAKEBUILDER) << "CMake arguments had meta character:" << cmakeargs;
            }
        }
    }
    args << rt->pathInRuntime(CMake::projectRoot( m_project )).toLocalFile();

    return args;
}

QString CMakeJob::environmentProfile() const
{
    return CMake::currentEnvironment( m_project );
}

void CMakeJob::setProject(KDevelop::IProject* project)
{
    m_project = project;

    if (m_project)
        setJobName( i18n("CMake: %1", m_project->name()) );
}

#include "moc_cmakejob.cpp"