Skip to content

Commit d7e66be

Browse files
authored
Merge pull request #119 from jepler/circuitpython-mpy-cross-command
Add circuitpython-mpy-cross command
2 parents 1f3c5bd + 9524f77 commit d7e66be

File tree

6 files changed

+80
-33
lines changed

6 files changed

+80
-33
lines changed

circuitpython_build_tools/build.py

Lines changed: 45 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,37 @@
2424
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2525
# THE SOFTWARE.
2626

27+
import functools
28+
import multiprocessing
2729
import os
2830
import os.path
2931
import platform
3032
import pathlib
33+
import re
3134
import requests
3235
import semver
3336
import shutil
3437
import stat
3538
import sys
3639
import subprocess
3740
import tempfile
41+
import platformdirs
42+
43+
@functools.cache
44+
def _git_version():
45+
version_str = subprocess.check_output(["git", "--version"], encoding="ascii", errors="replace")
46+
version_str = re.search("([0-9]\.*)*[0-9]", version_str).group(0)
47+
return tuple(int(part) for part in version_str.split("."))
48+
49+
def git_filter_arg():
50+
clone_supports_filter = (
51+
False if "NO_USE_CLONE_FILTER" in os.environ else _git_version() >= (2, 36, 0)
52+
)
53+
54+
if clone_supports_filter:
55+
return ["--filter=blob:none"]
56+
else:
57+
return []
3858

3959
# pyproject.toml `py_modules` values that are incorrect. These should all have PRs filed!
4060
# and should be removed when the fixed version is incorporated in its respective bundle.
@@ -60,6 +80,8 @@
6080
else:
6181
from tomli import loads as load_toml
6282

83+
mpy_cross_path = platformdirs.user_cache_path("circuitpython-build-tools", ensure_exists=True)
84+
6385
def load_pyproject_toml(lib_path: pathlib.Path):
6486
try:
6587
return load_toml((lib_path / "pyproject.toml") .read_text(encoding="utf-8"))
@@ -106,9 +128,14 @@ def version_string(path=None, *, valid_semver=False):
106128
version = commitish
107129
return version
108130

109-
def mpy_cross(mpy_cross_filename, circuitpython_tag, quiet=False):
131+
def mpy_cross(version, quiet=False):
132+
circuitpython_tag = version["tag"]
133+
name = version["name"]
134+
ext = ".exe" * (os.name == "nt")
135+
mpy_cross_filename = mpy_cross_path / f"mpy-cross-{name}{ext}"
136+
110137
if os.path.isfile(mpy_cross_filename):
111-
return
138+
return mpy_cross_filename
112139

113140
# Try to pull from S3
114141
uname = platform.uname()
@@ -136,7 +163,7 @@ def mpy_cross(mpy_cross_filename, circuitpython_tag, quiet=False):
136163
os.chmod(mpy_cross_filename, os.stat(mpy_cross_filename)[0] | stat.S_IXUSR)
137164
if not quiet:
138165
print(" FOUND")
139-
return
166+
return mpy_cross_filename
140167
except Exception as e:
141168
if not quiet:
142169
print(f" exception fetching from S3: {e}")
@@ -149,26 +176,21 @@ def mpy_cross(mpy_cross_filename, circuitpython_tag, quiet=False):
149176
print(title)
150177
print("=" * len(title))
151178

152-
os.makedirs("build_deps/", exist_ok=True)
153-
if not os.path.isdir("build_deps/circuitpython"):
154-
clone = subprocess.run("git clone https://github.com/adafruit/circuitpython.git build_deps/circuitpython", shell=True)
155-
if clone.returncode != 0:
156-
sys.exit(clone.returncode)
157-
158-
current_dir = os.getcwd()
159-
os.chdir("build_deps/circuitpython")
160-
make = subprocess.run("git fetch && git checkout {TAG} && git submodule update".format(TAG=circuitpython_tag), shell=True)
161-
os.chdir("tools")
162-
make = subprocess.run("git submodule update --init .", shell=True)
163-
os.chdir("../mpy-cross")
164-
make = subprocess.run("make clean && make", shell=True)
165-
os.chdir(current_dir)
166-
167-
if make.returncode != 0:
168-
print("Failed to build mpy-cross from source... bailing out")
169-
sys.exit(make.returncode)
170-
171-
shutil.copy("build_deps/circuitpython/mpy-cross/mpy-cross", mpy_cross_filename)
179+
build_dir = mpy_cross_path / f"build-circuitpython-{circuitpython_tag}"
180+
if not os.path.isdir(build_dir):
181+
subprocess.check_call(["git", "clone", *git_filter_arg(), "-b", circuitpython_tag, "https://github.com/adafruit/circuitpython.git", build_dir])
182+
183+
subprocess.check_call(["git", "submodule", "update", "--recursive"], cwd=build_dir)
184+
subprocess.check_call([sys.executable, "tools/ci_fetch_deps.py", "mpy-cross"], cwd=build_dir)
185+
subprocess.check_call(["make", "clean"], cwd=build_dir / "mpy-cross")
186+
subprocess.check_call(["make", f"-j{multiprocessing.cpu_count()}"], cwd=build_dir / "mpy-cross")
187+
188+
mpy_built = build_dir / f"mpy-cross/build/mpy-cross{ext}"
189+
if not os.path.exists(mpy_built):
190+
mpy_built = build_dir / f"mpy-cross/mpy-cross{ext}"
191+
192+
shutil.copy(mpy_built, mpy_cross_filename)
193+
return mpy_cross_filename
172194

