Re: [PATCH] RFC: C/C++: print help when a header can't be found

2018-11-15 Thread Eric Gallager
On 11/12/18, Martin Sebor  wrote:
> On 11/11/2018 04:33 PM, David Malcolm wrote:
>> When gcc can't find a header file, it's a hard error that stops the
>> build,
>> typically requiring the user to mess around with compile flags,
>> Makefiles,
>> dependencies, and so forth.
>>
>> Often the exact search paths aren't obvious to the user.  Consider the
>> case where the include paths are injected via a tool such as pkg-config,
>> such as e.g.:
>>
>>   gcc $(pkg-config --cflags glib-2.0) demo.c
>>
>> This patch is an attempt at being more helpful for such cases.  Given
>> that
>> the user can't proceed until the issue is resolved, I think it's
>> reasonable
>> to default to telling the user as much as possible about what happened.
>> This patch list all of the search paths, and any close matches (e.g. for
>> misspellings).
>>
>> Without the patch, the current behavior is:
>>
>> misspelled-header-1.c:1:10: fatal error: test-header.hpp: No such file or
>> directory
>> 1 | #include "test-header.hpp"
>>   |  ^
>> compilation terminated.
>>
>> With the patch, the user gets this output:
>>
>> misspelled-header-1.c:1:10: fatal error: test-header.hpp: No such file or
>> directory
>> 1 | #include "test-header.hpp"
>>   |  ^
>> misspelled-header-1.c:1:10: note: paths searched:
>> misspelled-header-1.c:1:10: note:  path: ''
>> misspelled-header-1.c:1:10: note:   not found: 'test-header.hpp'
>> misspelled-header-1.c:1:10: note:   close match: 'test-header.h'
>> 1 | #include "test-header.hpp"
>>   |  ^
>>   |  "test-header.h"
>> misspelled-header-1.c:1:10: note:  path: '/usr/include/glib-2.0' (via
>> '-I')
>> misspelled-header-1.c:1:10: note:   not found:
>> '/usr/include/glib-2.0/test-header.hpp'
>> misspelled-header-1.c:1:10: note:  path: '/usr/lib64/glib-2.0/include'
>> (via '-I')
>> misspelled-header-1.c:1:10: note:   not found:
>> '/usr/lib64/glib-2.0/include/test-header.hpp'
>> misspelled-header-1.c:1:10: note:  path: './include' (system directory)
>> misspelled-header-1.c:1:10: note:   not found:
>> './include/test-header.hpp'
>> misspelled-header-1.c:1:10: note:  path: './include-fixed' (system
>> directory)
>> misspelled-header-1.c:1:10: note:   not found:
>> './include-fixed/test-header.hpp'
>> misspelled-header-1.c:1:10: note:  path: '/usr/local/include' (system
>> directory)
>> misspelled-header-1.c:1:10: note:   not found:
>> '/usr/local/include/test-header.hpp'
>> misspelled-header-1.c:1:10: note:  path: '/usr/include' (system
>> directory)
>> misspelled-header-1.c:1:10: note:   not found:
>> '/usr/include/test-header.hpp'
>> compilation terminated.
>>
>> showing the paths that were tried, and why (e.g. the -I paths injected by
>> the pkg-config invocation), and the .hpp vs .h issue (with a fix-it
>> hint).
>>
>> It's verbose, but as I said above, the user can't proceed until they
>> resolve it, so I think being verbose is appropriate here.
>>
>> Thoughts?
>
> I think printing the directories and especially the near matches
> will be very helpful, especially for big projects with lots of -I
> options.
>
> The output could be made substantially shorter, less repetitive,
> and so easier to read -- basically cut in half -- by avoiding
> most of the duplication and collapsing two notes into one, e.g.
> like so:
>
>fatal error: test-header.hpp: No such file or directory
>1 | #include "test-header.hpp"
>  |  ^
>note: paths searched:
>note: -I '.'
>note:   close match: 'test-header.h'
>1 | #include "test-header.hpp"
>  |  ^
>  |  "test-header.h"
>note: -I '/usr/include/glib-2.0'
>note: -I '/usr/lib64/glib-2.0/include'
>note: -isystem './include'
>note: -isystem './include-fixed'
>note: -isystem '/usr/local/include'
>note: -isystem '/usr/include'
>
> or by printing the directories in sections:
>
>note: -I paths searched:
>note:   '.'
>note:   close match: 'test-header.h'
>1 | #include "test-header.hpp"
>  |  ^
>  |  "test-header.h"
>note:   '/usr/include/glib-2.0'
>note:   '/usr/lib64/glib-2.0/include'
>note: -isystem paths searched:
>note:   './include'
>note:   './include-fixed'
>note:   '/usr/local/include'
>note:   '/usr/include'
>
> Martin
>
>

