Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow inline generation of compile_commands.json while doing a qmk compile, using --compiledb #21549

Merged
merged 2 commits into from
Sep 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions lib/python/qmk/cli/compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
from milc import cli

import qmk.path
from qmk.constants import QMK_FIRMWARE
from qmk.decorators import automagic_keyboard, automagic_keymap
from qmk.commands import compile_configurator_json, create_make_command, parse_configurator_json, build_environment
from qmk.keyboard import keyboard_completer, keyboard_folder
from qmk.keymap import keymap_completer, locate_keymap
from qmk.cli.generate.compilation_database import write_compilation_database


def _is_keymap_target(keyboard, keymap):
Expand All @@ -30,6 +32,7 @@ def _is_keymap_target(keyboard, keymap):
@cli.argument('-j', '--parallel', type=int, default=1, help="Set the number of parallel make jobs; 0 means unlimited.")
@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.")
@cli.argument('--compiledb', arg_only=True, action='store_true', help="Generates the clang compile_commands.json file during build. Implies --clean.")
@cli.subcommand('Compile a QMK Firmware.')
@automagic_keyboard
@automagic_keymap
Expand All @@ -46,6 +49,9 @@ def compile(cli):
# Determine the compile command
commands = []

current_keyboard = None
current_keymap = None

if cli.args.filename:
# If a configurator JSON was provided generate a keymap and compile it
user_keymap = parse_configurator_json(cli.args.filename)
Expand All @@ -62,11 +68,21 @@ def compile(cli):
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))

current_keyboard = cli.config.compile.keyboard
current_keymap = cli.config.compile.keymap

if not commands:
cli.log.error('You must supply a configurator export, both `--keyboard` and `--keymap`, or be in a directory for a keyboard or keymap.')
cli.print_help()
return False

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')

cli.log.info('Compiling keymap with {fg_cyan}%s', ' '.join(commands[-1]))
if not cli.args.dry_run:
cli.echo('\n')
Expand Down
63 changes: 32 additions & 31 deletions lib/python/qmk/cli/generate/compilation_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,33 +76,9 @@ def parse_make_n(f: Iterator[str]) -> List[Dict[str, str]]:
return records


@cli.argument('-kb', '--keyboard', type=keyboard_folder, completer=keyboard_completer, help='The keyboard\'s name')
@cli.argument('-km', '--keymap', completer=keymap_completer, help='The keymap\'s name')
@cli.subcommand('Create a compilation database.')
@automagic_keyboard
@automagic_keymap
def generate_compilation_database(cli: MILC) -> Union[bool, int]:
"""Creates a compilation database for the given keyboard build.

Does a make clean, then a make -n for this target and uses the dry-run output to create
a compilation database (compile_commands.json). This file can help some IDEs and
IDE-like editors work better. For more information about this:

https://clang.llvm.org/docs/JSONCompilationDatabase.html
"""
command = None
# check both config domains: the magic decorator fills in `generate_compilation_database` but the user is
# more likely to have set `compile` in their config file.
current_keyboard = cli.config.generate_compilation_database.keyboard or cli.config.user.keyboard
current_keymap = cli.config.generate_compilation_database.keymap or cli.config.user.keymap

if current_keyboard and current_keymap:
# Generate the make command for a specific keyboard/keymap.
command = create_make_command(current_keyboard, current_keymap, dry_run=True)
elif not current_keyboard:
cli.log.error('Could not determine keyboard!')
elif not current_keymap:
cli.log.error('Could not determine keymap!')
def write_compilation_database(keyboard: str, keymap: str, output_path: Path) -> bool:
# Generate the make command for a specific keyboard/keymap.
command = create_make_command(keyboard, keymap, dry_run=True)

if not command:
cli.log.error('You must supply both `--keyboard` and `--keymap`, or be in a directory for a keyboard or keymap.')
Expand All @@ -128,9 +104,34 @@ def generate_compilation_database(cli: MILC) -> Union[bool, int]:

cli.log.info("Found %s compile commands", len(db))

dbpath = QMK_FIRMWARE / 'compile_commands.json'

cli.log.info(f"Writing build database to {dbpath}")
dbpath.write_text(json.dumps(db, indent=4))
cli.log.info(f"Writing build database to {output_path}")
output_path.write_text(json.dumps(db, indent=4))

return True


@cli.argument('-kb', '--keyboard', type=keyboard_folder, completer=keyboard_completer, help='The keyboard\'s name')
@cli.argument('-km', '--keymap', completer=keymap_completer, help='The keymap\'s name')
@cli.subcommand('Create a compilation database.')
@automagic_keyboard
@automagic_keymap
def generate_compilation_database(cli: MILC) -> Union[bool, int]:
"""Creates a compilation database for the given keyboard build.

Does a make clean, then a make -n for this target and uses the dry-run output to create
a compilation database (compile_commands.json). This file can help some IDEs and
IDE-like editors work better. For more information about this:

https://clang.llvm.org/docs/JSONCompilationDatabase.html
"""
# check both config domains: the magic decorator fills in `generate_compilation_database` but the user is
# more likely to have set `compile` in their config file.
current_keyboard = cli.config.generate_compilation_database.keyboard or cli.config.user.keyboard
current_keymap = cli.config.generate_compilation_database.keymap or cli.config.user.keymap

if not current_keyboard:
cli.log.error('Could not determine keyboard!')
elif not current_keymap:
cli.log.error('Could not determine keymap!')

return write_compilation_database(current_keyboard, current_keymap, QMK_FIRMWARE / 'compile_commands.json')