C/C++: Get default include dirs from compilers
This commit is contained in:
parent
488e57332f
commit
09ccd0eeaa
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue