Add introspection.h support and example.

This commit is contained in:
Nick Brassel 2025-02-07 23:30:48 +11:00
commit dd2ea4aae0
No known key found for this signature in database
6 changed files with 64 additions and 13 deletions

View file

@ -270,14 +270,19 @@ $(INTERMEDIATE_OUTPUT)/src/community_modules.c: $(KEYMAP_JSON) $(DD_CONFIG_FILES
$(eval CMD=$(QMK_BIN) generate-community-modules-c -kb $(KEYBOARD) --quiet --output $(INTERMEDIATE_OUTPUT)/src/community_modules.c $(KEYMAP_JSON))
@$(BUILD_CMD)
$(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.inc: $(KEYMAP_JSON) $(DD_CONFIG_FILES)
$(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.c: $(KEYMAP_JSON) $(DD_CONFIG_FILES)
@$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD)
$(eval CMD=$(QMK_BIN) generate-community-modules-introspection-inc -kb $(KEYBOARD) --quiet --output $(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.inc $(KEYMAP_JSON))
$(eval CMD=$(QMK_BIN) generate-community-modules-introspection-c -kb $(KEYBOARD) --quiet --output $(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.c $(KEYMAP_JSON))
@$(BUILD_CMD)
$(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.h: $(KEYMAP_JSON) $(DD_CONFIG_FILES)
@$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD)
$(eval CMD=$(QMK_BIN) generate-community-modules-introspection-h -kb $(KEYBOARD) --quiet --output $(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.h $(KEYMAP_JSON))
@$(BUILD_CMD)
SRC += $(INTERMEDIATE_OUTPUT)/src/community_modules.c
generated-files: $(INTERMEDIATE_OUTPUT)/src/community_modules.h $(INTERMEDIATE_OUTPUT)/src/community_modules.c $(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.inc
generated-files: $(INTERMEDIATE_OUTPUT)/src/community_modules.h $(INTERMEDIATE_OUTPUT)/src/community_modules.c $(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.c $(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.h
include $(BUILDDEFS_PATH)/converters.mk

View file

@ -202,9 +202,38 @@ def generate_community_modules_c(cli):
@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, help='Keyboard to generate community_modules.c for.')
@cli.argument('filename', nargs='?', type=qmk.path.FileType('r'), arg_only=True, completer=FilesCompleter('.json'), help='Configurator JSON file')
@cli.subcommand('Creates a community_modules_introspection.inc from a keymap.json file.')
def generate_community_modules_introspection_inc(cli):
"""Creates a community_modules_introspection.inc from a keymap.json file
@cli.subcommand('Creates a community_modules_introspection.h from a keymap.json file.')
def generate_community_modules_introspection_h(cli):
"""Creates a community_modules_introspection.h from a keymap.json file
"""
if cli.args.output and cli.args.output.name == '-':
cli.args.output = None
lines = [
GPL2_HEADER_C_LIKE,
GENERATED_HEADER_C_LIKE,
'',
]
modules = get_modules(cli.args.keyboard, cli.args.filename)
if len(modules) > 0:
for module in modules:
module_path = find_module_path(module)
lines.append(f'#if __has_include("{module_path}/introspection.h")')
lines.append(f'#include "{module_path}/introspection.h"')
lines.append(f'#endif // __has_include("{module_path}/introspection.h")')
lines.append('')
dump_lines(cli.args.output, lines, cli.args.quiet, remove_repeated_newlines=True)
@cli.argument('-o', '--output', arg_only=True, type=qmk.path.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, help='Keyboard to generate community_modules.c for.')
@cli.argument('filename', nargs='?', type=qmk.path.FileType('r'), arg_only=True, completer=FilesCompleter('.json'), help='Configurator JSON file')
@cli.subcommand('Creates a community_modules_introspection.c from a keymap.json file.')
def generate_community_modules_introspection_c(cli):
"""Creates a community_modules_introspection.c from a keymap.json file
"""
if cli.args.output and cli.args.output.name == '-':
cli.args.output = None

View file

@ -2,12 +2,12 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H
#include "introspection.h"
ASSERT_COMMUNITY_MODULES_MIN_API_VERSION(20250122);
extern int keymap_byte_count(void); // example of use of introspection
uint32_t delayed_hello_world(uint32_t trigger_time, void *cb_arg) {
printf("Hello, world! I'm a QMK based keyboard! The keymap array size is %d bytes.\n", keymap_byte_count());
printf("Hello, world! I'm a QMK based keyboard! The keymap array size is %d bytes.\n", hello_world_introspection().total_size);
return 0;
}

View file

@ -1,6 +1,10 @@
// Copyright 2025 Nick Brassel (@tzarc)
// SPDX-License-Identifier: GPL-2.0-or-later
int keymap_byte_count(void) {
return sizeof(keymaps);
hello_world_introspection_t hello_world_introspection(void) {
hello_world_introspection_t introspection = {
.total_size = sizeof(keymaps),
.layer_count = sizeof(keymaps) / sizeof(keymaps[0]),
};
return introspection;
}

View file

@ -0,0 +1,9 @@
// Copyright 2025 Nick Brassel (@tzarc)
// SPDX-License-Identifier: GPL-2.0-or-later
typedef struct hello_world_introspection_t {
int total_size;
int layer_count;
} hello_world_introspection_t;
hello_world_introspection_t hello_world_introspection(void);

View file

@ -12,6 +12,10 @@
#include "keymap_introspection.h"
#include "util.h"
#if defined(COMMUNITY_MODULES_ENABLE)
# include "community_modules_introspection.h"
#endif // defined(COMMUNITY_MODULES_ENABLE)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Key mapping
@ -173,8 +177,8 @@ __attribute__((weak)) const key_override_t* key_override_get(uint16_t key_overri
#endif // defined(KEY_OVERRIDE_ENABLE)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Community modules
// Community modules (must be last in this file!)
#if defined(COMMUNITY_MODULES_ENABLE)
# include "community_modules_introspection.inc"
# include "community_modules_introspection.c"
#endif // defined(COMMUNITY_MODULES_ENABLE)