Skip to content

Commit 0e4cfad

Browse files
committed
ProjectBuildConfig: add support for meson (#94)
The IDE can now build meson projects. Executables are tested only under linux. Windows should be trivial to fix. closes #94
1 parent 7f9af20 commit 0e4cfad

2 files changed

Lines changed: 95 additions & 0 deletions

File tree

src/plugins/ProjectManager/ProjectBuildConfig.cpp

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
#include <QJsonArray>
66
#include <QJsonDocument>
77
#include <QJsonObject>
8+
#include <QProcess>
9+
#include <QDir>
810

911
bool ExecutableInfo::operator==(const ExecutableInfo &other) const {
1012
/* clang-format off */
@@ -166,13 +168,105 @@ auto ProjectBuildConfig::tryGuessFromGo(const QString &directory)
166168
return value;
167169
}
168170

171+
auto findMesonExecutables(const QString &directory, const QString &buildDir)
172+
-> QHash<QString, QString> {
173+
auto fullBuildPath = directory + QDir::separator() + buildDir;
174+
auto process = QProcess();
175+
process.start("meson", QStringList() << "introspect" << fullBuildPath << "--targets");
176+
process.waitForFinished();
177+
178+
auto output = process.readAllStandardOutput();
179+
if (output.isEmpty()) {
180+
qCritical() << "No output from meson introspect.";
181+
return {};
182+
}
183+
184+
auto parseError = QJsonParseError();
185+
auto doc = QJsonDocument::fromJson(output, &parseError);
186+
if (parseError.error != QJsonParseError::NoError) {
187+
qCritical() << "Failed to parse JSON:" << parseError.errorString();
188+
return {};
189+
}
190+
191+
auto targets = doc.array();
192+
auto result = QHash<QString, QString>();
193+
for (auto value : targets) {
194+
QJsonObject obj = value.toObject();
195+
if (obj["type"].toString() == "executable") {
196+
auto name = obj["name"].toString();
197+
auto filenames = obj["filename"].toArray();
198+
if (!filenames.isEmpty()) {
199+
auto fullPath = filenames.first().toString();
200+
auto relativeToDir = QDir(directory).relativeFilePath(fullPath);
201+
result.insert(name, relativeToDir);
202+
}
203+
}
204+
}
205+
return result;
206+
}
207+
208+
std::shared_ptr<ProjectBuildConfig>
209+
ProjectBuildConfig::tryGuessFromMeson(const QString &directory) {
210+
auto gomodFileName = directory + "/" + "meson.build";
211+
auto di = QFileInfo(directory);
212+
auto fi = QFileInfo(gomodFileName);
213+
if (!fi.isReadable()) {
214+
return {};
215+
}
216+
217+
auto value = std::make_shared<ProjectBuildConfig>();
218+
value->name = di.baseName();
219+
value->sourceDir = directory;
220+
value->hideFilter = ".git;.vscode;";
221+
value->buildDir = "mbuild"; // meson build?
222+
223+
{
224+
auto executables = findMesonExecutables(directory, value->buildDir);
225+
for (auto it = executables.constBegin(); it != executables.constEnd(); ++it) {
226+
auto name = it.key();
227+
auto path = it.value();
228+
auto e = ExecutableInfo();
229+
e.name = name;
230+
e.runDirectory = "${source_directory}";
231+
e.executables["windows"] = path + ".exe";
232+
e.executables["linux"] = path;
233+
value->executables.push_back(e);
234+
}
235+
}
236+
{
237+
auto t = TaskInfo();
238+
t.name = "meson setup";
239+
t.runDirectory = "${source_directory}";
240+
t.command = "meson setup ${build_directory}";
241+
value->tasksInfo.push_back(t);
242+
}
243+
{
244+
auto t = TaskInfo();
245+
t.name = "meson build";
246+
t.runDirectory = "${source_directory}";
247+
t.command = "meson compile -C ${build_directory}";
248+
value->tasksInfo.push_back(t);
249+
}
250+
{
251+
auto t = TaskInfo();
252+
t.name = "meson tests";
253+
t.runDirectory = "${source_directory}";
254+
t.command = "meson test -C ${build_directory}";
255+
value->tasksInfo.push_back(t);
256+
}
257+
return value;
258+
}
259+
169260
std::shared_ptr<ProjectBuildConfig>
170261
ProjectBuildConfig::buildFromDirectory(const QString &directory) {
171262
auto configFileName = directory + QDir::separator() + "qtedit4.json";
172263
auto config = buildFromFile(configFileName);
173264
if (!config) {
174265
config = tryGuessFromCMake(directory);
175266
}
267+
if (!config) {
268+
config = tryGuessFromMeson(directory);
269+
}
176270
if (!config) {
177271
config = tryGuessFromCargo(directory);
178272
}

src/plugins/ProjectManager/ProjectBuildConfig.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ struct ProjectBuildConfig {
3939
static auto tryGuessFromCMake(const QString &directory) -> std::shared_ptr<ProjectBuildConfig>;
4040
static auto tryGuessFromCargo(const QString &directory) -> std::shared_ptr<ProjectBuildConfig>;
4141
static auto tryGuessFromGo(const QString &directory) -> std::shared_ptr<ProjectBuildConfig>;
42+
static auto tryGuessFromMeson(const QString &directory) -> std::shared_ptr<ProjectBuildConfig>;
4243
static auto buildFromDirectory(const QString &directory) -> std::shared_ptr<ProjectBuildConfig>;
4344
static auto buildFromFile(const QString &jsonFileName) -> std::shared_ptr<ProjectBuildConfig>;
4445
static auto canLoadFile(const QString &filename) -> bool;

0 commit comments

Comments
 (0)