3

When building chisel using sbt, when run as a batch process, how do I turn off the progress bars etc. so that the output is clean like I get with most compilers?

That is, I like to build chisel using sbt from within a makefile, like this:

${VLOG_DIR}/${NAME}.v: ${NAME}.scala
        setsid sbt \
          'runMain ${NAME}.${NAME} --top-name ${NAME} --target-dir ${VLOG_DIR}'

However sbt/scala/chisel like to attempt to generate some sort of progress bars while building that emit terminal escape codes to attempt to update the output in place. When run inside my shell this does not work very well, but when run inside emacs it makes a huge mess:

make
setsid sbt \
  'runMain HelloWorld.HelloWorld --top-name HelloWorld --target-dir Gen_HelloWor\
ld.verilog_dir'
^[[0m[^[[0m^[[0minfo^[[0m] ^[[0m^[[0mLoading project definition from /home/user/h\
ello-chisel/project^[[0m
^[[2K
^[[2K
^[[2K
^[[2K
^[[2K
^[[5A^[[2K
^[[2K
^[[2K
^[[2K
^[[2K
^[[2K  | => hello-chisel-build / update 0s
^[[6A^[[2K
^[[2K

Especially when there is an error message:

^[[2K
^[[2K
^[[2K  | => hello-chisel / Compile / compileIncremental 1s
^[[6A^[[2K^[[0m[^[[0m^[[31merror^[[0m] ^[[0m^[[0m/home/user/hello-chisel/HelloWor\
ld.scala:46:17: overloaded method value apply with alternatives:^[[0m
^[[2K

How do I turn all of that off and get normal looking output having clean error messages?

Daniel
  • 1,861
  • 1
  • 16
  • 24

1 Answers1

4

Short answer

Pass -no-colors to sbt on the command line, per the sbt FAQ:

$ sbt -no-colors 'test:runMain gcd.GCDMain'

Despite the name "no colors", it suppresses all terminal escape stuff, including the progress bars.

Other alternatives

The option can also be spelled --no-colors (two hyphens), which is how it appears in the output of sbt --help (and sbt -help).

The same effect can be achieved by passing -Dsbt.log.noformat=true to sbt (or to java if invoking that directly) as indicated in this answer:

$ sbt -Dsbt.log.noformat=true 'test:runMain gcd.GCDMain'

It can also be achieved by setting the JAVA_OPTS environment variable to -Dsbt.log.noformat=true:

$ JAVA_OPTS=-Dsbt.log.noformat=true sbt 'test:runMain gcd.GCDMain'

If you are using sbt-launch.jar, then you have to use the -D switch because -no-colors is not recognized in that context (the sbt shell script is what recognizes -no-colors):

$ java -jar ~/opt/sbt-1.3.4/bin/sbt-launch.jar -Dsbt.log.noformat=true 'test:runMain gcd.GCDMain'

Finally, when sbt detects that its stdout is not a TTY, it will suppress color output:

$ sbt 'test:runMain gcd.GCDMain' | cat

That's not a good option in a Makefile though because you lose the exit status of sbt (without further shenanigans).

Unfortunately, sbt does not respect NO_COLOR.

Chisel output has some colors anyway

When using Chisel, for example the chisel template, even with -no-colors, some terminal escape codes appear in the output anyway:

$ sbt -no-colors 'test:runMain gcd.GCDMain' | cat -tev
[info] Loading settings for project chisel-template-build from plugins.sbt ...$
[info] Loading project definition from /home/scott/wrk/learn/chisel/chisel-template/project$
[info] Loading settings for project chisel-template from build.sbt ...$
[info] Set current project to chisel-module-template (in build file:/home/scott/wrk/learn/chisel/chisel-template/)$
[warn] Multiple main classes detected.  Run 'show discoveredMainClasses' to see the list$
[info] running gcd.GCDMain $
[^[[35minfo^[[0m] [0.001] Elaborating design...$
[^[[35minfo^[[0m] [1.064] Done elaborating.$
Total FIRRTL Compile Time: 512.0 ms$
file loaded in 0.114380184 seconds, 22 symbols, 17 statements$
[^[[35minfo^[[0m] [0.001] SEED 1581769687441$
test GCD Success: 168 tests passed in 1107 cycles in 0.047873 seconds 23123.91 Hz$
[^[[35minfo^[[0m] [0.037] RAN 1102 CYCLES PASSED$
[success] Total time: 3 s, completed Feb 15, 2020 4:28:09 AM$

Note the [^[[35minfo^[[0m] output near the end. This happens because chiselFrontend/src/main/scala/chisel3/internal/Error.scala unconditionally prints color escape sequences (see the tag function), which is arguably a bug in Chisel since its output is clearly meant to look similar to sbt output.

Effect of setsid

In your example Makefile, you're invoking sbt via setsid. As far as I can tell, everything I've said applies equally to that circumstance. However, you probably want to pass --wait to setsid so it will wait for sbt to complete before exiting. In my testing, setsid will implicitly wait only when stdout is not a TTY, but I doubt you actually want that hidden variability.

Scott McPeak
  • 8,803
  • 2
  • 40
  • 79