diff --git a/ChangeLog.md b/ChangeLog.md index abc4cfc7405a..52d0ddd06e09 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -47,6 +47,9 @@ See docs/process.md for more on how version tagging works. #21276) - Added concept of external ports which live outside emscripten and are loaded on demand using the syntax `--use-port=/path/to/my_port.py` (#21316) +- `embuilder` can now build ports with options as well as external ports using + the same syntax introduced with `--use-port` + (ex: `embuilder sdl2_image:formats=png,jpg`) (#21345) - Allow comments in response files. Any line starting with `#` is now ignored. This is useful when listing exported symbols. (#21330) diff --git a/docs/emcc.txt b/docs/emcc.txt index e9fd0167bf89..55afc30fa550 100644 --- a/docs/emcc.txt +++ b/docs/emcc.txt @@ -471,9 +471,12 @@ Options that are modified or new in *emcc* are listed below: "--use-port=" [compile+link] Use the specified port. If you need to use more than - one port you can use this argument multiple times. For example: "-- - use-port=sdl2 --use-port=bzip2". To get the list of available - ports, use "--show-ports". + one port you can use this option multiple times (ex: "--use- + port=sdl2 --use-port=bzip2"). A port can have options separated by + ":" (ex: "--use-port=sdl2_image:formats=png,jpg"). To use an + external port, you provide the path to the port directly (ex: "-- + use-port=/path/to/my_port.py"). To get the list of available ports, + use "--show-ports". "--clear-ports" [general] Manually clears the local copies of ports from the diff --git a/site/source/docs/tools_reference/emcc.rst b/site/source/docs/tools_reference/emcc.rst index a9116455881c..8dc995529543 100644 --- a/site/source/docs/tools_reference/emcc.rst +++ b/site/source/docs/tools_reference/emcc.rst @@ -461,9 +461,13 @@ Options that are modified or new in *emcc* are listed below: ``--use-port=`` [compile+link] - Use the specified port. If you need to use more than one port you can use this - argument multiple times. For example: ``--use-port=sdl2 --use-port=bzip2``. - To get the list of available ports, use ``--show-ports``. + Use the specified port. If you need to use more than one port you can use + this option multiple times (ex: ``--use-port=sdl2 --use-port=bzip2``). A port + can have options separated by ``:`` + (ex: ``--use-port=sdl2_image:formats=png,jpg``). To use an external port, + you provide the path to the port directly + (ex: ``--use-port=/path/to/my_port.py``). To get the list of available ports, + use ``--show-ports``. .. _emcc-clear-ports: diff --git a/tools/ports/__init__.py b/tools/ports/__init__.py index 2241991ece9f..6aa46a834b47 100644 --- a/tools/ports/__init__.py +++ b/tools/ports/__init__.py @@ -9,7 +9,6 @@ import shutil import glob import importlib.util -import sys from typing import Set from tools import cache from tools import config @@ -67,19 +66,14 @@ def init_port(name, port): validate_port(port) -def load_port_by_name(name): - port = __import__(name, globals(), level=1, fromlist=[None]) - init_port(name, port) - - -def load_port_by_path(path): - name = os.path.splitext(os.path.basename(path))[0] +def load_port(path, name=None): + if not name: + name = shared.unsuffixed_basename(path) if name in ports_by_name: utils.exit_with_error(f'port path [`{path}`] is invalid: duplicate port name `{name}`') module_name = f'tools.ports.{name}' spec = importlib.util.spec_from_file_location(module_name, path) port = importlib.util.module_from_spec(spec) - sys.modules[module_name] = port spec.loader.exec_module(port) init_port(name, port) return name @@ -100,15 +94,14 @@ def read_ports(): for filename in os.listdir(ports_dir): if not filename.endswith('.py') or filename == '__init__.py': continue - filename = os.path.splitext(filename)[0] - load_port_by_name(filename) + load_port(os.path.join(ports_dir, filename)) contrib_dir = os.path.join(ports_dir, 'contrib') for filename in os.listdir(contrib_dir): if not filename.endswith('.py') or filename == '__init__.py': continue - filename = os.path.splitext(filename)[0] - load_port_by_name('contrib.' + filename) + name = 'contrib.' + shared.unsuffixed(filename) + load_port(os.path.join(contrib_dir, filename), name) def get_all_files_under(dirname): @@ -426,7 +419,7 @@ def error_handler(message): port_file_path = name if not os.path.isfile(port_file_path): error_handler(f'not a valid port path: {port_file_path}') - name = load_port_by_path(port_file_path) + name = load_port(port_file_path) elif name not in ports_by_name: error_handler(f'invalid port name: `{name}`') ports_needed.add(name)