How would this interact with -Wmissing-include-dirs?


Re: [PATCH] RFC: C/C++: print help when a header can't be found

2018-11-13 Thread Jason Merrill
On Mon, Nov 12, 2018 at 4:01 PM Martin Sebor  wrote:
> On 11/11/2018 04:33 PM, David Malcolm wrote:
> > When gcc can't find a header file, it's a hard error that stops the build,
> > typically requiring the user to mess around with compile flags, Makefiles,
> > dependencies, and so forth.
> >
> > Often the exact search paths aren't obvious to the user.  Consider the
> > case where the include paths are injected via a tool such as pkg-config,
> > such as e.g.:
> >
> >   gcc $(pkg-config --cflags glib-2.0) demo.c
> >
> > This patch is an attempt at being more helpful for such cases.  Given that
> > the user can't proceed until the issue is resolved, I think it's reasonable
> > to default to telling the user as much as possible about what happened.
> > This patch list all of the search paths, and any close matches (e.g. for
> > misspellings).
> >
> > Without the patch, the current behavior is:
> >
> > misspelled-header-1.c:1:10: fatal error: test-header.hpp: No such file or 
> > directory
> > 1 | #include "test-header.hpp"
> >   |  ^
> > compilation terminated.
> >
> > With the patch, the user gets this output:
> >
> > misspelled-header-1.c:1:10: fatal error: test-header.hpp: No such file or 
> > directory
> > 1 | #include "test-header.hpp"
> >   |  ^
> > misspelled-header-1.c:1:10: note: paths searched:
> > misspelled-header-1.c:1:10: note:  path: ''
> > misspelled-header-1.c:1:10: note:   not found: 'test-header.hpp'
> > misspelled-header-1.c:1:10: note:   close match: 'test-header.h'
> > 1 | #include "test-header.hpp"
> >   |  ^
> >   |  "test-header.h"
> > misspelled-header-1.c:1:10: note:  path: '/usr/include/glib-2.0' (via '-I')
> > misspelled-header-1.c:1:10: note:   not found: 
> > '/usr/include/glib-2.0/test-header.hpp'
> > misspelled-header-1.c:1:10: note:  path: '/usr/lib64/glib-2.0/include' (via 
> > '-I')
> > misspelled-header-1.c:1:10: note:   not found: 
> > '/usr/lib64/glib-2.0/include/test-header.hpp'
> > misspelled-header-1.c:1:10: note:  path: './include' (system directory)
> > misspelled-header-1.c:1:10: note:   not found: './include/test-header.hpp'
> > misspelled-header-1.c:1:10: note:  path: './include-fixed' (system 
> > directory)
> > misspelled-header-1.c:1:10: note:   not found: 
> > './include-fixed/test-header.hpp'
> > misspelled-header-1.c:1:10: note:  path: '/usr/local/include' (system 
> > directory)
> > misspelled-header-1.c:1:10: note:   not found: 
> > '/usr/local/include/test-header.hpp'
> > misspelled-header-1.c:1:10: note:  path: '/usr/include' (system directory)
> > misspelled-header-1.c:1:10: note:   not found: 
> > '/usr/include/test-header.hpp'
> > compilation terminated.
> >
> > showing the paths that were tried, and why (e.g. the -I paths injected by
> > the pkg-config invocation), and the .hpp vs .h issue (with a fix-it hint).
> >
> > It's verbose, but as I said above, the user can't proceed until they
> > resolve it, so I think being verbose is appropriate here.
> >
> > Thoughts?
>
> I think printing the directories and especially the near matches
> will be very helpful, especially for big projects with lots of -I
> options.
>
> The output could be made substantially shorter, less repetitive,
> and so easier to read -- basically cut in half -- by avoiding
> most of the duplication and collapsing two notes into one, e.g.
> like so:
>
>fatal error: test-header.hpp: No such file or directory
>1 | #include "test-header.hpp"
>  |  ^
>note: paths searched:
>note: -I '.'
>note:   close match: 'test-header.h'
>1 | #include "test-header.hpp"
>  |  ^
>  |  "test-header.h"
>note: -I '/usr/include/glib-2.0'
>note: -I '/usr/lib64/glib-2.0/include'
>note: -isystem './include'
>note: -isystem './include-fixed'
>note: -isystem '/usr/local/include'
>note: -isystem '/usr/include'
>
> or by printing the directories in sections:
>
>note: -I paths searched:
>note:   '.'
>note:   close match: 'test-header.h'
>1 | #include "test-header.hpp"
>  |  ^
>  |  "test-header.h"
>note:   '/usr/include/glib-2.0'
>note:   '/usr/lib64/glib-2.0/include'
>note: -isystem paths searched:
>note:   './include'
>note:   './include-fixed'
>note:   '/usr/local/include'
>note:   '/usr/include'

