Ninja Build System + gcc/clang doesn't output diagnostic colors - c++

When invoking ninja on a C or C++ (hence both tags) project, with the clang or gcc compiler, the output is not colored with ANSI colors.
For example:
error should be red, but isn't.
warning should be yellow/orange, but isn't.
Everything is the same color, and it's really hard to tell what's going on!

Why this happens
This happens because ninja internally creates a pipe(), which stdout and stderr from the compiler (gcc or clang in this case) is re-routed. This makes the check inside gcc and clang, which checks for terminals (which may support color), fail.
A check such as isatty(stdout) does not return true for a pipe, even though that pipe is then forwarded to stdout once again.
It's documented
Ninja's FAQ talks about this on GitHub.com, but this FAQ is not included with the software, not mentioned in the --help, there are no ninja manpages, and common search engines (ddg, google) do not seem to find that FAQ for common search queries relating to color.
Hence, this post, since SO has good SSO.
The fix
Add -fdiagnostics-color=always to your C or CXX flags. For example, with cmake, you can append -DCMAKE_CXX_FLAGS=-fdiagnostics-color=always (or CMAKE_C_FLAGS for C) (or, if you are using CMake 3.24 or later, you can use the CMAKE_COLOR_DIAGNOSTICS variable or environment variable).
This works for gcc (as documented in its manpage) and clang (clang's manpages do not mention this option, but it is included in their command line reference on llvm.org.
As a permanent fix, you could append the following to your .zshrc, .bashrc, or similar:
# force C colored diagnostic output
export CFLAGS="${CFLAGS} -fdiagnostics-color=always"
# force C++ colored diagnostic output
export CXXFLAGS="${CXXFLAGS} -fdiagnostics-color=always"
export CCFLAGS="${CCFLAGS} -fdiagnostics-color=always"
# force C, C++, Cpp (pre-processor) colored diagnostic output
export CPPFLAGS="${CPPFLAGS} -fdiagnostics-color=always"
You should only do this if you KNOW you will never need to pipe your compiler's output anywhere else. Also, this will only work with clang and gcc, and other compilers which support this - so make sure you dont use compilers that choke on this flag.

Related

Clang: Override all warning and warning-as-error flags specified earlier on the command line

With gcc I can throw a bunch of -Wsome-issue and -Werror=other-issue flags on the command line and the later cancel them all with a single -w flag somewhere near the end.
This doesn't appear to be the case with clang. A trailing -w suppresses some warnings, but not others. See here for an example. I know I can manually disable each warning individually via -Wno-some-issue and -Wno-error=other-issue, but that's a real pain to manage in the long term.
Am I missing something? Is there a way to cancel all earlier warning flags? Is there a reason why -w can suppress some warnings but not others?
Background: My specific use case is a library containing a mix of source files. Some new and some ancient, semi-third-party stuff that we never want to look at, let alone edit. The project has some semi-strict warning flags set globally, but for these few files I'd like to override the global flags and disable all warnings and warnings-as-werrors. In CMake this is done by settings the COMPILE_OPTIONS property for those files, which appends the given flags after the global flags. With gcc this works just fine, but with clang it's proving to be a headache.
(And yes I know I could reorganise the project to force those files to be compiled into a separate target, but I was hoping to avoid that.)
The flag you need is -Wno-everything.
Godbolt: https://godbolt.org/g/33uABD

What is gcc compiler option "-unsigned" meant for?

I am compiling legacy code using gcc compiler 4.8.5 on RHEL7. All C and C++ files have "-unsigned" as one of the default flags for both gcc and g++ compilation. The compiler accepts this option and compiles successfully. However, I cannot find any documentation of this option anywhere either in gcc manual or online. Does anyone know what this option is? I have to port the code and am confused whether this compiler option needs to be ported or not.
I suspect it was just a mistake in the Makefile, or whatever is used to compile the code.
gcc does not support a -unsigned option. However, it does pass options to the linker, and GNU ld has a -u option:
'-u SYMBOL'
'--undefined=SYMBOL'
Force SYMBOL to be entered in the output file as an undefined
symbol. Doing this may, for example, trigger linking of additional
modules from standard libraries. '-u' may be repeated with
different option arguments to enter additional undefined symbols.
This option is equivalent to the 'EXTERN' linker script command.
The space between -u and the symbol name is optional.
So the intent might have been to do something with unsigned types, but the effect, at least with modern versions of gcc, is to enter nsigned in the output file as an undefined symbol.
This seems to have no effect in the quick test I did (compiling and running a small "hello, world" program). The program runs correctly, and the output of nm hello includes:
U nsigned
With an older version of gcc (2.95.2) on a different system, I get a fatal link-time error about the undefined symbol.
I suspect the intention is for the program to be compiled with -funsigned-char. I don't know whether this instead used to be -unsigned, back in dinosaur times, and perhaps GCC actually still heeds that spelling; there's no way to know from the manual because, if it does, it's an undocumented feature.
I'd ask the original author for the intention here, since they didn't see fit to document.

What is the -D compiler flag C++ (clang, GNU, MSVC)

Okay I am assuming that the -D prefix means #define whatever variable name is followed by it, however I cannot find any documentation on this makefile feature for compiler flags.
CXX=clang -DTHISISPREPROCESSORVARIABLE
So -DTHISISPREPROCESSORVARIABLE in the make process would define the preprocessor variable THISISPREPROCESSORVARIABLE and would make the follow cout compiled.
#ifdef THISISPREPROCESSORVARIABLE
std::cout << "this should exist with the -D" << endl;
#endif
Is this the right assumption? It seems to work, just can anyone confirm this -D is referring to #define (anyone have any links to some makefile docs that can fill in all these commands definitions?)
GCC,
MSVC, and
Intel, all have this flag documented, and Clang just uses GCC flags by default. I just found it on Clang's help page waaaay at the bottom (for clang-cl for windows), and harmic found it more clearly here for linux.
Execute clang-cl /? to see a list of supported options:
/D <macro[=value]> Define macro
harmic observes that these are compiler flags, and have nothing at all to do with makefiles, which is why you can't find it in the makefile docs. These flags can be put inside a makefile which will pass them to the compiler, but are not part of makefiles.

how can I check a particular gcc feature in configure.ac

For example, gcc 4.7 has a new feature -Wnarrowing. In configure.ac, how can I test where a feature is supported by the current gcc or not?
There's a file in gnulibc, but doesn't make much sense to me.
Both gcc and clang support -W[no-]narrowing and -W[no-]error=narrowing options.
With -std=c++11, gcc emits a warning by default, and clang emits an error by default. Even though you only mention gcc, I think you could extend the functionality check to compilers like clang that attempt to provide the same options and extensions. That might include Intel's icc too.
Let's assume you've selected the C++ compiler with AC_PROG_CXX, and have ensured that it's using the C++11 standard.
ac_save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS -Werror -Wno-error=narrowing"
AC_LANG_PUSH([C++])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],
[[int i {1.0}; (void) i;]])],
[ac_cxx_warn_narrowing=1], [ac_cxx_warn_narrowing=0])
AS_IF([test $ac_cxx_warn_narrowing -ne 0],
[AC_MSG_RESULT(['$CXX' supports -Wnarrowing])])
AC_LANG_POP([C++])
CXXFLAGS="$ac_save_CXXFLAGS"
Compilation will only succeed if: 1) the compiler supports -Wnarrowing related options, which implies it supports -Werror, and: 2) recognizes C++11 initialization syntax.
Normally, configure.ac scripts and flags passed to configure should avoid -Werror, as it breaks too many internal tests. In this context, we ensure there are no other warnings besides the narrowing, which is why (void) i; is needed to prevent a warning about unused variables.
The logic behind this should probably be:
Create a correct file that should get a warning with -Wnarrowing. Verify that it gets compiled correctly. This is a sanity check.
Then compile that same file with -Wnarrowing, and verify that it still gets compiled correctly. This makes sure you detect compilers that don't support -Wnarrowing as an option, and don't attempt to pass bogus options to them.
Finally, compile that same file with -Werror=narrowing, and verify that it now does not get compiled correctly. If it now fails, you can be fairly certain that the compiler does indeed support -Wnarrowing. This last check is useful to detect compilers that do accept -Wnarrowing/-Werror=narrowing, but spit out a warning "ignoring unknown option -Wnarrowing". In that case, you shouldn't be passing -Wnarrowing.
Optionally, you may also want to compile a file that shouldn't get a warning with -Wnarrowing with -Werror=narrowing, in case you find a compiler where -Wnarrowing is useless and -Werror=narrowing is a hard error. I cannot think of a compiler where this would be required, though.
Translating this to a configure check should be trivial.
See http://code.google.com/p/opendoom/source/browse/trunk/VisualC8/autotools/ac_c_compile_flags.m4 for an example test of this sort - this tries to compile a trivial program with the given compiler flag, and adds it to CFLAGS if it works.

