---
...uild-when-it-was-pruned-due-to-resta.patch | 86 --------
...eck-that-rules-always-have-a-command.patch | 54 -----
...-rules-have-rspfile-iff-they-have-rs.patch | 56 -----
main/samurai/0004-tool-Implement-compdb.patch | 197 ------------------
...issing-depfile-as-empty-for-deps-log.patch | 64 ------
main/samurai/APKBUILD | 18 +-
6 files changed, 4 insertions(+), 471 deletions(-)
delete mode 100644 main/samurai/0001-Fix-manifest-rebuild-when-it-was-pruned-due-to-resta.patch
delete mode 100644 main/samurai/0002-parse-Check-that-rules-always-have-a-command.patch
delete mode 100644 main/samurai/0003-parse-Check-that-rules-have-rspfile-iff-they-have-rs.patch
delete mode 100644 main/samurai/0004-tool-Implement-compdb.patch
delete mode 100644 main/samurai/0005-deps-treat-missing-depfile-as-empty-for-deps-log.patch
diff --git a/main/samurai/0001-Fix-manifest-rebuild-when-it-was-pruned-due-to-resta.patch b/main/samurai/0001-Fix-manifest-rebuild-when-it-was-pruned-due-to-resta.patch
deleted file mode 100644
index eaabb4019c..0000000000
--- a/main/samurai/0001-Fix-manifest-rebuild-when-it-was-pruned-due-to-resta.patch
@@ -1,86 +0,0 @@
-From c7f1cfd9ed674936e21f99f8c18608b97685d5a7 Mon Sep 17 00:00:00 2001
-From: Michael Forney <mforney@mforney.org>
-Date: Fri, 17 Jan 2020 12:53:59 -0800
-Subject: [PATCH 1/4] Fix manifest rebuild when it was pruned due to restat
-
-If build.ninja depends on an output with `restat = 1`, it may get
-pruned if the output did not change. In this case, we can continue
-with the build, since the previously loaded manifest is still
-correct.
-
-To make sure that we can add new build targets and start a new build
-after executing the build for another target, add a function to
-reset the build state.
-
-Fixes #31.
----
- build.c | 17 +++++++++++++++++
- build.h | 2 ++
- samu.c | 10 +++++++---
- 3 files changed, 26 insertions(+), 3 deletions(-)
-
-diff --git a/build.c b/build.c
-index 7d50d1e..71dda17 100644
---- a/build.c
-+++ b/build.c
-@@ -32,6 +32,23 @@ static struct edge *work;
- static size_t nstarted, ntotal;
- static bool consoleused;
-
-+void
-+buildreset(void) {
-+ struct edge *e;
-+ struct node *n;
-+ size_t i;
-+
-+ for (e = alledges; e; e = e->allnext) {
-+ e->flags = 0;
-+ for (i = 0; i < e->nout; ++i) {
-+ n = e->out[i];
-+ free(n->use);
-+ n->nuse = 0;
-+ n->use = NULL;
-+ }
-+ }
-+}
-+
- /* returns whether n1 is newer than n2, or false if n1 is NULL */
- static bool
- isnewer(struct node *n1, struct node *n2)
-diff --git a/build.h b/build.h
-index fa221bd..6eb1988 100644
---- a/build.h
-+++ b/build.h
-@@ -7,6 +7,8 @@ struct buildoptions {
-
- extern struct buildoptions buildopts;
-
-+/* reset state, so a new build can be executed */
-+void buildreset(void);
- /* schedule a particular target to be built */
- void buildadd(struct node *);
- /* execute rules to build the scheduled targets */
-diff --git a/samu.c b/samu.c
-index a489b0f..f09c808 100644
---- a/samu.c
-+++ b/samu.c
-@@ -240,9 +240,13 @@ retry:
- buildadd(n);
- if (n->dirty) {
- build();
-- if (++tries > 100)
-- fatal("manifest '%s' dirty after 100 tries", manifest);
-- goto retry;
-+ if (n->gen->flags & FLAG_DIRTY_OUT || n->gen->nprune > 0) {
-+ if (++tries > 100)
-+ fatal("manifest '%s' dirty after 100 tries", manifest);
-+ goto retry;
-+ }
-+ /* manifest was pruned; reset state, then continue with build */
-+ buildreset();
- }
- }
-
---
-2.24.0
-
diff --git a/main/samurai/0002-parse-Check-that-rules-always-have-a-command.patch b/main/samurai/0002-parse-Check-that-rules-always-have-a-command.patch
deleted file mode 100644
index 9256ab9421..0000000000
--- a/main/samurai/0002-parse-Check-that-rules-always-have-a-command.patch
@@ -1,54 +0,0 @@
-From 6d510d99dee4135bcb6f973c6e208f05f889bc8d Mon Sep 17 00:00:00 2001
-From: Michael Forney <mforney@mforney.org>
-Date: Wed, 22 Jan 2020 10:45:07 -0800
-Subject: [PATCH 2/4] parse: Check that rules always have a command
-
-This way, we catch the error earlier than build(), and won't have
-to repeat the check for the compdb tool.
----
- build.c | 4 ----
- parse.c | 5 +++++
- 2 files changed, 5 insertions(+), 4 deletions(-)
-
-diff --git a/build.c b/build.c
-index 71dda17..c382c17 100644
---- a/build.c
-+++ b/build.c
-@@ -231,10 +231,6 @@ jobstart(struct job *j, struct edge *e)
- }
- j->edge = e;
- j->cmd = edgevar(e, "command", true);
-- if (!j->cmd) {
-- warn("rule '%s' has no command", e->rule->name);
-- goto err2;
-- }
- j->fd = fd[0];
- argv[2] = j->cmd->s;
-
-diff --git a/parse.c b/parse.c
-index f8f9509..6d07816 100644
---- a/parse.c
-+++ b/parse.c
-@@ -35,6 +35,7 @@ parserule(struct scanner *s, struct environment *env)
- struct rule *r;
- char *var;
- struct evalstring *val;
-+ bool hascommand = false;
-
- r = mkrule(scanname(s));
- scannewline(s);
-@@ -42,7 +43,11 @@ parserule(struct scanner *s, struct environment *env)
- var = scanname(s);
- parselet(s, &val);
- ruleaddvar(r, var, val);
-+ if (strcmp(var, "command") == 0)
-+ hascommand = true;
- }
-+ if (!hascommand)
-+ fatal("rule '%s' has no command", r->name);
- envaddrule(env, r);
- }
-
---
-2.24.0
-
diff --git a/main/samurai/0003-parse-Check-that-rules-have-rspfile-iff-they-have-rs.patch b/main/samurai/0003-parse-Check-that-rules-have-rspfile-iff-they-have-rs.patch
deleted file mode 100644
index 3915fc1bd2..0000000000
--- a/main/samurai/0003-parse-Check-that-rules-have-rspfile-iff-they-have-rs.patch
@@ -1,56 +0,0 @@
-From f549b757394fdb4ac27e4a4bc42e865e98434361 Mon Sep 17 00:00:00 2001
-From: Michael Forney <mforney@mforney.org>
-Date: Wed, 22 Jan 2020 11:36:30 -0800
-Subject: [PATCH 3/4] parse: Check that rules have $rspfile iff they have
- $rspfile_content
-
----
- parse.c | 8 +++++++-
- util.c | 2 +-
- 2 files changed, 8 insertions(+), 2 deletions(-)
-
-diff --git a/parse.c b/parse.c
-index 6d07816..413e5d7 100644
---- a/parse.c
-+++ b/parse.c
-@@ -35,7 +35,7 @@ parserule(struct scanner *s, struct environment *env)
- struct rule *r;
- char *var;
- struct evalstring *val;
-- bool hascommand = false;
-+ bool hascommand = false, hasrspfile = false, hasrspcontent = false;
-
- r = mkrule(scanname(s));
- scannewline(s);
-@@ -45,9 +45,15 @@ parserule(struct scanner *s, struct environment *env)
- ruleaddvar(r, var, val);
- if (strcmp(var, "command") == 0)
- hascommand = true;
-+ else if (strcmp(var, "rspfile") == 0)
-+ hasrspfile = true;
-+ else if (strcmp(var, "rspfile_content") == 0)
-+ hasrspcontent = true;
- }
- if (!hascommand)
- fatal("rule '%s' has no command", r->name);
-+ if (hasrspfile != hasrspcontent)
-+ fatal("rule '%s' has rspfile and no rspfile_content or vice versa", r->name);
- envaddrule(env, r);
- }
-
-diff --git a/util.c b/util.c
-index 8eccf92..39bab18 100644
---- a/util.c
-+++ b/util.c
-@@ -257,7 +257,7 @@ writefile(const char *name, struct string *s)
- return -1;
- }
- ret = 0;
-- if (s && (fwrite(s->s, 1, s->n, f) != s->n || fflush(f) != 0)) {
-+ if (fwrite(s->s, 1, s->n, f) != s->n || fflush(f) != 0) {
- warn("write %s:", name);
- ret = -1;
- }
---
-2.24.0
-
diff --git a/main/samurai/0004-tool-Implement-compdb.patch b/main/samurai/0004-tool-Implement-compdb.patch
deleted file mode 100644
index fff96e6804..0000000000
--- a/main/samurai/0004-tool-Implement-compdb.patch
@@ -1,197 +0,0 @@
-From 9c1f015c21211c5df5822f70d3d5be81bd54fee2 Mon Sep 17 00:00:00 2001
-From: Michael Forney <mforney@mforney.org>
-Date: Wed, 22 Jan 2020 11:50:03 -0800
-Subject: [PATCH 4/4] tool: Implement compdb
-
-This tool outputs a JSON compilation database[0], which is used for
-integration with certain IDEs (for example, GNOME Builder).
-
-Fixes #33.
-
-[0] https://clang.llvm.org/docs/JSONCompilationDatabase.html
----
- samu.1 | 21 +++++++++++--
- tool.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 117 insertions(+), 3 deletions(-)
-
-diff --git a/samu.1 b/samu.1
-index a4f3f70..0f10e93 100644
---- a/samu.1
-+++ b/samu.1
-@@ -1,4 +1,4 @@
--.Dd July 3, 2019
-+.Dd January 22, 2019
- .Dt SAMU 1
- .Os
- .Sh NAME
-@@ -20,6 +20,12 @@
- .Fl t Cm clean
- .Op Fl gr
- .Op Ar target...
-+.Nm
-+.Op Fl C Ar dir
-+.Op Fl f Ar buildfile
-+.Fl t Cm compdb
-+.Op Fl x
-+.Op Ar rule...
- .Sh DESCRIPTION
- .Nm
- loads a build manifest from
-@@ -48,6 +54,12 @@ Targets built with
- rules are only removed if
- .Fl g
- is specified.
-+.Pp
-+If the
-+.Cm compdb
-+tool is used, a compilation database
-+.Lk ( https://clang.llvm.org/docs/JSONCompilationDatabase.html )
-+is printed instead.
- .Sh OPTIONS
- .Bl -tag -width Ds
- .It Fl C
-@@ -106,9 +118,10 @@ only print a diagnostic message.
- .It Fl t
- Instead of building, invoke a subtool.
- All arguments and flags after the subtool are interpreted by the subtool.
--Currently,
-+The currently supported subtools are
- .Cm clean
--is the only subtool.
-+and
-+.Cm compdb .
- .It Fl g
- When cleaning, also clean outputs of
- .Sy generator
-@@ -117,6 +130,8 @@ actions.
- .Ar targets
- are interpreted as rules, and all outputs of actions with the specified rule
- types will be cleaned instead.
-+.It Fl x
-+When printing a compilation database, replace @$rspfile with $rspfile_content (with <blank> in place of <newline>).
- .El
- .Sh ENVIRONMENT
- .Bl -tag -width SAMUFLAGS
-diff --git a/tool.c b/tool.c
-index aae97c0..f77931e 100644
---- a/tool.c
-+++ b/tool.c
-@@ -1,7 +1,10 @@
-+#define _POSIX_C_SOURCE 200809L
- #include <errno.h>
-+#include <limits.h>
- #include <stdbool.h>
- #include <stdio.h>
- #include <string.h>
-+#include <unistd.h>
- #include "arg.h"
- #include "env.h"
- #include "graph.h"
-@@ -123,8 +126,104 @@ clean(int argc, char *argv[])
- return ret;
- }
-
-+static void
-+printjson(const char *s, size_t n, bool join)
-+{
-+ size_t i;
-+ char c;
-+
-+ for (i = 0; i < n; ++i) {
-+ c = s[i];
-+ switch (c) {
-+ case '"':
-+ case '\\':
-+ putchar('\\');
-+ break;
-+ case '\n':
-+ if (join)
-+ c = ' ';
-+ break;
-+ case '\0':
-+ return;
-+ }
-+ putchar(c);
-+ }
-+}
-+
-+static int
-+compdb(int argc, char *argv[])
-+{
-+ char dir[PATH_MAX], *p;
-+ struct edge *e;
-+ struct string *cmd, *rspfile, *content;
-+ bool expandrsp = false, first = true;
-+ int i;
-+ size_t off;
-+
-+ ARGBEGIN {
-+ case 'x':
-+ expandrsp = true;
-+ break;
-+ default:
-+ fprintf(stderr, "usage: %s ... -t compdb [-x] rules...\n", argv0);
-+ return 2;
-+ } ARGEND
-+
-+ if (!getcwd(dir, sizeof(dir)))
-+ fatal("getcwd:");
-+
-+ putchar('[');
-+ for (e = alledges; e; e = e->allnext) {
-+ if (e->nin == 0)
-+ continue;
-+ for (i = 0; i < argc; ++i) {
-+ if (strcmp(e->rule->name, argv[i]) == 0) {
-+ if (first)
-+ first = false;
-+ else
-+ putchar(',');
-+
-+ printf("\n {\n \"directory\": \"");
-+ printjson(dir, -1, false);
-+
-+ printf("\",\n \"command\": \"");
-+ cmd = edgevar(e, "command", true);
-+ rspfile = expandrsp ? edgevar(e, "rspfile", true) : NULL;
-+ p = rspfile ? strstr(cmd->s, rspfile->s) : NULL;
-+ if (!p || p == cmd->s || p[-1] != '@') {
-+ printjson(cmd->s, cmd->n, false);
-+ } else {
-+ off = p - cmd->s;
-+ printjson(cmd->s, off - 1, false);
-+ content = edgevar(e, "rspfile_content", true);
-+ printjson(content->s, content->n, true);
-+ off += rspfile->n;
-+ printjson(cmd->s + off, cmd->n - off, false);
-+ }
-+
-+ printf("\",\n \"file\": \"");
-+ printjson(e->in[0]->path->s, -1, false);
-+
-+ printf("\",\n \"output\": \"");
-+ printjson(e->out[0]->path->s, -1, false);
-+
-+ printf("\",\n }");
-+ break;
-+ }
-+ }
-+ }
-+ puts("\n]");
-+
-+ fflush(stdout);
-+ if (ferror(stdout))
-+ fatal("write failed");
-+
-+ return 0;
-+}
-+
- static const struct tool tools[] = {
- {"clean", clean},
-+ {"compdb", compdb},
- };
-
- const struct tool *
---
-2.24.0
-
diff --git a/main/samurai/0005-deps-treat-missing-depfile-as-empty-for-deps-log.patch b/main/samurai/0005-deps-treat-missing-depfile-as-empty-for-deps-log.patch
deleted file mode 100644
index cdb0cb78b3..0000000000
--- a/main/samurai/0005-deps-treat-missing-depfile-as-empty-for-deps-log.patch
@@ -1,64 +0,0 @@
-From 9d15bff89c1566e40569f689696d0393e7659df1 Mon Sep 17 00:00:00 2001
-From: Michael Forney <mforney@mforney.org>
-Date: Wed, 12 Feb 2020 23:19:05 -0800
-Subject: [PATCH] deps: Treat missing depfile as empty for deps log
-
-This matches ninja's behavior. When deps is not set, a missing
-depfile causes the output to be dirty. When it is set, an empty set
-of dependencies is recorded into the log.
----
- deps.c | 15 +++++++++------
- 1 file changed, 9 insertions(+), 6 deletions(-)
-
-diff --git a/deps.c b/deps.c
-index 4eef994..1338919 100644
---- a/deps.c
-+++ b/deps.c
-@@ -296,7 +296,7 @@ depsclose(void)
- }
-
- static struct nodearray *
--depsparse(const char *name)
-+depsparse(const char *name, bool allowmissing)
- {
- static struct buffer buf;
- static struct nodearray deps;
-@@ -306,12 +306,15 @@ depsparse(const char *name)
- int c, n;
- bool sawcolon;
-
-+ deps.len = 0;
- f = fopen(name, "r");
-- if (!f)
-+ if (!f) {
-+ if (errno == ENOENT && allowmissing)
-+ return &deps;
- return NULL;
-+ }
- sawcolon = false;
- buf.len = 0;
-- deps.len = 0;
- c = getc(f);
- for (;;) {
- /* TODO: this parser needs to be rewritten to be made simpler */
-@@ -438,9 +441,9 @@ depsload(struct edge *e)
- depfile = edgevar(e, "depfile", false);
- if (!depfile)
- return;
-- deps = depsparse(depfile->s);
-+ deps = depsparse(depfile->s, false);
- if (buildopts.explain && !deps)
-- warn("explain %s: missing or invalid dep file", n->path->s);
-+ warn("explain %s: missing or invalid depfile", n->path->s);
- }
- if (deps) {
- edgeadddeps(e, deps->node, deps->len);
-@@ -473,7 +476,7 @@ depsrecord(struct edge *e)
- return;
- }
- out = e->out[0];
-- deps = depsparse(depfile->s);
-+ deps = depsparse(depfile->s, true);
- if (!buildopts.keepdepfile)
- remove(depfile->s);
- if (!deps)
diff --git a/main/samurai/APKBUILD b/main/samurai/APKBUILD
index cd9777d5e9..c0c9159eeb 100644
--- a/main/samurai/APKBUILD
+++ b/main/samurai/APKBUILD
@@ -1,20 +1,15 @@
# Contributor: Drew DeVault <sir@cmpwn.com>
# Maintainer: Drew DeVault <sir@cmpwn.com>
pkgname=samurai
-pkgver=1.0
-pkgrel=4
+pkgver=1.1
+pkgrel=0
pkgdesc="ninja-compatible build tool written in C"
url="https://github.com/michaelforney/samurai"
arch="all"
license="Apache-2.0"
options="!check" # No test suite.
subpackages="$pkgname-doc"
-source="https://github.com/michaelforney/samurai/releases/download/$pkgver/samurai-$pkgver.tar.gz
- 0001-Fix-manifest-rebuild-when-it-was-pruned-due-to-resta.patch
- 0002-parse-Check-that-rules-always-have-a-command.patch
- 0003-parse-Check-that-rules-have-rspfile-iff-they-have-rs.patch
- 0004-tool-Implement-compdb.patch
- 0005-deps-treat-missing-depfile-as-empty-for-deps-log.patch"
+source="https://github.com/michaelforney/samurai/releases/download/$pkgver/samurai-$pkgver.tar.gz"
provides="ninja"
replaces="ninja"
@@ -27,9 +22,4 @@ package() {
ln -s samu "$pkgdir"/usr/bin/ninja
}
-sha512sums="87b2a11a39dc36f3582abdc7c9d358c8fce241fe4155b5177d3e8588d1c040a62eb9daafd2365febbfadd6fcc27a3ceacf6f29ca6f871c822aad6f4bad527a51 samurai-1.0.tar.gz
-a53c3a16a5d3115572a9c47d8a939bce6f5c5d05c9d4626a27a11c46a2bcec1497b1ca886d85da7f298340cc34fd6c65e613de9a4d726003b7f202376c267ae9 0001-Fix-manifest-rebuild-when-it-was-pruned-due-to-resta.patch
-2e4a061daa55115437af476c5e7721448d6986cf3111f4e94edf82f853e65a3da89e55103abc7f401506d3ea69aca34f3f9602c160bdf98c4c2ae3f38f8294e9 0002-parse-Check-that-rules-always-have-a-command.patch
-2558c16c5039bda1fb12f404e740dde780a195a875649cc87a51ccae8cee3e9ceb03befb9ba9301b6ed3cba02fd827ce50131a17aab74a5eacca9841a7e5efdd 0003-parse-Check-that-rules-have-rspfile-iff-they-have-rs.patch
-630a59438f8bf71466766b42aced2adf22bb19972b3d871f734b0fa9f09cb7fad8d3a5bc2acc4e690538f9f34339b8516fb1f1642817dbe66812b43095899114 0004-tool-Implement-compdb.patch
-03da692b82d4ec07e59600abf46dbdef44957709c10f216465456abd68ab7f259bff06f13f3e069393f69a8689081f69573a1ed6b21755dd9b91841d92d616c4 0005-deps-treat-missing-depfile-as-empty-for-deps-log.patch"
+sha512sums="b27302c34d736f483909e57c8b162609eaa4c86571c1167b71a5564b521cc3af2861307a16bb6dca55e80952088989e9526b103160d2ea054d15f4ed85b1cedb samurai-1.1.tar.gz"
--
2.26.0
On Sun, 29 Mar 2020 19:54:05 -0400
Drew DeVault <sir@cmpwn.com> wrote:
> ---
> ...uild-when-it-was-pruned-due-to-resta.patch | 86 --------
> ...eck-that-rules-always-have-a-command.patch | 54 -----
> ...-rules-have-rspfile-iff-they-have-rs.patch | 56 -----
> main/samurai/0004-tool-Implement-compdb.patch | 197
> ------------------ ...issing-depfile-as-empty-for-deps-log.patch |
> 64 ------ main/samurai/APKBUILD | 18 +-
> 6 files changed, 4 insertions(+), 471 deletions(-)
> delete mode 100644
> main/samurai/0001-Fix-manifest-rebuild-when-it-was-pruned-due-to-resta.patch
> delete mode 100644
> main/samurai/0002-parse-Check-that-rules-always-have-a-command.patch
> delete mode 100644
> main/samurai/0003-parse-Check-that-rules-have-rspfile-iff-they-have-rs.patch
> delete mode 100644 main/samurai/0004-tool-Implement-compdb.patch
> delete mode 100644
> main/samurai/0005-deps-treat-missing-depfile-as-empty-for-deps-log.patch
>
> diff --git
> a/main/samurai/0001-Fix-manifest-rebuild-when-it-was-pruned-due-to-resta.patch
> b/main/samurai/0001-Fix-manifest-rebuild-when-it-was-pruned-due-to-resta.patch
> deleted file mode 100644 index eaabb4019c..0000000000 ---
> a/main/samurai/0001-Fix-manifest-rebuild-when-it-was-pruned-due-to-resta.patch
> +++ /dev/null @@ -1,86 +0,0 @@
> -From c7f1cfd9ed674936e21f99f8c18608b97685d5a7 Mon Sep 17 00:00:00
> 2001 -From: Michael Forney <mforney@mforney.org>
> -Date: Fri, 17 Jan 2020 12:53:59 -0800
> -Subject: [PATCH 1/4] Fix manifest rebuild when it was pruned due to
> restat -
> -If build.ninja depends on an output with `restat = 1`, it may get
> -pruned if the output did not change. In this case, we can continue
> -with the build, since the previously loaded manifest is still
> -correct.
> -
> -To make sure that we can add new build targets and start a new build
> -after executing the build for another target, add a function to
> -reset the build state.
> -
> -Fixes #31.
> ----
> - build.c | 17 +++++++++++++++++
> - build.h | 2 ++
> - samu.c | 10 +++++++---
> - 3 files changed, 26 insertions(+), 3 deletions(-)
> -
> -diff --git a/build.c b/build.c
> -index 7d50d1e..71dda17 100644
> ---- a/build.c
> -+++ b/build.c
> -@@ -32,6 +32,23 @@ static struct edge *work;
> - static size_t nstarted, ntotal;
> - static bool consoleused;
> -
> -+void
> -+buildreset(void) {
> -+ struct edge *e;
> -+ struct node *n;
> -+ size_t i;
> -+
> -+ for (e = alledges; e; e = e->allnext) {
> -+ e->flags = 0;
> -+ for (i = 0; i < e->nout; ++i) {
> -+ n = e->out[i];
> -+ free(n->use);
> -+ n->nuse = 0;
> -+ n->use = NULL;
> -+ }
> -+ }
> -+}
> -+
> - /* returns whether n1 is newer than n2, or false if n1 is NULL */
> - static bool
> - isnewer(struct node *n1, struct node *n2)
> -diff --git a/build.h b/build.h
> -index fa221bd..6eb1988 100644
> ---- a/build.h
> -+++ b/build.h
> -@@ -7,6 +7,8 @@ struct buildoptions {
> -
> - extern struct buildoptions buildopts;
> -
> -+/* reset state, so a new build can be executed */
> -+void buildreset(void);
> - /* schedule a particular target to be built */
> - void buildadd(struct node *);
> - /* execute rules to build the scheduled targets */
> -diff --git a/samu.c b/samu.c
> -index a489b0f..f09c808 100644
> ---- a/samu.c
> -+++ b/samu.c
> -@@ -240,9 +240,13 @@ retry:
> - buildadd(n);
> - if (n->dirty) {
> - build();
> -- if (++tries > 100)
> -- fatal("manifest '%s' dirty after
> 100 tries", manifest); -- goto retry;
> -+ if (n->gen->flags & FLAG_DIRTY_OUT ||
> n->gen->nprune > 0) { -+ if (++tries >
> 100) -+ fatal("manifest '%s'
> dirty after 100 tries", manifest); -+
> goto retry; -+ }
> -+ /* manifest was pruned; reset state, then
> continue with build */ -+ buildreset();
> - }
> - }
> -
> ---
> -2.24.0
> -
> diff --git
> a/main/samurai/0002-parse-Check-that-rules-always-have-a-command.patch
> b/main/samurai/0002-parse-Check-that-rules-always-have-a-command.patch
> deleted file mode 100644 index 9256ab9421..0000000000 ---
> a/main/samurai/0002-parse-Check-that-rules-always-have-a-command.patch
> +++ /dev/null @@ -1,54 +0,0 @@
> -From 6d510d99dee4135bcb6f973c6e208f05f889bc8d Mon Sep 17 00:00:00
> 2001 -From: Michael Forney <mforney@mforney.org>
> -Date: Wed, 22 Jan 2020 10:45:07 -0800
> -Subject: [PATCH 2/4] parse: Check that rules always have a command
> -
> -This way, we catch the error earlier than build(), and won't have
> -to repeat the check for the compdb tool.
> ----
> - build.c | 4 ----
> - parse.c | 5 +++++
> - 2 files changed, 5 insertions(+), 4 deletions(-)
> -
> -diff --git a/build.c b/build.c
> -index 71dda17..c382c17 100644
> ---- a/build.c
> -+++ b/build.c
> -@@ -231,10 +231,6 @@ jobstart(struct job *j, struct edge *e)
> - }
> - j->edge = e;
> - j->cmd = edgevar(e, "command", true);
> -- if (!j->cmd) {
> -- warn("rule '%s' has no command", e->rule->name);
> -- goto err2;
> -- }
> - j->fd = fd[0];
> - argv[2] = j->cmd->s;
> -
> -diff --git a/parse.c b/parse.c
> -index f8f9509..6d07816 100644
> ---- a/parse.c
> -+++ b/parse.c
> -@@ -35,6 +35,7 @@ parserule(struct scanner *s, struct environment
> *env)
> - struct rule *r;
> - char *var;
> - struct evalstring *val;
> -+ bool hascommand = false;
> -
> - r = mkrule(scanname(s));
> - scannewline(s);
> -@@ -42,7 +43,11 @@ parserule(struct scanner *s, struct environment
> *env)
> - var = scanname(s);
> - parselet(s, &val);
> - ruleaddvar(r, var, val);
> -+ if (strcmp(var, "command") == 0)
> -+ hascommand = true;
> - }
> -+ if (!hascommand)
> -+ fatal("rule '%s' has no command", r->name);
> - envaddrule(env, r);
> - }
> -
> ---
> -2.24.0
> -
> diff --git
> a/main/samurai/0003-parse-Check-that-rules-have-rspfile-iff-they-have-rs.patch
> b/main/samurai/0003-parse-Check-that-rules-have-rspfile-iff-they-have-rs.patch
> deleted file mode 100644 index 3915fc1bd2..0000000000 ---
> a/main/samurai/0003-parse-Check-that-rules-have-rspfile-iff-they-have-rs.patch
> +++ /dev/null @@ -1,56 +0,0 @@
> -From f549b757394fdb4ac27e4a4bc42e865e98434361 Mon Sep 17 00:00:00
> 2001 -From: Michael Forney <mforney@mforney.org>
> -Date: Wed, 22 Jan 2020 11:36:30 -0800
> -Subject: [PATCH 3/4] parse: Check that rules have $rspfile iff they
> have
> - $rspfile_content
> -
> ----
> - parse.c | 8 +++++++-
> - util.c | 2 +-
> - 2 files changed, 8 insertions(+), 2 deletions(-)
> -
> -diff --git a/parse.c b/parse.c
> -index 6d07816..413e5d7 100644
> ---- a/parse.c
> -+++ b/parse.c
> -@@ -35,7 +35,7 @@ parserule(struct scanner *s, struct environment
> *env)
> - struct rule *r;
> - char *var;
> - struct evalstring *val;
> -- bool hascommand = false;
> -+ bool hascommand = false, hasrspfile = false, hasrspcontent
> = false;
> -
> - r = mkrule(scanname(s));
> - scannewline(s);
> -@@ -45,9 +45,15 @@ parserule(struct scanner *s, struct environment
> *env)
> - ruleaddvar(r, var, val);
> - if (strcmp(var, "command") == 0)
> - hascommand = true;
> -+ else if (strcmp(var, "rspfile") == 0)
> -+ hasrspfile = true;
> -+ else if (strcmp(var, "rspfile_content") == 0)
> -+ hasrspcontent = true;
> - }
> - if (!hascommand)
> - fatal("rule '%s' has no command", r->name);
> -+ if (hasrspfile != hasrspcontent)
> -+ fatal("rule '%s' has rspfile and no rspfile_content
> or vice versa", r->name);
> - envaddrule(env, r);
> - }
> -
> -diff --git a/util.c b/util.c
> -index 8eccf92..39bab18 100644
> ---- a/util.c
> -+++ b/util.c
> -@@ -257,7 +257,7 @@ writefile(const char *name, struct string *s)
> - return -1;
> - }
> - ret = 0;
> -- if (s && (fwrite(s->s, 1, s->n, f) != s->n || fflush(f) !=
> 0)) { -+ if (fwrite(s->s, 1, s->n, f) != s->n || fflush(f) !=
> 0) {
> - warn("write %s:", name);
> - ret = -1;
> - }
> ---
> -2.24.0
> -
> diff --git a/main/samurai/0004-tool-Implement-compdb.patch
> b/main/samurai/0004-tool-Implement-compdb.patch deleted file mode
> 100644 index fff96e6804..0000000000
> --- a/main/samurai/0004-tool-Implement-compdb.patch
> +++ /dev/null
> @@ -1,197 +0,0 @@
> -From 9c1f015c21211c5df5822f70d3d5be81bd54fee2 Mon Sep 17 00:00:00
> 2001 -From: Michael Forney <mforney@mforney.org>
> -Date: Wed, 22 Jan 2020 11:50:03 -0800
> -Subject: [PATCH 4/4] tool: Implement compdb
> -
> -This tool outputs a JSON compilation database[0], which is used for
> -integration with certain IDEs (for example, GNOME Builder).
> -
> -Fixes #33.
> -
> -[0] https://clang.llvm.org/docs/JSONCompilationDatabase.html
> ----
> - samu.1 | 21 +++++++++++--
> - tool.c | 99
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> - 2 files changed, 117 insertions(+), 3 deletions(-)
> -
> -diff --git a/samu.1 b/samu.1
> -index a4f3f70..0f10e93 100644
> ---- a/samu.1
> -+++ b/samu.1
> -@@ -1,4 +1,4 @@
> --.Dd July 3, 2019
> -+.Dd January 22, 2019
> - .Dt SAMU 1
> - .Os
> - .Sh NAME
> -@@ -20,6 +20,12 @@
> - .Fl t Cm clean
> - .Op Fl gr
> - .Op Ar target...
> -+.Nm
> -+.Op Fl C Ar dir
> -+.Op Fl f Ar buildfile
> -+.Fl t Cm compdb
> -+.Op Fl x
> -+.Op Ar rule...
> - .Sh DESCRIPTION
> - .Nm
> - loads a build manifest from
> -@@ -48,6 +54,12 @@ Targets built with
> - rules are only removed if
> - .Fl g
> - is specified.
> -+.Pp
> -+If the
> -+.Cm compdb
> -+tool is used, a compilation database
> -+.Lk ( https://clang.llvm.org/docs/JSONCompilationDatabase.html )
> -+is printed instead.
> - .Sh OPTIONS
> - .Bl -tag -width Ds
> - .It Fl C
> -@@ -106,9 +118,10 @@ only print a diagnostic message.
> - .It Fl t
> - Instead of building, invoke a subtool.
> - All arguments and flags after the subtool are interpreted by the
> subtool. --Currently,
> -+The currently supported subtools are
> - .Cm clean
> --is the only subtool.
> -+and
> -+.Cm compdb .
> - .It Fl g
> - When cleaning, also clean outputs of
> - .Sy generator
> -@@ -117,6 +130,8 @@ actions.
> - .Ar targets
> - are interpreted as rules, and all outputs of actions with the
> specified rule
> - types will be cleaned instead.
> -+.It Fl x
> -+When printing a compilation database, replace @$rspfile with
> $rspfile_content (with <blank> in place of <newline>).
> - .El
> - .Sh ENVIRONMENT
> - .Bl -tag -width SAMUFLAGS
> -diff --git a/tool.c b/tool.c
> -index aae97c0..f77931e 100644
> ---- a/tool.c
> -+++ b/tool.c
> -@@ -1,7 +1,10 @@
> -+#define _POSIX_C_SOURCE 200809L
> - #include <errno.h>
> -+#include <limits.h>
> - #include <stdbool.h>
> - #include <stdio.h>
> - #include <string.h>
> -+#include <unistd.h>
> - #include "arg.h"
> - #include "env.h"
> - #include "graph.h"
> -@@ -123,8 +126,104 @@ clean(int argc, char *argv[])
> - return ret;
> - }
> -
> -+static void
> -+printjson(const char *s, size_t n, bool join)
> -+{
> -+ size_t i;
> -+ char c;
> -+
> -+ for (i = 0; i < n; ++i) {
> -+ c = s[i];
> -+ switch (c) {
> -+ case '"':
> -+ case '\\':
> -+ putchar('\\');
> -+ break;
> -+ case '\n':
> -+ if (join)
> -+ c = ' ';
> -+ break;
> -+ case '\0':
> -+ return;
> -+ }
> -+ putchar(c);
> -+ }
> -+}
> -+
> -+static int
> -+compdb(int argc, char *argv[])
> -+{
> -+ char dir[PATH_MAX], *p;
> -+ struct edge *e;
> -+ struct string *cmd, *rspfile, *content;
> -+ bool expandrsp = false, first = true;
> -+ int i;
> -+ size_t off;
> -+
> -+ ARGBEGIN {
> -+ case 'x':
> -+ expandrsp = true;
> -+ break;
> -+ default:
> -+ fprintf(stderr, "usage: %s ... -t compdb [-x]
> rules...\n", argv0); -+ return 2;
> -+ } ARGEND
> -+
> -+ if (!getcwd(dir, sizeof(dir)))
> -+ fatal("getcwd:");
> -+
> -+ putchar('[');
> -+ for (e = alledges; e; e = e->allnext) {
> -+ if (e->nin == 0)
> -+ continue;
> -+ for (i = 0; i < argc; ++i) {
> -+ if (strcmp(e->rule->name, argv[i]) == 0) {
> -+ if (first)
> -+ first = false;
> -+ else
> -+ putchar(',');
> -+
> -+ printf("\n {\n \"directory\":
> \""); -+ printjson(dir, -1, false);
> -+
> -+ printf("\",\n \"command\": \"");
> -+ cmd = edgevar(e, "command", true);
> -+ rspfile = expandrsp ? edgevar(e,
> "rspfile", true) : NULL; -+ p =
> rspfile ? strstr(cmd->s, rspfile->s) : NULL; -+
> if (!p || p == cmd->s || p[-1] != '@') { -+
> printjson(cmd->s, cmd->n, false);
> -+ } else { -+
> off = p - cmd->s; -+
> printjson(cmd->s, off - 1, false); -+
> content = edgevar(e, "rspfile_content", true);
> -+ printjson(content->s,
> content->n, true); -+ off +=
> rspfile->n; -+
> printjson(cmd->s + off, cmd->n - off, false); -+
> } -+ -+ printf("\",\n
> \"file\": \""); -+
> printjson(e->in[0]->path->s, -1, false); -+
> -+ printf("\",\n \"output\": \"");
> -+ printjson(e->out[0]->path->s, -1,
> false); -+
> -+ printf("\",\n }");
> -+ break;
> -+ }
> -+ }
> -+ }
> -+ puts("\n]");
> -+
> -+ fflush(stdout);
> -+ if (ferror(stdout))
> -+ fatal("write failed");
> -+
> -+ return 0;
> -+}
> -+
> - static const struct tool tools[] = {
> - {"clean", clean},
> -+ {"compdb", compdb},
> - };
> -
> - const struct tool *
> ---
> -2.24.0
> -
> diff --git
> a/main/samurai/0005-deps-treat-missing-depfile-as-empty-for-deps-log.patch
> b/main/samurai/0005-deps-treat-missing-depfile-as-empty-for-deps-log.patch
> deleted file mode 100644 index cdb0cb78b3..0000000000 ---
> a/main/samurai/0005-deps-treat-missing-depfile-as-empty-for-deps-log.patch
> +++ /dev/null @@ -1,64 +0,0 @@
> -From 9d15bff89c1566e40569f689696d0393e7659df1 Mon Sep 17 00:00:00
> 2001 -From: Michael Forney <mforney@mforney.org>
> -Date: Wed, 12 Feb 2020 23:19:05 -0800
> -Subject: [PATCH] deps: Treat missing depfile as empty for deps log
> -
> -This matches ninja's behavior. When deps is not set, a missing
> -depfile causes the output to be dirty. When it is set, an empty set
> -of dependencies is recorded into the log.
> ----
> - deps.c | 15 +++++++++------
> - 1 file changed, 9 insertions(+), 6 deletions(-)
> -
> -diff --git a/deps.c b/deps.c
> -index 4eef994..1338919 100644
> ---- a/deps.c
> -+++ b/deps.c
> -@@ -296,7 +296,7 @@ depsclose(void)
> - }
> -
> - static struct nodearray *
> --depsparse(const char *name)
> -+depsparse(const char *name, bool allowmissing)
> - {
> - static struct buffer buf;
> - static struct nodearray deps;
> -@@ -306,12 +306,15 @@ depsparse(const char *name)
> - int c, n;
> - bool sawcolon;
> -
> -+ deps.len = 0;
> - f = fopen(name, "r");
> -- if (!f)
> -+ if (!f) {
> -+ if (errno == ENOENT && allowmissing)
> -+ return &deps;
> - return NULL;
> -+ }
> - sawcolon = false;
> - buf.len = 0;
> -- deps.len = 0;
> - c = getc(f);
> - for (;;) {
> - /* TODO: this parser needs to be rewritten to be
> made simpler */ -@@ -438,9 +441,9 @@ depsload(struct edge *e)
> - depfile = edgevar(e, "depfile", false);
> - if (!depfile)
> - return;
> -- deps = depsparse(depfile->s);
> -+ deps = depsparse(depfile->s, false);
> - if (buildopts.explain && !deps)
> -- warn("explain %s: missing or invalid dep
> file", n->path->s); -+ warn("explain %s:
> missing or invalid depfile", n->path->s);
> - }
> - if (deps) {
> - edgeadddeps(e, deps->node, deps->len);
> -@@ -473,7 +476,7 @@ depsrecord(struct edge *e)
> - return;
> - }
> - out = e->out[0];
> -- deps = depsparse(depfile->s);
> -+ deps = depsparse(depfile->s, true);
> - if (!buildopts.keepdepfile)
> - remove(depfile->s);
> - if (!deps)
> diff --git a/main/samurai/APKBUILD b/main/samurai/APKBUILD
> index cd9777d5e9..c0c9159eeb 100644
> --- a/main/samurai/APKBUILD
> +++ b/main/samurai/APKBUILD
> @@ -1,20 +1,15 @@
> # Contributor: Drew DeVault <sir@cmpwn.com>
> # Maintainer: Drew DeVault <sir@cmpwn.com>
> pkgname=samurai
> -pkgver=1.0
> -pkgrel=4
> +pkgver=1.1
> +pkgrel=0
> pkgdesc="ninja-compatible build tool written in C"
> url="https://github.com/michaelforney/samurai"
> arch="all"
> license="Apache-2.0"
> options="!check" # No test suite.
> subpackages="$pkgname-doc"
> -source="https://github.com/michaelforney/samurai/releases/download/$pkgver/samurai-$pkgver.tar.gz
> -
> 0001-Fix-manifest-rebuild-when-it-was-pruned-due-to-resta.patch
> - 0002-parse-Check-that-rules-always-have-a-command.patch
> -
> 0003-parse-Check-that-rules-have-rspfile-iff-they-have-rs.patch
> - 0004-tool-Implement-compdb.patch
> - 0005-deps-treat-missing-depfile-as-empty-for-deps-log.patch"
> +source="https://github.com/michaelforney/samurai/releases/download/$pkgver/samurai-$pkgver.tar.gz"
> provides="ninja"
> replaces="ninja"
>
> @@ -27,9 +22,4 @@ package() {
> ln -s samu "$pkgdir"/usr/bin/ninja
> }
>
> -sha512sums="87b2a11a39dc36f3582abdc7c9d358c8fce241fe4155b5177d3e8588d1c040a62eb9daafd2365febbfadd6fcc27a3ceacf6f29ca6f871c822aad6f4bad527a51
> samurai-1.0.tar.gz
> -a53c3a16a5d3115572a9c47d8a939bce6f5c5d05c9d4626a27a11c46a2bcec1497b1ca886d85da7f298340cc34fd6c65e613de9a4d726003b7f202376c267ae9
> 0001-Fix-manifest-rebuild-when-it-was-pruned-due-to-resta.patch
> -2e4a061daa55115437af476c5e7721448d6986cf3111f4e94edf82f853e65a3da89e55103abc7f401506d3ea69aca34f3f9602c160bdf98c4c2ae3f38f8294e9
> 0002-parse-Check-that-rules-always-have-a-command.patch
> -2558c16c5039bda1fb12f404e740dde780a195a875649cc87a51ccae8cee3e9ceb03befb9ba9301b6ed3cba02fd827ce50131a17aab74a5eacca9841a7e5efdd
> 0003-parse-Check-that-rules-have-rspfile-iff-they-have-rs.patch
> -630a59438f8bf71466766b42aced2adf22bb19972b3d871f734b0fa9f09cb7fad8d3a5bc2acc4e690538f9f34339b8516fb1f1642817dbe66812b43095899114
> 0004-tool-Implement-compdb.patch
> -03da692b82d4ec07e59600abf46dbdef44957709c10f216465456abd68ab7f259bff06f13f3e069393f69a8689081f69573a1ed6b21755dd9b91841d92d616c4
> 0005-deps-treat-missing-depfile-as-empty-for-deps-log.patch"
> +sha512sums="b27302c34d736f483909e57c8b162609eaa4c86571c1167b71a5564b521cc3af2861307a16bb6dca55e80952088989e9526b103160d2ea054d15f4ed85b1cedb
> samurai-1.1.tar.gz"
Applied