|
1 |
| -#!/usr/bin/env python3 |
2 |
| -# |
3 | 1 | # This file is part of the MicroPython project, http://micropython.org/
|
4 | 2 | #
|
5 | 3 | # The MIT License (MIT)
|
|
25 | 23 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
26 | 24 | # THE SOFTWARE.
|
27 | 25 |
|
28 |
| -from __future__ import print_function |
29 |
| -import os |
30 |
| -import re |
31 |
| -import stat |
32 |
| -import subprocess |
33 |
| - |
34 |
| -NATIVE_ARCHS = { |
35 |
| - "NATIVE_ARCH_NONE": "", |
36 |
| - "NATIVE_ARCH_X86": "x86", |
37 |
| - "NATIVE_ARCH_X64": "x64", |
38 |
| - "NATIVE_ARCH_ARMV6": "armv6", |
39 |
| - "NATIVE_ARCH_ARMV6M": "armv6m", |
40 |
| - "NATIVE_ARCH_ARMV7M": "armv7m", |
41 |
| - "NATIVE_ARCH_ARMV7EM": "armv7em", |
42 |
| - "NATIVE_ARCH_ARMV7EMSP": "armv7emsp", |
43 |
| - "NATIVE_ARCH_ARMV7EMDP": "armv7emdp", |
44 |
| - "NATIVE_ARCH_XTENSA": "xtensa", |
45 |
| - "NATIVE_ARCH_XTENSAWIN": "xtensawin", |
46 |
| -} |
47 |
| - |
48 |
| -globals().update(NATIVE_ARCHS) |
49 |
| - |
50 |
| -__all__ = ["version", "compile", "run", "CrossCompileError"] + list(NATIVE_ARCHS.keys()) |
51 |
| - |
52 |
| - |
53 |
| -class CrossCompileError(Exception): |
54 |
| - pass |
55 |
| - |
56 |
| - |
57 |
| -_VERSION_RE = re.compile("mpy-cross emitting mpy v([0-9]+)(?:.([0-9]+))?") |
58 |
| - |
59 |
| - |
60 |
| -def _find_mpy_cross_binary(mpy_cross): |
61 |
| - if mpy_cross: |
62 |
| - return mpy_cross |
63 |
| - return os.path.abspath(os.path.join(os.path.dirname(__file__), "../build/mpy-cross")) |
64 |
| - |
65 |
| - |
66 |
| -def mpy_version(mpy_cross=None): |
67 |
| - """ |
68 |
| - Get the version and sub-version of the .mpy file format generated by this version of mpy-cross. |
69 |
| -
|
70 |
| - Returns: A tuple of `(mpy_version, mpy_sub_version)` |
71 |
| - Optional keyword arguments: |
72 |
| - - mpy_cross: Specific mpy-cross binary to use |
73 |
| - """ |
74 |
| - version_info = run(["--version"], mpy_cross=mpy_cross) |
75 |
| - match = re.search(_VERSION_RE, version_info) |
76 |
| - mpy_version, mpy_sub_version = int(match.group(1)), int(match.group(2) or "0") |
77 |
| - return ( |
78 |
| - mpy_version, |
79 |
| - mpy_sub_version, |
80 |
| - ) |
81 |
| - |
82 |
| - |
83 |
| -def compile(src, dest=None, src_path=None, opt=None, march=None, mpy_cross=None, extra_args=None): |
84 |
| - """ |
85 |
| - Compile the specified .py file with mpy-cross. |
86 |
| -
|
87 |
| - Returns: Standard output from mpy-cross as a string. |
88 |
| -
|
89 |
| - Required arguments: |
90 |
| - - src: The path to the .py file |
91 |
| -
|
92 |
| - Optional keyword arguments: |
93 |
| - - dest: The output .mpy file. Defaults to `src` (with .mpy extension) |
94 |
| - - src_path: The path to embed in the .mpy file (defaults to `src`) |
95 |
| - - opt: Optimisation level (0-3, default 0) |
96 |
| - - march: One of the `NATIVE_ARCH_*` constants (defaults to NATIVE_ARCH_NONE) |
97 |
| - - mpy_cross: Specific mpy-cross binary to use |
98 |
| - - extra_args: Additional arguments to pass to mpy-cross (e.g. `["-X", "emit=native"]`) |
99 |
| - """ |
100 |
| - if not src: |
101 |
| - raise ValueError("src is required") |
102 |
| - if not os.path.exists(src): |
103 |
| - raise CrossCompileError("Input .py file not found: {}.".format(src_py)) |
104 |
| - |
105 |
| - args = [] |
106 |
| - |
107 |
| - if src_path: |
108 |
| - args += ["-s", src_path] |
109 |
| - |
110 |
| - if dest: |
111 |
| - args += ["-o", dest] |
112 | 26 |
|
113 |
| - if march: |
114 |
| - args += ["-march=" + march] |
| 27 | +from .compiler import * |
115 | 28 |
|
116 |
| - if opt is not None: |
117 |
| - args += ["-O{}".format(opt)] |
118 | 29 |
|
119 |
| - if extra_args: |
120 |
| - args += extra_args |
| 30 | +def mpy_version(): |
| 31 | + return default_compiler().mpy_version() |
121 | 32 |
|
122 |
| - args += [src] |
123 | 33 |
|
124 |
| - run(args, mpy_cross) |
| 34 | +def version(): |
| 35 | + return default_compiler().version() |
125 | 36 |
|
126 | 37 |
|
127 |
| -def run(args, mpy_cross=None): |
128 |
| - """ |
129 |
| - Run mpy-cross with the specified command line arguments. |
130 |
| - Prefer to use `compile()` instead. |
| 38 | +def compile(*args, **kwargs): |
| 39 | + compiler_kwargs = {} |
131 | 40 |
|
132 |
| - Returns: Standard output from mpy-cross as a string. |
| 41 | + if "mpy_cross" in kwargs: |
| 42 | + compiler_kwargs.update(binary=kwargs["mpy_cross"]) |
| 43 | + del kwargs["mpy_cross"] |
133 | 44 |
|
134 |
| - Optional keyword arguments: |
135 |
| - - mpy_cross: Specific mpy-cross binary to use |
136 |
| - """ |
137 |
| - mpy_cross = _find_mpy_cross_binary(mpy_cross) |
| 45 | + if "extra_args" in kwargs: |
| 46 | + for arg in kwargs["extra_args"]: |
| 47 | + if arg.startswith("-march="): |
| 48 | + kwargs.update(march=arg[7:]) |
| 49 | + else: |
| 50 | + raise ValueError("Unknown mpy-cross arg: {}".format(arg)) |
| 51 | + del kwargs["extra_args"] |
138 | 52 |
|
139 |
| - if not os.path.exists(mpy_cross): |
140 |
| - raise CrossCompileError("mpy-cross binary not found at {}.".format(mpy_cross)) |
| 53 | + return default_compiler(**compiler_kwargs).compile(*args, **kwargs) |
141 | 54 |
|
142 |
| - try: |
143 |
| - st = os.stat(mpy_cross) |
144 |
| - os.chmod(mpy_cross, st.st_mode | stat.S_IEXEC) |
145 |
| - except OSError: |
146 |
| - pass |
147 | 55 |
|
148 |
| - try: |
149 |
| - return subprocess.check_output([mpy_cross] + args, stderr=subprocess.STDOUT).decode() |
150 |
| - except subprocess.CalledProcessError as er: |
151 |
| - raise CrossCompileError(er.output.decode()) |
| 56 | +def description(): |
| 57 | + return default_compiler().description() |
0 commit comments