Commit cfa48aec authored by Robert Bradshaw's avatar Robert Bradshaw Committed by GitHub

Merge pull request #1654 from jdemeyer/include_dirs_from_externs

Automatically add include_dirs for externs
parents c5a56e4b 8f71406d
...@@ -375,14 +375,30 @@ def normalize_existing(base_path, rel_paths): ...@@ -375,14 +375,30 @@ def normalize_existing(base_path, rel_paths):
@cached_function @cached_function
def normalize_existing0(base_dir, rel_paths): def normalize_existing0(base_dir, rel_paths):
"""
Given some base directory ``base_dir`` and a list of path names
``rel_paths``, normalize each relative path name ``rel`` by
replacing it by ``os.path.join(base, rel)`` if that file exists.
Return a couple ``(normalized, needed_base)`` where ``normalized``
if the list of normalized file names and ``needed_base`` is
``base_dir`` if we actually needed ``base_dir``. If no paths were
changed (for example, if all paths were already absolute), then
``needed_base`` is ``None``.
"""
normalized = [] normalized = []
needed_base = None
for rel in rel_paths: for rel in rel_paths:
if os.path.isabs(rel):
normalized.append(rel)
continue
path = join_path(base_dir, rel) path = join_path(base_dir, rel)
if path_exists(path): if path_exists(path):
normalized.append(os.path.normpath(path)) normalized.append(os.path.normpath(path))
needed_base = base_dir
else: else:
normalized.append(rel) normalized.append(rel)
return normalized return (normalized, needed_base)
def resolve_depends(depends, include_dirs): def resolve_depends(depends, include_dirs):
...@@ -483,20 +499,25 @@ class DependencyTree(object): ...@@ -483,20 +499,25 @@ class DependencyTree(object):
return all return all
@cached_method @cached_method
def cimports_and_externs(self, filename): def cimports_externs_incdirs(self, filename):
# This is really ugly. Nested cimports are resolved with respect to the # This is really ugly. Nested cimports are resolved with respect to the
# includer, but includes are resolved with respect to the includee. # includer, but includes are resolved with respect to the includee.
cimports, includes, externs = self.parse_dependencies(filename)[:3] cimports, includes, externs = self.parse_dependencies(filename)[:3]
cimports = set(cimports) cimports = set(cimports)
externs = set(externs) externs = set(externs)
incdirs = set()
for include in self.included_files(filename): for include in self.included_files(filename):
included_cimports, included_externs = self.cimports_and_externs(include) included_cimports, included_externs, included_incdirs = self.cimports_externs_incdirs(include)
cimports.update(included_cimports) cimports.update(included_cimports)
externs.update(included_externs) externs.update(included_externs)
return tuple(cimports), normalize_existing(filename, externs) incdirs.update(included_incdirs)
externs, incdir = normalize_existing(filename, externs)
if incdir:
incdirs.add(incdir)
return tuple(cimports), externs, incdirs
def cimports(self, filename): def cimports(self, filename):
return self.cimports_and_externs(filename)[0] return self.cimports_externs_incdirs(filename)[0]
def package(self, filename): def package(self, filename):
return package(filename) return package(filename)
...@@ -579,12 +600,22 @@ class DependencyTree(object): ...@@ -579,12 +600,22 @@ class DependencyTree(object):
def distutils_info0(self, filename): def distutils_info0(self, filename):
info = self.parse_dependencies(filename)[3] info = self.parse_dependencies(filename)[3]
externs = self.cimports_and_externs(filename)[1] kwds = info.values
cimports, externs, incdirs = self.cimports_externs_incdirs(filename)
# Add dependencies on "cdef extern from ..." files
if externs: if externs:
if 'depends' in info.values: if 'depends' in kwds:
info.values['depends'] = list(set(info.values['depends']).union(externs)) kwds['depends'] = list(set(kwds['depends']).union(externs))
else: else:
info.values['depends'] = list(externs) kwds['depends'] = list(externs)
# Add include_dirs to ensure that the C compiler will find the
# "cdef extern from ..." files
if incdirs:
include_dirs = kwds.get('include_dirs', [])
for inc in incdirs:
if inc not in include_dirs:
include_dirs = include_dirs + [inc]
kwds['include_dirs'] = include_dirs
return info return info
def distutils_info(self, filename, aliases=None, base=None): def distutils_info(self, filename, aliases=None, base=None):
......
...@@ -19,8 +19,15 @@ setup( ...@@ -19,8 +19,15 @@ setup(
######## site-packages/b/other.pxd ######## ######## site-packages/b/other.pxd ########
cdef inline foo(int a): cdef extern from "foo.c":
return a**2 int foo(int)
######## site-packages/b/foo.c ########
static int foo(int a)
{
return a * a;
}
######## a.pyx ######## ######## a.pyx ########
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment