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

Optimise LAYOUT macro generation #18262

Merged
merged 1 commit into from
Sep 19, 2022
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
24 changes: 9 additions & 15 deletions builddefs/build_keyboard.mk
Original file line number Diff line number Diff line change
Expand Up @@ -241,21 +241,20 @@ endif
#
# https://docs.qmk.fm/#/feature_layouts?id=tips-for-making-layouts-keyboard-agnostic
#
QMK_KEYBOARD_H = $(KEYBOARD_OUTPUT)/src/default_keyboard.h
ifneq ("$(wildcard $(KEYBOARD_PATH_1)/$(KEYBOARD_FOLDER_1).h)","")
QMK_KEYBOARD_H = $(KEYBOARD_FOLDER_1).h
FOUND_KEYBOARD_H = $(KEYBOARD_FOLDER_1).h
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_2)/$(KEYBOARD_FOLDER_2).h)","")
QMK_KEYBOARD_H = $(KEYBOARD_FOLDER_2).h
FOUND_KEYBOARD_H = $(KEYBOARD_FOLDER_2).h
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_3)/$(KEYBOARD_FOLDER_3).h)","")
QMK_KEYBOARD_H = $(KEYBOARD_FOLDER_3).h
FOUND_KEYBOARD_H = $(KEYBOARD_FOLDER_3).h
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_4)/$(KEYBOARD_FOLDER_4).h)","")
QMK_KEYBOARD_H = $(KEYBOARD_FOLDER_4).h
FOUND_KEYBOARD_H = $(KEYBOARD_FOLDER_4).h
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_5)/$(KEYBOARD_FOLDER_5).h)","")
QMK_KEYBOARD_H = $(KEYBOARD_FOLDER_5).h
FOUND_KEYBOARD_H = $(KEYBOARD_FOLDER_5).h
endif

# Determine and set parameters based on the keyboard's processor family.
Expand Down Expand Up @@ -329,7 +328,7 @@ ifneq ("$(wildcard $(KEYBOARD_PATH_5)/info.json)","")
INFO_JSON_FILES += $(KEYBOARD_PATH_5)/info.json
endif

CONFIG_H += $(KEYBOARD_OUTPUT)/src/info_config.h $(KEYBOARD_OUTPUT)/src/layouts.h
CONFIG_H += $(KEYBOARD_OUTPUT)/src/info_config.h
KEYBOARD_SRC += $(KEYBOARD_OUTPUT)/src/default_keyboard.c

$(KEYBOARD_OUTPUT)/src/info_config.h: $(INFO_JSON_FILES)
Expand All @@ -344,15 +343,10 @@ $(KEYBOARD_OUTPUT)/src/default_keyboard.c: $(INFO_JSON_FILES)

$(KEYBOARD_OUTPUT)/src/default_keyboard.h: $(INFO_JSON_FILES)
@$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD)
$(eval CMD=$(QMK_BIN) generate-keyboard-h --quiet --keyboard $(KEYBOARD) --output $(KEYBOARD_OUTPUT)/src/default_keyboard.h)
$(eval CMD=$(QMK_BIN) generate-keyboard-h --quiet --keyboard $(KEYBOARD) --include $(FOUND_KEYBOARD_H) --output $(KEYBOARD_OUTPUT)/src/default_keyboard.h)
@$(BUILD_CMD)

$(KEYBOARD_OUTPUT)/src/layouts.h: $(INFO_JSON_FILES)
@$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD)
$(eval CMD=$(QMK_BIN) generate-layouts --quiet --keyboard $(KEYBOARD) --output $(KEYBOARD_OUTPUT)/src/layouts.h)
@$(BUILD_CMD)

generated-files: $(KEYBOARD_OUTPUT)/src/info_config.h $(KEYBOARD_OUTPUT)/src/default_keyboard.c $(KEYBOARD_OUTPUT)/src/default_keyboard.h $(KEYBOARD_OUTPUT)/src/layouts.h
generated-files: $(KEYBOARD_OUTPUT)/src/info_config.h $(KEYBOARD_OUTPUT)/src/default_keyboard.c $(KEYBOARD_OUTPUT)/src/default_keyboard.h

.INTERMEDIATE : generated-files

Expand Down Expand Up @@ -471,7 +465,7 @@ ALL_CONFIGS := $(PROJECT_CONFIG) $(CONFIG_H)
OUTPUTS := $(KEYMAP_OUTPUT) $(KEYBOARD_OUTPUT)
$(KEYMAP_OUTPUT)_SRC := $(SRC)
$(KEYMAP_OUTPUT)_DEFS := $(OPT_DEFS) \
-DQMK_KEYBOARD=\"$(KEYBOARD)\" -DQMK_KEYBOARD_H=\"$(QMK_KEYBOARD_H)\" \
-DQMK_KEYBOARD=\"$(KEYBOARD)\" -DQMK_KEYBOARD_H=\"$(KEYBOARD_OUTPUT)/src/default_keyboard.h\" \
-DQMK_KEYMAP=\"$(KEYMAP)\" -DQMK_KEYMAP_H=\"$(KEYMAP).h\" -DQMK_KEYMAP_CONFIG_H=\"$(KEYMAP_PATH)/config.h\"
$(KEYMAP_OUTPUT)_INC := $(VPATH) $(EXTRAINCDIRS)
$(KEYMAP_OUTPUT)_CONFIG := $(CONFIG_H)
Expand Down
1 change: 0 additions & 1 deletion keyboards/ktec/ergodone/ergodone.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#pragma once

