I was experiencing unnecessary rebuilds while using this matching pattern:
getDirectoryFiles "" $ "foo" </> "//*.c"
I'm on Linux so from my understanding the second argument will evaluate to
"foo///*.c"
and I presume that it would be incorrect to replace this with
"foo" </> "/*.c"
as that would not work on windows? On Linux however this works as I expect it to.
From testing I concluded that the pattern matched files outside of "foo" which makes no sense in my world. As an example the pattern above would match both testA.c and testB.c in a directory structure like the one below.
foo/testA.c
bar/testB.c
I see now that there is a <//>
operator, so maybe I should be using "foo" <//> "*.c"
instead but still. This was quite nasty to find and what does "foo///*.c"
actually do?
The problem is that the </>
operator is defined so that:
"foo" </> "//*.c" == "//*.c"
That means that using </>
to create a //
value is almost never the right thing to do. <//>
solves that, but as you note, it's not predictable and quite nasty.
The solution is using foo/**/*.c
as an alternative pattern to foo//*.c
. The advantage of the first form is that it is perfectly predictable and works well with </>
, eliminating the need for <//>
. Since Shake 0.15.6 that has been a permissible alternative, and in Shake 0.16 it will probably be recommended over //
.
As to your other questions: 1) for Windows you can use either /
or \
interchangeably in pattern values, so writing foo//*.c
literally is just fine. 2) foo///*.c
is equivalent to foo//*.c
, and there are extensive test suites for such forms in Shake.