Hello,

I would like to propose the following patches which introduce a compile option 
--record-gcc-command-line. When passed to gcc, it saves the command line option 
into the produced object file. The option makes it trivial to trace back how a 
file was compiled and by which version of the gcc. It helps with debugging, 
reproducing bugs and repeating the build process.

This option is similar to -frecord-gcc-switches. However, they have three 
fundamental differences: Firstly, -frecord-gcc-switches saves the internal 
state after the argv is processed and passed by the driver. As opposed to that, 
--record-gcc-command-line saves the command-line as received by the driver. 
Secondly, -frecord-gcc-switches saves the switches as separate entries into a 
mergeable string section. Therefore, the entries belonging to different object 
files get mixed up after being linked. The new --record-gcc-command-line, on 
the other hand, creates one entry per invocation. By doing so, it makes it 
clear which options were used together in a single gcc invocation. Lastly, 
--record-gcc-command-line also adds the version of the gcc into this single 
entry to make it clear which version of gcc was called with any given command 
line. This is useful in cases where .comment section reports multiple versions.

While there are also similarities between the implementations of these two 
options, they are completely independent. These commands can be used separately 
or together without issues. I used the same section that -frecord-gcc-switches 
uses on purpose. I could not use the name -frecord-gcc-command-line for this 
option; because of a {f*} in the specs, which forwards all options starting 
with -f to cc1/cc1plus as is. This is not we want for this option. We would 
like to append it a filename as well to pass the argv of the driver to child 
processes.

This functionality operates as the following: It saves gcc's argv into a 
temporary file, and passes --record-gcc-command-line <tempfilename> to cc1 or 
cc1plus. The functionality of the backend is implemented via a hook. This patch 
includes an example implementation of the hook for elf targets: 
elf_record_gcc_command_line function. This function reads the given file and 
writes gcc's version and the command line into a mergeable string section, 
.GCC.command.line.

Here is an *example usage* of the option:
[egeyar@localhost save-commandline]$ gcc main.c --record-gcc-command-line
[egeyar@localhost save-commandline]$ readelf -p .GCC.command.line a.out

String dump of section '.GCC.command.line':
  [     0]  10.0.0 20191025 (experimental) : gcc main.c 
--record-gcc-command-line


The following is a *second example* calling g++ with -save-temps, 
-frecord-gcc-switches, and repetition of options, where --save-temps saves the 
intermediate file, main.cmdline in this case. You can see that the options are 
recorded unprocessed:

[egeyar@localhost save-commandline]$ g++ main.c -save-temps 
--record-gcc-command-line -O0 -O2 -O3 --record-gcc-command-line
[egeyar@localhost save-commandline]$ readelf -p .GCC.command.line a.out

String dump of section '.GCC.command.line':
  [     0]  10.0.0 20191025 (experimental) : g++ main.c -save-temps 
--record-gcc-command-line -O0 -O2 -O3 --record-gcc-command-line


Here is a *third example* calling g++ with both -frecord-gcc-switches and 
--record-gcc-command-line for comparison:
[egeyar@localhost save-commandline]$ g++ main.c --record-gcc-command-line 
-frecord-gcc-switches
[egeyar@localhost save-commandline]$ readelf -p .GCC.command.line a.out

String dump of section '.GCC.command.line':
  [     0]  10.0.0 20191025 (experimental) : g++ main.c 
--record-gcc-command-line -frecord-gcc-switches
  [    5c]  -D_GNU_SOURCE
  [    6a]  main.c
  [    71]  -mtune=generic
  [    80]  -march=x86-64
  [    8e]  --record-gcc-command-line /tmp/ccgC4ZtS.cmdline


The first patch of this two-patch-series only extends the testsuite machinery, 
while the second patch implements this functionality and adds a test case for 
it. In addition to that new test case, I built binutils as my test case after 
passing this option to CFLAGS. The added .GCC.command.line section of ld listed 
many compile commands as expected. Tested on x86_64-pc-linux-gnu.

Please review the patches, let me know what you think and apply if appropriate.

Regards
Egeyar
 

Egeyar Bagcioglu (2):
  Introduce dg-require-target-object-format
  Introduce the gcc option --record-gcc-command-line

 gcc/common.opt                                     |  4 +++
 gcc/config/elfos.h                                 |  5 +++
 gcc/doc/tm.texi                                    | 22 ++++++++++++
 gcc/doc/tm.texi.in                                 |  4 +++
 gcc/gcc.c                                          | 41 ++++++++++++++++++++++
 gcc/gcc.h                                          |  1 +
 gcc/target.def                                     | 30 ++++++++++++++++
 gcc/target.h                                       |  3 ++
 .../c-c++-common/record-gcc-command-line.c         |  8 +++++
 gcc/testsuite/lib/target-supports-dg.exp           | 11 ++++++
 gcc/toplev.c                                       | 13 +++++++
 gcc/varasm.c                                       | 36 +++++++++++++++++++
 12 files changed, 178 insertions(+)
 create mode 100644 gcc/testsuite/c-c++-common/record-gcc-command-line.c

-- 
1.8.3.1

Reply via email to