#include "quantum.h"
#include "layouts.h" // Ensure access to info.json layouts

// This file only exists to pull in....
#include "ergodox_compat.h"
1 change: 0 additions & 1 deletion lib/python/qmk/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@
'qmk.cli.generate.info_json',
'qmk.cli.generate.keyboard_c',
'qmk.cli.generate.keyboard_h',
'qmk.cli.generate.layouts',
'qmk.cli.generate.rgb_breathe_table',
'qmk.cli.generate.rules_mk',
'qmk.cli.generate.version_h',
Expand Down
69 changes: 59 additions & 10 deletions lib/python/qmk/cli/generate/keyboard_h.py
Original file line number Diff line number Diff line change
@@ -1,47 +1,96 @@
"""Used by the make system to generate keyboard.h from info.json.
"""
from pathlib import Path

from milc import cli

from qmk.path import normpath
from qmk.info import info_json
from qmk.commands import dump_lines
from qmk.keyboard import keyboard_completer, keyboard_folder
from qmk.path import normpath
from qmk.constants import GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE
from qmk.constants import COL_LETTERS, ROW_LETTERS, GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE


def would_populate_layout_h(keyboard):
"""Detect if a given keyboard is doing data driven layouts
def _generate_layouts(keyboard):
"""Generates the layouts.h file.
"""
# Build the info.json file
kb_info_json = info_json(keyboard)

if 'matrix_size' not in kb_info_json:
cli.log.error(f'{keyboard}: Invalid matrix config.')
return []

col_num = kb_info_json['matrix_size']['cols']
row_num = kb_info_json['matrix_size']['rows']

lines = []
for layout_name in kb_info_json['layouts']:
if kb_info_json['layouts'][layout_name]['c_macro']:
continue

if 'matrix' not in kb_info_json['layouts'][layout_name]['layout'][0]:
cli.log.debug('%s/%s: No matrix data!', keyboard, layout_name)
cli.log.debug(f'{keyboard}/{layout_name}: No matrix data!')
continue

return True
layout_keys = []
layout_matrix = [['KC_NO' for i in range(col_num)] for i in range(row_num)]

for i, key in enumerate(kb_info_json['layouts'][layout_name]['layout']):
row = key['matrix'][0]
col = key['matrix'][1]
identifier = 'k%s%s' % (ROW_LETTERS[row], COL_LETTERS[col])

return False
try:
layout_matrix[row][col] = identifier
layout_keys.append(identifier)
except IndexError:
key_name = key.get('label', identifier)
cli.log.error(f'Matrix data out of bounds for layout {layout_name} at index {i} ({key_name}): [{row}, {col}]')
return []

lines.append('')
lines.append('#define %s(%s) {\\' % (layout_name, ', '.join(layout_keys)))

rows = ', \\\n'.join(['\t {' + ', '.join(row) + '}' for row in layout_matrix])
rows += ' \\'
lines.append(rows)
lines.append('}')

for alias, target in kb_info_json.get('layout_aliases', {}).items():
lines.append('')
lines.append(f'#ifndef {alias}')
lines.append(f'# define {alias} {target}')
lines.append('#endif')

return lines


@cli.argument('-i', '--include', nargs='?', arg_only=True, help='Optional file to include')
@cli.argument('-o', '--output', arg_only=True, type=normpath, help='File to write to')
@cli.argument('-q', '--quiet', arg_only=True, action='store_true', help="Quiet mode, only output error messages")
@cli.argument('-kb', '--keyboard', arg_only=True, type=keyboard_folder, completer=keyboard_completer, required=True, help='Keyboard to generate keyboard.h for.')
@cli.subcommand('Used by the make system to generate keyboard.h from info.json', hidden=True)
def generate_keyboard_h(cli):
"""Generates the keyboard.h file.
"""
has_layout_h = would_populate_layout_h(cli.args.keyboard)
keyboard_h = cli.args.include
dd_layouts = _generate_layouts(cli.args.keyboard)
valid_config = dd_layouts or keyboard_h

# Build the layouts.h file.
keyboard_h_lines = [GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE, '#pragma once', '#include "quantum.h"']

if not has_layout_h:
keyboard_h_lines.append('#error("<keyboard>.h is only optional for data driven keyboards - kb.h == bad times")')
keyboard_h_lines.append('')
keyboard_h_lines.append('// Layout content')
if dd_layouts:
keyboard_h_lines.extend(dd_layouts)
if keyboard_h:
keyboard_h_lines.append(f'#include "{Path(keyboard_h).name}"')

# Protect against poorly configured keyboards
if not valid_config:
keyboard_h_lines.append('#error("<keyboard>.h is required unless your keyboard uses data-driven configuration. Please rename your keyboard\'s header file to <keyboard>.h")')

# Show the results
dump_lines(cli.args.output, keyboard_h_lines, cli.args.quiet)
84 changes: 0 additions & 84 deletions lib/python/qmk/cli/generate/layouts.py

This file was deleted.

6 changes: 0 additions & 6 deletions lib/python/qmk/tests/test_cli_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,12 +288,6 @@ def test_generate_version_h():
assert '#define QMK_VERSION' in result.stdout


def test_generate_layouts():
result = check_subcommand('generate-layouts', '-kb', 'handwired/pytest/basic')
check_returncode(result)
assert '#define LAYOUT_custom(k0A) {' in result.stdout


def test_format_json_keyboard():
result = check_subcommand('format-json', '--format', 'keyboard', 'lib/python/qmk/tests/minimal_info.json')
check_returncode(result)
Expand Down