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

new qmk subcommand for creating compile_commands.json for better clangd/IDE interop #10264

Closed
wants to merge 37 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
47365ae
pulled source from dev branch
Apr 25, 2020
e0bff4d
missed a file from origin
Apr 25, 2020
5a51eaa
formatting
Apr 25, 2020
d817b7d
revised argument names. relaxed matching rules to work for avr too
Apr 25, 2020
30b564f
add docstrings
Apr 25, 2020
849a12f
added docs. tightened up regex
Apr 25, 2020
b671c40
remove unused imports
Apr 25, 2020
f42cadc
cleaning up command file. use existing qmk dir constant
May 9, 2020
e768fac
rename parser library file
May 9, 2020
21c5b63
move lib functions into command file. there are only 2 and they aren'…
May 9, 2020
3fe7817
currently debugging...
May 9, 2020
ec3739b
more robustly find config
May 9, 2020
bf2aef2
updated docs
May 9, 2020
10171f8
remove unused imports
May 9, 2020
697ca67
reuse make executable from the main make command
May 19, 2020
82a8be3
pulled source from dev branch
Apr 25, 2020
3a95195
missed a file from origin
Apr 25, 2020
3ed55aa
formatting
Apr 25, 2020
c9a4d97
revised argument names. relaxed matching rules to work for avr too
Apr 25, 2020
9226ba5
add docstrings
Apr 25, 2020
764f35d
added docs. tightened up regex
Apr 25, 2020
b0a5e1a
remove unused imports
Apr 25, 2020
67c08c6
cleaning up command file. use existing qmk dir constant
May 9, 2020
c0fc66e
rename parser library file
May 9, 2020
2f103f5
move lib functions into command file. there are only 2 and they aren'…
May 9, 2020
c03da56
currently debugging...
May 9, 2020
8db4e13
more robustly find config
May 9, 2020
67ae7d8
updated docs
May 9, 2020
976b0b1
remove unused imports
May 9, 2020
7ab3465
reuse make executable from the main make command
May 19, 2020
16c47fd
Merge branch 'compile_commands' of https://github.com/xton/qmk_firmwa…
Aug 24, 2020
70dfd86
Merge branch 'master' into compile_commands
Sep 7, 2020
c558c5d
remove MAKEFLAGS from environment for better control over process man…
Sep 7, 2020
afb2527
Update .gitignore
xton Sep 27, 2020
f64f64a
add a usage line to docs
Oct 11, 2020
3830823
Merge branch 'compile_commands' of https://github.com/xton/qmk_firmwa…
Oct 11, 2020
6cbcc9c
doc change as suggested
xton Nov 30, 2020
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
Prev Previous commit
Next Next commit
cleaning up command file. use existing qmk dir constant
  • Loading branch information
Xton committed May 9, 2020
commit f42cadc361f02faf13ed954eb83b9a987d29578a
39 changes: 6 additions & 33 deletions lib/python/qmk/cli/compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,12 @@
import qmk.path
from qmk.decorators import automagic_keyboard, automagic_keymap
from qmk.commands import compile_configurator_json, create_make_command, parse_configurator_json
from qmk.compile_commands_json import parse_make_n, qmk_dir
import json


@cli.argument('filename', nargs='?', arg_only=True, type=FileType('r'), help='The configurator export to compile')
@cli.argument('-kb', '--keyboard', help='The keyboard to build a firmware for. Ignored when a configurator export is supplied.')
@cli.argument('-km', '--keymap', help='The keymap to build a firmware for. Ignored when a configurator export is supplied.')
@cli.argument('-n', '--dry-run', arg_only=True, action='store_true', help="Don't actually build, just show the make command to be run.")
@cli.argument('-c', '--compile-commands', arg_only=True, action='store_true',
help="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")
@cli.subcommand('Compile a QMK Firmware.')
@automagic_keyboard
@automagic_keymap
Expand All @@ -47,39 +40,19 @@ def compile(cli):
else:
if cli.config.compile.keyboard and cli.config.compile.keymap:
# Generate the make command for a specific keyboard/keymap.
dry_run = cli.args.compile_commands
command = create_make_command(cli.config.compile.keyboard, cli.config.compile.keymap, dry_run=dry_run)
command = create_make_command(cli.config.compile.keyboard, cli.config.compile.keymap)

