Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bsys: Meson build system #92

Merged
merged 10 commits into from
Jan 11, 2025
36 changes: 19 additions & 17 deletions src/bsys.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,12 @@ bsys_t const* bsys_identify(void) {
}

int bsys_dep_tree(bsys_t const* bsys, int argc, char* argv[]) {
dep_node_t* tree = NULL;
int rv = -1;

if (bsys->dep_tree == NULL) {
return 0;
rv = 0;
goto no_tree;
}

// Parse the arguments as a list of hashes.
Expand All @@ -43,27 +47,29 @@ int bsys_dep_tree(bsys_t const* bsys, int argc, char* argv[]) {
// Create dependency tree.

bool circular;
dep_node_t* const tree = bsys->dep_tree(argc, hashes, &circular);
tree = bsys->dep_tree(argc, hashes, &circular);
free(hashes);

if (tree == NULL) {
if (circular) {
printf(BOB_DEPS_CIRCULAR);
return 0;
}
if (tree == NULL && circular) {
printf(BOB_DEPS_CIRCULAR);
return 0;
}

return -1;
if (tree != NULL) {
rv = 0;
}

assert(!circular);

// Serialize and output it.

char* const STR_CLEANUP serialized = dep_node_serialize(tree);
no_tree:;

char* const STR_CLEANUP serialized = tree == NULL ? strdup("") : dep_node_serialize(tree);
printf(DEP_TAG_START "%s" DEP_TAG_END, serialized);

deps_tree_free(tree);
return 0;
return rv;
}

static int do_build_deps(bsys_t const* bsys) {
Expand Down Expand Up @@ -117,16 +123,12 @@ int bsys_build(bsys_t const* bsys) {
// TODO Do this with mkdir_recursive? Do this in main.c?

if (bsys->key != NULL) {
char* STR_CLEANUP path;
asprintf(&path, "%s/%s", out_path, bsys->key);
assert(path != NULL);

if (mkdir_wrapped(path, 0755) < 0 && errno != EEXIST) {
LOG_FATAL("mkdir(\"%s\"): %s", path, strerror(errno));
if (mkdir_wrapped(bsys_out_path, 0755) < 0 && errno != EEXIST) {
LOG_FATAL("mkdir(\"%s\"): %s", bsys_out_path, strerror(errno));
return -1;
}

set_owner(path);
set_owner(bsys_out_path);
}

// Actually build.
Expand Down
84 changes: 83 additions & 1 deletion src/bsys/meson/main.c
Original file line number Diff line number Diff line change
@@ -1,18 +1,100 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2024 Aymeric Wibo

#include <common.h>

#include <bsys.h>
#include <cmd.h>
#include <fsutil.h>
#include <logging.h>
#include <str.h>

#include <assert.h>
#include <stdio.h>
#include <unistd.h>

#define BUILD_PATH "meson.build"

static bool identify(void) {
return false;
return access(BUILD_PATH, F_OK) != -1;
}

static int setup(void) {
if (!cmd_exists("meson")) {
LOG_FATAL("Couldn't find 'meson' executable in PATH. Meson is something you must install separately.");
return -1;
}

if (!cmd_exists("ninja")) {
LOG_FATAL("Couldn't find 'ninja' executable in PATH. Ninja is something you must install separately, and is necessary for the Meson BSYS.");
return -1;
}

return 0;
}

static int build(void) {
LOG_INFO("Meson setup...");

char* STR_CLEANUP prefix = NULL;
asprintf(&prefix, "-Dprefix=%s", install_prefix);
assert(prefix != NULL);

cmd_t CMD_CLEANUP cmd = {0};
cmd_create(&cmd, "meson", "setup", bsys_out_path, prefix, NULL);
cmd_set_redirect(&cmd, false);

if (cmd_exec(&cmd) < 0) {
LOG_FATAL("Meson setup failed.");
return -1;
}

else {
LOG_SUCCESS("Meson setup succeeded.");
}

LOG_INFO("Ninja build...");

cmd_free(&cmd);
cmd_create(&cmd, "ninja", "-C", bsys_out_path, NULL);
cmd_set_redirect(&cmd, false);

if (cmd_exec(&cmd) < 0) {
LOG_FATAL("Ninja build failed.");
return -1;
}

else {
LOG_SUCCESS("Ninja build succeeded.");
}

return 0;
}

static int install(void) {
LOG_SUCCESS("Ninja install...");

cmd_t CMD_CLEANUP cmd = {0};
cmd_create(&cmd, "ninja", "-C", bsys_out_path, "install", NULL);
cmd_set_redirect(&cmd, false);

if (cmd_exec(&cmd) < 0) {
LOG_FATAL("Ninja install failed.");
return -1;
}

else {
LOG_SUCCESS("Ninja install succeeded.");
}

return 0;
}

bsys_t const BSYS_MESON = {
.name = "Meson",
.key = "meson",
.identify = identify,
.setup = setup,
.build = build,
.install = install,
};
2 changes: 1 addition & 1 deletion src/class/linker.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ static int prep_link(state_t* state, flamingo_arg_list_t* args, flamingo_val_t**
}

char* STR_CLEANUP cookie = NULL;
asprintf(&cookie, "%s/bob/linker.%s.cookie.%" PRIx64 ".%s", out_path, infinitive, total_hash, archive ? "a" : "l");
asprintf(&cookie, "%s/linker.%s.cookie.%" PRIx64 ".%s", bsys_out_path, infinitive, total_hash, archive ? "a" : "l");
assert(cookie != NULL);
*rv = flamingo_val_make_cstr(cookie);

Expand Down
1 change: 1 addition & 0 deletions src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ extern char const* bootstrap_import_path;

extern char const* out_path;
extern char const* abs_out_path;
extern char* bsys_out_path;

extern char* deps_path;
extern _Bool build_deps;
Expand Down
4 changes: 2 additions & 2 deletions src/cookie.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@

char* gen_cookie(char* path, size_t path_size, char const* ext) {
char* cookie = NULL;
asprintf(&cookie, "%s/bob/%.*s.cookie.%" PRIx64 ".%s", out_path, (int) path_size, path, str_hash(path, path_size), ext);
asprintf(&cookie, "%s/%.*s.cookie.%" PRIx64 ".%s", bsys_out_path, (int) path_size, path, str_hash(path, path_size), ext);
assert(cookie != NULL);

size_t const prefix_len = strlen(out_path) + strlen("/bob/");
size_t const prefix_len = strlen(bsys_out_path) + strlen("/");

for (size_t i = prefix_len; i < prefix_len + path_size; i++) {
if (cookie[i] == '/') {
Expand Down
6 changes: 6 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ char const* bootstrap_import_path = "import";

char const* out_path = ".bob"; // Default output path.
char const* abs_out_path = NULL;
char* bsys_out_path = NULL;

char* deps_path = NULL;
bool build_deps = true;
Expand Down Expand Up @@ -284,6 +285,11 @@ int main(int argc, char* argv[]) {
return EXIT_FAILURE;
}

if (bsys->key != NULL) {
asprintf(&bsys_out_path, "%s/%s", out_path, bsys->key);
assert(bsys_out_path != NULL);
}

if (bsys->setup && bsys->setup() < 0) {
return EXIT_FAILURE;
}
Expand Down
14 changes: 14 additions & 0 deletions tests/dep_tree.sh
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,17 @@ elif ! echo $out | grep -q "Could not find local dependency at 'this-dep-doesnt-
echo "Another issue occurred when attempting to create a dependency tree with a dependency which doesn't exist: $out" >&2
exit 1
fi

# Test that we output an empty tree if there are no dependencies.
# Regression test for d1619dd "bsys: Output empty dependency tree if bsys doesn't have `dep_tree` function".

cp tests/deps/build.none.fl tests/deps/build.fl
out=$(bob -C tests/deps dep-tree 2>&1)

if [ $? != 0 ]; then
echo "Failed when attempting to create a dependency tree with no dependencies: $out" >&2
exit 1
elif ! echo $out | grep -q "<bob-dep-tree> </bob-dep-tree>"; then
echo "Dependency tree not empty when attempting to create a dependency tree with no dependencies: $out" >&2
exit 1
fi
6 changes: 6 additions & 0 deletions tests/deps/build.none.fl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# SPDX-License-Identifier: MIT
# Copyright (c) 2025 Aymeric Wibo

import bob

deps = []
Loading