diff --git a/docs/librarymanager/config.rst b/docs/librarymanager/config.rst index 3f96814a..67a5e6bb 100644 --- a/docs/librarymanager/config.rst +++ b/docs/librarymanager/config.rst @@ -533,6 +533,13 @@ More details :ref:`projectconf_extra_script`. Archive object files to Static Library. This is default behavior of PlatformIO Build System (``"libArchive": true``). +``libLDFMode`` +~~~~~~~~~~~~~~ + +*Optional* | Type: ``Integer`` + +Specify Library Dependency Finder Mode. See :ref:`ldf_mode` for details. + **Examples** 1. Custom macros/defines diff --git a/docs/librarymanager/ldf.rst b/docs/librarymanager/ldf.rst index bd5889ff..269b1e6a 100644 --- a/docs/librarymanager/ldf.rst +++ b/docs/librarymanager/ldf.rst @@ -65,10 +65,10 @@ project (:ref:`projectconf_pio_src_dir`) and can work in the next modes: * ``0`` - "manual mode", does not process source files of a project and dependencies. Builds only the libraries that are specified in manifests (:ref:`library_config`, ``module.json``) or in the :ref:`projectconf`. -* ``1`` - parses ALL C/C++ source code of the project and follows only by - nested includes/chain (``#include ...``) from the libraries. -* ``2`` - **default** - parses ALL C/C++ source code of the project and parses - ALL C/C++ source code of the each dependency (recursively). +* ``1`` - **default** - parses ALL C/C++ source code of the project and follows + only by nested includes (``#include ...``, chain...) from the libraries. +* ``2`` - parses ALL C/C++ source code of the project and parses + ALL C/C++ source code of the each found dependency (recursively). This mode can be changed using :ref:`projectconf_lib_ldf_mode` option in :ref:`projectconf`. diff --git a/docs/projectconf.rst b/docs/projectconf.rst index dd2c2c0a..357473f2 100644 --- a/docs/projectconf.rst +++ b/docs/projectconf.rst @@ -812,13 +812,8 @@ Example: .. seealso:: Please make sure to read :ref:`ldf` guide first. -Library Dependency Finder starts work from analyzing source files of the -project (:ref:`projectconf_pio_src_dir`) and can work in the different modes -(see :ref:`ldf_mode`). - -By default, this value is set to ``lib_ldf_mode = 2`` and means that LDF -will parse ALL C/C++ source code of the project and will parse ALL C/C++ -source code of the each dependent library (recursively). +This option specifies how does Library Dependency Finder should analyze +dependencies (``#include`` directives). See :ref:`ldf_mode` for details. .. _projectconf_lib_compat_mode: diff --git a/platformio/__init__.py b/platformio/__init__.py index 7c94ebc9..d6a8a6dc 100644 --- a/platformio/__init__.py +++ b/platformio/__init__.py @@ -14,7 +14,7 @@ import sys -VERSION = (3, 0, "0b3") +VERSION = (3, 0, "0b4") __version__ = ".".join([str(s) for s in VERSION]) __title__ = "platformio" diff --git a/platformio/builder/tools/piolib.py b/platformio/builder/tools/piolib.py index 47f0351c..74748609 100644 --- a/platformio/builder/tools/piolib.py +++ b/platformio/builder/tools/piolib.py @@ -34,9 +34,7 @@ class LibBuilderFactory(object): @staticmethod def new(env, path): clsname = "UnknownLibBuilder" - if isfile(join(path, "library.properties")): - clsname = "ArduinoLibBuilder" - elif isfile(join(path, "library.json")): + if isfile(join(path, "library.json")): clsname = "PlatformIOLibBuilder" else: env_frameworks = [ @@ -76,8 +74,10 @@ class LibBuilderFactory(object): return ["mbed"] return [] +# pylint: disable=too-many-instance-attributes, too-many-public-methods -class LibBuilderBase(object): # pylint: disable=too-many-instance-attributes + +class LibBuilderBase(object): INC_SCANNER = SCons.Scanner.C.CScanner() @@ -153,6 +153,10 @@ class LibBuilderBase(object): # pylint: disable=too-many-instance-attributes def lib_archive(self): return True + @property + def lib_ldf_mode(self): + return int(self.env.get("LIB_LDF_MODE", 1)) + @property def depbuilders(self): return self._depbuilders @@ -210,7 +214,7 @@ class LibBuilderBase(object): # pylint: disable=too-many-instance-attributes if not search_paths: search_paths = tuple() assert isinstance(search_paths, tuple) - deep_search = int(self.env.get("LIB_LDF_MODE", 2)) == 2 + deep_search = self.lib_ldf_mode == 2 if not self._scanned_paths and ( isinstance(self, ProjectAsLibBuilder) or deep_search): @@ -265,8 +269,7 @@ class LibBuilderBase(object): # pylint: disable=too-many-instance-attributes self._process_dependencies(lib_builders) # when LDF is disabled - if "LIB_LDF_MODE" in self.env and \ - int(self.env.get("LIB_LDF_MODE")) == 0: + if self.lib_ldf_mode == 0: return lib_inc_map = {} @@ -346,9 +349,10 @@ class ArduinoLibBuilder(LibBuilderBase): def get_inc_dirs(self): inc_dirs = LibBuilderBase.get_inc_dirs(self) - if not isdir(join(self.path, "utility")): + if isdir(join(self.path, "src")): return inc_dirs - inc_dirs.append(join(self.path, "utility")) + if isdir(join(self.path, "utility")): + inc_dirs.append(join(self.path, "utility")) return inc_dirs @property @@ -391,6 +395,12 @@ class MbedLibBuilder(LibBuilderBase): def is_framework_compatible(self, framework): 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): @@ -400,10 +410,15 @@ class PlatformIOLibBuilder(LibBuilderBase): assert "name" in manifest return manifest + def _is_arduino_manifest(self): + return isfile(join(self.path, "library.properties")) + @property def src_filter(self): if "srcFilter" in self._manifest.get("build", {}): return self._manifest.get("build").get("srcFilter") + elif self._is_arduino_manifest(): + return ArduinoLibBuilder.src_filter.fget(self) return LibBuilderBase.src_filter.fget(self) @property @@ -430,6 +445,12 @@ class PlatformIOLibBuilder(LibBuilderBase): return self._manifest.get("build").get("libArchive") return LibBuilderBase.lib_archive.fget(self) + @property + def lib_ldf_mode(self): + if "libLDFMode" in self._manifest.get("build", {}): + return int(self._manifest.get("build").get("libLDFMode")) + return LibBuilderBase.lib_ldf_mode.fget(self) + def is_platform_compatible(self, platform): items = self._manifest.get("platforms") if not items: @@ -451,6 +472,13 @@ class PlatformIOLibBuilder(LibBuilderBase): def get_inc_dirs(self): inc_dirs = LibBuilderBase.get_inc_dirs(self) + + # backwards compatibility with PlatformIO 2.0 + if ("build" not in self._manifest and self._is_arduino_manifest() and + not isdir(join(self.path, "src")) and + isdir(join(self.path, "utility"))): + inc_dirs.append(join(self.path, "utility")) + for path in self.env['CPPPATH']: if path not in self.envorigin['CPPPATH']: inc_dirs.append(self.env.subst(path))