8000 tools/manifestfile.py: Change library search to use a list of paths. · ukicomputers/micropython@35dd959 · GitHub
[go: up one dir, main page]

Skip to content

Commit 35dd959

Browse files
committed
tools/manifestfile.py: Change library search to use a list of paths.
This commit changes how library packages are searched for when a manifest file is loaded: there is now simply a list of library paths that is searched in order for the given package. This list defaults to the main directories in micropython-lib, but can be added to -- either appended or prepended -- by using `add_library()`. In particular the way unix-ffi library packages are searched has changed, because the `unix_ffi` argument to `require()` is now removed. Instead, if a build wants to include packages from micropython-lib/unix-ffi, then it must explicitly add this to the list of paths to search using: add_library("unix-ffi", "$(MPY_LIB_DIR)/unix-ffi") Work done in collaboration with Jim Mussared. Signed-off-by: Damien George <damien@micropython.org>
1 parent 2bdaa1b commit 35dd959

File tree

2 files changed

+49
-33
lines changed

2 files changed

+49
-33
lines changed

docs/reference/manifest.rst

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,17 @@ Note: The ``opt`` keyword argument can be set on the various functions, this con
9595
the optimisation level used by the cross-compiler.
9696
See :func:`micropython.opt_level`.
9797

98+
.. function:: add_library(library, library_path, prepend=False)
99+
100+
Register the path to an external named *library*.
101+
102+
The path *library_path* will be automatically searched when using `require`.
103+
By default the added library is added to the end of the list of libraries to
104+
search. Pass ``True`` to *prepend* to add it to the start of the list.
105+
106+
Additionally, the added library can be explicitly requested by using
107+
``require("name", library="library")``.
108+
98109
.. function:: package(package_path, files=None, base_path=".", opt=None)
99110

100111
This is equivalent to copying the "package_path" directory to the device
@@ -138,11 +149,13 @@ See :func:`micropython.opt_level`.
138149
139150
You can use the variables above, such as ``$(PORT_DIR)`` in ``base_path``.
140151

141-
.. function:: require(name, unix_ffi=False)
152+
.. function:: require(name, library=None)
142153

143154
Require a package by name (and its dependencies) from :term:`micropython-lib`.
144155

145-
Optionally specify unix_ffi=True to use a module from the unix-ffi directory.
156+
Optionally specify *library* (a string) to reference a package from a
157+
library that has been previously registered with `add_library`. Otherwise
158+
the list of library paths will be used.
146159

147160
.. function:: include(manifest_path)
148161

tools/manifestfile.py

Lines changed: 34 additions & 31 deletions
10000
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@
6262
# URL to file. (TODO)
6363
FILE_TYPE_HTTP = 2
6464

65+
# Default list of libraries in micropython-lib to search for library packages.
66+
BASE_LIBRARY_NAMES = ("micropython", "python-stdlib", "python-ecosys")
67+
6568

6669
class ManifestFileError(Exception):
6770
pass
@@ -196,6 +199,12 @@ def __init__(self, mode, path_vars=None):
196199
self._metadata = [ManifestPackageMetadata()]
197200
# Registered external libraries.
198201
self._libraries = {}
202+
# List of directories to search for packages.
203+
self._library_dirs = []
204+
# Add default micropython-lib libraries if $(MPY_LIB_DIR) has been specified.
205+
if self._path_vars["MPY_LIB_DIR"]:
206+
for lib in BASE_LIBRARY_NAMES:
207+
self.add_library(lib, os.path.join("$(MPY_LIB_DIR)", lib))
199208

200209
def _resolve_path(self, path):
201210
# Convert path to an absolute path, applying variable substitutions.
@@ -398,18 +407,16 @@ def _require_from_path(self, library_path, name, version, extra_kwargs):
398407
return True
399408
return False
400409

401-
def require(self, name, version=None, unix_ffi=False, pypi=None, library=None, **kwargs):
410+
def require(self, name, version=None, pypi=None, library=None, **kwargs):
402411
"""
403412
Require a package by name from micropython-lib.
404413
405-
Optionally specify unix_ffi=True to use a module from the unix-ffi directory.
406-
407414
Optionally specify pipy="package-name" to indicate that this should
408415
use the named package from PyPI when building for CPython.
409416
410417
Optionally specify library="name" to reference a package from a
411418
library that has been previously registered with add_library(). Otherwise
412-
micropython-lib will be used.
419+
the list of library paths will be used.
413420
"""
414421
self._metadata[-1].check_initialised(self._mode)
415422

@@ -426,39 +433,35 @@ def require(self, name, version=None, unix_ffi=False, pypi=None, library=None, *
426433
raise ValueError("Unknown library '{}' for require('{}').".format(library, name))
427434
library_path = self._libraries[library]
428435
# Search for {library_path}/**/{name}/manifest.py.
429-
if not self._require_from_path(library_path, name, version, kwargs):
430-
raise ValueError(
431-
"Package '{}' not found in external library '{}' ({}).".format(
432-
name, library, library_path
433-
)
436+
if self._require_from_path(library_path, name, version, kwargs):
437+
return
438+
raise ValueError(
439+
"Package '{}' not found in external library '{}' ({}).".format(
440+
name, library, library_path
434441
)
435-
elif self._path_vars["MPY_LIB_DIR"]:
436-
# Find package in micropython-lib, in one of the three top-level directories.
437-
lib_dirs = ["micropython", "python-stdlib", "python-ecosys"]
438-
if unix_ffi:
439-
# Additionally search unix-ffi only if unix_ffi=True, and make unix-ffi modules
440-
# take precedence.
441-
lib_dirs = ["unix-ffi"] + lib_dirs
442-
443-
for lib_dir in lib_dirs:
444-
# Search for {lib_dir}/**/{name}/manifest.py.
445-
if self._require_from_path(
446-
os.path.join(self._path_vars["MPY_LIB_DIR"], lib_dir), name, version, kwargs
447-
):
448-
return
449-
450-
raise ValueError("Package '{}' not found in local micropython-lib.".format(name))
451-
else:
452-
# TODO: HTTP request to obtain URLs from manifest.json.
453-
raise ValueError("micropython-lib not available for require('{}').", name)
442+
)
454443

455-
def add_library(self, library, library_path):
444+
for lib_dir in self._library_dirs:
445+
# Search for {lib_dir}/**/{name}/manifest.py.
446+
if self._require_from_path(lib_dir, name, version, kwargs):
447+
return
448+
449+
raise ValueError("Package '{}' not found in any known library.".format(name))
450+
451+
def add_library(self, library, library_path, prepend=False):
456452
"""
457453
Register the path to an external named library.
458454
459-
This allows require("name", library="library") to find packages in that library.
455+
The path will be automatically searched when using require(). By default the
456+
added library is added to the end of the list of libraries to search. Pass
457+
`prepend=True` to add it to the start of the list.
458+
459+
Additionally, the added library can be explicitly requested by using
460+
`require("name", library="library")`.
460461
"""
461-
self._libraries[library] = self._resolve_path(library_path)
462+
library_path = self._resolve_path(library_path)
463+
self._libraries[library] = library_path
464+
self._library_dirs.insert(0 if prepend else len(self._library_dirs), library_path)
462465

463466
def package(self, package_path, files=None, base_path=".", opt=None):
464467
"""

0 commit comments

Comments
 (0)
0