I agree that the "not found" lines are unnecessary; I don't feel
strongly about the other formatting.

Jason


Re: [PATCH] RFC: C/C++: print help when a header can't be found

2018-11-12 Thread Martin Sebor

On 11/11/2018 04:33 PM, David Malcolm wrote:

When gcc can't find a header file, it's a hard error that stops the build,
typically requiring the user to mess around with compile flags, Makefiles,
dependencies, and so forth.

Often the exact search paths aren't obvious to the user.  Consider the
case where the include paths are injected via a tool such as pkg-config,
such as e.g.:

  gcc $(pkg-config --cflags glib-2.0) demo.c

This patch is an attempt at being more helpful for such cases.  Given that
the user can't proceed until the issue is resolved, I think it's reasonable
to default to telling the user as much as possible about what happened.
This patch list all of the search paths, and any close matches (e.g. for
misspellings).

Without the patch, the current behavior is:

misspelled-header-1.c:1:10: fatal error: test-header.hpp: No such file or 
directory
1 | #include "test-header.hpp"
  |  ^
compilation terminated.

With the patch, the user gets this output:

misspelled-header-1.c:1:10: fatal error: test-header.hpp: No such file or 
directory
1 | #include "test-header.hpp"
  |  ^
misspelled-header-1.c:1:10: note: paths searched:
misspelled-header-1.c:1:10: note:  path: ''
misspelled-header-1.c:1:10: note:   not found: 'test-header.hpp'
misspelled-header-1.c:1:10: note:   close match: 'test-header.h'
1 | #include "test-header.hpp"
  |  ^
  |  "test-header.h"
misspelled-header-1.c:1:10: note:  path: '/usr/include/glib-2.0' (via '-I')
misspelled-header-1.c:1:10: note:   not found: 
'/usr/include/glib-2.0/test-header.hpp'
misspelled-header-1.c:1:10: note:  path: '/usr/lib64/glib-2.0/include' (via 
'-I')
misspelled-header-1.c:1:10: note:   not found: 
'/usr/lib64/glib-2.0/include/test-header.hpp'
misspelled-header-1.c:1:10: note:  path: './include' (system directory)
misspelled-header-1.c:1:10: note:   not found: './include/test-header.hpp'
misspelled-header-1.c:1:10: note:  path: './include-fixed' (system directory)
misspelled-header-1.c:1:10: note:   not found: './include-fixed/test-header.hpp'
misspelled-header-1.c:1:10: note:  path: '/usr/local/include' (system directory)
misspelled-header-1.c:1:10: note:   not found: 
'/usr/local/include/test-header.hpp'
misspelled-header-1.c:1:10: note:  path: '/usr/include' (system directory)
misspelled-header-1.c:1:10: note:   not found: '/usr/include/test-header.hpp'
compilation terminated.

showing the paths that were tried, and why (e.g. the -I paths injected by
the pkg-config invocation), and the .hpp vs .h issue (with a fix-it hint).

It's verbose, but as I said above, the user can't proceed until they
resolve it, so I think being verbose is appropriate here.

Thoughts?


I think printing the directories and especially the near matches
will be very helpful, especially for big projects with lots of -I
options.

The output could be made substantially shorter, less repetitive,
and so easier to read -- basically cut in half -- by avoiding
most of the duplication and collapsing two notes into one, e.g.
like so:

  fatal error: test-header.hpp: No such file or directory
  1 | #include "test-header.hpp"
|  ^
  note: paths searched:
  note: -I '.'
  note:   close match: 'test-header.h'
  1 | #include "test-header.hpp"
|  ^
|  "test-header.h"
  note: -I '/usr/include/glib-2.0'
  note: -I '/usr/lib64/glib-2.0/include'
  note: -isystem './include'
  note: -isystem './include-fixed'
  note: -isystem '/usr/local/include'
  note: -isystem '/usr/include'

or by printing the directories in sections:

  note: -I paths searched:
  note:   '.'
  note:   close match: 'test-header.h'
  1 | #include "test-header.hpp"
|  ^
|  "test-header.h"
  note:   '/usr/include/glib-2.0'
  note:   '/usr/lib64/glib-2.0/include'
  note: -isystem paths searched:
  note:   './include'
  note:   './include-fixed'
  note:   '/usr/local/include'
  note:   '/usr/include'

Martin