File indexing completed on 2024-04-28 04:38:20
0001 /* 0002 SPDX-FileCopyrightText: 2006-2007 Andreas Pakulat <apaku@gmx.de> 0003 SPDX-FileCopyrightText: 2008 Hamish Rodda <rodda@kde.org> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 0009 #include "cmakejob.h" 0010 0011 #include <cmakebuilderconfig.h> 0012 #include <cmakebuilder.h> 0013 0014 #include <QDir> 0015 0016 #include <project/projectmodel.h> 0017 0018 #include <interfaces/iproject.h> 0019 #include <interfaces/icore.h> 0020 #include <interfaces/iruntime.h> 0021 #include <interfaces/iruntimecontroller.h> 0022 0023 #include <cmakeutils.h> 0024 #include <cmakefileapi.h> 0025 #include "debug.h" 0026 0027 #include <KShell> 0028 #include <KLocalizedString> 0029 0030 using namespace KDevelop; 0031 0032 CMakeJob::CMakeJob(QObject* parent) 0033 : OutputExecuteJob(parent) 0034 { 0035 setCapabilities( Killable ); 0036 setFilteringStrategy( OutputModel::CompilerFilter ); 0037 setProperties( NeedWorkingDirectory | PortableMessages | DisplayStderr | IsBuilderHint ); 0038 setToolTitle( i18n("CMake") ); 0039 setStandardToolView( KDevelop::IOutputView::BuildView ); 0040 setBehaviours(KDevelop::IOutputView::AllowUserClose | KDevelop::IOutputView::AutoScroll ); 0041 } 0042 0043 void CMakeJob::start() 0044 { 0045 qCDebug(KDEV_CMAKEBUILDER) << "Configuring cmake" << workingDirectory(); 0046 0047 auto error = [this](ErrorTypes error, const QString &message) 0048 { 0049 qCWarning(KDEV_CMAKEBUILDER) << "failed" << error << message; 0050 setError(error); 0051 setErrorText(message); 0052 emitResult(); 0053 }; 0054 0055 if( !m_project ) { 0056 error(NoProjectError, i18n("Internal error: no project specified to configure.")); 0057 return; 0058 } 0059 0060 const auto workingDir = workingDirectory().toLocalFile(); 0061 QDir dir; 0062 if (!dir.mkpath(workingDir)) { 0063 error(FailedError, i18n("Failed to create build directory %1.", workingDir)); 0064 return; 0065 } 0066 CMake::FileApi::writeClientQueryFile(workingDir); 0067 CMake::updateConfig( m_project, CMake::currentBuildDirIndex(m_project) ); 0068 0069 OutputExecuteJob::start(); 0070 } 0071 0072 QUrl CMakeJob::workingDirectory() const 0073 { 0074 KDevelop::Path path = CMake::currentBuildDir( m_project ); 0075 qCDebug(KDEV_CMAKEBUILDER) << "builddir: " << path; 0076 Q_ASSERT(path.isValid()); //We cannot get the project folder as a build directory! 0077 return path.toUrl(); 0078 } 0079 0080 QStringList CMakeJob::commandLine() const 0081 { 0082 QStringList args; 0083 args << CMake::currentCMakeExecutable( m_project ).toLocalFile(); 0084 0085 args << QStringLiteral("-DCMAKE_EXPORT_COMPILE_COMMANDS=ON"); 0086 0087 QString installDir = CMake::currentInstallDir( m_project ).toLocalFile(); 0088 if( !installDir.isEmpty() ) 0089 { 0090 args << QStringLiteral("-DCMAKE_INSTALL_PREFIX=%1").arg(installDir); 0091 } 0092 QString buildType = CMake::currentBuildType( m_project ); 0093 if( !buildType.isEmpty() ) 0094 { 0095 args << QStringLiteral("-DCMAKE_BUILD_TYPE=%1").arg(buildType); 0096 } 0097 QVariantMap cacheArgs = property("extraCMakeCacheValues").toMap(); 0098 for( auto it = cacheArgs.constBegin(), itEnd = cacheArgs.constEnd(); it!=itEnd; ++it) { 0099 args << QStringLiteral("-D%1=%2").arg(it.key(), it.value().toString()); 0100 } 0101 0102 auto rt = ICore::self()->runtimeController()->currentRuntime(); 0103 //if we are creating a new build directory, we'll want to specify the generator 0104 QDir builddir(rt->pathInRuntime(CMake::currentBuildDir( m_project )).toLocalFile()); 0105 if(!builddir.exists() || !builddir.exists(QStringLiteral("CMakeCache.txt"))) { 0106 CMakeBuilderSettings::self()->load(); 0107 args << QStringLiteral("-G") << CMake::defaultGenerator(); 0108 } 0109 QString cmakeargs = CMake::currentExtraArguments( m_project ); 0110 if( !cmakeargs.isEmpty() ) { 0111 KShell::Errors err; 0112 QStringList tmp = KShell::splitArgs( cmakeargs, KShell::TildeExpand | KShell::AbortOnMeta, &err ); 0113 if( err == KShell::NoError ) { 0114 args += tmp; 0115 } else { 0116 qCWarning(KDEV_CMAKEBUILDER) << "Ignoring cmake Extra arguments"; 0117 if( err == KShell::BadQuoting ) { 0118 qCWarning(KDEV_CMAKEBUILDER) << "CMake arguments badly quoted:" << cmakeargs; 0119 } else { 0120 qCWarning(KDEV_CMAKEBUILDER) << "CMake arguments had meta character:" << cmakeargs; 0121 } 0122 } 0123 } 0124 args << rt->pathInRuntime(CMake::projectRoot( m_project )).toLocalFile(); 0125 0126 return args; 0127 } 0128 0129 QString CMakeJob::environmentProfile() const 0130 { 0131 return CMake::currentEnvironment( m_project ); 0132 } 0133 0134 void CMakeJob::setProject(KDevelop::IProject* project) 0135 { 0136 m_project = project; 0137 0138 if (m_project) 0139 setJobName( i18n("CMake: %1", m_project->name()) ); 0140 } 0141 0142 #include "moc_cmakejob.cpp"