edi/src/lib/edi_build_provider_meson.c

170 lines
3.7 KiB
C

#ifdef HAVE_CONFIG
# include "config.h"
#endif
#include <unistd.h>
#include <Eina.h>
#include <Ecore.h>
#include <Ecore_File.h>
#include "Edi.h"
#include "edi_private.h"
typedef struct {
char *basedir;
char *builddir;
char *fulldir; /* basedir + builddir */
} Meson_Data;
static Eina_Bool
_meson_project_supported(const char *path)
{
return edi_path_relative_exists(path, "meson.build");
}
static Meson_Data *
_meson_data_get(void)
{
// FIXME: I hate static globals
// FIXME: this needs to be freed on project change / shutdown!
static Meson_Data *md = NULL;
if (md) return md;
md = calloc(1, sizeof(*md));
md->basedir = strdup(edi_project_get());
md->builddir = strdup("build"); // FIXME: "build" dir needs to be user-defined
md->fulldir = edi_path_append(md->basedir, md->builddir);
return md;
}
static Eina_Bool
_meson_configured_check(const char *dir)
{
const char *build_ninja;
build_ninja = eina_slstr_steal_new(edi_path_append(dir, "build.ninja"));
if (ecore_file_exists(build_ninja))
return EINA_TRUE;
return EINA_FALSE;
}
static Eina_Bool
_meson_file_hidden_is(const char *file)
{
size_t k;
if (!file || strlen(file) == 0)
return EINA_FALSE;
static const char *hidden_exts[] = {
".o", ".so", ".lo",
".ninja", ".ninja", ".ninja_deps", ".ninja_log",
"compile_commands.json", "meson-logs", "meson-private", "@exe"
};
if (ecore_file_is_dir(file) && _meson_configured_check(file))
return EINA_TRUE;
for (k = 0; k < EINA_C_ARRAY_LENGTH(hidden_exts); k++)
if (eina_str_has_extension(file, hidden_exts[k]))
return EINA_TRUE;
return EINA_FALSE;
}
static Eina_Bool
_meson_project_runnable_is(const char *path)
{
return ecore_file_can_exec(path);
}
static const char *
_meson_ninja_cmd(Meson_Data *md, const char *arg)
{
return eina_slstr_printf("ninja -C %s %s", md->fulldir, arg ?: "");
}
static void
_meson_ninja_do(Meson_Data *md, const char *arg)
{
const char *cmd;
cmd = _meson_ninja_cmd(md, arg);
if (arg && !strcmp(arg, "clean"))
edi_exe_notify("edi_clean", cmd);
else if (arg && !strcmp(arg, "test"))
edi_exe_notify("edi_test", cmd);
else
edi_exe_notify("edi_build", cmd);
}
static Eina_Bool
_meson_prepare(Meson_Data *md)
{
const char *cmd;
if (_meson_configured_check(md->fulldir)) return EINA_TRUE;
if (chdir(md->basedir) != 0) return EINA_FALSE;
cmd = eina_slstr_printf("meson %s && %s", md->builddir, _meson_ninja_cmd(md, ""));
edi_exe_notify("edi_build", cmd);
return EINA_FALSE;
}
static void
_meson_build(void)
{
Meson_Data *md = _meson_data_get();
if (!_meson_prepare(md))
return;
_meson_ninja_do(md, NULL);
}
static void
_meson_test(void)
{
Meson_Data *md = _meson_data_get();
//if (!_meson_configured_check(md->fulldir)) return;
_meson_ninja_do(md, "test");
}
static void
_meson_run(const char *path, const char *args)
{
Meson_Data *md = _meson_data_get();
const char *cmd;
if (chdir(edi_project_get()) != 0)
ERR("Could not chdir");
if (args) cmd = eina_slstr_printf("%s %s", path, args);
else cmd = path;
edi_exe_project_run(cmd,
ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_PIPE_READ |
ECORE_EXE_PIPE_ERROR_LINE_BUFFERED | ECORE_EXE_PIPE_ERROR |
ECORE_EXE_PIPE_WRITE /*| ECORE_EXE_USE_SH*/, md);
}
static void
_meson_clean(void)
{
Meson_Data *md = _meson_data_get();
//if (!_meson_configured_check(md->fulldir)) return;
_meson_ninja_do(md, "clean");
}
Edi_Build_Provider _edi_build_provider_meson =
{"meson", _meson_project_supported, _meson_file_hidden_is,
_meson_project_runnable_is, _meson_build, _meson_test,
_meson_run, _meson_clean};