2021-05-10 01:06:44 +10:00
"""Compile all keyboards.
This will compile everything in parallel, for testing purposes.
"""
2021-06-09 17:25:21 +10:00
import os
2021-05-10 01:06:44 +10:00
import re
from pathlib import Path
2021-05-19 15:24:46 -07:00
from subprocess import DEVNULL
2021-05-10 01:06:44 +10:00
from milc import cli
from qmk.constants import QMK_FIRMWARE
2021-08-18 01:46:59 +03:00
from qmk.commands import _find_make , get_make_parallel_args
2021-05-10 01:06:44 +10:00
import qmk.keyboard
2021-06-09 17:25:21 +10:00
import qmk.keymap
2021-05-10 01:06:44 +10:00
def _make_rules_mk_filter ( key , value ):
def _rules_mk_filter ( keyboard_name ):
rules_mk = qmk . keyboard . rules_mk ( keyboard_name )
return True if key in rules_mk and rules_mk [ key ] . lower () == str ( value ) . lower () else False
2021-05-10 03:15:00 +10:00
2021-05-10 01:06:44 +10:00
return _rules_mk_filter
def _is_split ( keyboard_name ):
rules_mk = qmk . keyboard . rules_mk ( keyboard_name )
return True if 'SPLIT_KEYBOARD' in rules_mk and rules_mk [ 'SPLIT_KEYBOARD' ] . lower () == 'yes' else False
2021-08-18 01:46:59 +03:00
@cli.argument ( '-j' , '--parallel' , type = int , default = 1 , help = "Set the number of parallel make jobs; 0 means unlimited." )
2021-05-10 01:06:44 +10:00
@cli.argument ( '-c' , '--clean' , arg_only = True , action = 'store_true' , help = "Remove object files before compiling." )
@cli.argument ( '-f' , '--filter' , arg_only = True , action = 'append' , default = [], help = "Filter the list of keyboards based on the supplied value in rules.mk. Supported format is 'SPLIT_KEYBOARD=yes'. May be passed multiple times." )
2021-06-09 17:25:21 +10:00
@cli.argument ( '-km' , '--keymap' , type = str , default = 'default' , help = "The keymap name to build. Default is 'default'." )
2022-02-02 15:30:22 +11:00
@cli.argument ( '-e' , '--env' , arg_only = True , action = 'append' , default = [], help = "Set a variable to be passed to make. May be passed multiple times." )
2021-05-10 01:06:44 +10:00
@cli.subcommand ( 'Compile QMK Firmware for all keyboards.' , hidden = False if cli . config . user . developer else True )
def multibuild ( cli ):
"""Compile QMK Firmware against all keyboards.
"""
make_cmd = _find_make ()
if cli . args . clean :
2021-05-19 15:24:46 -07:00
cli . run ([ make_cmd , 'clean' ], capture_output = False , stdin = DEVNULL )
2021-05-10 01:06:44 +10:00
builddir = Path ( QMK_FIRMWARE ) / '.build'
makefile = builddir / 'parallel_kb_builds.mk'
keyboard_list = qmk . keyboard . list_keyboards ()
filter_re = re . compile ( r '^(?P<key>[A-Z0-9_]+)\s*=\s*(?P<value>[^#]+)$' )
for filter_txt in cli . args . filter :
f = filter_re . match ( filter_txt )
if f is not None :
keyboard_list = filter ( _make_rules_mk_filter ( f . group ( 'key' ), f . group ( 'value' )), keyboard_list )
keyboard_list = list ( sorted ( keyboard_list ))
if len ( keyboard_list ) == 0 :
return
builddir . mkdir ( parents = True , exist_ok = True )
with open ( makefile , "w" ) as f :
for keyboard_name in keyboard_list :
2021-06-09 17:25:21 +10:00
if qmk . keymap . locate_keymap ( keyboard_name , cli . args . keymap ) is not None :
keyboard_safe = keyboard_name . replace ( '/' , '_' )
# yapf: disable
f . write (
f """ \
2021-05-10 01:06:44 +10:00
all: { keyboard_safe } _binary
{ keyboard_safe } _binary:
@rm -f " { QMK_FIRMWARE } /.build/failed.log. { keyboard_safe } " || true
2022-02-10 17:45:51 +00:00
+@$(MAKE) -C " { QMK_FIRMWARE } " -f " { QMK_FIRMWARE } /builddefs/build_keyboard.mk" KEYBOARD=" { keyboard_name } " KEYMAP=" { cli . args . keymap } " REQUIRE_PLATFORM_KEY= COLOR=true SILENT=false { ' ' . join ( cli . args . env ) } \\
2021-06-09 17:25:21 +10:00
>>" { QMK_FIRMWARE } /.build/build.log. { os . getpid () } . { keyboard_safe } " 2>&1 \\
|| cp " { QMK_FIRMWARE } /.build/build.log. { os . getpid () } . { keyboard_safe } " " { QMK_FIRMWARE } /.build/failed.log. { os . getpid () } . { keyboard_safe } "
@ {{ grep '\[ERRORS\]' " { QMK_FIRMWARE } /.build/build.log. { os . getpid () } . { keyboard_safe } " >/dev/null 2>&1 && printf "Build %-64s \e[1;31m[ERRORS]\e[0m \\ n" " { keyboard_name } : { cli . args . keymap } " ; }} \\
|| {{ grep '\[WARNINGS\]' " { QMK_FIRMWARE } /.build/build.log. { os . getpid () } . { keyboard_safe } " >/dev/null 2>&1 && printf "Build %-64s \e[1;33m[WARNINGS]\e[0m \\ n" " { keyboard_name } : { cli . args . keymap } " ; }} \\
|| printf "Build %-64s \e[1;32m[OK]\e[0m \\ n" " { keyboard_name } : { cli . args . keymap } "
@rm -f " { QMK_FIRMWARE } /.build/build.log. { os . getpid () } . { keyboard_safe } " || true
2021-05-10 01:06:44 +10:00
2021-05-09 11:30:17 -07:00
""" # noqa
2021-06-09 17:25:21 +10:00
)
# yapf: enable
2021-05-10 01:06:44 +10:00
2021-08-18 01:46:59 +03:00
cli . run ([ make_cmd , * get_make_parallel_args ( cli . args . parallel ), '-f' , makefile . as_posix (), 'all' ], capture_output = False , stdin = DEVNULL )
2021-06-09 17:25:21 +10:00
# Check for failures
failures = [ f for f in builddir . glob ( f 'failed.log. { os . getpid () } .*' )]
if len ( failures ) > 0 :
return False