173195
def _munge_to_temp(original_path, temp_file, library_version):
174196
with open(original_path, "r", encoding="utf-8") as original_file:

circuitpython_build_tools/scripts/build_bundles.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
else:
4242
import importlib.metadata as importlib_metadata
4343

44-
4544
BLINKA_LIBRARIES = [
4645
"adafruit-blinka",
4746
"adafruit-blinka-bleio",
@@ -280,10 +279,8 @@ def build_bundles(filename_prefix, output_directory, library_location, library_d
280279

281280
# Build .mpy bundle(s)
282281
if "mpy" not in ignore:
283-
os.makedirs("build_deps", exist_ok=True)
284282
for version in target_versions.VERSIONS:
285-
mpy_cross = "build_deps/mpy-cross-" + version["name"] + (".exe" * (os.name == "nt"))
286-
build.mpy_cross(mpy_cross, version["tag"])
283+
mpy_cross = build.mpy_cross(version)
287284
zip_filename = os.path.join(output_directory,
288285
filename_prefix + '-{TAG}-mpy-{VERSION}.zip'.format(
289286
TAG=version["name"],

circuitpython_build_tools/scripts/build_mpy_cross.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,14 @@
2828
import os
2929
import sys
3030

31+
import click
32+
33+
@click.command
34+
@click.argument("versions")
35+
def main(versions):
36+
print(versions)
37+
for version in [v for v in target_versions.VERSIONS if v['name'] in versions]:
38+
print(f"{version['name']}: {build.mpy_cross(version)}")
39+
3140
if __name__ == "__main__":
32-
output_directory = sys.argv[1]
33-
os.makedirs(output_directory, exist_ok=True)
34-
for version in target_versions.VERSIONS:
35-
mpy_cross = output_directory + "/mpy-cross-" + version["name"]
36-
build.mpy_cross(mpy_cross, version["tag"])
41+
main()
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import subprocess
2+
3+
import click
4+
5+
from ..target_versions import VERSIONS
6+
from ..build import mpy_cross
7+
8+
@click.command(context_settings={"ignore_unknown_options": True})
9+
@click.option("--circuitpython-version", type=click.Choice([version["name"] for version in VERSIONS]))
10+
@click.option("--quiet/--no-quiet", "quiet", type=bool, default=True)
11+
@click.argument("mpy-cross-args", nargs=-1, required=True)
12+
def main(circuitpython_version, quiet, mpy_cross_args):
13+
version_info, = [v for v in VERSIONS if v["name"] == circuitpython_version]
14+
mpy_cross_exe = str(mpy_cross(version_info, quiet))
15+
try:
16+
subprocess.check_call([mpy_cross_exe, *mpy_cross_args])
17+
except subprocess.CalledProcessError as e:
18+
raise SystemExit(e.returncode)
19+
20+
if __name__ == '__main__':
21+
main()

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ requests
33
semver
44
wheel
55
tomli; python_version < "3.11"
6+
platformdirs

setup.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@
1414
package_data={'circuitpython_build_tools': ['data/mpy-cross-*']},
1515
zip_safe=False,
1616
python_requires='>=3.10',
17-
install_requires=['Click', 'requests', 'semver', 'tomli; python_version < "3.11"'],
17+
install_requires=['Click', 'requests', 'semver', 'tomli; python_version < "3.11"', 'platformdirs'],
1818
entry_points='''
1919
[console_scripts]
2020
circuitpython-build-bundles=circuitpython_build_tools.scripts.build_bundles:build_bundles
21+
circuitpython-mpy-cross=circuitpython_build_tools.scripts.circuitpython_mpy_cross:main
2122
'''
2223
)

0 commit comments

Comments
 (0)