From e9630f4dcca9ce1f2d2a97c41df1fa76807f4898 Mon Sep 17 00:00:00 2001 From: Jade Abraham Date: Tue, 17 Dec 2024 14:45:29 -0800 Subject: [PATCH 1/3] only include system directories as system includes if we have to Signed-off-by: Jade Abraham --- util/chplenv/chpl_llvm.py | 61 +++++++++++++++++++++++++++++++++------ 1 file changed, 52 insertions(+), 9 deletions(-) diff --git a/util/chplenv/chpl_llvm.py b/util/chplenv/chpl_llvm.py index b5e9b307969e..584ee74fd6da 100755 --- a/util/chplenv/chpl_llvm.py +++ b/util/chplenv/chpl_llvm.py @@ -1024,6 +1024,42 @@ def get_clang_prgenv_args(): return (comp_args, link_args) +@memoize +def get_system_include_directories(flag, lang): + """ + Runs 'COMPILER -E -Wp,-v -' to determine the system include directories + """ + directories = [] + compiler = chpl_compiler.get_compiler_command(flag, lang) + _, _, stdout, _ = try_run_command( + compiler + ["-E", "-Wp,-v", "-", "-o", "/dev/null"], + combine_output=True, cmd_input="" + ) + if stdout: + lines = stdout.splitlines() + start_includes_regex = re.compile(r"#include.+search starts here") + end_includes_regex = re.compile(r"End of search list") + ignoring_regex = re.compile(r"ignoring nonexistent") + collecting = False + for line in lines: + if start_includes_regex.search(line): + collecting = True + elif end_includes_regex.search(line): + collecting = False + break + elif collecting and not ignoring_regex.search(line): + directories.append(line.strip()) + return directories + +@memoize +def is_path_system_include_directory(path, flag, lang): + """ + Returns True if the given path is a system include directory + """ + directories = get_system_include_directories(flag, lang) + p = os.path.realpath(os.path.abspath(path)) + return any([os.path.realpath(os.path.abspath(d)) == p for d in directories]) + # Filters out C++ compilation flags from llvm-config. # The flags are passed as a list of strings. # Returns a list of strings containing the kept flags. @@ -1047,19 +1083,26 @@ def filter_llvm_config_flags(llvm_val, flags): flag == '-std=c++14'): continue # filter out these flags - # - # include LLVM headers as system headers + # include LLVM headers as system headers using -isystem # this avoids warnings inside of LLVM headers by treating LLVM headers # - # when adding LLVM=system as system headers, we should not perturb the - # include search path, so use -isystem-after/-idirafter - # - # when adding LLVM=bundled, we should include the LLVM headers as system - # headers and prefer the bundled headers, so use -isystem + # With LLVM=system, also add the include as -I. This preserves the + # directory search order if the directory is already a system include + # see https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html # - include_flag = '-idirafter' if llvm_val == 'system' else '-isystem' if flag.startswith('-I'): - ret.append(include_flag + flag[2:]) + directory = flag[2:] + if llvm_val == "system": + if not is_path_system_include_directory(directory, 'host', 'c++'): + # its not included by the compiler, so its safe to use -isystem + ret.append('-isystem' + directory) + else: + # technically don't need to add this for + # but it's harmless to use -I + ret.append("-I" + directory) + else: + # bundled LLVM is always safe to use -isystem + ret.append("-isystem" + directory) continue if flag.startswith('-W'): From f3dbe4f548b957218bcb36fccdb9d34ba9b0d2a1 Mon Sep 17 00:00:00 2001 From: Jade Abraham Date: Tue, 17 Dec 2024 14:52:19 -0800 Subject: [PATCH 2/3] improve comment Signed-off-by: Jade Abraham --- util/chplenv/chpl_llvm.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/util/chplenv/chpl_llvm.py b/util/chplenv/chpl_llvm.py index 584ee74fd6da..549e7564ebaa 100755 --- a/util/chplenv/chpl_llvm.py +++ b/util/chplenv/chpl_llvm.py @@ -1083,12 +1083,12 @@ def filter_llvm_config_flags(llvm_val, flags): flag == '-std=c++14'): continue # filter out these flags + # # include LLVM headers as system headers using -isystem # this avoids warnings inside of LLVM headers by treating LLVM headers # - # With LLVM=system, also add the include as -I. This preserves the - # directory search order if the directory is already a system include - # see https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html + # If the header is already a system header, using -isystem will break + # the include search. In that case, just use -I (which technically wont do anythings) # if flag.startswith('-I'): directory = flag[2:] From f021c8c0c8e5be95504548749729a3dfd5d2176d Mon Sep 17 00:00:00 2001 From: Jade Abraham Date: Tue, 17 Dec 2024 14:54:01 -0800 Subject: [PATCH 3/3] improve regex Signed-off-by: Jade Abraham --- util/chplenv/chpl_llvm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/chplenv/chpl_llvm.py b/util/chplenv/chpl_llvm.py index 549e7564ebaa..62dd46befb8b 100755 --- a/util/chplenv/chpl_llvm.py +++ b/util/chplenv/chpl_llvm.py @@ -1039,7 +1039,7 @@ def get_system_include_directories(flag, lang): lines = stdout.splitlines() start_includes_regex = re.compile(r"#include.+search starts here") end_includes_regex = re.compile(r"End of search list") - ignoring_regex = re.compile(r"ignoring nonexistent") + ignoring_regex = re.compile(r"(?:ignoring nonexistent)|(?:as it is a non-system)") collecting = False for line in lines: if start_includes_regex.search(line):