==> 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}