From 09ccd0eeaad402f1e7e5b18bd1ad168a9db2998b Mon Sep 17 00:00:00 2001 From: Niklas Claesson Date: Thu, 14 Sep 2017 10:05:37 +0200 Subject: C/C++: Get default include dirs from compilers --- mesonbuild/compilers/c.py | 8 ++++++++ mesonbuild/compilers/compilers.py | 39 +++++++++++++++++++++++++++++++++++++++ mesonbuild/dependencies/misc.py | 13 +------------ 3 files changed, 48 insertions(+), 12 deletions(-) diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py index d4da2da..3f9ba5c 100644 --- a/mesonbuild/compilers/c.py +++ b/mesonbuild/compilers/c.py @@ -172,6 +172,9 @@ class CCompiler(Compiler): def get_linker_search_args(self, dirname): return ['-L' + dirname] + def get_default_include_dirs(self): + return [] + def gen_import_library_args(self, implibname): """ The name of the outputted import library @@ -1082,3 +1085,8 @@ class VisualStudioCCompiler(CCompiler): elif version < 1920: return '14.1' # (Visual Studio 2017) return None + + def get_default_include_dirs(self): + if 'INCLUDE' not in os.environ: + return [] + return os.environ['INCLUDE'].split(os.pathsep) diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 89208e0..3f088b0 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -13,6 +13,7 @@ # limitations under the License. import contextlib, os.path, re, tempfile +import subprocess from ..linkers import StaticLinker from .. import coredata @@ -917,6 +918,35 @@ def get_largefile_args(compiler): # those features explicitly. return [] +# TODO: The result from calling compiler should be cached. So that calling this +# function multiple times don't add latency. +def gnulike_default_include_dirs(compiler, lang): + if lang == 'cpp': + lang = 'c++' + p = subprocess.Popen( + compiler + ['-x{}'.format(lang), '-E', '-v', '-'], + stdin=subprocess.DEVNULL, + stderr=subprocess.PIPE, + stdout=subprocess.PIPE + ) + stderr = p.stderr.read().decode('utf-8') + parse_state = 0 + paths = [] + for line in stderr.split('\n'): + if parse_state == 0: + if line == '#include "..." search starts here:': + parse_state = 1 + elif parse_state == 1: + if line == '#include <...> search starts here:': + parse_state = 2 + else: + paths.append(line[1:]) + elif parse_state == 2: + if line == 'End of search list.': + break + else: + paths.append(line[1:]) + return paths class GnuCompiler: # Functionality that is common to all GNU family compilers. @@ -998,6 +1028,9 @@ class GnuCompiler: def get_instruction_set_args(self, instruction_set): return gnulike_instruction_set_args.get(instruction_set, None) + def get_default_include_dirs(self): + return gnulike_default_include_dirs(self.exelist, self.language) + class ClangCompiler: def __init__(self, clang_type): @@ -1082,6 +1115,9 @@ class ClangCompiler: def get_instruction_set_args(self, instruction_set): return gnulike_instruction_set_args.get(instruction_set, None) + def get_default_include_dirs(self): + return gnulike_default_include_dirs(self.exelist, self.language) + # Tested on linux for ICC 14.0.3, 15.0.6, 16.0.4, 17.0.1 class IntelCompiler: @@ -1132,3 +1168,6 @@ class IntelCompiler: # if self.icc_type == ICC_OSX: # return ['-bundle'] return ['-shared'] + + def get_default_include_dirs(self): + return gnulike_default_include_dirs(self.exelist, self.language) diff --git a/mesonbuild/dependencies/misc.py b/mesonbuild/dependencies/misc.py index c2b6dbd..61d0d77 100644 --- a/mesonbuild/dependencies/misc.py +++ b/mesonbuild/dependencies/misc.py @@ -116,18 +116,7 @@ class BoostDependency(ExternalDependency): # and http://stackoverflow.com/questions/37218953/isystem-on-a-system-include-directory-causes-errors # for more details - # TODO: The correct solution would probably be to ask the - # compiler for it's default include paths (ie: "gcc -xc++ -E - # -v -") and avoid including those with -isystem - - # For now, use -isystem for all includes except for some - # typical defaults (which don't need to be included at all - # since they are in the default include paths). These typical - # defaults include the usual directories at the root of the - # filesystem, but also any path that ends with those directory - # names in order to handle cases like cross-compiling where we - # might have a different sysroot. - if not include_dir.endswith(('/usr/include', '/usr/local/include')): + if include_dir and include_dir not in self.compiler.get_default_include_dirs(): args.append("".join(self.compiler.get_include_args(include_dir, True))) return args -- cgit v1.1