Clang tools, like clang-tidy, clang-check, don't show errors when run in headers, even with a compilation_database (the compilation database doesn't include a compile command for headers)
Skipping /path/to/header.h. Compile command not found.
This is not an ALE problem, but it would be great to add options for a workaround. One option would to run the tool instead of pointing to the current header, pointing to the source file (which is compiled) including the header file.
so:
clang-tidy -p /path/folder_compilation_database header.h
Skipping /path/to/header.h. Compile command not found.
clang-tidy -p /path/folder_compilation_database source_with_header.cpp
... It works, show errors in header ...
We could consider creating temporary .c files for checking header files which include the header files. There are two problems with this.
foo.h? include/foo.h?We could write the temporary files with a .cpp extension instead. That _might_ work. I don't know if either linters only run against the files on disk. If they do, then that's not an option.
It sounds like this problem should really be fixed in clang-tidy and clang-check.
It is a long standing problem, even cmake, which generates the compilation_database knows nothing about headers. There is this clangd (Language protocol server by clang) that might solve most of these problems. But still on development.
One non-automated solution would be to let the user choose the file included in the compilation database which uses the header. YouCompleteMe does some sophisticated thing to guess headers, but still it doesn't work when the class in the header uses templates ( a lot of them). Pointing to a source file will solve this, because the template is instantiated there.
It is not an easy problem, and not the job of Ale to solve it, but it would be super nice to have something, with the flexibility of your plugin.
Could we just stop setting the -p options for clang-tidy and clang-check if the file extension is .h or .hpp? There are no compile commands for headers anyway. Maybe there is some kind parsing that could be done like in #725 for getting the include paths from the compile_commands.json file.
This is all yet another reason to want modules to become part of the C++ standard.
Sounds good, and the list for headers extensions should be flexible (there are .hxx, .txx, .tcc, ...).
Relevant conversation in YCM when this arose: https://github.com/Valloric/YouCompleteMe/issues/174.
They faced this, and opted for a python .ycm_conf_file, where the user can set its own compilation flags, or deal with particular files (independent of the compilation database, but also can use it). @valloric commented there that he changed the suffix in header files to cpp, and then handle that to libclang, or the actual logic of YCM to get completions. But note that YCM/libclang still doesn't autocomplete in headers with templates.
I, as an ALE user, would be happy to setlocal a variable in the .h buffer, pointing to the relevant source (included in the compilation database to get the flags) that actually use that header. If the project is long/complex enough, maybe even creating a vimL auto-command doing this mapping automatically instead of manually.
You could use g:ale_pattern_options to define options for the linters based on patterns for the filenames.
Can I change the target file where run the checker for a file different than the current?
I don't understand your last message.
You can change any buffer-local option with g:ale_pattern_options. Check out :help g:ale_pattern_options.
Testing it with no luck:
let g:ale_pattern_options = {
\ '\.h$': {
\ 'ale_linters': {'cpp': ['clangtidy']},
\ 'ale_cpp_clangtidy_options': '/path/src.cpp',
\ },
\}
ALEInfo:
Current Filetype: cpp
Available Linters: ['clang', 'clangcheck', 'clangtidy', 'cppcheck', 'cpplint', 'g++']
Enabled Linters: ['clangtidy']
Linter Variables:
let g:ale_cpp_clangtidy_checks = ['*']
let g:ale_cpp_clangtidy_executable = 'clang-tidy'
let g:ale_cpp_clangtidy_options = ''
let b:ale_cpp_clangtidy_options = '/path/src.cpp'
Global Variables:
let g:ale_echo_cursor = 1
let g:ale_echo_msg_error_str = 'Error'
let g:ale_echo_msg_format = '%s'
let g:ale_echo_msg_warning_str = 'Warning'
let g:ale_enabled = 1
let g:ale_fix_on_save = 0
let g:ale_fixers = {}
let g:ale_keep_list_window_open = 0
let g:ale_lint_delay = 200
let g:ale_lint_on_enter = 1
let g:ale_lint_on_save = 1
let g:ale_lint_on_text_changed = 'always'
let g:ale_linter_aliases = {}
let g:ale_linters = {'cpp': ['clangtidy']}
let b:ale_linters = {'cpp': ['clangtidy']}
let g:ale_open_list = 0
let g:ale_set_highlights = 1
let g:ale_set_loclist = 1
let g:ale_set_quickfix = 0
let g:ale_set_signs = 1
let g:ale_sign_column_always = 0
let g:ale_sign_error = '>>'
let g:ale_sign_offset = 1000000
let g:ale_sign_warning = '--'
let g:ale_statusline_format = ['%d error(s)', '%d warning(s)', 'OK']
let g:ale_warn_about_trailing_whitespace = 1
Command History:
(finished - exit code 0) ['/bin/zsh', '-c', '''clang-tidy'' -checks=''*'' ''/path/include/header.h'' -p ''/path/project/build''']
<<<NO OUTPUT RETURNED>>>
Being editing header.h, and having a compile_commands.json in /path/project/build I would like a command like:
['/bin/zsh', '-c', '''clang-tidy'' -checks=''*'' ''/path/src.cpp'' -p ''/path/project/build''']
The guy who implemented the build directory options made it so any additional options are ignored if the build directory is detected. This is because you can't set additional options if you're using a compile_commands.json file.
We might consider adding another option to disable using compile_commands.json, so you can set options manually. This could be the default for header files.
I pushed a commit now which makes it so the -p build directory option is never set if the filename ends with .h or .hpp. It should also set the options you define now.
Passing a .cpp filename as an option won't really do much, but you can pass other compiler arguments, which will be set after --.
I have created a PR with an option header_sourcefile to let the user choose a sourcefile when in a header.
It works! #790
I have tested with:
vim header.h -c "let b:ale_cpp_clangtidy_header_sourcefile='source.cpp'"
And ALEInfo:
Current Filetype: cpp
Available Linters: ['clang', 'clangcheck', 'clangtidy', 'cppcheck', 'cpplint', 'g++']
Enabled Linters: ['clangtidy']
Linter Variables:
let g:ale_cpp_clangtidy_checks = ['*']
let g:ale_cpp_clangtidy_executable = 'clang-tidy'
let g:ale_cpp_clangtidy_header_sourcefile = ''
let b:ale_cpp_clangtidy_header_sourcefile = 'source.cpp'
let g:ale_cpp_clangtidy_header_suffixes = ['h', 'hpp', 'hxx', 'tcc']
let g:ale_cpp_clangtidy_options = ''
Global Variables:
let g:ale_echo_cursor = 1
let g:ale_echo_msg_error_str = 'Error'
let g:ale_echo_msg_format = '%s'
let g:ale_echo_msg_warning_str = 'Warning'
let g:ale_enabled = 1
let g:ale_fix_on_save = 0
let g:ale_fixers = {}
let g:ale_keep_list_window_open = 0
let g:ale_lint_delay = 200
let g:ale_lint_on_enter = 1
let g:ale_lint_on_save = 1
let g:ale_lint_on_text_changed = 'always'
let g:ale_linter_aliases = {}
let g:ale_linters = {'cpp': ['clangtidy']}
let g:ale_open_list = 0
let g:ale_set_highlights = 1
let g:ale_set_loclist = 1
let g:ale_set_quickfix = 0
let g:ale_set_signs = 1
let g:ale_sign_column_always = 0
let g:ale_sign_error = '>>'
let g:ale_sign_offset = 1000000
let g:ale_sign_warning = '--'
let g:ale_statusline_format = ['%d error(s)', '%d warning(s)', 'OK']
let g:ale_warn_about_trailing_whitespace = 1
Command History:
(started) ['/bin/zsh', '-c', '''clang-tidy'' -checks=''*'' ''source.cpp'' -p ''/path/build''']
I closed that pull request. I don't like the solution, I think it's much too complicated, and that's a recipe for creating a series of further issues.
I think we should either not check header files with clang-tidy at all, or maybe check the directory the header is in, something like that. Something which is along the lines of something clang-tidy really supports. Having to configure a filename to check for each header you want to check is too much work, and it's going to lead to weird issues when we start implementing showing errors from other files in quickfix, etc.
I understand, it is hack. clang-tools works with cpp files. I will use it though, I work most of the time in headers with templates. And thanks for the review, first time with vimL.
In terms of checking for the directory of the headers, usually all the headers are in an include directory, where no .cpp files are, so nothing will change in that case.
I wonder what tools are best to use for this. If you're writing a lot of generic code, you're probably looking at headers almost entirely.
If you ever need to, you can also add your own custom linter in ale_linters in your .vim directory. See :help ale-linter-loading-behaviour and :help ale#linter#Define(). That might be helpful if you need something heavily specialised.
I'm not sure clang-tools will be able to deal with this issue.
I looked a little bit into Rip-Rip/clang_complete plugin because the doc speaks about the header issue, and apparently, the workaround is to use actual clang to run a dry compilation and passing the -header flag :
My main problem with this investigation is that I can't find information on either -header or even -fsyntax-only when I print the help from the clang in my path, so I can't be sure that it's the workaround here.
There is the concept of "companion files" which are files with the same basename, one cpp and one h.
A simple option would be to add a flag that when turned on does
clang-tidy myfile.cpp -header-filter=myfile.h
If _myfile.cpp_ exist when opening _myfile.h_
A workaround right now would be to create a clang-tidy wrapper that just does this check and then runs
clang-tidy -p build myfile.cpp -line-filter='[{"name":"myfile.h"}]' -header-filter=myfile.h
Python is not my language but I took a swing at making a simple wrapper. Works for simple cases:
https://gist.github.com/sasq64/b1bc795a5a8b971e36a664a3427ba805
...except ALE removes the compilation database from the options. Is there a flag to turn that "feature" off ?
I don't know what you're talking about, so I don't know. I know that clang-tidy stops detecting compile_commands.json files if you pass other options with --.
Just about all code in this repository must be VimL only.
I meant that you did a change so that "-p
87616c5e91746181182a1f7eb0c09487d6ade3e7
I'm not sure I understand either. The help from clang-tidy seem to tell that -header-filter's purpose is to keep only the warnings from given header files while checking a cpp file :
-header-filter=<string> -
Regular expression matching the names of the
headers to output diagnostics from. Diagnostics
from the main file of each translation unit are
always displayed.
Can be used together with -line-filter.
This option overrides the 'HeaderFilter' option
in .clang-tidy file, if any.
-line-filter=<string> -
List of files with line ranges to filter the
warnings. Can be used together with
-header-filter. The format of the list is a
JSON array of objects:
[
{"name":"file1.cpp","lines":[[1,3],[5,7]]},
{"name":"file2.h"}
]
Therefore, we still have the same issue (How can we actually run the clang-tools checking header files with the correct include and compilation flags from a compilation database). Also, clang-check does not have any options like this. And the workaround you propose ( clang-tidy -p build myfile.cpp -line-filter='[{"name":"myfile.h"}]' -header-filter=myfile.h) looks like it's the same solution as the original post : lint the 'associated' cpp file and filter the output to only have errors related to header. The whole discussion has been made as to why it's not seen as the best solution here (then again, you can disagree)
Do you have a MWE to show how we can make it work ? Like 1 cpp, 1 header, 1 compilation database so that clang-tidy test.h shows relevant errors (ie. not "can't find
I think our best shot is to parse the compilation database and try to guess relevant folder from here https://github.com/w0rp/ale/pull/725 but the PR does not advance much these days (time is a rare resource)
So I've noticed that if you run the linter on a cpp file and then later on the header, for a moment, the correct errors will show up in the header, before being replaced by garbage.
As a temporary solution it seems like having header files do the callbacks when you call :ALELint without actually trying to lint would at least give the correct errors/warnings. It's not a real solution, but since linting headers doesnt work at all right now, and i'm guessing (maybe?) it wouldnt be too hard to implement, it might be worth doing.
When you 'lint' cpp files, you call a compiler so you can check the translation unit it's associated with. This program will find some errors and warnings, linked to lines written in the headers they include, so you get hits for these lines.
It seems that what's happening on what you describe is that you see the warnings associated to the implementation file you just linted, and they just disappear after some time because an event triggered :ALELint again.
The current issue with header files (if you want to find "errors" and "warnings" that are not just whitespace changes), is that we need a translation unit to try to "compile" the code and see if warnings and issues arise. I don't know if it is that easy. Usually, to get the hits inside a header file, you need to try to compile the files including them. So there seem to be only 2 solutions in my opinion :
makeprg asynchronously to try to compile the whole project and collect header errorsBoth solutions do not look that easy to implement efficiently.
EDIT : I commented without really checking the whole thread because I thought my answer would be short, I hope I don't repeat myself too much
yeah, which is why as a temporary measure you let :ALELint in header files only call the callbacks and skip trying to lint, so if you've run the linter in the implementation file, you get warnings and errors in the associated header.
it's not a real solution, because it requires linting the implementation file manually, but it lets you lint a header.
Until the compile_commands.json doesn't include headers this task is complicated.
There is a utility: https://github.com/Sarcasm/compdb that aims to do exactly that, creating compile_commands.json for headers from an existing json, that might be worth exploring, but I haven't tested it properly.
I tried a workaround that I personally use, but I understand it is not the best solution: https://github.com/phcerdan/ale/commit/5d9f6f915a2de98a695c39bb98cb05d502ec7163
There you set in the local buffer of your header:
let b:cpp_clangtidy_header_sourcefile=/path/source_file.cpp
And ALE will compile the source file when your header is modified, that will lint your current header.
I think the solution for clang-tidy and clang-check is to do something similar to what you did. Look for a file like foo.c or foo.cpp for a header named something like foo.h or foo.hpp, and run the tools against the source files instead. For headers where no translation-unit can be found, we can just not run the commands.
That automatic lookup is something YouCompleteMe uses as well, and it is good.
Pointing to a user selected source file has the benefits that also work for template headers, which have no .cpp source file. User can point to a test.cpp using the template class to get the lint.
Okay, sounds like a good idea. I'll give it a go when I can.
The problem with the look up is that cpp doesn't impose a convention in structure as rust (for example) does.
Majority of people put headers in include, cpp files in src and tests... somewhere, in a paralell test or tests folder, or somewhere else. But the naming for the test is not standarized. I tend to use test_headername.cpp, but ... random choice.
Yes, that's the big problem with C++. There are no standards for these things. If the standards existed, the this problem would have already been solved in some way. I think the best you can do is try to look for what the majority of people use, and make most people happy.
Thank you so much for ale, it's really great!
I would really love for clang-tidy to be supported better, i.e. for it to work on headers. Sadly, I am super tight on time currently and can't really contribute anything, but if the status on this changes, that would be cool.
Specifically, I'm getting this error:
Command History:
(executable check - success) clang++
(started) ['/bin/zsh', '-c', '''clang++'' -S -x c++ -fsyntax-only -iquote ''/home/flrn/workbench/eich18/software/vimeTK/include'' -std=c++14 -Wall -Wextra -pedantic -I./include -I./thirdparty/docopt.cpp -I./thirdparty/yaml-cpp/include -I./thirdparty/progress_bar/include -I./thirdparty/spdlog/include - < ''/tmp/vAV126U/1/core.h''']
(executable check - success) clang-tidy
(started) ['/bin/zsh', '-c', '''clang-tidy'' -checks=''boost-*,bugprone-*,cert-*,cppcoreguidelines-*,clang-analyzer-*,hicpp-*,misc-*,modernize-*,performance-*,portability-*,readability-*'' ''/home/flrn/workbench/eich18/software/vimeTK/include/core.h''']
(finished - exit code 0) ['/bin/zsh', '-c', '''clang++'' -S -x c++ -fsyntax-only -iquote ''/home/flrn/workbench/eich18/software/vimeTK/include'' -std=c++14 -Wall -Wextra -pedantic -I./include -I./thirdparty/docopt.cpp -I./thirdparty/yaml-cpp/include -I./thirdparty/progress_bar/include -I./thirdparty/spdlog/include - < ''/tmp/vAV126U/2/core.h''']
<<<NO OUTPUT RETURNED>>>
(finished - exit code 1) ['/bin/zsh', '-c', '''clang-tidy'' -checks=''boost-*,bugprone-*,cert-*,cppcoreguidelines-*,clang-analyzer-*,hicpp-*,misc-*,modernize-*,performance-*,portability-*,readability-*'' ''/path/to/project/vimeTK/include/core.h''']
<<<OUTPUT STARTS>>>
/home/flrn/workbench/eich18/software/vimeTK/include/core.h:20:10: error: 'functional' file not found [clang-diagnostic-error]
#include <functional>
^
<<<OUTPUT ENDS>>>
if and only if I turn on clang-tidy. I want to use clang and clang-tidy, thus:
let g:ale_cpp_clang_executable = 'clang++'
let g:ale_cpp_clang_options = '-std=c++14 -Wall -Wextra -pedantic -I./include -I./thirdparty/docopt.cpp -I./thirdparty/yaml-cpp/include -I./thirdparty/progress_bar/include -I./thirdparty/spdlog/include'
let g:ale_cpp_clangtidy_checks = ['boost-*', 'bugprone-*', 'cert-*', 'cppcoreguidelines-*', 'clang-analyzer-*', 'hicpp-*', 'misc-*', 'modernize-*', 'performance-*', 'portability-*', 'readability-*']
let g:ale_cpp_clangtidy_executable = 'clang-tidy'
let g:ale_cpp_clangtidy_options = ''
clang-tidy should get what it needs vom compile-commands.json.
Any comment on why this is and possibly how to solve it is greatly appreciated.
Open an issue for that. clang-tidy should be getting options from compile_commands.json, as you say.
Using the compile_commands files for header files is not as easy as it can be, since they contain only compilation commands (so only matching implementation files, not header files)
@phcerdan exposed the quickest reasonable solution in an earlier comment, guessing the good implementation files to lint in order to get the warnings in a selected header file is no easy issue. This is hard because a header file can be included potentially in the whole project so you'd need to actually compile everything to be sure to catch all clang-tidy errors in the header.
At this point I really do think it is more sensible to either use the fix mentioned above, or maybe wait and hope that LSP can provide ways of generating this file list like https://github.com/Sarcasm/compdb is apparently aiming to do, but without having to add another dependency on the user's side.
I don't really understand that reasoning. clang-tidy will happily show errors from headers based on what is included from source files - in header only template libraries I run it on the unit test sources and get errors back for my headers.
However, I can't get ale to use my compilation database at all right now, not even for the clang checker, so I can't really provide meaningful input as to whether or not clang-tidy works the way I want it to. Probably I'm doing something wrong; am still looking for what that might be and in the meantime just living with passing the options manually.
What might work for this is using -header-filter='.*'.
As a note, I have rebased my workaround on top of current master.
Still works good, setting let b:ale_cpp_clangtidy_header_sourcefile='main.cpp' in a header, you get ale (clangtidy) working of that header. Also works if the header uses templates that have been instantiated in main.cpp.
Maybe instead of modifying clangtidy, this could be called clangtidy-with-headers or similar.
Also the name of the option is incredible long, an alias could be handy. It works for me, maybe it works for others. Here is the diff:
https://github.com/phcerdan/ale/commit/12224d12bbbccc93faa314d217ee87c660fa61c2
Minimal example to test it: https://gist.github.com/phcerdan/ee005812a62753214124783ee4e14256
PR #2272 seems to have fixed linting header files with clang/gcc linters when compilation database is used.
PR #2272 seems to have fixed linting header files with clang/gcc linters when compilation database is used.
It fixed a bug, but not this "issue".
In a project I was working on, compile_commands.json didn't include entries for headers where there are entries for the .c files that go with them. Now ALE will fall back on using arguments for source files with a similar name to a header file.
I don't see the behaviour described in the last patch. It seems that clang-tidy is called without any -p option on header files.
Current Filetype: cpp
Available Linters: ['ccls', 'clang', 'clangcheck', 'clangd', 'clangtidy', 'clazy', 'cppcheck', 'cpplint', 'cquery', 'flawfinder', 'gcc']
Linter Aliases:
'gcc' -> ['g++']
Enabled Linters: ['ccls', 'clang', 'clangcheck', 'clangd', 'clangtidy', 'clazy', 'cppcheck', 'cpplint', 'cquery', 'flawfinder', 'gcc']
Suggested Fixers:
'clang-format' - Fix C/C++ and cuda files with clang-format.
'clangtidy' - Fix C/C++ and ObjectiveC files with clang-tidy.
'remove_trailing_lines' - Remove all blank lines at the end of a file.
'trim_whitespace' - Remove all trailing whitespace characters at the end of every line.
'uncrustify' - Fix C, C++, C#, ObjectiveC, ObjectiveC++, D, Java, Pawn, and VALA files with uncrustify.
Linter Variables:
let g:ale_cpp_ccls_executable = 'ccls'
let g:ale_cpp_ccls_init_options = {}
let g:ale_cpp_clang_executable = 'clang++'
let g:ale_cpp_clang_options = '-std=c++14 -Wall'
let g:ale_cpp_clangcheck_executable = 'clang-check'
let g:ale_cpp_clangcheck_options = ''
let g:ale_cpp_clangd_executable = 'clangd'
let g:ale_cpp_clangd_options = ''
let g:ale_cpp_clangtidy_checks = []
let g:ale_cpp_clangtidy_executable = 'clang-tidy'
let g:ale_cpp_clangtidy_extra_options = ''
let g:ale_cpp_clangtidy_options = ''
let g:ale_cpp_clazy_checks = ['level1']
let g:ale_cpp_clazy_executable = 'clazy-standalone'
let g:ale_cpp_clazy_options = ''
let g:ale_cpp_cppcheck_executable = 'cppcheck'
let g:ale_cpp_cppcheck_options = '--enable=style'
let g:ale_cpp_cpplint_executable = 'cpplint'
let g:ale_cpp_cpplint_options = ''
let g:ale_cpp_cquery_cache_directory = '/home/ramsi/.cache/cquery'
let g:ale_cpp_cquery_executable = 'cquery'
let g:ale_cpp_flawfinder_executable = 'flawfinder'
let g:ale_cpp_flawfinder_minlevel = 1
let g:ale_cpp_flawfinder_options = ''
let g:ale_cpp_gcc_executable = 'gcc'
let g:ale_cpp_gcc_options = '-std=c++14 -Wall'
Global Variables:
let g:ale_cache_executable_check_failures = v:null
let g:ale_change_sign_column_color = 0
let g:ale_command_wrapper = ''
let g:ale_completion_delay = v:null
let g:ale_completion_enabled = 0
let g:ale_completion_max_suggestions = v:null
let g:ale_echo_cursor = 1
let g:ale_echo_msg_error_str = 'Error'
let g:ale_echo_msg_format = '%code: %%s'
let g:ale_echo_msg_info_str = 'Info'
let g:ale_echo_msg_warning_str = 'Warning'
let g:ale_enabled = 1
let g:ale_fix_on_save = 0
let g:ale_fixers = {}
let g:ale_history_enabled = 1
let g:ale_history_log_output = 1
let g:ale_keep_list_window_open = 0
let g:ale_lint_delay = 200
let g:ale_lint_on_enter = 1
let g:ale_lint_on_filetype_changed = 1
let g:ale_lint_on_insert_leave = 1
let g:ale_lint_on_save = 1
let g:ale_lint_on_text_changed = 'normal'
let g:ale_linter_aliases = {}
let g:ale_linters = {}
let g:ale_linters_explicit = 0
let g:ale_list_vertical = 0
let g:ale_list_window_size = 10
let g:ale_loclist_msg_format = '%code: %%s'
let g:ale_lsp_root = {}
let g:ale_max_buffer_history_size = 20
let g:ale_max_signs = -1
let g:ale_maximum_file_size = v:null
let g:ale_open_list = 0
let g:ale_pattern_options = v:null
let g:ale_pattern_options_enabled = v:null
let g:ale_set_balloons = 0
let g:ale_set_highlights = 1
let g:ale_set_loclist = 1
let g:ale_set_quickfix = 0
let g:ale_set_signs = 1
let g:ale_sign_column_always = 0
let g:ale_sign_error = '>>'
let g:ale_sign_info = '--'
let g:ale_sign_offset = 1000000
let g:ale_sign_style_error = '>>'
let g:ale_sign_style_warning = '--'
let g:ale_sign_warning = '--'
let g:ale_sign_highlight_linenrs = 0
let g:ale_statusline_format = v:null
let g:ale_type_map = {}
let g:ale_use_global_executables = v:null
let g:ale_virtualtext_cursor = 0
let g:ale_warn_about_trailing_blank_lines = 1
let g:ale_warn_about_trailing_whitespace = 1
Command History:
<snip>
(executable check - success) clang-tidy
(finished - exit code 1) ['/bin/zsh', '-c', '''clang-tidy'' ''/home/ramsi/src/celeraone/src/hashmap.hpp''']
<<<OUTPUT STARTS>>>
/home/ramsi/src/celeraone/src/hashmap.hpp:5:1: warning: #includes are not sorted properly [llvm-include-order]
#include <tuple>
^ ~~~~~~~
<memory>
<snip>
Seems like the previous behaviour of ignoring build directories when in a header file is still present. The following patch will fix it.
diff --git a/autoload/ale/c.vim b/autoload/ale/c.vim
index 9b42870..8202afe 100644
--- a/autoload/ale/c.vim
+++ b/autoload/ale/c.vim
@@ -9,13 +9,6 @@ let s:sep = has('win32') ? '\' : '/'
let g:__ale_c_project_filenames = ['.git/HEAD', 'configure', 'Makefile', 'CMakeLists.txt']
function! ale#c#GetBuildDirectory(buffer) abort
- " Don't include build directory for header files, as compile_commands.json
- " files don't consider headers to be translation units, and provide no
- " commands for compiling header files.
- if expand('#' . a:buffer) =~# '\v\.(h|hpp)$'
- return ''
- endif
-
let l:build_dir = ale#Var(a:buffer, 'c_build_dir')
" c_build_dir has the priority if defined
There is already a MR open for this. https://github.com/dense-analysis/ale/pull/2919
Almost all C/C++ issues with flags should now be discussed in #3276, so a comprehensive solution can be found for most people, for automatically detecting flags.
Most helpful comment
This is all yet another reason to want modules to become part of the C++ standard.