* describe how data driven configuration works * Apply suggestions from code review Co-authored-by: ridingqwerty <george.g.koenig@gmail.com> Co-authored-by: Erovia <Erovia@users.noreply.github.com> Co-authored-by: ridingqwerty <george.g.koenig@gmail.com> Co-authored-by: Erovia <Erovia@users.noreply.github.com>
4.6 KiB
Data Driven Configuration
This page describes how QMK’s data driven JSON configuration system works. It is aimed at developers who want to work on QMK itself.
History
Historically QMK has been configured through a combination of two
mechanisms- rules.mk and config.h. While this
worked well when QMK was only a handful of keyboards we’ve grown to
encompass nearly 1500 supported keyboards. That extrapolates out to 6000
configuration files under keyboards/ alone! The freeform
nature of these files and the unique patterns people have used to avoid
duplication have made ongoing maintenance a challenge, and a large
number of our keyboards follow patterns that are outdated and sometimes
harder to understand.
We have also been working on bringing the power of QMK to people who
aren’t comformable with a CLI, and other projects such as VIA are
working to make using QMK as easy as installing a program. These tools
need information about how a keyboard is laid out or what pins and
features are available so that users can take full advantage of QMK. We
introduced info.json as a first step towards this. The QMK
API is an effort to combine these 3 sources of information-
config.h, rules.mk, and
info.json- into a single source of truth that end-user
tools can use.
Now we have support for generating rules.mk and
config.h values from info.json, allowing us to
have a single source of truth. This will allow us to use automated
tooling to maintain keyboards saving a lot of time and maintenance
work.
Overview
On the C side of things nothing really changes. When you need to create a new rule or define you follow the same process:
- Add it to
docs/config_options.md - Set a default in the appropriate core file
- Add your
ifdefand/or#ifdefstatements as needed
You will then need to add support for your new configuration to
info.json. The basic process is:
- Add it to the schema in
data/schemas/keyboards.jsonschema - Add code to extract it from
config.h/rules.mktolib/python/qmk/info.py - Add code to generate it to one of:
lib/python/qmk/cli/generate/config_h.pylib/python/qmk/cli/generate/rules_mk.py
Adding an option to info.json
This section describes adding support for a
config.h/rules.mk value to info.json.
Add it to the schema
QMK maintains schema files in data/schemas. The values
that go into keyboard-specific info.json files are kept in
keyboard.jsonschema. Any value you want to make available
to end users to edit must go in here.
In some cases you can simply add a new top-level key. Some examples
to follow are keyboard_name, maintainer,
processor, and url. This is appropriate when
your option is self-contained and not directly related to other options.
In other cases you should group like options together in an
object. This is particularly true when adding support for a
feature. Some examples to follow for this are indicators,
matrix_pins, and rgblight. If you are not sure
how to integrate your new option(s) open
an issue or join #cli on
Discord and start a conversation there.
Add code to extract it
Whenever QMK generates a complete info.json it extracts
information from config.h and rules.mk. You
will need to add code for your new config value to
lib/python/qmk/info.py. Typically this means adding a new
_extract_<feature>() function and then calling your
function in either _extract_config_h() or
_extract_rules_mk().
If you are not sure how to edit this file or are not comfortable with Python open an issue or join #cli on Discord and someone can help you with this part.
Add code to generate it
The final piece of the puzzle is providing your new option to the build system. This is done by generating two files:
.build/obj_<keyboard>/src/info_config.h.build/obj_<keyboard>/src/rules.mk
These two files are generated by the code here:
lib/python/qmk/cli/generate/config_h.pylib/python/qmk/cli/generate/rules_mk.py
For config.h values you’ll need to write a function for
your rule(s) and call that function in
generate_config_h().
If you have a new top-level info.json key for
rules.mk you can simply add your keys to
info_to_rules at the top of
lib/python/qmk/cli/generate/rules_mk.py. Otherwise you’ll
need to create a new if block for your feature in
generate_rules_mk().