How does "swift build" cache builds?

(Pierpaolo Frasa) #1

I have this weird situation where I have a script spec, which does this:


set -o pipefail && swift test "$@" 2>&1 | xcpretty -s && swiftlint --quiet

I usually use this to run tests because the output is nicer. However, sometimes there are issues where xcpretty hides too many details, so I have to run swift test to get all the output (e.g. log statements).

However, I observe the following behaviour:

  • When I run ./spec several times without changing the code, it only needs to compile the code the first time
  • The same thing happens when I run swift test several times
  • However, if I run ./spec and then swift test, or the other way around, it somehow needs to recompile everything (even all the dependencies). This happens every time I switch between the two commands: apparently Swift doesn't keep a separate cache for ./spec and for swift test, but it just destroys the cache for one command every time I run the other command.

What could be the reason for this behaviour, and is there any way to avoid this? My project takes a long time to compile from scratch, so it would be really nice if this didn't happen.

1 Like
(Jacob Williams) #2

I too would be interested to know how build caching works. I use syntastic with vim but it’s very slow because it recompiles everything on each build.

(Ankit Aggarwal) #3

When you pipe the output, the compiler arguments change (I think it’s just colour diagnostics right now) and llbuild thinks it needs to recompile everything. This is a bug in SwiftPM and it needs to ignore that flag when computing the signature of Swift tasks. I think you can avoid hitting this bug by making SwiftPM think that it’s in a dumb terminal.

(Pierpaolo Frasa) #4

interesting, do you have more details on that (especially about the workaround)?

(Ankit Aggarwal) #5

Try executing vanilla swift test with this variable: TERM=dumb

1 Like
(Pierpaolo Frasa) #6

that seems to help. :+1:
has this bug already been logged?

(Ankit Aggarwal) #7