skip to content
==> tests/build.c <==
1/* The builder's rules on temporary trees that need no tools: package ids,
2 * the arch rule, sexc.json fields; a wrong manifest name refused; a wasm-only
3 * program (wasm images skipped) gets its manifest and its variants; a native
4 * program for another OS gets its manifest and source.hash but no binary; a
5 * variant with the wrong name refused. */
6#include "mesh/check.h"
7
8#include "../src/build.h"
9
10#include <stdio.h>
11#include <stdlib.h>
12#include <sys/stat.h>
13#include <unistd.h>
14
15static char root[] = "/tmp/mesh-build-programs-XXXXXX";
16
17static void put(const char *rel, const char *text) {
18    char p[512];
19    snprintf(p, sizeof p, "%s/%s", root, rel);
20    for (char *s = p + strlen(root) + 1; *s; s++)
21        if (*s == '/') { *s = 0; mkdir(p, 0755); *s = '/'; }
22    FILE *f = fopen(p, "w");
23    fputs(text, f);
24    fclose(f);
25}
26static bool exists(const char *rel) {
27    char p[512];
28    snprintf(p, sizeof p, "%s/%s", root, rel);
29    return access(p, F_OK) == 0;
30}
31
32int main(void) {
33    char *id = mbp_pkg_id("@ajax/mesh-prog-hello");
34    CHECK_S(id, "ajax-mesh-prog-hello");
35    free(id);
36    CHECK(mbp_valid_arch("sm_86") && mbp_valid_arch("sm_121") && mbp_valid_arch("sm_90a"));
37    CHECK(!mbp_valid_arch("sm_8") && !mbp_valid_arch("86") && !mbp_valid_arch("sm_86b"));
38    char *f = mbp_json_field("{\n  \"name\": \"@ajax/x\",\n  \"kind\" : \"ptx\"\n}", "kind");
39    CHECK_S(f, "ptx");
40    free(f);
41    CHECK(mbp_json_field("{\"name\": 3}", "name") == NULL);
42    CHECK(strlen(mbp_triple()) > 0);
43
44    CHECK(mkdtemp(root) != NULL);
45    char out[600];
46    snprintf(out, sizeof out, "%s/out", root);
47    mbp_opts o = {.root = root, .out = out, .arch = "sm_86", .sexc = "/nonexistent/sexc", .ptx_link = "/nonexistent/link", .skip_wasm = true};
48    /* A wasm-only program and its variant. */
49    put("programs/pipesrc-wasm/program.toml", "name = \"pipesrc\"\nbackends = [\"wasm\"]\n");
50    put("programs/pipesrc-wasm/sexc.json", "{\"name\": \"@ajax/mesh-prog-pipesrc-wasm\", \"kind\": \"wasm\"}\n");
51    put("programs/pipesrc-wasm/variants/pipesrc-b.toml", "name = \"pipesrc-b\"\nbackends = [\"wasm\"]\n");
52    /* A native program built on another OS only. */
53    put("programs/ane/program.toml", "# build-os: Plan9\nname = \"ane\"\nbackends = [\"native\"]\n");
54    put("programs/ane/sexc.json", "{\"name\": \"@ajax/mesh-prog-ane\", \"kind\": \"executable\"}\n");
55    put("programs/ane/src/main.c", "int main(void) { return 0; }\n");
56    put("packages/mesh-abi-x/include/x.h", "int x;\n");
57    char *names[] = {(char *)"pipesrc", (char *)"ane"};
58    CHECK_I(mbp_run(&o, names, 2), 0);
59    CHECK(exists("out/pipesrc/program.toml"));
60    CHECK(!exists("out/pipesrc/pipesrc.wasm"));
61    CHECK(exists("out/pipesrc-b/program.toml"));
62    CHECK(exists("out/ane/program.toml") && exists("out/ane/source.hash"));
63    char tb[256];
64    snprintf(tb, sizeof tb, "out/ane/%s/ane", mbp_triple());
65    CHECK(!exists(tb));
66    /* A GPU program with no tools: the build fails, it does not invent an image. */
67    put("programs/hello/program.toml", "name = \"hello\"\nbackends = [\"cuda\"]\n");
68    put("programs/hello/sexc.json", "{\"name\": \"@ajax/mesh-prog-hello\", \"kind\": \"ptx\"}\n");
69    char *h[] = {(char *)"hello"};
70    CHECK_I(mbp_run(&o, h, 1), 1);
71    CHECK(!exists("out/hello/hello.ptx"));
72    /* A bad arch, a wrong variant name, then a wrong manifest name. */
73    mbp_opts bad = o;
74    bad.arch = "sm_8";
75    CHECK_I(mbp_run(&bad, names, 1), 1);
76    put("programs/pipesrc-wasm/variants/oops.toml", "name = \"other\"\n");
77    CHECK_I(mbp_run(&o, names, 1), 1);
78    put("programs/wrong/program.toml", "name = \"right\"\n");
79    put("programs/wrong/sexc.json", "{\"name\": \"@ajax/x\", \"kind\": \"ptx\"}\n");
80    CHECK_I(mbp_run(&o, names, 1), 1);
81    char cmd[600];
82    snprintf(cmd, sizeof cmd, "rm -rf %s", root);
83    CHECK(system(cmd) == 0);
84    return mesh_check_done();
85}