Re: [PATCH] RFC: C/C++: print help when a header can't be found
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
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
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