forked from platformio/platformio-core
Refactored lib_force
and lib_ignore
logic
This commit is contained in:
@ -595,18 +595,19 @@ Example:
|
|||||||
[env:depends_on_some_libs]
|
[env:depends_on_some_libs]
|
||||||
lib_install = 1,13,19
|
lib_install = 1,13,19
|
||||||
|
|
||||||
``lib_use``
|
``lib_force``
|
||||||
^^^^^^^^^^^
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
Specify libraries which should be used by ``Library Dependency Finder (LDF)`` with
|
Force Library Build System to build specified libraries if even they are not
|
||||||
the highest priority.
|
included in the project source code. Also, these libraries will be processed
|
||||||
|
in the first order.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
.. code-block:: ini
|
.. code-block:: ini
|
||||||
|
|
||||||
[env:libs_with_highest_priority]
|
[env:myenv]
|
||||||
lib_use = OneWire_ID1,SPI
|
lib_force = OneWire, SPI
|
||||||
|
|
||||||
``lib_ignore``
|
``lib_ignore``
|
||||||
^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^
|
||||||
@ -618,7 +619,7 @@ Example:
|
|||||||
.. code-block:: ini
|
.. code-block:: ini
|
||||||
|
|
||||||
[env:ignore_some_libs]
|
[env:ignore_some_libs]
|
||||||
lib_ignore = SPI,EngduinoV3_ID123
|
lib_ignore = SPI, Ethernet
|
||||||
|
|
||||||
``lib_deep_search``
|
``lib_deep_search``
|
||||||
^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
VERSION = (3, 0, "0.dev2")
|
VERSION = (3, 0, "0.dev3")
|
||||||
__version__ = ".".join([str(s) for s in VERSION])
|
__version__ = ".".join([str(s) for s in VERSION])
|
||||||
|
|
||||||
__title__ = "platformio"
|
__title__ = "platformio"
|
||||||
|
@ -43,7 +43,7 @@ commonvars.AddVariables(
|
|||||||
("SRC_FILTER",),
|
("SRC_FILTER",),
|
||||||
("LIB_DEEP_SEARCH",),
|
("LIB_DEEP_SEARCH",),
|
||||||
("LIB_IGNORE",),
|
("LIB_IGNORE",),
|
||||||
("LIB_USE",),
|
("LIB_FORCE",),
|
||||||
|
|
||||||
# board options
|
# board options
|
||||||
("BOARD",),
|
("BOARD",),
|
||||||
@ -104,7 +104,7 @@ for k in commonvars.keys():
|
|||||||
env.LoadDevPlatform(commonvars)
|
env.LoadDevPlatform(commonvars)
|
||||||
|
|
||||||
# Parse library names
|
# Parse library names
|
||||||
for opt in ("LIB_IGNORE", "LIB_USE"):
|
for opt in ("LIB_IGNORE", "LIB_FORCE"):
|
||||||
if opt not in env:
|
if opt not in env:
|
||||||
continue
|
continue
|
||||||
env[opt] = [l.strip() for l in env[opt].split(",") if l.strip()]
|
env[opt] = [l.strip() for l in env[opt].split(",") if l.strip()]
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
# pylint: disable=no-member
|
||||||
|
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
import os
|
import os
|
||||||
@ -73,6 +75,7 @@ class LibBuilderBase(object):
|
|||||||
self.env = env
|
self.env = env
|
||||||
self.path = path
|
self.path = path
|
||||||
self._is_built = False
|
self._is_built = False
|
||||||
|
self._manifest = self.load_manifest()
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "%s(%r)" % (self.__class__, self.path)
|
return "%s(%r)" % (self.__class__, self.path)
|
||||||
@ -82,7 +85,11 @@ class LibBuilderBase(object):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
return basename(self.path)
|
return self._manifest.get("name", basename(self.path))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def version(self):
|
||||||
|
return self._manifest.get("version")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def src_filter(self):
|
def src_filter(self):
|
||||||
@ -105,13 +112,25 @@ class LibBuilderBase(object):
|
|||||||
def is_built(self):
|
def is_built(self):
|
||||||
return self._is_built
|
return self._is_built
|
||||||
|
|
||||||
|
def load_manifest(self): # pylint: disable=no-self-use
|
||||||
|
return {}
|
||||||
|
|
||||||
def get_path_dirs(self, use_build_dir=False):
|
def get_path_dirs(self, use_build_dir=False):
|
||||||
return [self.build_dir if use_build_dir else self.src_dir]
|
return [self.build_dir if use_build_dir else self.src_dir]
|
||||||
|
|
||||||
|
def append_to_cpppath(self):
|
||||||
|
self.env.AppendUnique(
|
||||||
|
CPPPATH=self.get_path_dirs(use_build_dir=True)
|
||||||
|
)
|
||||||
|
|
||||||
def build(self):
|
def build(self):
|
||||||
print "Depends on <%s>" % self.name
|
if self.version:
|
||||||
|
print "Depends on <%s> v%s" % (self.name, self.version)
|
||||||
|
else:
|
||||||
|
print "Depends on <%s>" % self.name
|
||||||
assert self._is_built is False
|
assert self._is_built is False
|
||||||
self._is_built = True
|
self._is_built = True
|
||||||
|
self.append_to_cpppath()
|
||||||
return self.env.BuildLibrary(self.build_dir, self.src_dir)
|
return self.env.BuildLibrary(self.build_dir, self.src_dir)
|
||||||
|
|
||||||
|
|
||||||
@ -121,33 +140,43 @@ class UnknownLibBuilder(LibBuilderBase):
|
|||||||
|
|
||||||
class ArduinoLibBuilder(LibBuilderBase):
|
class ArduinoLibBuilder(LibBuilderBase):
|
||||||
|
|
||||||
|
def load_manifest(self):
|
||||||
|
manifest = {}
|
||||||
|
if not isfile(join(self.path, "library.properties")):
|
||||||
|
return manifest
|
||||||
|
with open(join(self.path, "library.properties")) as fp:
|
||||||
|
for line in fp.readlines():
|
||||||
|
if "=" not in line:
|
||||||
|
continue
|
||||||
|
key, value = line.split("=", 1)
|
||||||
|
manifest[key.strip()] = value.strip()
|
||||||
|
return manifest
|
||||||
|
|
||||||
def get_path_dirs(self, use_build_dir=False):
|
def get_path_dirs(self, use_build_dir=False):
|
||||||
path_dirs = LibBuilderBase.get_path_dirs(self, use_build_dir)
|
path_dirs = LibBuilderBase.get_path_dirs(self, use_build_dir)
|
||||||
if not isdir(join(self.src_dir, "utility")):
|
if not isdir(join(self.src_dir, "utility")):
|
||||||
return path_dirs
|
return path_dirs
|
||||||
path_dirs.append(join(self.build_dir if use_build_dir
|
path_dirs.append(
|
||||||
else self.src_dir, "utility"))
|
join(self.build_dir if use_build_dir else self.src_dir, "utility"))
|
||||||
return path_dirs
|
return path_dirs
|
||||||
|
|
||||||
|
|
||||||
class MbedLibBuilder(LibBuilderBase):
|
class MbedLibBuilder(LibBuilderBase):
|
||||||
|
|
||||||
def __init__(self, env, path):
|
def load_manifest(self):
|
||||||
self.module_json = {}
|
if not isfile(join(self.path, "module.json")):
|
||||||
if isfile(join(path, "module.json")):
|
return {}
|
||||||
self.module_json = util.load_json(join(path, "module.json"))
|
return util.load_json(join(self.path, "module.json"))
|
||||||
|
|
||||||
LibBuilderBase.__init__(self, env, path)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def src_dir(self):
|
def src_dir(self):
|
||||||
if isdir(join(self.path, "source")):
|
if isdir(join(self.path, "source")):
|
||||||
return join(self.path, "source")
|
return join(self.path, "source")
|
||||||
return LibBuilderBase.src_dir.fget(self) # pylint: disable=no-member
|
return LibBuilderBase.src_dir.fget(self)
|
||||||
|
|
||||||
def get_path_dirs(self, use_build_dir=False):
|
def get_path_dirs(self, use_build_dir=False):
|
||||||
path_dirs = LibBuilderBase.get_path_dirs(self, use_build_dir)
|
path_dirs = LibBuilderBase.get_path_dirs(self, use_build_dir)
|
||||||
for p in self.module_json.get("extraIncludes", []):
|
for p in self._manifest.get("extraIncludes", []):
|
||||||
if p.startswith("source/"):
|
if p.startswith("source/"):
|
||||||
p = p[7:]
|
p = p[7:]
|
||||||
path_dirs.append(
|
path_dirs.append(
|
||||||
@ -157,12 +186,11 @@ class MbedLibBuilder(LibBuilderBase):
|
|||||||
|
|
||||||
class PlatformIOLibBuilder(LibBuilderBase):
|
class PlatformIOLibBuilder(LibBuilderBase):
|
||||||
|
|
||||||
def __init__(self, env, path):
|
def load_manifest(self):
|
||||||
self.library_json = {}
|
assert isfile(join(self.path, "library.json"))
|
||||||
if isfile(join(path, "library.json")):
|
manifest = util.load_json(join(self.path, "library.json"))
|
||||||
self.library_json = util.load_json(join(path, "library.json"))
|
assert "name" in manifest
|
||||||
|
return manifest
|
||||||
LibBuilderBase.__init__(self, env, path)
|
|
||||||
|
|
||||||
|
|
||||||
def find_deps(env, scanner, path_dirs, src_dir, src_filter):
|
def find_deps(env, scanner, path_dirs, src_dir, src_filter):
|
||||||
@ -195,11 +223,9 @@ def find_and_build_deps(env, lib_builders, scanner,
|
|||||||
break
|
break
|
||||||
|
|
||||||
libs = []
|
libs = []
|
||||||
# add build dirs to global CPPPATH
|
# append PATH directories to global CPPPATH before build starts
|
||||||
for lb in target_lbs:
|
for lb in target_lbs:
|
||||||
env.Append(
|
lb.append_to_cpppath()
|
||||||
CPPPATH=lb.get_path_dirs(use_build_dir=True)
|
|
||||||
)
|
|
||||||
# start builder
|
# start builder
|
||||||
for lb in target_lbs:
|
for lb in target_lbs:
|
||||||
libs.append(lb.build())
|
libs.append(lb.build())
|
||||||
@ -212,24 +238,45 @@ def find_and_build_deps(env, lib_builders, scanner,
|
|||||||
return libs
|
return libs
|
||||||
|
|
||||||
|
|
||||||
def BuildDependentLibraries(env, src_dir):
|
def GetLibBuilders(env):
|
||||||
lib_builders = []
|
items = []
|
||||||
libs_dirs = [env.subst(d) for d in env.get("LIBSOURCE_DIRS", [])
|
libs_dirs = [env.subst(d) for d in env.get("LIBSOURCE_DIRS", [])
|
||||||
if isdir(env.subst(d))]
|
if isdir(env.subst(d))]
|
||||||
for libs_dir in libs_dirs:
|
for libs_dir in libs_dirs:
|
||||||
if not isdir(libs_dir):
|
|
||||||
continue
|
|
||||||
for item in sorted(os.listdir(libs_dir)):
|
for item in sorted(os.listdir(libs_dir)):
|
||||||
if isdir(join(libs_dir, item)):
|
if item == "__cores__" or not isdir(join(libs_dir, item)):
|
||||||
lib_builders.append(
|
continue
|
||||||
LibBuilderFactory.new(env, join(libs_dir, item)))
|
lb = LibBuilderFactory.new(env, join(libs_dir, item))
|
||||||
|
if lb.name in env.get("LIB_IGNORE", []):
|
||||||
|
continue
|
||||||
|
items.append(lb)
|
||||||
|
return items
|
||||||
|
|
||||||
|
|
||||||
|
def BuildDependentLibraries(env, src_dir):
|
||||||
|
libs = []
|
||||||
|
scanner = SCons.Scanner.C.CScanner()
|
||||||
|
lib_builders = env.GetLibBuilders()
|
||||||
|
|
||||||
print "Looking for dependencies..."
|
print "Looking for dependencies..."
|
||||||
print "Collecting %d libraries" % len(lib_builders)
|
print "Collecting %d libraries" % len(lib_builders)
|
||||||
|
|
||||||
return find_and_build_deps(
|
built_lib_names = []
|
||||||
env, lib_builders, SCons.Scanner.C.CScanner(),
|
for lib_name in env.get("LIB_FORCE", []):
|
||||||
src_dir, env.get("SRC_FILTER"))
|
for lb in lib_builders:
|
||||||
|
if lb.name != lib_name or lb.name in built_lib_names:
|
||||||
|
continue
|
||||||
|
built_lib_names.append(lb.name)
|
||||||
|
libs.extend(find_and_build_deps(
|
||||||
|
env, lib_builders, scanner, lb.src_dir, lb.src_filter))
|
||||||
|
if not lb.is_built:
|
||||||
|
libs.append(lb.build())
|
||||||
|
|
||||||
|
# process project source code
|
||||||
|
libs.extend(find_and_build_deps(
|
||||||
|
env, lib_builders, scanner, src_dir, env.get("SRC_FILTER")))
|
||||||
|
|
||||||
|
return libs
|
||||||
|
|
||||||
|
|
||||||
def exists(_):
|
def exists(_):
|
||||||
@ -237,5 +284,6 @@ def exists(_):
|
|||||||
|
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
|
env.AddMethod(GetLibBuilders)
|
||||||
env.AddMethod(BuildDependentLibraries)
|
env.AddMethod(BuildDependentLibraries)
|
||||||
return env
|
return env
|
||||||
|
@ -145,7 +145,7 @@ def DumpIDEData(env):
|
|||||||
|
|
||||||
def get_includes(env_):
|
def get_includes(env_):
|
||||||
includes = []
|
includes = []
|
||||||
# includes from used framework and libs
|
# includes from used frameworks and libs
|
||||||
for item in env_.get("VARIANT_DIRS", []):
|
for item in env_.get("VARIANT_DIRS", []):
|
||||||
if "$BUILDSRC_DIR" in item[0]:
|
if "$BUILDSRC_DIR" in item[0]:
|
||||||
continue
|
continue
|
||||||
@ -158,9 +158,8 @@ def DumpIDEData(env):
|
|||||||
includes.append(env_.subst(item))
|
includes.append(env_.subst(item))
|
||||||
|
|
||||||
# installed libs
|
# installed libs
|
||||||
for d in env_.get("LIBSOURCE_DIRS", []):
|
for lb in env.GetLibBuilders():
|
||||||
lsd_dir = env_.subst(d)
|
includes.extend(lb.get_path_dirs())
|
||||||
_append_lib_includes(env_, lsd_dir, includes)
|
|
||||||
|
|
||||||
# includes from toolchains
|
# includes from toolchains
|
||||||
p = env.DevPlatform()
|
p = env.DevPlatform()
|
||||||
@ -177,30 +176,6 @@ def DumpIDEData(env):
|
|||||||
|
|
||||||
return includes
|
return includes
|
||||||
|
|
||||||
def _append_lib_includes(env_, libs_dir, includes):
|
|
||||||
if not isdir(libs_dir):
|
|
||||||
return
|
|
||||||
for name in env_.get("LIB_USE", []) + sorted(listdir(libs_dir)):
|
|
||||||
if not isdir(join(libs_dir, name)):
|
|
||||||
continue
|
|
||||||
# ignore user's specified libs
|
|
||||||
if name in env_.get("LIB_IGNORE", []):
|
|
||||||
continue
|
|
||||||
if name == "__cores__":
|
|
||||||
board_core = env_.BoardConfig().get("build.core")
|
|
||||||
if isdir(join(libs_dir, name, board_core)):
|
|
||||||
_append_lib_includes(
|
|
||||||
env_, join(libs_dir, name, board_core), includes)
|
|
||||||
return
|
|
||||||
|
|
||||||
include = (
|
|
||||||
join(libs_dir, name, "src")
|
|
||||||
if isdir(join(libs_dir, name, "src"))
|
|
||||||
else join(libs_dir, name)
|
|
||||||
)
|
|
||||||
if include not in includes:
|
|
||||||
includes.append(include)
|
|
||||||
|
|
||||||
def get_defines(env_):
|
def get_defines(env_):
|
||||||
defines = []
|
defines = []
|
||||||
# global symbols
|
# global symbols
|
||||||
|
@ -100,9 +100,8 @@ class EnvironmentProcessor(object):
|
|||||||
RENAMED_OPTIONS = {
|
RENAMED_OPTIONS = {
|
||||||
"INSTALL_LIBS": "LIB_INSTALL",
|
"INSTALL_LIBS": "LIB_INSTALL",
|
||||||
"IGNORE_LIBS": "LIB_IGNORE",
|
"IGNORE_LIBS": "LIB_IGNORE",
|
||||||
"USE_LIBS": "LIB_USE",
|
"LIB_USE": "LIB_FORCE",
|
||||||
"LIB_DFCYCLIC": "LIB_DEEP_SEARCH",
|
"LIB_DFCYCLIC": "LIB_DEEP_SEARCH"
|
||||||
"SRCBUILD_FLAGS": "SRC_BUILD_FLAGS"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, cmd_ctx, name, options, # pylint: disable=R0913
|
def __init__(self, cmd_ctx, name, options, # pylint: disable=R0913
|
||||||
|
Reference in New Issue
Block a user