mirror of
https://github.com/platformio/platformio-core.git
synced 2025-07-30 10:07:14 +02:00
Improve Library Dependency Finder in mode=1
This commit is contained in:
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
VERSION = (3, 0, "0b5")
|
VERSION = (3, 0, "0b6")
|
||||||
__version__ = ".".join([str(s) for s in VERSION])
|
__version__ = ".".join([str(s) for s in VERSION])
|
||||||
|
|
||||||
__title__ = "platformio"
|
__title__ = "platformio"
|
||||||
|
@ -80,6 +80,7 @@ class LibBuilderFactory(object):
|
|||||||
class LibBuilderBase(object):
|
class LibBuilderBase(object):
|
||||||
|
|
||||||
INC_SCANNER = SCons.Scanner.C.CScanner()
|
INC_SCANNER = SCons.Scanner.C.CScanner()
|
||||||
|
INC_DIRS_CACHE = None
|
||||||
|
|
||||||
def __init__(self, env, path, manifest=None):
|
def __init__(self, env, path, manifest=None):
|
||||||
self.env = env.Clone()
|
self.env = env.Clone()
|
||||||
@ -87,8 +88,8 @@ class LibBuilderBase(object):
|
|||||||
self.path = realpath(env.subst(path))
|
self.path = realpath(env.subst(path))
|
||||||
self._manifest = manifest if manifest else self.load_manifest()
|
self._manifest = manifest if manifest else self.load_manifest()
|
||||||
self._is_dependent = False
|
self._is_dependent = False
|
||||||
self._depbuilders = tuple()
|
self._depbuilders = list()
|
||||||
self._scanned_paths = tuple()
|
self._scanned_paths = list()
|
||||||
self._built_node = None
|
self._built_node = None
|
||||||
|
|
||||||
# process extra options and append to build environment
|
# process extra options and append to build environment
|
||||||
@ -155,7 +156,7 @@ class LibBuilderBase(object):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def lib_ldf_mode(self):
|
def lib_ldf_mode(self):
|
||||||
return int(self.env.get("LIB_LDF_MODE", 2))
|
return int(self.env.get("LIB_LDF_MODE", 1))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def depbuilders(self):
|
def depbuilders(self):
|
||||||
@ -174,6 +175,13 @@ class LibBuilderBase(object):
|
|||||||
def load_manifest(self):
|
def load_manifest(self):
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
def get_src_files(self):
|
||||||
|
return [
|
||||||
|
join(self.src_dir, item)
|
||||||
|
for item in self.env.MatchSourceFiles(self.src_dir,
|
||||||
|
self.src_filter)
|
||||||
|
]
|
||||||
|
|
||||||
def process_extra_options(self):
|
def process_extra_options(self):
|
||||||
with util.cd(self.path):
|
with util.cd(self.path):
|
||||||
self.env.ProcessUnFlags(self.build_unflags)
|
self.env.ProcessUnFlags(self.build_unflags)
|
||||||
@ -212,44 +220,40 @@ class LibBuilderBase(object):
|
|||||||
|
|
||||||
def _validate_search_paths(self, search_paths=None):
|
def _validate_search_paths(self, search_paths=None):
|
||||||
if not search_paths:
|
if not search_paths:
|
||||||
search_paths = tuple()
|
search_paths = []
|
||||||
assert isinstance(search_paths, tuple)
|
assert isinstance(search_paths, list)
|
||||||
deep_search = self.lib_ldf_mode == 2
|
|
||||||
|
|
||||||
if not self._scanned_paths and (
|
_search_paths = []
|
||||||
isinstance(self, ProjectAsLibBuilder) or deep_search):
|
|
||||||
for item in self.env.MatchSourceFiles(self.src_dir,
|
|
||||||
self.src_filter):
|
|
||||||
path = join(self.src_dir, item)
|
|
||||||
if (path not in self._scanned_paths and
|
|
||||||
path not in search_paths):
|
|
||||||
search_paths += (path, )
|
|
||||||
|
|
||||||
_search_paths = tuple()
|
|
||||||
for path in search_paths:
|
for path in search_paths:
|
||||||
if path not in self._scanned_paths:
|
if path not in self._scanned_paths:
|
||||||
_search_paths += (path, )
|
_search_paths.append(path)
|
||||||
self._scanned_paths += (path, )
|
self._scanned_paths.append(path)
|
||||||
|
|
||||||
return _search_paths
|
return _search_paths
|
||||||
|
|
||||||
def _get_found_includes(self, lib_builders, search_paths=None):
|
def _get_found_includes(self, lib_builders, search_paths=None):
|
||||||
inc_dirs = tuple()
|
# all include directories
|
||||||
used_inc_dirs = tuple()
|
if not LibBuilderBase.INC_DIRS_CACHE:
|
||||||
for lb in (self, ) + lib_builders:
|
inc_dirs = []
|
||||||
items = tuple(self.env.Dir(d) for d in lb.get_inc_dirs())
|
used_inc_dirs = []
|
||||||
if lb.dependent:
|
for lb in lib_builders:
|
||||||
used_inc_dirs += items
|
items = [self.env.Dir(d) for d in lb.get_inc_dirs()]
|
||||||
else:
|
if lb.dependent:
|
||||||
inc_dirs += items
|
used_inc_dirs.extend(items)
|
||||||
inc_dirs = used_inc_dirs + inc_dirs
|
else:
|
||||||
|
inc_dirs.extend(items)
|
||||||
|
LibBuilderBase.INC_DIRS_CACHE = used_inc_dirs + inc_dirs
|
||||||
|
|
||||||
result = tuple()
|
# append self include directories
|
||||||
|
inc_dirs = [self.env.Dir(d) for d in self.get_inc_dirs()]
|
||||||
|
inc_dirs.extend(LibBuilderBase.INC_DIRS_CACHE)
|
||||||
|
|
||||||
|
result = []
|
||||||
for path in self._validate_search_paths(search_paths):
|
for path in self._validate_search_paths(search_paths):
|
||||||
for inc in self.env.File(path).get_found_includes(
|
for inc in self.env.File(path).get_found_includes(
|
||||||
self.env, LibBuilderBase.INC_SCANNER, inc_dirs):
|
self.env, LibBuilderBase.INC_SCANNER, tuple(inc_dirs)):
|
||||||
if inc not in result:
|
if inc not in result:
|
||||||
result += (inc, )
|
result.append(inc)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def depend_recursive(self, lb, lib_builders, search_paths=None):
|
def depend_recursive(self, lb, lib_builders, search_paths=None):
|
||||||
@ -260,13 +264,17 @@ class LibBuilderBase(object):
|
|||||||
"between `%s` and `%s`\n" %
|
"between `%s` and `%s`\n" %
|
||||||
(self.path, lb.path))
|
(self.path, lb.path))
|
||||||
elif lb not in self._depbuilders:
|
elif lb not in self._depbuilders:
|
||||||
self._depbuilders += (lb, )
|
self._depbuilders.append(lb)
|
||||||
|
LibBuilderBase.INC_DIRS_CACHE = None
|
||||||
lb.search_deps_recursive(lib_builders, search_paths)
|
lb.search_deps_recursive(lib_builders, search_paths)
|
||||||
|
|
||||||
def search_deps_recursive(self, lib_builders, search_paths=None):
|
def search_deps_recursive(self, lib_builders, search_paths=None):
|
||||||
self._is_dependent = True
|
if not self._is_dependent:
|
||||||
|
self._is_dependent = True
|
||||||
|
self._process_dependencies(lib_builders)
|
||||||
|
|
||||||
self._process_dependencies(lib_builders)
|
if self.lib_ldf_mode == 2:
|
||||||
|
search_paths = self.get_src_files()
|
||||||
|
|
||||||
# when LDF is disabled
|
# when LDF is disabled
|
||||||
if self.lib_ldf_mode == 0:
|
if self.lib_ldf_mode == 0:
|
||||||
@ -277,12 +285,12 @@ class LibBuilderBase(object):
|
|||||||
for lb in lib_builders:
|
for lb in lib_builders:
|
||||||
if inc.get_abspath() in lb:
|
if inc.get_abspath() in lb:
|
||||||
if lb not in lib_inc_map:
|
if lb not in lib_inc_map:
|
||||||
lib_inc_map[lb] = tuple()
|
lib_inc_map[lb] = []
|
||||||
lib_inc_map[lb] += (inc.get_abspath(), )
|
lib_inc_map[lb].append(inc.get_abspath())
|
||||||
break
|
break
|
||||||
|
|
||||||
for lb, lb_src_files in lib_inc_map.items():
|
for lb, lb_search_paths in lib_inc_map.items():
|
||||||
self.depend_recursive(lb, lib_builders, lb_src_files)
|
self.depend_recursive(lb, lib_builders, lb_search_paths)
|
||||||
|
|
||||||
def build(self):
|
def build(self):
|
||||||
libs = []
|
libs = []
|
||||||
@ -309,6 +317,10 @@ class UnknownLibBuilder(LibBuilderBase):
|
|||||||
|
|
||||||
class ProjectAsLibBuilder(LibBuilderBase):
|
class ProjectAsLibBuilder(LibBuilderBase):
|
||||||
|
|
||||||
|
@property
|
||||||
|
def lib_ldf_mode(self):
|
||||||
|
return 2 # parse all project files
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def src_filter(self):
|
def src_filter(self):
|
||||||
return self.env.get("SRC_FILTER", LibBuilderBase.src_filter.fget(self))
|
return self.env.get("SRC_FILTER", LibBuilderBase.src_filter.fget(self))
|
||||||
@ -395,12 +407,6 @@ class MbedLibBuilder(LibBuilderBase):
|
|||||||
def is_framework_compatible(self, framework):
|
def is_framework_compatible(self, framework):
|
||||||
return framework.lower() == "mbed"
|
return framework.lower() == "mbed"
|
||||||
|
|
||||||
@property
|
|
||||||
def lib_ldf_mode(self):
|
|
||||||
if "dependencies" in self._manifest:
|
|
||||||
return 2
|
|
||||||
return LibBuilderBase.lib_ldf_mode.fget(self)
|
|
||||||
|
|
||||||
|
|
||||||
class PlatformIOLibBuilder(LibBuilderBase):
|
class PlatformIOLibBuilder(LibBuilderBase):
|
||||||
|
|
||||||
@ -486,7 +492,7 @@ class PlatformIOLibBuilder(LibBuilderBase):
|
|||||||
|
|
||||||
|
|
||||||
def GetLibBuilders(env):
|
def GetLibBuilders(env):
|
||||||
items = tuple()
|
items = []
|
||||||
env_frameworks = [
|
env_frameworks = [
|
||||||
f.lower().strip() for f in env.get("PIOFRAMEWORK", "").split(",")
|
f.lower().strip() for f in env.get("PIOFRAMEWORK", "").split(",")
|
||||||
]
|
]
|
||||||
@ -529,13 +535,13 @@ def GetLibBuilders(env):
|
|||||||
% join(libs_dir, item))
|
% join(libs_dir, item))
|
||||||
continue
|
continue
|
||||||
if _check_lib_builder(lb):
|
if _check_lib_builder(lb):
|
||||||
items += (lb, )
|
items.append(lb)
|
||||||
else:
|
else:
|
||||||
found_incompat = True
|
found_incompat = True
|
||||||
|
|
||||||
for lb in env.get("EXTRA_LIB_BUILDERS", []):
|
for lb in env.get("EXTRA_LIB_BUILDERS", []):
|
||||||
if _check_lib_builder(lb):
|
if _check_lib_builder(lb):
|
||||||
items += (lb, )
|
items.append(lb)
|
||||||
else:
|
else:
|
||||||
found_incompat = True
|
found_incompat = True
|
||||||
|
|
||||||
@ -550,6 +556,16 @@ def GetLibBuilders(env):
|
|||||||
|
|
||||||
def BuildDependentLibraries(env, src_dir):
|
def BuildDependentLibraries(env, src_dir):
|
||||||
|
|
||||||
|
def correct_found_libs(lib_builders):
|
||||||
|
# build full dependency graph
|
||||||
|
found_lbs = [lb for lb in lib_builders if lb.dependent]
|
||||||
|
for lb in lib_builders:
|
||||||
|
lb.search_deps_recursive(lib_builders, lb.get_src_files())
|
||||||
|
for lb in lib_builders:
|
||||||
|
for deplb in lb.depbuilders[:]:
|
||||||
|
if deplb not in found_lbs:
|
||||||
|
lb.depbuilders.remove(deplb)
|
||||||
|
|
||||||
def print_deps_tree(root, level=0):
|
def print_deps_tree(root, level=0):
|
||||||
margin = "| " * (level)
|
margin = "| " * (level)
|
||||||
for lb in root.depbuilders:
|
for lb in root.depbuilders:
|
||||||
@ -571,6 +587,9 @@ def BuildDependentLibraries(env, src_dir):
|
|||||||
project.env = env
|
project.env = env
|
||||||
project.search_deps_recursive(lib_builders)
|
project.search_deps_recursive(lib_builders)
|
||||||
|
|
||||||
|
if int(env.get("LIB_LDF_MODE", 1)) == 1 and project.depbuilders:
|
||||||
|
correct_found_libs(lib_builders)
|
||||||
|
|
||||||
if project.depbuilders:
|
if project.depbuilders:
|
||||||
print "Library Dependency Graph"
|
print "Library Dependency Graph"
|
||||||
print_deps_tree(project)
|
print_deps_tree(project)
|
||||||
|
Reference in New Issue
Block a user