Skip to content

Commit

Permalink
[analyzer] Relative include paths to --sysroot
Browse files Browse the repository at this point in the history
If a -I flag is followed by a path starting with "=" sign, it means that
it's relative to --sysroot. In CodeChecker we tend to convert all paths
to absolute, however, these should be skipped. For example:
-I =/usr/include/my_lib
  • Loading branch information
bruntib committed May 5, 2021
1 parent a628f5e commit 938b9b3
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 46 deletions.
77 changes: 36 additions & 41 deletions analyzer/codechecker_analyzer/buildlog/log_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -722,48 +722,43 @@ def __collect_transform_include_opts(flag_iterator, details):

m = COMPILE_OPTIONS_MERGED.match(flag_iterator.item)

if m:
flag = m.group(0)
together = len(flag) != len(flag_iterator.item)
if not m:
return False

if together:
param = flag_iterator.item[len(flag):]
else:
next(flag_iterator)
param = flag_iterator.item

# The .plist file contains a section with a list of files. For some
# further actions these need to be given with an absolute path. Clang
# prints them with absolute path if the original compiler invocation
# was given absolute paths.
# TODO: If Clang will be extended with an extra analyzer option in
# order to print these absolute paths natively, this conversion will
# not be necessary.
flags_with_path = ['-I', '-idirafter', '-imultilib',
'-iquote', '-isysroot', '-isystem',
'-iwithprefix', '-iwithprefixbefore', '-sysroot',
'--sysroot']
if flag in flags_with_path:
# --sysroot format can be --sysroot=/path/to/include
# in this case before the normalization the '='
# sign must be removed.
# We put back the original
# --sysroot=/path/to/include as
# --sysroot /path/to/include
# which is a valid format too.
if param.startswith("="):
param = param[1:]
together = False
param = os.path.normpath(
os.path.join(details['directory'], param))

if together:
details['analyzer_options'].append(flag + param)
else:
details['analyzer_options'].extend([flag, param])
flag = m.group(0)
together = len(flag) != len(flag_iterator.item)

return True
return False
if together:
param = flag_iterator.item[len(flag):]
else:
next(flag_iterator)
param = flag_iterator.item

# The .plist file contains a section with a list of files. For some
# further actions these need to be given with an absolute path. Clang
# prints them with absolute path if the original compiler invocation
# was given absolute paths.
# TODO: If Clang will be extended with an extra analyzer option in
# order to print these absolute paths natively, this conversion will
# not be necessary.
flags_with_path = ['-I', '-idirafter', '-iquote', '-isysroot', '-isystem',
'-sysroot', '--sysroot']
if flag in flags_with_path and ('sysroot' in flag or param[0] != '='):
# --sysroot format can be --sysroot=/path/to/include in this case
# before the normalization the '=' sign must be removed.
# We put back the original
# --sysroot=/path/to/include as
# --sysroot /path/to/include
# which is a valid format too.
if param[0] == '=':
param = param[1:]
together = False
param = os.path.normpath(os.path.join(details['directory'], param))

details['analyzer_options'].extend(
[flag + param] if together else [flag, param])

return True


def __collect_compile_opts(flag_iterator, details):
Expand Down Expand Up @@ -1001,8 +996,8 @@ def parse_options(compilation_db_entry,
gcc_flag_transformers = [
__skip_gcc,
__replace,
__collect_compile_opts,
__collect_transform_include_opts,
__collect_compile_opts,
__determine_action_type,
__skip_sources,
__get_arch,
Expand Down
11 changes: 6 additions & 5 deletions analyzer/tests/unit/test_option_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,12 +170,13 @@ def test_compile_with_include_paths(self):
"-include", "/include/myheader2.h",
"--include", "/include/myheader3.h",
"--sysroot", "/home/sysroot",
"--sysroot=/home/sysroot3",
"-isysroot", "/home/isysroot",
"-isysroot/home/isysroot2",
"-I/home/test", "-I", "/home/test2",
"-idirafter", "/dirafter1",
"-idirafter/dirafter2"]
"-idirafter/dirafter2",
"-I=relative_path1",
"-I", "=relative_path2"]
linker_options = ["-L/home/test_lib", "-lm"]
build_cmd = "g++ -o myapp " + \
' '.join(compiler_options) + ' ' + \
Expand All @@ -184,14 +185,14 @@ def test_compile_with_include_paths(self):
action = {
'file': 'main.cpp',
'command': build_cmd,
'directory': ''}
'directory': '/path/to/proj'}

res = log_parser.parse_options(action)
print(res)
print(compiler_options)
print(res.analyzer_options)
self.assertTrue('main.cpp' == res.source)
self.assertTrue(set(compiler_options) == set(res.analyzer_options))
self.assertEqual('main.cpp', res.source)
self.assertEqual(set(compiler_options), set(res.analyzer_options))
self.assertEqual(BuildAction.COMPILE, res.action_type)

def test_link_only_multiple_files(self):
Expand Down

0 comments on commit 938b9b3

Please sign in to comment.