Split gcc output by thread/job - gcc

I want to do statistics on compiler warnings per compilation unit based on the compiler output of gcc/g++. This is no problem with -j1 but with multiple threads, e.g. -j4, the output is completely mixed. Can I either
get the compiler to write the output per compiler thread to different files/outputs or
"atomically" print all output/warnings for a single compilation unit together?
I'm using gcc/g++ 8.1 and (if this helps) buildbot.

Recent enough versions of GNU make have an option, -O, which controls the behavior of parallel output:
Output During Parallel Execution
It is a good idea to specify -O each time you request a parallel build with a -j option.

Related

Is there a method to make `gcc' dump/display all the flags in use while compiling code?

Do note this is different from
Get the compiler options from a compiled executable? which I did go through in detail.
Although -frecord-gcc-switches is great, it only captures the command line arguments.
For example, I am not interested in capturing -O2 which is usually passed in command line. I am more curious about recording all the flags like -fauto-inc-dec which are enabled by -O2.
(In contrast to the link above, do note that I have access to the source, the compiler and the build infrastructure. I just want to capture the flags during compilation. Not picky about any specific gcc version)
You can try -fverbose-asm. That dumps the optimisation options used in a comment at the top of the assembly file.

What is the difference between "-c opt" and "--copt=-O3" in Bazel build (or GCC)

I'm learning GCC and Bazel. I want to enable all the optimization for Bazel to build a project which requires the best performance.
Then I found -c opt which means to set the compilation mode to optimized without debug information.
And --copt=-O3 means set the optimization level to the third one. There are -O2, -Os, etc.
I'm confused with these two options.
What is the difference between -c opt and --copt=-O3?
Will they trigger each other. So I only need to write one of them with bazel build?
--copt is for passing args to to the compiler.
-c is a short form of --compilation-mode.
Its effect is described in the user-manual:
It sets compiler options (e.g. -c opt implies -O2 -DNDEBUG)
There are different output directories per compilation mode, so you can switch between debug and optimized builds without full recompilation.
So usually, -c optis enough. If you want the behaviour of -c opt but with a different optimization level, you combine the two options like in -c opt --copt=-O3 and the compiler will get both options -O2 and -O3, but the last one will win.
And watch out, there is a third similar option:
--config=configname is for selecting a configuration. You can have a .bazelrc which defines default options. Some of them are not always active, but some only if you activate them by the --config=configname command line option. Now opt is a popular configname, so if you have a .bazelrc that contains
build:opt --copt=-O3
then bazel build --config=opt has the same effect as bazel build --copt=-O3

How to make gcc uses march=native as default?

Is there a way to change the specs file so that it will pass -march=native if nothing is specified in command line?
Related things in the default specs file is:
*cc1:
%(cc1_cpu)
*cc1_cpu:
%{march=native:%>march=native %:local_cpu_detect(arch) %{!mtune=*:%>mtune=native %:local_cpu_detect(tune)}} %{mtune=native:%>mtune=native %:local_cpu_detect(tune)}
I am not sure how specs works. Simply specifying -march=native before or after %(cc1_cpu) doesn't work. However, this line does take effect because GCC will report error if I put -something_wierd instead of -march=native.
Another thing I noticed is if I put %{march=i386:-something_wierd} before %(cc1_cpu), gcc reports error so looks like -march=i386 is always passed in if nothing is specified, so is there a way to distinguish between nothing specified and -march=i386 in specs file?
BTW, what does %> do? Seems like it is not specified in the documentation.
I am using MinGW's gcc-4.6.2.
Referring to your last question: The gcc 4.6.1 sources (gcc/gcc.c) contain the following comment on %>:
%>S Similar to "%<S", but keep it in the GCC command line.
For the sake of completeness following the comment for %< form the same file:
%<S remove all occurrences of -S from the command line.
Note - this command is position dependent. % commands in the
spec string before this one will see -S, % commands in the
spec string after this one will not.
To answer the first question in short: yes, but ....
... the only generic solution I found has the significant drawback that the -march option will be ignored, so every build is done as if -march=native had been specified. Anyhow there is a workaround to that.
1 The solution (without workaround)
Create a specs-file called let's say specs.nativealways containing:
*cc1_cpu:
%<march=* -march=native %>march=native %:local_cpu_detect(arch) %{!mtune=*:%>mtune=native %:local_cpu_detect(tune)} %{mtune=native:%>mtune=native %:local_cpu_detect(tune)}
When using the specs-file (for example by invoking gcc with the option -specs=specs.nativealways) the build will be done as if -march=native was specified (with the mentioned drawback that any occurrence of option -march=<arch> would have simply been ignored).
2 The workaround
To still by able to override the newly configured default behavior one can use a modified version of the specs-file described above, introducing a new option called -myarch using the same syntax as -march (except for -myarch=native, which won't work, which does not metter as native now is the default).
The modfied specs-file looks like this:
*cc1_cpu:
%<march=* %{myarch=*:%<myarch* -march=%* ; :-march=native %>march=native %:local_cpu_detect(arch) %{!mtune=*:%>mtune=native %:local_cpu_detect(tune)}} %{mtune=native:%>mtune=native %:local_cpu_detect(tune)}
PS: This has been tested with with gcc 4.6.2 on Linux, but should work on MinGW.
While not a direct answer to your question, you can reach a very similar effect by defining CFLAGS and CXXFLAGS in your shell's initialization file. 99% of the Makefiles are sufficiently standard to pick up the environment values and pass the flags to gcc.
*cc1_cpu:
+ %{!march*:-march=native}

GCC -M dependency generation issue

According to GNU's documentation
If there are many included files then the rule is split into several lines using \-newline.
After running the following command, why is the output from gcc -M not as expected?
How do I ensure that each dependency appears on a separate line? Thanks for your help in advance.
gcc -Iinc/ -Isrc/ -M -MM src/BitSet.c
BitSet.o: src/BitSet.c \
inc/BitSet.h inc/StdDefs.h
I am using GCC 4.5.2 (MinGW) on Windows.
You came to expect the wrong thing.
If there are many included files then the rule is split into
several lines using \ -newline.
The rule is split if it is longer than a certain length. Nowhere does the documentation say that the rule will be split after each token.
I.e., fault in the expected output, not in the observed output.
Regarding your comment (building a build tool of your own that uses gcc -M output for its dependency tracking)... the output of gcc -M is meant to be parsed by make, using make's parsing rules. If you want to use the output yourself, you will have to follow the same parsing rules - which aren't that difficult to begin with.

Preprocessor output

How do I view the output produced by the C pre-processor, prior to its conversion into an object file?
I want to see what the MACRO definitions do to my code.
gcc -E file.c
or
g++ -E file.cpp
will do this for you. The -E switch forces the compiler to stop after the preprocessing phase, spitting all it’s got at the moment to standard output.
Note: Surely you must have some #include directives. The included files get preprocessed, too, so you might get lots of output.
For Visual C++ the switch is /E which spits the preprocessor output to screen.
You can also call the C Preprocessor directly.
cpp infile outfile
Check out man cpp for more info.
For GCC,
gcc -E -dM file.c
or
g++ -E -dM file.cpp
should do the job. -dM, as GNU Preprocessor manual puts it, should generate a list of ‘#define’ directives for all the macros defined during the execution of the preprocessor, including predefined macros.
It depends on the compiler you use.
With GCC, you can specify the -E flag on the command-line to let the compiler produce the pre-processor output.
If using CLion by Jetbrains, you can use the action "clangd: Preprocess current TU"
So hit shift shift and start typing clangd...
Best assign it to a shortcut for simpler reuse in preferences->keymap:
Shout out to marcosbento
PS: TU means 'translation unit' (see here LLVM translation unit)
You can check out my script described here:
http://mosermichael.github.io/cstuff/all/projects/2011/09/16/preprocessor.html
It formats the preprocessor output into a (hopefully) readable html document: lines that are different due to preprocessor are marked in the file.

Resources