Hendrik Langer
5 years ago
2 changed files with 99 additions and 0 deletions
@ -0,0 +1,96 @@ |
|||||
|
#!/usr/bin/env python |
||||
|
|
||||
|
import codecs |
||||
|
import json |
||||
|
import os.path |
||||
|
import re |
||||
|
import subprocess |
||||
|
import sys |
||||
|
import shlex |
||||
|
|
||||
|
root_path = os.path.abspath(os.path.normpath(os.path.join(__file__, '..', '..'))) |
||||
|
basepath = os.path.join(root_path, 'src') |
||||
|
temp_header_file = os.path.join(root_path, '.temp-clang-tidy.cpp') |
||||
|
|
||||
|
|
||||
|
def shlex_quote(s): |
||||
|
if not s: |
||||
|
return u"''" |
||||
|
if re.search(r'[^\w@%+=:,./-]', s) is None: |
||||
|
print(s) |
||||
|
return s |
||||
|
|
||||
|
return u"'" + s.replace(u"'", u"'\"'\"'") + u"'" |
||||
|
|
||||
|
def build_all_include(): |
||||
|
# Build a cpp file that includes all header files in this repo. |
||||
|
# Otherwise header-only integrations would not be tested by clang-tidy |
||||
|
headers = [] |
||||
|
for path in walk_files(basepath): |
||||
|
filetypes = ('.h',) |
||||
|
ext = os.path.splitext(path)[1] |
||||
|
if ext in filetypes: |
||||
|
path = os.path.relpath(path, root_path) |
||||
|
include_p = path.replace(os.path.sep, '/') |
||||
|
headers.append('#include "{}"'.format(include_p)) |
||||
|
headers.sort() |
||||
|
headers.append('') |
||||
|
content = '\n'.join(headers) |
||||
|
with codecs.open(temp_header_file, 'w', encoding='utf-8') as f: |
||||
|
f.write(content) |
||||
|
|
||||
|
def build_compile_commands(): |
||||
|
gcc_flags_json = os.path.join(root_path, '.gcc-flags.json') |
||||
|
if not os.path.isfile(gcc_flags_json): |
||||
|
print("Could not find {} file which is required for clang-tidy.") |
||||
|
print('Please run "pio init --ide atom" in the project folder to generate that file.') |
||||
|
sys.exit(1) |
||||
|
with codecs.open(gcc_flags_json, 'r', encoding='utf-8') as f: |
||||
|
gcc_flags = json.load(f) |
||||
|
exec_path = gcc_flags['execPath'] |
||||
|
include_paths = gcc_flags['gccIncludePaths'].split(',') |
||||
|
includes = ['-isystem{}'.format(p) for p in include_paths] |
||||
|
cpp_flags = shlex.split(gcc_flags['gccDefaultCppFlags']) |
||||
|
defines = [flag for flag in cpp_flags if flag.startswith('-D')] |
||||
|
command = [exec_path] |
||||
|
command.extend(includes) |
||||
|
command.extend(defines) |
||||
|
command.append('-std=gnu++11') |
||||
|
command.append('-Wall') |
||||
|
command.append('-Wno-delete-non-virtual-dtor') |
||||
|
command.append('-Wno-unused-variable') |
||||
|
command.append('-Wunreachable-code') |
||||
|
|
||||
|
source_files = [] |
||||
|
for path in walk_files(basepath): |
||||
|
filetypes = ('.cpp',) |
||||
|
ext = os.path.splitext(path)[1] |
||||
|
if ext in filetypes: |
||||
|
source_files.append(os.path.abspath(path)) |
||||
|
source_files.append(temp_header_file) |
||||
|
source_files.sort() |
||||
|
compile_commands = [{ |
||||
|
'directory': root_path, |
||||
|
'command': ' '.join(shlex_quote(x) for x in (command + ['-o', p + '.o', '-c', p])), |
||||
|
'file': p |
||||
|
} for p in source_files] |
||||
|
compile_commands_json = os.path.join(root_path, 'compile_commands.json') |
||||
|
if os.path.isfile(compile_commands_json): |
||||
|
with codecs.open(compile_commands_json, 'r', encoding='utf-8') as f: |
||||
|
try: |
||||
|
if json.load(f) == compile_commands: |
||||
|
return |
||||
|
except: |
||||
|
pass |
||||
|
with codecs.open(compile_commands_json, 'w', encoding='utf-8') as f: |
||||
|
json.dump(compile_commands, f, indent=2) |
||||
|
|
||||
|
|
||||
|
def walk_files(path): |
||||
|
for root, _, files in os.walk(path): |
||||
|
for name in files: |
||||
|
yield os.path.join(root, name) |
||||
|
|
||||
|
if __name__ == "__main__": |
||||
|
build_compile_commands() |
||||
|
build_all_include() |
Loading…
Reference in new issue