This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] RFC: C/C++: print help when a header can't be found
On 11/12/18, Martin Sebor <msebor@gmail.com> 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?