How to use C++11 features with Autoconf? [duplicate]

This question already has answers here:
Autotools check for C++11
(2 answers)
Closed 9 years ago.
I have a project configured via Autoconf, and I want to start using C++11 features in this project. How to have the "-std=gnu++0x" switch always enabled and support for the features checked while configuring?
Have you checked ax_cxx_compile_stdcxx_11 ?
I think this is exactly what you want.
There is a big macro library on gnu website.
You can do this with something like AX_CHECK_COMPILE_FLAG, e.g.:
AX_CHECK_COMPILE_FLAG([-std=c++0x], [
CXXFLAGS="$CXXFLAGS -std=c++0x"])
(You need to be careful here that AC_LANG is C++, not C at the point this is called because it's possible to use gcc for C and something else for C++ or vice versa).
I think the simplest way to do this is to add:
CXXFLAGS="$CXXFLAGS -std=c++0x"
in configure.ac before AC_PROG_CXX. If the compiler does not accept -std=c++0x, then configure will fail with "C++ compiler cannot create executables". It is not the best error messages, but it ensures that builds will succeed if configure succeeds. For a better error message, you can check that the compiler accepts the flag after AC_PROG_CXX. In either case, you want configure to fail if the compiler does not provide the necessary features but your software requires it.
Note that setting CXXFLAGS before AC_PROG_CXX has the undesirable side effect of preventing the default setting for CXXFLAGS in the case that the user does not set that variable when running configure. For this reason, it is normally not recommended to set CXXFLAGS in the configury, so it is probably better to check the flag after AC_PROG_CXX (eg using awoodland's solution)--just make sure you add an AC_MSG_ERROR in the third argument of AX_CHECK_COMPILE_FLAG so that configure fails if the features are not available.
To enable the compiler switch (unless, of course, the user overrides it), put this in your Makefile.am:
AM_CXXFLAGS=-std=c++0x
I don't think there's a check available for the presence of C++11 features, but you should be able to write a test program fairly easily with the features you want to use, that will fail if those features are not supported. Then you can write a test as described in this section of the Autoconf manual.