elif not cli.config.compile.keyboard:
cli.log.error('Could not determine keyboard!')
elif not cli.config.compile.keymap:
cli.log.error('Could not determine keymap!')

# Compile the firmware, if we're able to
if command:
if cli.args.compile_commands:
cli.log.info('Making clean')
subprocess.run(['make', 'clean'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

cli.log.info('Gathering build instructions')
proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
db = parse_make_n(proc.stdout)
res = proc.wait()
if res != 0:
raise RuntimeError(f"Got error from: {repr(command)}")

cli.log.info(f"Found {len(db)} compile commands")

dbpath = qmk_dir / 'compile_commands.json'

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

else:
# Compile the firmware, if we're able to
cli.log.info('Compiling keymap with {fg_cyan}%s', ' '.join(command))
if not cli.args.dry_run:
cli.echo('\n')
subprocess.run(command)
cli.log.info('Compiling keymap with {fg_cyan}%s', ' '.join(command))
if not cli.args.dry_run:
cli.echo('\n')
subprocess.run(command)

else:
cli.log.error('You must supply a configurator export, both `--keyboard` and `--keymap`, or be in a directory for a keyboard or keymap.')
Expand Down
61 changes: 61 additions & 0 deletions lib/python/qmk/cli/compiledb.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
"""Creates a compilation database for the given keyboard build.
"""
import subprocess
from argparse import FileType

from milc import cli

from qmk.decorators import automagic_keyboard, automagic_keymap
from qmk.commands import create_make_command
from qmk.compile_commands_json import parse_make_n
from qmk.constants import QMK_FIRMWARE
import json


@cli.argument('-kb', '--keyboard', help='The keyboard to build a firmware for. Ignored when a configurator export is supplied.')
@cli.argument('-km', '--keymap', help='The keymap to build a firmware for. Ignored when a configurator export is supplied.')
@cli.subcommand('Create a compilation database.')
@automagic_keyboard
@automagic_keymap
def compile(cli):
"""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

if cli.config.compile.keyboard and cli.config.compile.keymap:
# Generate the make command for a specific keyboard/keymap.
command = create_make_command(cli.config.compile.keyboard, cli.config.compile.keymap, dry_run=True)

elif not cli.config.compile.keyboard:
cli.log.error('Could not determine keyboard!')
elif not cli.config.compile.keymap:
cli.log.error('Could not determine keymap!')

if command:
cli.log.info('Making clean')
subprocess.run(['make', 'clean'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

cli.log.info('Gathering build instructions')
proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
db = parse_make_n(proc.stdout)
res = proc.wait()
if res != 0:
raise RuntimeError(f"Got error from: {repr(command)}")

cli.log.info(f"Found {len(db)} compile commands")

dbpath = QMK_FIRMWARE / 'compile_commands.json'

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

else:
cli.log.error('You must supply both `--keyboard` and `--keymap`, or be in a directory for a keyboard or keymap.')
cli.echo('usage: qmk compiledb [-kb KEYBOARD] [-km KEYMAP]')
return False
5 changes: 2 additions & 3 deletions lib/python/qmk/compile_commands_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@
from functools import lru_cache
from subprocess import check_output

from qmk.constants import QMK_FIRMWARE

from typing import TextIO, List, Dict

qmk_dir = Path(__file__).parent.parent.parent.parent


@lru_cache(maxsize=10)
def system_libs(binary: str):
Expand Down Expand Up @@ -56,7 +55,7 @@ def parse_make_n(f: TextIO) -> List[Dict[str, str]]:
args = shlex.split(this_cmd)
args += ['-I%s' % s for s in system_libs(args[0])]
new_cmd = ' '.join(shlex.quote(s) for s in args if s != '-mno-thumb-interwork')
records.append({"directory": str(qmk_dir), "command": new_cmd, "file": this_file})
records.append({"directory": str(QMK_FIRMWARE.resolve()), "command": new_cmd, "file": this_file})
state = 'start'

return records
Expand Down