commands.py 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. """This script sets up the QMK-provided toolchains.
  2. """
  3. import platform
  4. import shutil
  5. import subprocess
  6. import os
  7. from milc import cli
  8. from pathlib import Path
  9. from qmk.constants import QMK_TOOLCHAINS_PATH, QMK_TOOLCHAINS_TAG
  10. from qmk.util import download_with_progress, cached_get
  11. def _os_prefix():
  12. os = platform.system().lower()
  13. if "linux" in os:
  14. return "linux"
  15. elif "darwin" in os or "mac" in os or "macos" in os or "osx" in os or "macosx" in os:
  16. return "macos"
  17. elif "windows" in os or "cygwin" in os or "msys" in os or "win32" in os or "win64" in os or "nt" in os:
  18. return "windows"
  19. return "unknown"
  20. def _arch_suffix():
  21. arch = platform.machine().lower()
  22. if "amd64" in arch or "x86_64" in arch or "x64" in arch or "x86-64" in arch:
  23. return "X64"
  24. elif "arm64" in arch or "aarch64" in arch:
  25. return "ARM64"
  26. return "unknown"
  27. def _os_arch():
  28. return f'{_os_prefix()}{_arch_suffix()}'
  29. def _gcc_version_str(gcc_exe):
  30. lines = cli.run([gcc_exe, '-v'], check=True, capture_output=True, combined_output=True, stdin=subprocess.DEVNULL).stdout.strip().splitlines()
  31. return list(filter(lambda x: x.startswith('gcc version'), lines))[0].strip()
  32. @cli.argument('-t', '--tag', default=QMK_TOOLCHAINS_TAG, help=f'The tag of the QMK-provided toolchains to download. Defaults to `{QMK_TOOLCHAINS_TAG}`.')
  33. @cli.subcommand('Set up the QMK-provided toolchains.', hidden=False if cli.config.user.developer else True)
  34. def toolchain_setup(cli):
  35. """Set up the QMK-provided toolchains.
  36. """
  37. # Remove the toolchains directory if it exists already
  38. if QMK_TOOLCHAINS_PATH.exists():
  39. cli.log.info(f'Removing existing toolchains at `{QMK_TOOLCHAINS_PATH}`...')
  40. shutil.rmtree(QMK_TOOLCHAINS_PATH)
  41. url = f'https://api.github.com/repos/qmk/qmk_toolchains/releases/tags/{cli.args.tag}'
  42. payload = cached_get(url)
  43. if payload.status_code != 200:
  44. cli.log.error(f'Failed to fetch toolchain metadata from `{url}`.')
  45. return
  46. downloadables = filter(lambda x: _os_arch() in x['name'], payload.json()['assets'])
  47. for downloadable in downloadables:
  48. if not Path(downloadable["name"]).exists():
  49. download_with_progress(downloadable['browser_download_url'], downloadable["name"])
  50. cli.log.info(f'Extracting `{downloadable["name"]}` to `{QMK_TOOLCHAINS_PATH}`...')
  51. QMK_TOOLCHAINS_PATH.mkdir(parents=True, exist_ok=True)
  52. cli.run(['tar', 'xf', downloadable["name"], '-C', QMK_TOOLCHAINS_PATH, '--strip-components=1'], capture_output=False, check=True, stdin=subprocess.DEVNULL)
  53. os.environ['PATH'] = f'{QMK_TOOLCHAINS_PATH}/bin{os.pathsep}{os.environ["PATH"]}'
  54. for gcc_exe in ['avr-gcc', 'arm-none-eabi-gcc', 'riscv32-unknown-elf-gcc']:
  55. cli.log.info(f'{gcc_exe:24s}: {_gcc_version_str(gcc_exe)}')