Skip to content

Commit

Permalink
Force coloured output on GCC and Clang
Browse files Browse the repository at this point in the history
Signed-off-by: Antonin Décimo <antonin@tarides.com>
  • Loading branch information
MisterDA committed Jan 15, 2021
1 parent b73f68f commit 1aa25a0
Show file tree
Hide file tree
Showing 3 changed files with 184 additions and 4 deletions.
21 changes: 17 additions & 4 deletions src/dune_rules/super_context.ml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,26 @@ let default_context_flags (ctx : Context.t) ~project =
| Some false ->
(Build.return cflags, Build.return cxxflags)
| Some true ->
let c = cflags @ Ocaml_config.ocamlc_cppflags ctx.ocaml_config in
let colors ccomp_type acc =
match ccomp_type with
| Cxx_flags.Gcc
| Clang
when Lazy.force Ansi_color.stderr_supports_color ->
"-fdiagnostics-color=always" :: acc
| _ -> acc
in
let c =
let open Build.O in
let+ ccomp_type, _ = Cxx_flags.get_flags ctx.build_dir in
cflags @ Ocaml_config.ocamlc_cppflags ctx.ocaml_config
|> colors ccomp_type
in
let cxx =
let open Build.O in
let+ _, db_flags = Cxx_flags.get_flags ctx.build_dir in
db_flags @ cxxflags
let+ ccomp_type, db_flags = Cxx_flags.get_flags ctx.build_dir in
db_flags @ cxxflags |> colors ccomp_type
in
(Build.return c, cxx)
(c, cxx)
in
Foreign_language.Dict.make ~c ~cxx

Expand Down
166 changes: 166 additions & 0 deletions test/blackbox-tests/test-cases/c-flags-diagnostics-color.t/run.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
Check that -fdiagnostics-color=always is added to :standard flag set
and the :standard set only if and only if
- Dune is running in a tty;
- the compiler is GCC or Clang;
- use_standard_c_and_cxx_flags is true.

The compiler is detected using the command name, that may not be most
portable way.

$ O_CC=$(ocamlc -config-var c_compiler)

We also have to trick Dune into believing it's executed in a tty,
otherwise it won't output colors!

$ function cc_supported() {
> if [[ "${O_CC}" == *gcc || "${O_CC}" = "clang" ]]; then
> echo "1";
> else echo "0"; fi }

$ function build_isatty() {
> if [[ "$(cc_supported)" = 1 ]]; then
> echo "int isatty(int fd) { return 1; }" |
> $(ocamlc -config-var native_c_compiler) -shared -ldl -o isatty-yes.so -xc -;
> echo "int isatty(int fd) { return 0; }" |
> $(ocamlc -config-var native_c_compiler) -shared -ldl -o isatty-no.so -xc -;
> fi
> }

$ function env_isatty() {
> local b=$1; shift;
> if [[ "$(cc_supported)" = 1 ]]; then
> env \
> TERM=not_dumb \
> "DYLD_INSERT_LIBRARIES=$PWD/isatty-$b.so" \
> DYLD_FORCE_FLAT_NAMESPACE=y \
> "LD_PRELOAD=$PWD/isatty-$b.so" \
> "$@";
> else
> env "$@";
> fi
> }

tty /\ not (:standard) => not (-fdiagnostics-color)
==================================

The flag shouldn't be present in the command, as we only want it in
the :standard set.

$ cat >dune-project <<EOF
> (lang dune 2.8)
> (use_standard_c_and_cxx_flags false)
> EOF
$ cat >dune <<EOF
> (library
> (name test)
> (foreign_stubs (language c) (names stub)))
> EOF

$ build_isatty
$ env_isatty yes dune rules -m stub.o | tr -s '\t\n\\' ' ' > out_stub

$ grep -ce "-fdiagnostics-color=always" out_stub
0
[1]

tty /\ :standard => -fdiagnostics-color
==================================

The flag should be present in the command, as we want it in the
:standard set.

$ cat >dune-project <<EOF
> (lang dune 2.8)
> (use_standard_c_and_cxx_flags true)
> EOF
$ cat >dune <<EOF
> (library
> (name test)
> (foreign_stubs (language c) (names stub)))
> EOF

$ build_isatty
$ env_isatty yes dune rules -m stub.o | tr -s '\t\n\\' ' ' > out_stub

$ out=$(grep -ce "-fdiagnostics-color=always" out_stub);
> if [[ "$(cc_supported)" = 1 ]]; then
> echo $out;
> elif [ $out = 0 ]; then
> echo 1;
> else
> echo 0;
> fi
1

tty /\ :standard /\ not (-fdiagnostics-color) => not (-fdiagnostics-color)
==================================

If the flag is disabled, it should never appear in the command line.

$ cat >dune-project <<EOF
> (lang dune 2.8)
> (use_standard_c_and_cxx_flags true)
> EOF
$ cat >dune <<EOF
> (library
> (name test)
> (foreign_stubs (language c) (names stub)
> (flags :standard \ -fdiagnostics-color=always)))
> EOF

$ build_isatty
$ env_isatty yes dune rules -m stub.o | tr -s '\t\n\\' ' ' > out_stub

$ grep -ce "-fdiagnostics-color=always" out_stub
0
[1]

not(tty) /\ :standard => not (-fdiagnostics-color)
==================================

If not running in a tty, the flag should not be present.

$ cat >dune-project <<EOF
> (lang dune 2.8)
> (use_standard_c_and_cxx_flags true)
> EOF
$ cat >dune <<EOF
> (library
> (name test)
> (foreign_stubs (language c) (names stub)))
> EOF

$ build_isatty
$ env_isatty no dune rules -m stub.o > out_stub

$ out=$(grep -ce "-fdiagnostics-color=always" out_stub);
> if [[ "$(cc_supported)" = 1 ]]; then
> echo $out;
> elif [ $out = 0 ]; then
> echo 1;
> else
> echo 0;
> fi
0

tty /\ :standard overridden => not (-fdiagnostics-color)
==================================

If the flag is disabled, it should never appear in the command line.

$ cat >dune-project <<EOF
> (lang dune 2.8)
> (use_standard_c_and_cxx_flags true)
> EOF
$ cat >dune <<EOF
> (library
> (name test)
> (foreign_stubs (language c) (names stub) (flags)))
> EOF

$ build_isatty
$ env_isatty yes dune rules -m stub.o | tr -s '\t\n\\' ' ' > out_stub

$ grep -ce "-fdiagnostics-color=always" out_stub
0
[1]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#error "error message"

0 comments on commit 1aa25a0

Please sign in to comment.