* [PATCH 0/2] some unit-test Makefile polishing
@ 2024-01-29 3:15 Jeff King
2024-01-29 3:18 ` [PATCH 1/2] Makefile: use order-only prereq for UNIT_TEST_BIN Jeff King
` (2 more replies)
0 siblings, 3 replies; 24+ messages in thread
From: Jeff King @ 2024-01-29 3:15 UTC (permalink / raw)
To: git; +Cc: Phillip Wood
The patches fixes two small hiccups I found with the unit-tests. Neither
is a show-stopper, but mostly just small quality-of-life fixes.
[1/2]: Makefile: use order-only prereq for UNIT_TEST_BIN
[2/2]: t/Makefile: get UNIT_TESTS list from C sources
Makefile | 2 +-
t/Makefile | 4 +++-
2 files changed, 4 insertions(+), 2 deletions(-)
-Peff
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 1/2] Makefile: use order-only prereq for UNIT_TEST_BIN
2024-01-29 3:15 [PATCH 0/2] some unit-test Makefile polishing Jeff King
@ 2024-01-29 3:18 ` Jeff King
2024-01-29 20:22 ` SZEDER Gábor
2024-01-29 3:19 ` [PATCH 2/2] t/Makefile: get UNIT_TESTS list from C sources Jeff King
2024-01-30 5:37 ` [PATCH v2 0/3] some unit-test Makefile polishing Jeff King
2 siblings, 1 reply; 24+ messages in thread
From: Jeff King @ 2024-01-29 3:18 UTC (permalink / raw)
To: git; +Cc: Phillip Wood
We build the UNIT_TEST_BIN directory (t/unit-tests/bin) on the fly with
"mkdir -p". And so the recipe for UNIT_TEST_PROGS, which put their
output in that directory, depend on UNIT_TEST_BIN to make sure it's
there.
But using a normal dependency leads to weird outcomes, because the
timestamp of the directory is important. For example, try this:
$ make
[...builds everything...]
[now re-build one unit test]
$ touch t/unit-tests/t-ctype.c
$ make
SUBDIR templates
CC t/unit-tests/t-ctype.o
LINK t/unit-tests/bin/t-ctype
So far so good. Now running make again should build nothing. But it
doesn't!
$ make
SUBDIR templates
LINK t/unit-tests/bin/t-basic
LINK t/unit-tests/bin/t-mem-pool
LINK t/unit-tests/bin/t-strbuf
Er, what? Let's rebuild again:
$ make
SUBDIR templates
LINK t/unit-tests/bin/t-ctype
Weird. And now we ping-pong back and forth forever:
$ make
SUBDIR templates
LINK t/unit-tests/bin/t-basic
LINK t/unit-tests/bin/t-mem-pool
LINK t/unit-tests/bin/t-strbuf
$ make
SUBDIR templates
LINK t/unit-tests/bin/t-ctype
What happens is that writing t/unit-tests/bin/t-ctype updates the mtime
of the directory t/unit-tests/bin. And then on the next invocation of
make, all of those other tests are now older and so get rebuilt. And
back and forth forever.
We can fix this by using an order-only prereq. This is a GNU-ism that
tells make to only care that the dependency exists at all, and to ignore
its mtime. It was designed for exactly this sort of situation (the
documentation example even uses "mkdir").
We already rely on GNU make, so that's not a problem. This particular
feature was added in GNU make 3.80, released in October 2002. This is
obviously quite old by date, but it's also worth thinking about macOS,
as Apple stopped updating packages that switched to GPLv3 tools. In this
their dev tools ship GNU make 3.81, which is recent enough.
If it is a problem, there are two alternatives:
- we can just "mkdir -p" in the recipe to build the individual
binaries. This will mean some redundant "mkdir" calls, but only when
actually invoking the compiler.
- we could stop making the directory on the fly, and just add it with
a .gitignore of "*". This would work fine, but might be awkward when
moving back and forth in history.
Signed-off-by: Jeff King <peff@peff.net>
---
I may be overly paranoid about the ".gitignore" strategy. I feel like
I've been bitten by this in the past by things switching from source to
build (I think with git-remote-testgit). But that's an actual built
file. Git would probably be OK with the "bin/" directory coming and
going as a tracked entity, because the index really only cares about
the file "bin/.gitignore". Still, this make fix was easy enough.
Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
index 1a62e48759..958f4cd0bf 100644
--- a/Makefile
+++ b/Makefile
@@ -3866,7 +3866,7 @@ fuzz-all: $(FUZZ_PROGRAMS)
$(UNIT_TEST_BIN):
@mkdir -p $(UNIT_TEST_BIN)
-$(UNIT_TEST_PROGS): $(UNIT_TEST_BIN)/%$X: $(UNIT_TEST_DIR)/%.o $(UNIT_TEST_DIR)/test-lib.o $(GITLIBS) GIT-LDFLAGS $(UNIT_TEST_BIN)
+$(UNIT_TEST_PROGS): $(UNIT_TEST_BIN)/%$X: $(UNIT_TEST_DIR)/%.o $(UNIT_TEST_DIR)/test-lib.o $(GITLIBS) GIT-LDFLAGS | $(UNIT_TEST_BIN)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) \
$(filter %.o,$^) $(filter %.a,$^) $(LIBS)
--
2.43.0.797.g29b680fc68
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH 2/2] t/Makefile: get UNIT_TESTS list from C sources
2024-01-29 3:15 [PATCH 0/2] some unit-test Makefile polishing Jeff King
2024-01-29 3:18 ` [PATCH 1/2] Makefile: use order-only prereq for UNIT_TEST_BIN Jeff King
@ 2024-01-29 3:19 ` Jeff King
2024-01-29 11:26 ` Patrick Steinhardt
2024-01-29 21:51 ` Junio C Hamano
2024-01-30 5:37 ` [PATCH v2 0/3] some unit-test Makefile polishing Jeff King
2 siblings, 2 replies; 24+ messages in thread
From: Jeff King @ 2024-01-29 3:19 UTC (permalink / raw)
To: git; +Cc: Phillip Wood
We decide on the set of unit tests to run by asking make to expand the
wildcard "t/unit-tests/bin/*". One unfortunate outcome of this is that
we'll run anything in that directory, even if it is leftover cruft from
a previous build. This isn't _quite_ as bad as it sounds, since in
theory the unit test executables are self-contained (so if they passed
before, they'll pass even though they now have nothing to do with the
checked out version of Git). But at the very least it's wasteful, and if
they _do_ fail it can be quite confusing to understand why they are
being run at all.
This wildcarding presumably came from our handling of the regular
shell-script tests, which match "t[0-9][0-9][0-9][0-9]-*.sh". But the
difference there is that those are actual tracked files. So if you
checkout a different commit, they'll go away. Whereas the contents of
unit-tests/bin are ignored (so not only do they stick around, but you
are not even warned of the stale files via "git status").
This patch fixes the situation by looking for the actual unit-test
source files and then massaging those names into the final executable
names. This has two additional benefits:
1. It will notice if we failed to build one or more unit-tests for
some reason (wheras the current code just runs whatever made it to
the bin/ directory).
2. The wildcard should avoid other build cruft, like the pdb files we
worked around in 0df903d402 (unit-tests: do not mistake `.pdb`
files for being executable, 2023-09-25).
Our new wildcard does make an assumption that unit tests are build from
C sources. It would be a bit cleaner if we consulted UNIT_TEST_PROGRAMS
from the top-level Makefile. But doing so is tricky unless we reorganize
that Makefile to split the source file lists into include-able subfiles.
That might be worth doing in general, but in the meantime, the
assumptions made by the wildcard here seems reasonable.
Signed-off-by: Jeff King <peff@peff.net>
---
I of course hit this when moving between "next" and "master" for an
up-and-coming unit-test file which sometimes failed.
t/Makefile | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/t/Makefile b/t/Makefile
index b7a6fefe28..c5c6e2ef6b 100644
--- a/t/Makefile
+++ b/t/Makefile
@@ -42,7 +42,9 @@ TPERF = $(sort $(wildcard perf/p[0-9][0-9][0-9][0-9]-*.sh))
TINTEROP = $(sort $(wildcard interop/i[0-9][0-9][0-9][0-9]-*.sh))
CHAINLINTTESTS = $(sort $(patsubst chainlint/%.test,%,$(wildcard chainlint/*.test)))
CHAINLINT = '$(PERL_PATH_SQ)' chainlint.pl
-UNIT_TESTS = $(sort $(filter-out %.pdb unit-tests/bin/t-basic%,$(wildcard unit-tests/bin/t-*)))
+UNIT_TEST_SOURCES = $(wildcard unit-tests/t-*.c)
+UNIT_TEST_PROGRAMS = $(patsubst unit-tests/%.c,unit-tests/bin/%,$(UNIT_TEST_SOURCES))
+UNIT_TESTS = $(sort $(filter-out unit-tests/bin/t-basic%,$(UNIT_TEST_PROGRAMS)))
# `test-chainlint` (which is a dependency of `test-lint`, `test` and `prove`)
# checks all tests in all scripts via a single invocation, so tell individual
--
2.43.0.797.g29b680fc68
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH 2/2] t/Makefile: get UNIT_TESTS list from C sources
2024-01-29 3:19 ` [PATCH 2/2] t/Makefile: get UNIT_TESTS list from C sources Jeff King
@ 2024-01-29 11:26 ` Patrick Steinhardt
2024-01-29 17:49 ` Jeff King
2024-01-29 21:51 ` Junio C Hamano
1 sibling, 1 reply; 24+ messages in thread
From: Patrick Steinhardt @ 2024-01-29 11:26 UTC (permalink / raw)
To: Jeff King; +Cc: git, Phillip Wood
[-- Attachment #1: Type: text/plain, Size: 3289 bytes --]
On Sun, Jan 28, 2024 at 10:19:33PM -0500, Jeff King wrote:
> We decide on the set of unit tests to run by asking make to expand the
> wildcard "t/unit-tests/bin/*". One unfortunate outcome of this is that
> we'll run anything in that directory, even if it is leftover cruft from
> a previous build. This isn't _quite_ as bad as it sounds, since in
> theory the unit test executables are self-contained (so if they passed
> before, they'll pass even though they now have nothing to do with the
> checked out version of Git). But at the very least it's wasteful, and if
> they _do_ fail it can be quite confusing to understand why they are
> being run at all.
>
> This wildcarding presumably came from our handling of the regular
> shell-script tests, which match "t[0-9][0-9][0-9][0-9]-*.sh". But the
> difference there is that those are actual tracked files. So if you
> checkout a different commit, they'll go away. Whereas the contents of
> unit-tests/bin are ignored (so not only do they stick around, but you
> are not even warned of the stale files via "git status").
>
> This patch fixes the situation by looking for the actual unit-test
> source files and then massaging those names into the final executable
> names. This has two additional benefits:
>
> 1. It will notice if we failed to build one or more unit-tests for
> some reason (wheras the current code just runs whatever made it to
> the bin/ directory).
>
> 2. The wildcard should avoid other build cruft, like the pdb files we
> worked around in 0df903d402 (unit-tests: do not mistake `.pdb`
> files for being executable, 2023-09-25).
>
> Our new wildcard does make an assumption that unit tests are build from
> C sources. It would be a bit cleaner if we consulted UNIT_TEST_PROGRAMS
> from the top-level Makefile. But doing so is tricky unless we reorganize
> that Makefile to split the source file lists into include-able subfiles.
> That might be worth doing in general, but in the meantime, the
> assumptions made by the wildcard here seems reasonable.
>
> Signed-off-by: Jeff King <peff@peff.net>
> ---
> I of course hit this when moving between "next" and "master" for an
> up-and-coming unit-test file which sometimes failed.
>
> t/Makefile | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/t/Makefile b/t/Makefile
> index b7a6fefe28..c5c6e2ef6b 100644
> --- a/t/Makefile
> +++ b/t/Makefile
> @@ -42,7 +42,9 @@ TPERF = $(sort $(wildcard perf/p[0-9][0-9][0-9][0-9]-*.sh))
> TINTEROP = $(sort $(wildcard interop/i[0-9][0-9][0-9][0-9]-*.sh))
> CHAINLINTTESTS = $(sort $(patsubst chainlint/%.test,%,$(wildcard chainlint/*.test)))
> CHAINLINT = '$(PERL_PATH_SQ)' chainlint.pl
> -UNIT_TESTS = $(sort $(filter-out %.pdb unit-tests/bin/t-basic%,$(wildcard unit-tests/bin/t-*)))
> +UNIT_TEST_SOURCES = $(wildcard unit-tests/t-*.c)
> +UNIT_TEST_PROGRAMS = $(patsubst unit-tests/%.c,unit-tests/bin/%,$(UNIT_TEST_SOURCES))
> +UNIT_TESTS = $(sort $(filter-out unit-tests/bin/t-basic%,$(UNIT_TEST_PROGRAMS)))
Wouldn't we have to honor `$X` on Windows systems so that the unit tests
have the expected ".exe" suffix here?
Other than this question the patch series looks good to me, thanks!
Patrick
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 2/2] t/Makefile: get UNIT_TESTS list from C sources
2024-01-29 11:26 ` Patrick Steinhardt
@ 2024-01-29 17:49 ` Jeff King
2024-01-29 21:31 ` Adam Dinwoodie
0 siblings, 1 reply; 24+ messages in thread
From: Jeff King @ 2024-01-29 17:49 UTC (permalink / raw)
To: Patrick Steinhardt; +Cc: git, Phillip Wood
On Mon, Jan 29, 2024 at 12:26:42PM +0100, Patrick Steinhardt wrote:
> > -UNIT_TESTS = $(sort $(filter-out %.pdb unit-tests/bin/t-basic%,$(wildcard unit-tests/bin/t-*)))
> > +UNIT_TEST_SOURCES = $(wildcard unit-tests/t-*.c)
> > +UNIT_TEST_PROGRAMS = $(patsubst unit-tests/%.c,unit-tests/bin/%,$(UNIT_TEST_SOURCES))
> > +UNIT_TESTS = $(sort $(filter-out unit-tests/bin/t-basic%,$(UNIT_TEST_PROGRAMS)))
>
> Wouldn't we have to honor `$X` on Windows systems so that the unit tests
> have the expected ".exe" suffix here?
Hmm, good point. It seems like the answer should obviously be "yes", but
Windows CI seemed to pass all the same (and I checked that it indeed ran
the unit tests). Do we only get the $X suffix for MSVC builds or
something? Looks like maybe cygwin, as well.
I imagine the solution is just:
diff --git a/t/Makefile b/t/Makefile
index c5c6e2ef6b..9b9b30f559 100644
--- a/t/Makefile
+++ b/t/Makefile
@@ -43,7 +43,7 @@ TINTEROP = $(sort $(wildcard interop/i[0-9][0-9][0-9][0-9]-*.sh))
CHAINLINTTESTS = $(sort $(patsubst chainlint/%.test,%,$(wildcard chainlint/*.test)))
CHAINLINT = '$(PERL_PATH_SQ)' chainlint.pl
UNIT_TEST_SOURCES = $(wildcard unit-tests/t-*.c)
-UNIT_TEST_PROGRAMS = $(patsubst unit-tests/%.c,unit-tests/bin/%,$(UNIT_TEST_SOURCES))
+UNIT_TEST_PROGRAMS = $(patsubst unit-tests/%.c,unit-tests/bin/%$(X),$(UNIT_TEST_SOURCES))
UNIT_TESTS = $(sort $(filter-out unit-tests/bin/t-basic%,$(UNIT_TEST_PROGRAMS)))
# `test-chainlint` (which is a dependency of `test-lint`, `test` and `prove`)
but it looks like we might need to include config.mak.uname, as well. It
would be nice to identify a build that actually needs it so I can
confirm that the fix works.
-Peff
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH 1/2] Makefile: use order-only prereq for UNIT_TEST_BIN
2024-01-29 3:18 ` [PATCH 1/2] Makefile: use order-only prereq for UNIT_TEST_BIN Jeff King
@ 2024-01-29 20:22 ` SZEDER Gábor
2024-01-29 22:06 ` Junio C Hamano
2024-01-30 5:21 ` Jeff King
0 siblings, 2 replies; 24+ messages in thread
From: SZEDER Gábor @ 2024-01-29 20:22 UTC (permalink / raw)
To: Jeff King; +Cc: git, Phillip Wood
On Sun, Jan 28, 2024 at 10:18:16PM -0500, Jeff King wrote:
> We build the UNIT_TEST_BIN directory (t/unit-tests/bin) on the fly with
> "mkdir -p". And so the recipe for UNIT_TEST_PROGS, which put their
> output in that directory, depend on UNIT_TEST_BIN to make sure it's
> there.
>
> But using a normal dependency leads to weird outcomes, because the
> timestamp of the directory is important. For example, try this:
>
> $ make
> [...builds everything...]
>
> [now re-build one unit test]
> $ touch t/unit-tests/t-ctype.c
> $ make
> SUBDIR templates
> CC t/unit-tests/t-ctype.o
> LINK t/unit-tests/bin/t-ctype
>
> So far so good. Now running make again should build nothing. But it
> doesn't!
>
> $ make
> SUBDIR templates
> LINK t/unit-tests/bin/t-basic
> LINK t/unit-tests/bin/t-mem-pool
> LINK t/unit-tests/bin/t-strbuf
>
> Er, what? Let's rebuild again:
>
> $ make
> SUBDIR templates
> LINK t/unit-tests/bin/t-ctype
>
> Weird. And now we ping-pong back and forth forever:
>
> $ make
> SUBDIR templates
> LINK t/unit-tests/bin/t-basic
> LINK t/unit-tests/bin/t-mem-pool
> LINK t/unit-tests/bin/t-strbuf
> $ make
> SUBDIR templates
> LINK t/unit-tests/bin/t-ctype
>
> What happens is that writing t/unit-tests/bin/t-ctype updates the mtime
> of the directory t/unit-tests/bin. And then on the next invocation of
> make, all of those other tests are now older and so get rebuilt. And
> back and forth forever.
>
> We can fix this by using an order-only prereq. This is a GNU-ism that
> tells make to only care that the dependency exists at all, and to ignore
> its mtime. It was designed for exactly this sort of situation (the
> documentation example even uses "mkdir").
>
> We already rely on GNU make, so that's not a problem. This particular
> feature was added in GNU make 3.80, released in October 2002. This is
> obviously quite old by date, but it's also worth thinking about macOS,
> as Apple stopped updating packages that switched to GPLv3 tools. In this
> their dev tools ship GNU make 3.81, which is recent enough.
>
> If it is a problem, there are two alternatives:
>
> - we can just "mkdir -p" in the recipe to build the individual
> binaries. This will mean some redundant "mkdir" calls, but only when
> actually invoking the compiler.
>
> - we could stop making the directory on the fly, and just add it with
> a .gitignore of "*". This would work fine, but might be awkward when
> moving back and forth in history.
A third alternative is to use $(call mkdir_p_parent_template) in the
recipe and get rid of the thus unnecessary UNIT_TEST_BIN dependency
and target. It will only run mkdir when needed, and it's a well
established pattern in our Makefile, so you won't have to spend a
paragraph or two arguing about potential problems with GNU-isms :)
On a related note, 'make clean' doesn't remove this 't/unit-tests/bin'
directory.
> Signed-off-by: Jeff King <peff@peff.net>
> ---
> I may be overly paranoid about the ".gitignore" strategy. I feel like
> I've been bitten by this in the past by things switching from source to
> build (I think with git-remote-testgit). But that's an actual built
> file. Git would probably be OK with the "bin/" directory coming and
> going as a tracked entity, because the index really only cares about
> the file "bin/.gitignore". Still, this make fix was easy enough.
>
> Makefile | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/Makefile b/Makefile
> index 1a62e48759..958f4cd0bf 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -3866,7 +3866,7 @@ fuzz-all: $(FUZZ_PROGRAMS)
> $(UNIT_TEST_BIN):
> @mkdir -p $(UNIT_TEST_BIN)
>
> -$(UNIT_TEST_PROGS): $(UNIT_TEST_BIN)/%$X: $(UNIT_TEST_DIR)/%.o $(UNIT_TEST_DIR)/test-lib.o $(GITLIBS) GIT-LDFLAGS $(UNIT_TEST_BIN)
> +$(UNIT_TEST_PROGS): $(UNIT_TEST_BIN)/%$X: $(UNIT_TEST_DIR)/%.o $(UNIT_TEST_DIR)/test-lib.o $(GITLIBS) GIT-LDFLAGS | $(UNIT_TEST_BIN)
> $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) \
> $(filter %.o,$^) $(filter %.a,$^) $(LIBS)
>
> --
> 2.43.0.797.g29b680fc68
>
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 2/2] t/Makefile: get UNIT_TESTS list from C sources
2024-01-29 17:49 ` Jeff King
@ 2024-01-29 21:31 ` Adam Dinwoodie
2024-01-30 0:27 ` Junio C Hamano
2024-01-30 5:23 ` Jeff King
0 siblings, 2 replies; 24+ messages in thread
From: Adam Dinwoodie @ 2024-01-29 21:31 UTC (permalink / raw)
To: Jeff King; +Cc: Patrick Steinhardt, git, Phillip Wood
On Mon, 29 Jan 2024 at 17:49, Jeff King wrote:
>
> On Mon, Jan 29, 2024 at 12:26:42PM +0100, Patrick Steinhardt wrote:
>
> > > -UNIT_TESTS = $(sort $(filter-out %.pdb unit-tests/bin/t-basic%,$(wildcard unit-tests/bin/t-*)))
> > > +UNIT_TEST_SOURCES = $(wildcard unit-tests/t-*.c)
> > > +UNIT_TEST_PROGRAMS = $(patsubst unit-tests/%.c,unit-tests/bin/%,$(UNIT_TEST_SOURCES))
> > > +UNIT_TESTS = $(sort $(filter-out unit-tests/bin/t-basic%,$(UNIT_TEST_PROGRAMS)))
> >
> > Wouldn't we have to honor `$X` on Windows systems so that the unit tests
> > have the expected ".exe" suffix here?
>
> Hmm, good point. It seems like the answer should obviously be "yes", but
> Windows CI seemed to pass all the same (and I checked that it indeed ran
> the unit tests). Do we only get the $X suffix for MSVC builds or
> something? Looks like maybe cygwin, as well.
Cygwin will automatically append ".exe" when doing directory listings;
a check if the file "a" exists will return true on Cygwin if "a" or
"a.exe" exists; a glob for "a*" in a directory containing files "a1"
and "a2.exe" will return "a1" and "a2". This causes problems in some
edge cases, but it means *nix scripts and applications are much more
likely to work without any Cygwin-specific handling. I *think* this
logic is carried downstream to MSYS2 and thence to Git for Windows.
As a result, I'm not surprised this worked without handling $X, but I
don't think there's any harm in adding it either.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 2/2] t/Makefile: get UNIT_TESTS list from C sources
2024-01-29 3:19 ` [PATCH 2/2] t/Makefile: get UNIT_TESTS list from C sources Jeff King
2024-01-29 11:26 ` Patrick Steinhardt
@ 2024-01-29 21:51 ` Junio C Hamano
1 sibling, 0 replies; 24+ messages in thread
From: Junio C Hamano @ 2024-01-29 21:51 UTC (permalink / raw)
To: Jeff King; +Cc: git, Phillip Wood
Jeff King <peff@peff.net> writes:
> Our new wildcard does make an assumption that unit tests are build from
"build" -> "built", probably.
> C sources. It would be a bit cleaner if we consulted UNIT_TEST_PROGRAMS
> from the top-level Makefile. But doing so is tricky unless we reorganize
> that Makefile to split the source file lists into include-able subfiles.
> That might be worth doing in general, but in the meantime, the
> assumptions made by the wildcard here seems reasonable.
>
> Signed-off-by: Jeff King <peff@peff.net>
> ---
> I of course hit this when moving between "next" and "master" for an
> up-and-coming unit-test file which sometimes failed.
Thanks. globbing the build products is indeed sloppy for all the
reasons you mentioned. Will queue.
> t/Makefile | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/t/Makefile b/t/Makefile
> index b7a6fefe28..c5c6e2ef6b 100644
> --- a/t/Makefile
> +++ b/t/Makefile
> @@ -42,7 +42,9 @@ TPERF = $(sort $(wildcard perf/p[0-9][0-9][0-9][0-9]-*.sh))
> TINTEROP = $(sort $(wildcard interop/i[0-9][0-9][0-9][0-9]-*.sh))
> CHAINLINTTESTS = $(sort $(patsubst chainlint/%.test,%,$(wildcard chainlint/*.test)))
> CHAINLINT = '$(PERL_PATH_SQ)' chainlint.pl
> -UNIT_TESTS = $(sort $(filter-out %.pdb unit-tests/bin/t-basic%,$(wildcard unit-tests/bin/t-*)))
> +UNIT_TEST_SOURCES = $(wildcard unit-tests/t-*.c)
> +UNIT_TEST_PROGRAMS = $(patsubst unit-tests/%.c,unit-tests/bin/%,$(UNIT_TEST_SOURCES))
> +UNIT_TESTS = $(sort $(filter-out unit-tests/bin/t-basic%,$(UNIT_TEST_PROGRAMS)))
>
> # `test-chainlint` (which is a dependency of `test-lint`, `test` and `prove`)
> # checks all tests in all scripts via a single invocation, so tell individual
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 1/2] Makefile: use order-only prereq for UNIT_TEST_BIN
2024-01-29 20:22 ` SZEDER Gábor
@ 2024-01-29 22:06 ` Junio C Hamano
2024-01-30 5:21 ` Jeff King
1 sibling, 0 replies; 24+ messages in thread
From: Junio C Hamano @ 2024-01-29 22:06 UTC (permalink / raw)
To: SZEDER Gábor; +Cc: Jeff King, git, Phillip Wood
SZEDER Gábor <szeder.dev@gmail.com> writes:
> A third alternative is to use $(call mkdir_p_parent_template) in the
> recipe and get rid of the thus unnecessary UNIT_TEST_BIN dependency
> and target.
Yeah, that sounds like a good approach in this case.
> On a related note, 'make clean' doesn't remove this 't/unit-tests/bin'
> directory.
Not a new problem, but I did notice this, too.
Thanks.
Makefile | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git c/Makefile w/Makefile
index 958f4cd0bf..7f035a1c9f 100644
--- c/Makefile
+++ w/Makefile
@@ -3676,7 +3676,7 @@ cocciclean:
$(RM) contrib/coccinelle/*.cocci.patch
clean: profile-clean coverage-clean cocciclean
- $(RM) -r .build
+ $(RM) -r .build $(UNIT_TEST_BIN)
$(RM) po/git.pot po/git-core.pot
$(RM) git.res
$(RM) $(OBJECTS)
@@ -3863,10 +3863,8 @@ $(FUZZ_PROGRAMS): all
fuzz-all: $(FUZZ_PROGRAMS)
-$(UNIT_TEST_BIN):
- @mkdir -p $(UNIT_TEST_BIN)
-
-$(UNIT_TEST_PROGS): $(UNIT_TEST_BIN)/%$X: $(UNIT_TEST_DIR)/%.o $(UNIT_TEST_DIR)/test-lib.o $(GITLIBS) GIT-LDFLAGS | $(UNIT_TEST_BIN)
+$(UNIT_TEST_PROGS): $(UNIT_TEST_BIN)/%$X: $(UNIT_TEST_DIR)/%.o $(UNIT_TEST_DIR)/test-lib.o $(GITLIBS) GIT-LDFLAGS
+ $(call mkdir_p_parent_template)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) \
$(filter %.o,$^) $(filter %.a,$^) $(LIBS)
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH 2/2] t/Makefile: get UNIT_TESTS list from C sources
2024-01-29 21:31 ` Adam Dinwoodie
@ 2024-01-30 0:27 ` Junio C Hamano
2024-01-30 5:25 ` Jeff King
2024-01-31 19:13 ` Adam Dinwoodie
2024-01-30 5:23 ` Jeff King
1 sibling, 2 replies; 24+ messages in thread
From: Junio C Hamano @ 2024-01-30 0:27 UTC (permalink / raw)
To: Adam Dinwoodie; +Cc: Jeff King, Patrick Steinhardt, git, Phillip Wood
Adam Dinwoodie <adam@dinwoodie.org> writes:
>> Hmm, good point. It seems like the answer should obviously be "yes", but
>> Windows CI seemed to pass all the same (and I checked that it indeed ran
>> the unit tests). Do we only get the $X suffix for MSVC builds or
>> something? Looks like maybe cygwin, as well.
>
> Cygwin will automatically append ".exe" when doing directory listings;
> a check if the file "a" exists will return true on Cygwin if "a" or
> "a.exe" exists; a glob for "a*" in a directory containing files "a1"
> and "a2.exe" will return "a1" and "a2". This causes problems in some
> edge cases, but it means *nix scripts and applications are much more
> likely to work without any Cygwin-specific handling. I *think* this
> logic is carried downstream to MSYS2 and thence to Git for Windows.
Interesting, especially that "a*" is globbed to "a2" and not
"a2.exe".
> As a result, I'm not surprised this worked without handling $X, but I
> don't think there's any harm in adding it either.
OK.
I wonder if something like this is sufficient? I am not sure if we
should lift the building of t/unit-tests/* up to the primary Makefile
to mimic the way stuff related to test-tool are built and linked.
That way, we do not have to contaminate t/Makefile with compilation
related stuff that we didn't need originally.
t/Makefile | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git c/t/Makefile w/t/Makefile
index b7a6fefe28..010ce083b1 100644
--- c/t/Makefile
+++ w/t/Makefile
@@ -6,6 +6,7 @@ include ../shared.mak
# Copyright (c) 2005 Junio C Hamano
#
+include ../config.mak.uname
-include ../config.mak.autogen
-include ../config.mak
@@ -42,7 +43,9 @@ TPERF = $(sort $(wildcard perf/p[0-9][0-9][0-9][0-9]-*.sh))
TINTEROP = $(sort $(wildcard interop/i[0-9][0-9][0-9][0-9]-*.sh))
CHAINLINTTESTS = $(sort $(patsubst chainlint/%.test,%,$(wildcard chainlint/*.test)))
CHAINLINT = '$(PERL_PATH_SQ)' chainlint.pl
-UNIT_TESTS = $(sort $(filter-out %.pdb unit-tests/bin/t-basic%,$(wildcard unit-tests/bin/t-*)))
+UNIT_TEST_SOURCES = $(wildcard unit-tests/t-*.c)
+UNIT_TEST_PROGRAMS = $(patsubst unit-tests/%.c,unit-tests/bin/%$X,$(UNIT_TEST_SOURCES))
+UNIT_TESTS = $(sort $(filter-out unit-tests/bin/t-basic%,$(UNIT_TEST_PROGRAMS)))
# `test-chainlint` (which is a dependency of `test-lint`, `test` and `prove`)
# checks all tests in all scripts via a single invocation, so tell individual
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH 1/2] Makefile: use order-only prereq for UNIT_TEST_BIN
2024-01-29 20:22 ` SZEDER Gábor
2024-01-29 22:06 ` Junio C Hamano
@ 2024-01-30 5:21 ` Jeff King
1 sibling, 0 replies; 24+ messages in thread
From: Jeff King @ 2024-01-30 5:21 UTC (permalink / raw)
To: SZEDER Gábor; +Cc: git, Phillip Wood
On Mon, Jan 29, 2024 at 09:22:01PM +0100, SZEDER Gábor wrote:
> > If it is a problem, there are two alternatives:
> >
> > - we can just "mkdir -p" in the recipe to build the individual
> > binaries. This will mean some redundant "mkdir" calls, but only when
> > actually invoking the compiler.
> >
> > - we could stop making the directory on the fly, and just add it with
> > a .gitignore of "*". This would work fine, but might be awkward when
> > moving back and forth in history.
>
> A third alternative is to use $(call mkdir_p_parent_template) in the
> recipe and get rid of the thus unnecessary UNIT_TEST_BIN dependency
> and target. It will only run mkdir when needed, and it's a well
> established pattern in our Makefile, so you won't have to spend a
> paragraph or two arguing about potential problems with GNU-isms :)
Thanks, I somehow didn't know about that (and didn't find it when
grepping around for similar cases, probably because "mkdir -p" no longer
appears in those cases ;) ).
I agree it's a better solution here. I'll send a v2 in a moment with
that.
(Ironically, that template requires "call" which is in make 3.81, but
the commit adding it didn't discuss that at all).
> On a related note, 'make clean' doesn't remove this 't/unit-tests/bin'
> directory.
Not the end of the world, as we do clean out the contents, so "ls-files
-o" would not mention any leftover cruft. But I agree that we should
strive for "make clean" to be the opposite of "make" as much as
possible.
I'll add in a patch to v2.
-Peff
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 2/2] t/Makefile: get UNIT_TESTS list from C sources
2024-01-29 21:31 ` Adam Dinwoodie
2024-01-30 0:27 ` Junio C Hamano
@ 2024-01-30 5:23 ` Jeff King
1 sibling, 0 replies; 24+ messages in thread
From: Jeff King @ 2024-01-30 5:23 UTC (permalink / raw)
To: Adam Dinwoodie; +Cc: Patrick Steinhardt, git, Phillip Wood
On Mon, Jan 29, 2024 at 09:31:11PM +0000, Adam Dinwoodie wrote:
> > Hmm, good point. It seems like the answer should obviously be "yes", but
> > Windows CI seemed to pass all the same (and I checked that it indeed ran
> > the unit tests). Do we only get the $X suffix for MSVC builds or
> > something? Looks like maybe cygwin, as well.
>
> Cygwin will automatically append ".exe" when doing directory listings;
> a check if the file "a" exists will return true on Cygwin if "a" or
> "a.exe" exists; a glob for "a*" in a directory containing files "a1"
> and "a2.exe" will return "a1" and "a2". This causes problems in some
> edge cases, but it means *nix scripts and applications are much more
> likely to work without any Cygwin-specific handling. I *think* this
> logic is carried downstream to MSYS2 and thence to Git for Windows.
>
> As a result, I'm not surprised this worked without handling $X, but I
> don't think there's any harm in adding it either.
Ah, that makes sense. I do think it will work under the conditions you
laid out, but I don't know if there are platforms where that's not the
case. I'll add the $(X) just to be sure (as that really feels more
consistent with what the top-level Makefile is doing anyway).
Thanks.
-Peff
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 2/2] t/Makefile: get UNIT_TESTS list from C sources
2024-01-30 0:27 ` Junio C Hamano
@ 2024-01-30 5:25 ` Jeff King
2024-01-31 19:13 ` Adam Dinwoodie
1 sibling, 0 replies; 24+ messages in thread
From: Jeff King @ 2024-01-30 5:25 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Adam Dinwoodie, Patrick Steinhardt, git, Phillip Wood
On Mon, Jan 29, 2024 at 04:27:59PM -0800, Junio C Hamano wrote:
> > As a result, I'm not surprised this worked without handling $X, but I
> > don't think there's any harm in adding it either.
>
> OK.
>
> I wonder if something like this is sufficient?
> [...]
Yeah, that matches the patch I came up with locally. I'll roll that into
v2.
> I am not sure if we
> should lift the building of t/unit-tests/* up to the primary Makefile
> to mimic the way stuff related to test-tool are built and linked.
> That way, we do not have to contaminate t/Makefile with compilation
> related stuff that we didn't need originally.
I didn't quite understand this comment, though. The building of
t/unit-tests _is_ in the top-level Makefile. It's just here in the
recursive Makefile that we need to have the list of built programs.
-Peff
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 0/3] some unit-test Makefile polishing
2024-01-29 3:15 [PATCH 0/2] some unit-test Makefile polishing Jeff King
2024-01-29 3:18 ` [PATCH 1/2] Makefile: use order-only prereq for UNIT_TEST_BIN Jeff King
2024-01-29 3:19 ` [PATCH 2/2] t/Makefile: get UNIT_TESTS list from C sources Jeff King
@ 2024-01-30 5:37 ` Jeff King
2024-01-30 5:37 ` [PATCH v2 1/3] Makefile: use mkdir_p_parent_template for UNIT_TEST_BIN Jeff King
` (3 more replies)
2 siblings, 4 replies; 24+ messages in thread
From: Jeff King @ 2024-01-30 5:37 UTC (permalink / raw)
To: git
Cc: Phillip Wood, SZEDER Gábor, Junio C Hamano, Adam Dinwoodie,
Patrick Steinhardt, git
On Sun, Jan 28, 2024 at 10:15:40PM -0500, Jeff King wrote:
> The patches fixes two small hiccups I found with the unit-tests. Neither
> is a show-stopper, but mostly just small quality-of-life fixes.
And here's another iteration based on the feedback from v1. It uses the
mkdir_p template mentioned by Gábor, fixes the $(X) issue mentioned by
Patrick, and adds a new patch to handle the directory in "make clean".
No range diff, as range-diff refuses to admit that the patches are
related (presumably because even though the changes are small, the
original patches were also tiny).
[1/3]: Makefile: use mkdir_p_parent_template for UNIT_TEST_BIN
[2/3]: Makefile: remove UNIT_TEST_BIN directory with "make clean"
[3/3]: t/Makefile: get UNIT_TESTS list from C sources
Makefile | 10 ++++------
t/Makefile | 5 ++++-
2 files changed, 8 insertions(+), 7 deletions(-)
-Peff
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 1/3] Makefile: use mkdir_p_parent_template for UNIT_TEST_BIN
2024-01-30 5:37 ` [PATCH v2 0/3] some unit-test Makefile polishing Jeff King
@ 2024-01-30 5:37 ` Jeff King
2024-01-30 5:38 ` [PATCH v2 2/3] Makefile: remove UNIT_TEST_BIN directory with "make clean" Jeff King
` (2 subsequent siblings)
3 siblings, 0 replies; 24+ messages in thread
From: Jeff King @ 2024-01-30 5:37 UTC (permalink / raw)
To: git
Cc: Phillip Wood, SZEDER Gábor, Junio C Hamano, Adam Dinwoodie,
Patrick Steinhardt, git
We build the UNIT_TEST_BIN directory (t/unit-tests/bin) on the fly with
"mkdir -p". And so the recipe for UNIT_TEST_PROGS, which put their
output in that directory, depend on UNIT_TEST_BIN to make sure it's
there.
But using a normal dependency leads to weird outcomes, because the
timestamp of the directory is important. For example, try this:
$ make
[...builds everything...]
[now re-build one unit test]
$ touch t/unit-tests/t-ctype.c
$ make
SUBDIR templates
CC t/unit-tests/t-ctype.o
LINK t/unit-tests/bin/t-ctype
So far so good. Now running make again should build nothing. But it
doesn't!
$ make
SUBDIR templates
LINK t/unit-tests/bin/t-basic
LINK t/unit-tests/bin/t-mem-pool
LINK t/unit-tests/bin/t-strbuf
Er, what? Let's rebuild again:
$ make
SUBDIR templates
LINK t/unit-tests/bin/t-ctype
Weird. And now we ping-pong back and forth forever:
$ make
SUBDIR templates
LINK t/unit-tests/bin/t-basic
LINK t/unit-tests/bin/t-mem-pool
LINK t/unit-tests/bin/t-strbuf
$ make
SUBDIR templates
LINK t/unit-tests/bin/t-ctype
What happens is that writing t/unit-tests/bin/t-ctype updates the mtime
of the directory t/unit-tests/bin. And then on the next invocation of
make, all of those other tests are now older and so get rebuilt. And
back and forth forever.
We can fix this by making the directory as part of the build recipe for
the programs, using the template from 0b6d0bc924 (Makefiles: add and use
wildcard "mkdir -p" template, 2022-03-03).
Helped-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Jeff King <peff@peff.net>
---
Makefile | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/Makefile b/Makefile
index 0f748a52e6..228f34a3fe 100644
--- a/Makefile
+++ b/Makefile
@@ -3868,10 +3868,8 @@ $(FUZZ_PROGRAMS): %: %.o oss-fuzz/dummy-cmd-main.o $(GITLIBS) GIT-LDFLAGS
fuzz-all: $(FUZZ_PROGRAMS)
-$(UNIT_TEST_BIN):
- @mkdir -p $(UNIT_TEST_BIN)
-
-$(UNIT_TEST_PROGS): $(UNIT_TEST_BIN)/%$X: $(UNIT_TEST_DIR)/%.o $(UNIT_TEST_DIR)/test-lib.o $(GITLIBS) GIT-LDFLAGS $(UNIT_TEST_BIN)
+$(UNIT_TEST_PROGS): $(UNIT_TEST_BIN)/%$X: $(UNIT_TEST_DIR)/%.o $(UNIT_TEST_DIR)/test-lib.o $(GITLIBS) GIT-LDFLAGS
+ $(call mkdir_p_parent_template)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) \
$(filter %.o,$^) $(filter %.a,$^) $(LIBS)
--
2.43.0.797.g29b680fc68
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 2/3] Makefile: remove UNIT_TEST_BIN directory with "make clean"
2024-01-30 5:37 ` [PATCH v2 0/3] some unit-test Makefile polishing Jeff King
2024-01-30 5:37 ` [PATCH v2 1/3] Makefile: use mkdir_p_parent_template for UNIT_TEST_BIN Jeff King
@ 2024-01-30 5:38 ` Jeff King
2024-01-30 5:40 ` [PATCH v2 3/3] t/Makefile: get UNIT_TESTS list from C sources Jeff King
2024-02-02 1:20 ` [PATCH v2 0/3] some unit-test Makefile polishing Junio C Hamano
3 siblings, 0 replies; 24+ messages in thread
From: Jeff King @ 2024-01-30 5:38 UTC (permalink / raw)
To: git
Cc: Phillip Wood, SZEDER Gábor, Junio C Hamano, Adam Dinwoodie,
Patrick Steinhardt, git
We remove $(UNIT_TEST_PROGS), but that leaves the automatically
generated "bin" dir they reside in. And once we start cleaning that,
there is no point in removing the individual programs, as they'll by
wiped out by the recurse "rm".
Signed-off-by: Jeff King <peff@peff.net>
---
The layout of the clean rule is kind of weird, in that we put only
sort-of related things together on their own $(RM) line. I suspect a lot
more of this could be lumped together, reducing the total number of
shells and rm invocations needed, but I guess nobody really cares that
much about the runtime cost of "make clean".
Makefile | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Makefile b/Makefile
index 228f34a3fe..b5ae34ea7b 100644
--- a/Makefile
+++ b/Makefile
@@ -3680,14 +3680,14 @@ cocciclean:
$(RM) contrib/coccinelle/*.cocci.patch
clean: profile-clean coverage-clean cocciclean
- $(RM) -r .build
+ $(RM) -r .build $(UNIT_TEST_BIN)
$(RM) po/git.pot po/git-core.pot
$(RM) git.res
$(RM) $(OBJECTS)
$(RM) headless-git.o
$(RM) $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB) $(REFTABLE_TEST_LIB)
$(RM) $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) $(OTHER_PROGRAMS)
- $(RM) $(TEST_PROGRAMS) $(UNIT_TEST_PROGS)
+ $(RM) $(TEST_PROGRAMS)
$(RM) $(FUZZ_PROGRAMS)
$(RM) $(SP_OBJ)
$(RM) $(HCC)
--
2.43.0.797.g29b680fc68
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 3/3] t/Makefile: get UNIT_TESTS list from C sources
2024-01-30 5:37 ` [PATCH v2 0/3] some unit-test Makefile polishing Jeff King
2024-01-30 5:37 ` [PATCH v2 1/3] Makefile: use mkdir_p_parent_template for UNIT_TEST_BIN Jeff King
2024-01-30 5:38 ` [PATCH v2 2/3] Makefile: remove UNIT_TEST_BIN directory with "make clean" Jeff King
@ 2024-01-30 5:40 ` Jeff King
2024-01-31 22:58 ` Junio C Hamano
2024-02-01 10:50 ` Phillip Wood
2024-02-02 1:20 ` [PATCH v2 0/3] some unit-test Makefile polishing Junio C Hamano
3 siblings, 2 replies; 24+ messages in thread
From: Jeff King @ 2024-01-30 5:40 UTC (permalink / raw)
To: git
Cc: Phillip Wood, SZEDER Gábor, Junio C Hamano, Adam Dinwoodie,
Patrick Steinhardt, git
We decide on the set of unit tests to run by asking make to expand the
wildcard "t/unit-tests/bin/*". One unfortunate outcome of this is that
we'll run anything in that directory, even if it is leftover cruft from
a previous build. This isn't _quite_ as bad as it sounds, since in
theory the unit tests executables are self-contained (so if they passed
before, they'll pass even though they now have nothing to do with the
checked out version of Git). But at the very least it's wasteful, and if
they _do_ fail it can be quite confusing to understand why they are
being run at all.
This wildcarding presumably came from our handling of the regular
shell-script tests, which use $(wildcard t[0-9][0-9][0-9][0-9]-*.sh).
But the difference there is that those are actual tracked files. So if
you checkout a different commit, they'll go away. Whereas the contents
of unit-tests/bin are ignored (so not only do they stick around, but you
are not even warned of the stale files via "git status").
This patch fixes the situation by looking for the actual unit-test
source files and then massaging those names into the final executable
names. This has two additional benefits:
1. It will notice if we failed to build one or more unit-tests for
some reason (wheras the current code just runs whatever made it to
the bin/ directory).
2. The wildcard should avoid other build cruft, like the pdb files we
worked around in 0df903d402 (unit-tests: do not mistake `.pdb`
files for being executable, 2023-09-25).
Our new wildcard does make an assumption that unit tests are built from
C sources. It would be a bit cleaner if we consulted UNIT_TEST_PROGRAMS
from the top-level Makefile. But doing so is tricky unless we reorganize
that Makefile to split the source file lists into include-able subfiles.
That might be worth doing in general, but in the meantime, the
assumptions made by the wildcard here seems reasonable.
Note that we do need to include config.mak.uname either way, though, as
we need the value of $(X) to compute the correct executable names (which
would be true even if we had acess to the top-level's UNIT_TEST_PROGRAMS
variable).
Signed-off-by: Jeff King <peff@peff.net>
---
This is actually pretty easy to test on Linux if you just set "X"
yourself. I confirmed that it is needed for "make X=.exe unit-tests" to
work, and that fudging an "X = .exe" line into config.mak.uname, as
would happen on real platforms works with the extra include.
t/Makefile | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/t/Makefile b/t/Makefile
index b7a6fefe28..281f4c3534 100644
--- a/t/Makefile
+++ b/t/Makefile
@@ -6,6 +6,7 @@ include ../shared.mak
# Copyright (c) 2005 Junio C Hamano
#
+-include ../config.mak.uname
-include ../config.mak.autogen
-include ../config.mak
@@ -42,7 +43,9 @@ TPERF = $(sort $(wildcard perf/p[0-9][0-9][0-9][0-9]-*.sh))
TINTEROP = $(sort $(wildcard interop/i[0-9][0-9][0-9][0-9]-*.sh))
CHAINLINTTESTS = $(sort $(patsubst chainlint/%.test,%,$(wildcard chainlint/*.test)))
CHAINLINT = '$(PERL_PATH_SQ)' chainlint.pl
-UNIT_TESTS = $(sort $(filter-out %.pdb unit-tests/bin/t-basic%,$(wildcard unit-tests/bin/t-*)))
+UNIT_TEST_SOURCES = $(wildcard unit-tests/t-*.c)
+UNIT_TEST_PROGRAMS = $(patsubst unit-tests/%.c,unit-tests/bin/%$(X),$(UNIT_TEST_SOURCES))
+UNIT_TESTS = $(sort $(filter-out unit-tests/bin/t-basic%,$(UNIT_TEST_PROGRAMS)))
# `test-chainlint` (which is a dependency of `test-lint`, `test` and `prove`)
# checks all tests in all scripts via a single invocation, so tell individual
--
2.43.0.797.g29b680fc68
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH 2/2] t/Makefile: get UNIT_TESTS list from C sources
2024-01-30 0:27 ` Junio C Hamano
2024-01-30 5:25 ` Jeff King
@ 2024-01-31 19:13 ` Adam Dinwoodie
1 sibling, 0 replies; 24+ messages in thread
From: Adam Dinwoodie @ 2024-01-31 19:13 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jeff King, Patrick Steinhardt, git, Phillip Wood
On Tue, 30 Jan 2024 at 00:28, Junio C Hamano <gitster@pobox.com> wrote:
>
> Adam Dinwoodie <adam@dinwoodie.org> writes:
>
> >> Hmm, good point. It seems like the answer should obviously be "yes", but
> >> Windows CI seemed to pass all the same (and I checked that it indeed ran
> >> the unit tests). Do we only get the $X suffix for MSVC builds or
> >> something? Looks like maybe cygwin, as well.
> >
> > Cygwin will automatically append ".exe" when doing directory listings;
> > a check if the file "a" exists will return true on Cygwin if "a" or
> > "a.exe" exists; a glob for "a*" in a directory containing files "a1"
> > and "a2.exe" will return "a1" and "a2". This causes problems in some
> > edge cases, but it means *nix scripts and applications are much more
> > likely to work without any Cygwin-specific handling. I *think* this
> > logic is carried downstream to MSYS2 and thence to Git for Windows.
>
> Interesting, especially that "a*" is globbed to "a2" and not
> "a2.exe".
My error, sorry! I've just double-checked and Cygwin's globbing will
report the file with the .exe extension. I clearly misremembered how
this works.
Having looked up a bit more of the implementation is simply that, if
Cygwin tries to open a file named "x" and doesn't find it, it will
attempt to open "x.exe" before it returns the failure. This means that
scripts that call (say) `/usr/bin/env bash` or `cat` or `[ "$x" = "$y"
]` or whatever will broadly Just Work(TM) rather than needing to be
rewritten with the extension added. But the behaviour only applies
when Cygwin is looking for a specific filename.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 3/3] t/Makefile: get UNIT_TESTS list from C sources
2024-01-30 5:40 ` [PATCH v2 3/3] t/Makefile: get UNIT_TESTS list from C sources Jeff King
@ 2024-01-31 22:58 ` Junio C Hamano
2024-02-01 10:50 ` Phillip Wood
1 sibling, 0 replies; 24+ messages in thread
From: Junio C Hamano @ 2024-01-31 22:58 UTC (permalink / raw)
To: Jeff King
Cc: git, Phillip Wood, SZEDER Gábor, Adam Dinwoodie,
Patrick Steinhardt
Jeff King <peff@peff.net> writes:
> 1. It will notice if we failed to build one or more unit-tests for
> some reason (wheras the current code just runs whatever made it to
> the bin/ directory).
"whereas"
> would be true even if we had acess to the top-level's UNIT_TEST_PROGRAMS
"access"
I've typofixed them while queuing; no need to resend the patch only
to fix it.
Thanks.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 3/3] t/Makefile: get UNIT_TESTS list from C sources
2024-01-30 5:40 ` [PATCH v2 3/3] t/Makefile: get UNIT_TESTS list from C sources Jeff King
2024-01-31 22:58 ` Junio C Hamano
@ 2024-02-01 10:50 ` Phillip Wood
1 sibling, 0 replies; 24+ messages in thread
From: Phillip Wood @ 2024-02-01 10:50 UTC (permalink / raw)
To: Jeff King, git
Cc: Phillip Wood, SZEDER Gábor, Junio C Hamano, Adam Dinwoodie,
Patrick Steinhardt
Hi Peff
On 30/01/2024 05:40, Jeff King wrote:
> We decide on the set of unit tests to run by asking make to expand the
> wildcard "t/unit-tests/bin/*". One unfortunate outcome of this is that
> we'll run anything in that directory, even if it is leftover cruft from
> a previous build. This isn't _quite_ as bad as it sounds, since in
> theory the unit tests executables are self-contained (so if they passed
> before, they'll pass even though they now have nothing to do with the
> checked out version of Git). But at the very least it's wasteful, and if
> they _do_ fail it can be quite confusing to understand why they are
> being run at all.
>
> This wildcarding presumably came from our handling of the regular
> shell-script tests, which use $(wildcard t[0-9][0-9][0-9][0-9]-*.sh).
> But the difference there is that those are actual tracked files. So if
> you checkout a different commit, they'll go away. Whereas the contents
> of unit-tests/bin are ignored (so not only do they stick around, but you
> are not even warned of the stale files via "git status").
>
> This patch fixes the situation by looking for the actual unit-test
> source files and then massaging those names into the final executable
> names. This has two additional benefits:
>
> 1. It will notice if we failed to build one or more unit-tests for
> some reason (wheras the current code just runs whatever made it to
> the bin/ directory).
The downside to this is that if there are any cruft C files lying about
t/unit-tests we'll fail to run the unit tests. In the past we've avoided
using wildcard rules on C sources to avoid problems like this[1]. This
change may well be the lesser of two evils but a test run that fails due
to a cruft C file cannot be fixed by "make clean && make" whereas that
will fix the problem of a stale test executable.
> 2. The wildcard should avoid other build cruft, like the pdb files we
> worked around in 0df903d402 (unit-tests: do not mistake `.pdb`
> files for being executable, 2023-09-25).
>
> Our new wildcard does make an assumption that unit tests are built from
> C sources. It would be a bit cleaner if we consulted UNIT_TEST_PROGRAMS
> from the top-level Makefile. But doing so is tricky unless we reorganize
> that Makefile to split the source file lists into include-able subfiles.
> That might be worth doing in general, but in the meantime, the
> assumptions made by the wildcard here seems reasonable.
Using UNIT_TEST_PROGRAMS would definitely be a nicer approach long term.
Best Wishes
Phillip
[1] https://lore.kernel.org/git/xmqqtugl102l.fsf@gitster.g/
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 0/3] some unit-test Makefile polishing
2024-01-30 5:37 ` [PATCH v2 0/3] some unit-test Makefile polishing Jeff King
` (2 preceding siblings ...)
2024-01-30 5:40 ` [PATCH v2 3/3] t/Makefile: get UNIT_TESTS list from C sources Jeff King
@ 2024-02-02 1:20 ` Junio C Hamano
2024-02-02 23:52 ` Johannes Schindelin
3 siblings, 1 reply; 24+ messages in thread
From: Junio C Hamano @ 2024-02-02 1:20 UTC (permalink / raw)
To: git
Cc: Jeff King, Phillip Wood, SZEDER Gábor, Adam Dinwoodie,
Patrick Steinhardt
Jeff King <peff@peff.net> writes:
> On Sun, Jan 28, 2024 at 10:15:40PM -0500, Jeff King wrote:
>
>> The patches fixes two small hiccups I found with the unit-tests. Neither
>> is a show-stopper, but mostly just small quality-of-life fixes.
>
> And here's another iteration based on the feedback from v1. It uses the
> mkdir_p template mentioned by Gábor, fixes the $(X) issue mentioned by
> Patrick, and adds a new patch to handle the directory in "make clean".
>
> No range diff, as range-diff refuses to admit that the patches are
> related (presumably because even though the changes are small, the
> original patches were also tiny).
>
> [1/3]: Makefile: use mkdir_p_parent_template for UNIT_TEST_BIN
> [2/3]: Makefile: remove UNIT_TEST_BIN directory with "make clean"
> [3/3]: t/Makefile: get UNIT_TESTS list from C sources
Merging this topic seems to stop all "win test (n)" jobs at GitHub
CI, which is puzzling (I would have understood a broken build, but
that is not what we are seeing).
https://github.com/git/git/actions/runs/7748054008 is a run of 'next'
that is broken.
https://github.com/git/git/actions/runs/7748547579 is a run of 'seen~1'
with this topic reverted (the ps/reftable-backend topic is excluded),
which seems to pass.
Does it ring a bell, anybody?
Thanks.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 0/3] some unit-test Makefile polishing
2024-02-02 1:20 ` [PATCH v2 0/3] some unit-test Makefile polishing Junio C Hamano
@ 2024-02-02 23:52 ` Johannes Schindelin
2024-02-03 1:32 ` Junio C Hamano
0 siblings, 1 reply; 24+ messages in thread
From: Johannes Schindelin @ 2024-02-02 23:52 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Jeff King, Phillip Wood, SZEDER Gábor, Adam Dinwoodie,
Patrick Steinhardt
Hi Junio,
On Thu, 1 Feb 2024, Junio C Hamano wrote:
> https://github.com/git/git/actions/runs/7748054008 is a run of 'next'
> that is broken.
>
> https://github.com/git/git/actions/runs/7748547579 is a run of 'seen~1'
> with this topic reverted (the ps/reftable-backend topic is excluded),
> which seems to pass.
>
> Does it ring a bell, anybody?
Yes, it does ring a clear bell over here.
https://github.com/git/git/actions/runs/7748054008/job/21130098985#step:5:81
points to the culprit:
fatal: not a git repository (or any of the parent directories): .git
make: *** [../config.mak.uname:753: vcxproj] Error 128
The line 753 of that file (as can be seen at
https://github.com/git/git/blob/38aa6559b0c513d755d6d5ccf32414ed63754726/config.mak.uname#L753)
is the first statement of the `vcxproj` target, executing `update-refresh`:
vcxproj:
# Require clean work tree
git update-index -q --refresh && \
git diff-files --quiet && \
git diff-index --cached --quiet HEAD --
[...]
This means that `vcxproj` is executed. And the explanation is in
https://github.com/git/git/actions/runs/7748054008/job/21130098985#step:5:78,
which runs `make --quiet -C t 'T=<long-list-of-files>'`, crucially
_without_ specifying any Makefile rule, and the `vcxproj` rule happens to
be the first one that is defined on Windows, so it's used by default.
One workaround would be to remove the `vcxproj` rule (which by now has
been safely superseded by the CMake support we have in
`contrib/buildsystems/`).
But the safer way would be to insert these two lines at the beginning of
`t/Makefile` (cargo-culted from the top-level `Makefile`):
# The default target of this Makefile is...
all::
Ciao,
Johannes
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 0/3] some unit-test Makefile polishing
2024-02-02 23:52 ` Johannes Schindelin
@ 2024-02-03 1:32 ` Junio C Hamano
2024-02-04 4:41 ` Jeff King
0 siblings, 1 reply; 24+ messages in thread
From: Junio C Hamano @ 2024-02-03 1:32 UTC (permalink / raw)
To: Johannes Schindelin
Cc: git, Jeff King, Phillip Wood, SZEDER Gábor, Adam Dinwoodie,
Patrick Steinhardt
Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> The line 753 of that file (as can be seen at
> https://github.com/git/git/blob/38aa6559b0c513d755d6d5ccf32414ed63754726/config.mak.uname#L753)
Ouch. When it is laid out like this it is very obvious why this is
broken, and what its workaround should be.
Thanks. Let's queue this on top.
------- >8 ------------- >8 ------------- >8 ------------- >8 -------
Subject: [PATCH] t/Makefile: say the default target upfront
Similar to how 2731d048 (Makefile: say the default target upfront.,
2005-12-01) added the default target to the very beginning of the
main Makefile to prevent a random rule that happens to be defined
first in an included makefile fragments from becoming the default
target, protect this Makefile the same way.
This started to matter as we started to include config.mak.uname
and that included makefile fragment does more than defining Make
macros, unfortunately.
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
t/Makefile | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/t/Makefile b/t/Makefile
index 281f4c3534..2d95046f26 100644
--- a/t/Makefile
+++ b/t/Makefile
@@ -1,3 +1,6 @@
+# The default target of this Makefile is...
+all::
+
# Import tree-wide shared Makefile behavior and libraries
include ../shared.mak
@@ -52,7 +55,7 @@ UNIT_TESTS = $(sort $(filter-out unit-tests/bin/t-basic%,$(UNIT_TEST_PROGRAMS)))
# scripts not to run the external "chainlint.pl" script themselves
CHAINLINTSUPPRESS = GIT_TEST_EXT_CHAIN_LINT=0 && export GIT_TEST_EXT_CHAIN_LINT &&
-all: $(DEFAULT_TEST_TARGET)
+all:: $(DEFAULT_TEST_TARGET)
test: pre-clean check-chainlint $(TEST_LINT)
$(CHAINLINTSUPPRESS) $(MAKE) aggregate-results-and-cleanup
--
2.43.0-522-g2a540e432f
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH v2 0/3] some unit-test Makefile polishing
2024-02-03 1:32 ` Junio C Hamano
@ 2024-02-04 4:41 ` Jeff King
0 siblings, 0 replies; 24+ messages in thread
From: Jeff King @ 2024-02-04 4:41 UTC (permalink / raw)
To: Junio C Hamano
Cc: Johannes Schindelin, git, Phillip Wood, SZEDER Gábor,
Adam Dinwoodie, Patrick Steinhardt
On Fri, Feb 02, 2024 at 05:32:42PM -0800, Junio C Hamano wrote:
> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>
> > The line 753 of that file (as can be seen at
> > https://github.com/git/git/blob/38aa6559b0c513d755d6d5ccf32414ed63754726/config.mak.uname#L753)
>
> Ouch. When it is laid out like this it is very obvious why this is
> broken, and what its workaround should be.
>
> Thanks. Let's queue this on top.
>
> ------- >8 ------------- >8 ------------- >8 ------------- >8 -------
> Subject: [PATCH] t/Makefile: say the default target upfront
>
> Similar to how 2731d048 (Makefile: say the default target upfront.,
> 2005-12-01) added the default target to the very beginning of the
> main Makefile to prevent a random rule that happens to be defined
> first in an included makefile fragments from becoming the default
> target, protect this Makefile the same way.
>
> This started to matter as we started to include config.mak.uname
> and that included makefile fragment does more than defining Make
> macros, unfortunately.
>
> Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Thanks both of you for identifying and fixing this. I should have been
able to catch this, as it triggers with a simple "make" in the t/
directory (rather than "make prove" or "make unit-test", which is of
course what I checked).
Sorry I'm slow to chime in; I've been offline all week (and probably
will be for another few days) due to a family emergency. But hopefully
with this fix the topic is OK now.
-Peff
^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2024-02-04 4:41 UTC | newest]
Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-01-29 3:15 [PATCH 0/2] some unit-test Makefile polishing Jeff King
2024-01-29 3:18 ` [PATCH 1/2] Makefile: use order-only prereq for UNIT_TEST_BIN Jeff King
2024-01-29 20:22 ` SZEDER Gábor
2024-01-29 22:06 ` Junio C Hamano
2024-01-30 5:21 ` Jeff King
2024-01-29 3:19 ` [PATCH 2/2] t/Makefile: get UNIT_TESTS list from C sources Jeff King
2024-01-29 11:26 ` Patrick Steinhardt
2024-01-29 17:49 ` Jeff King
2024-01-29 21:31 ` Adam Dinwoodie
2024-01-30 0:27 ` Junio C Hamano
2024-01-30 5:25 ` Jeff King
2024-01-31 19:13 ` Adam Dinwoodie
2024-01-30 5:23 ` Jeff King
2024-01-29 21:51 ` Junio C Hamano
2024-01-30 5:37 ` [PATCH v2 0/3] some unit-test Makefile polishing Jeff King
2024-01-30 5:37 ` [PATCH v2 1/3] Makefile: use mkdir_p_parent_template for UNIT_TEST_BIN Jeff King
2024-01-30 5:38 ` [PATCH v2 2/3] Makefile: remove UNIT_TEST_BIN directory with "make clean" Jeff King
2024-01-30 5:40 ` [PATCH v2 3/3] t/Makefile: get UNIT_TESTS list from C sources Jeff King
2024-01-31 22:58 ` Junio C Hamano
2024-02-01 10:50 ` Phillip Wood
2024-02-02 1:20 ` [PATCH v2 0/3] some unit-test Makefile polishing Junio C Hamano
2024-02-02 23:52 ` Johannes Schindelin
2024-02-03 1:32 ` Junio C Hamano
2024-02-04 4:41 ` Jeff King
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).