2019-08-26 00:58:24 +06:00
""" Compile a QMK Firmware.
You can compile a keymap already in the repo or using a QMK Configurator export .
"""
2021-04-15 08:00:22 +06:00
from argcomplete . completers import FilesCompleter
2022-10-20 19:35:27 +06:00
2019-08-26 00:58:24 +06:00
from milc import cli
2021-02-08 03:02:51 +06:00
import qmk . path
2023-09-28 16:48:58 +06:00
from qmk . constants import QMK_FIRMWARE
2020-03-14 04:47:04 +06:00
from qmk . decorators import automagic_keyboard , automagic_keymap
2022-10-20 19:35:27 +06:00
from qmk . commands import compile_configurator_json , create_make_command , parse_configurator_json , build_environment
2023-09-22 08:12:20 +06:00
from qmk . keyboard import keyboard_completer , keyboard_folder_or_all , is_all_keyboards
2023-01-19 06:24:13 +06:00
from qmk . keymap import keymap_completer , locate_keymap
2023-09-28 16:48:58 +06:00
from qmk . cli . generate . compilation_database import write_compilation_database
2023-01-19 06:24:13 +06:00
def _is_keymap_target ( keyboard , keymap ) :
if keymap == ' all ' :
return True
if locate_keymap ( keyboard , keymap ) :
return True
return False
2019-08-26 00:58:24 +06:00
2021-04-15 08:00:22 +06:00
@cli.argument ( ' filename ' , nargs = ' ? ' , arg_only = True , type = qmk . path . FileType ( ' r ' ) , completer = FilesCompleter ( ' .json ' ) , help = ' The configurator export to compile ' )
2023-09-22 08:12:20 +06:00
@cli.argument ( ' -kb ' , ' --keyboard ' , type = keyboard_folder_or_all , completer = keyboard_completer , help = ' The keyboard to build a firmware for. Ignored when a configurator export is supplied. ' )
2021-04-15 08:00:22 +06:00
@cli.argument ( ' -km ' , ' --keymap ' , completer = keymap_completer , help = ' The keymap to build a firmware for. Ignored when a configurator export is supplied. ' )
2020-03-14 04:47:04 +06:00
@cli.argument ( ' -n ' , ' --dry-run ' , arg_only = True , action = ' store_true ' , help = " Don ' t actually build, just show the make command to be run. " )
2021-08-18 04:46:59 +06:00
@cli.argument ( ' -j ' , ' --parallel ' , type = int , default = 1 , help = " Set the number of parallel make jobs; 0 means unlimited. " )
2021-01-17 05:13:04 +06: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. " )
@cli.argument ( ' -c ' , ' --clean ' , arg_only = True , action = ' store_true ' , help = " Remove object files before compiling. " )
2023-09-28 16:48:58 +06:00
@cli.argument ( ' --compiledb ' , arg_only = True , action = ' store_true ' , help = " Generates the clang compile_commands.json file during build. Implies --clean. " )
2019-09-23 02:25:33 +06:00
@cli.subcommand ( ' Compile a QMK Firmware. ' )
2020-03-14 04:47:04 +06:00
@automagic_keyboard
@automagic_keymap
2019-09-23 02:25:33 +06:00
def compile ( cli ) :
2019-08-26 00:58:24 +06:00
""" Compile a QMK Firmware.
If a Configurator export is supplied this command will create a new keymap , overwriting an existing keymap if one exists .
2020-02-18 01:42:11 +06:00
If a keyboard and keymap are provided this command will build a firmware based on that .
2019-08-26 00:58:24 +06:00
"""
2023-09-22 08:12:20 +06:00
if is_all_keyboards ( cli . args . keyboard ) :
from . mass_compile import mass_compile
cli . args . builds = [ ]
cli . args . filter = [ ]
cli . args . no_temp = False
return mass_compile ( cli )
2021-01-17 05:13:04 +06:00
# Build the environment vars
2022-10-20 19:35:27 +06:00
envs = build_environment ( cli . args . env )
2021-01-17 05:13:04 +06:00
# Determine the compile command
2022-10-20 19:35:27 +06:00
commands = [ ]
2020-03-14 04:47:04 +06:00
2023-09-28 16:48:58 +06:00
current_keyboard = None
current_keymap = None
2019-08-26 00:58:24 +06:00
if cli . args . filename :
2020-03-14 04:47:04 +06:00
# If a configurator JSON was provided generate a keymap and compile it
2019-10-05 12:38:34 +06:00
user_keymap = parse_configurator_json ( cli . args . filename )
2022-10-20 19:35:27 +06:00
commands = [ compile_configurator_json ( user_keymap , parallel = cli . config . compile . parallel , clean = cli . args . clean , * * envs ) ]
2019-10-05 12:38:34 +06:00
2022-10-20 19:35:27 +06:00
elif cli . config . compile . keyboard and cli . config . compile . keymap :
# Generate the make command for a specific keyboard/keymap.
2023-01-19 06:24:13 +06:00
if not _is_keymap_target ( cli . config . compile . keyboard , cli . config . compile . keymap ) :
cli . log . error ( ' Invalid keymap argument. ' )
cli . print_help ( )
return False
2022-10-20 19:35:27 +06:00
if cli . args . clean :
commands . append ( create_make_command ( cli . config . compile . keyboard , cli . config . compile . keymap , ' clean ' , * * envs ) )
commands . append ( create_make_command ( cli . config . compile . keyboard , cli . config . compile . keymap , parallel = cli . config . compile . parallel , * * envs ) )
2020-03-14 04:47:04 +06:00
2023-09-28 16:48:58 +06:00
current_keyboard = cli . config . compile . keyboard
current_keymap = cli . config . compile . keymap
2022-10-20 19:35:27 +06:00
if not commands :
2020-03-14 04:47:04 +06:00
cli . log . error ( ' You must supply a configurator export, both `--keyboard` and `--keymap`, or be in a directory for a keyboard or keymap. ' )
2022-10-20 19:35:27 +06:00
cli . print_help ( )
2020-03-14 04:47:04 +06:00
return False
2022-10-20 19:35:27 +06:00
2023-09-28 16:48:58 +06:00
if cli . args . compiledb :
if current_keyboard is None or current_keymap is None :
cli . log . error ( ' You must supply both `--keyboard` and `--keymap` or be in a directory with a keymap to generate a compile_commands.json file. ' )
cli . print_help ( )
return False
write_compilation_database ( current_keyboard , current_keymap , QMK_FIRMWARE / ' compile_commands.json ' )
2022-10-20 19:35:27 +06:00
cli . log . info ( ' Compiling keymap with {fg_cyan} %s ' , ' ' . join ( commands [ - 1 ] ) )
if not cli . args . dry_run :
cli . echo ( ' \n ' )
for command in commands :
ret = cli . run ( command , capture_output = False )
if ret . returncode :
return ret . returncode