summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJoel Challis <git@zvecr.com>2025-04-23 01:27:47 +0100
committerGitHub <noreply@github.com>2025-04-23 10:27:47 +1000
commit8cd71917ce74dd8301e24d80f4eabb2bfa1a7c69 (patch)
tree8b12d8679d1ce7633339a387e0b627eb8df2a3e5 /lib
parent7a2cd0fa962eb5e6e18ce8b0213a7171bc823c1f (diff)
Avoid duplication in generated community modules `rules.mk` (#25135)
Diffstat (limited to 'lib')
-rw-r--r--lib/python/qmk/cli/generate/community_modules.py65
-rwxr-xr-xlib/python/qmk/cli/generate/rules_mk.py36
-rw-r--r--lib/python/qmk/info.py16
3 files changed, 69 insertions, 48 deletions
diff --git a/lib/python/qmk/cli/generate/community_modules.py b/lib/python/qmk/cli/generate/community_modules.py
index 23678a2fb5..e12daccf1c 100644
--- a/lib/python/qmk/cli/generate/community_modules.py
+++ b/lib/python/qmk/cli/generate/community_modules.py
@@ -8,7 +8,7 @@ import qmk.path
8from qmk.info import get_modules 8from qmk.info import get_modules
9from qmk.keyboard import keyboard_completer, keyboard_folder 9from qmk.keyboard import keyboard_completer, keyboard_folder
10from qmk.commands import dump_lines 10from qmk.commands import dump_lines
11from qmk.constants import GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE 11from qmk.constants import GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE, GPL2_HEADER_SH_LIKE, GENERATED_HEADER_SH_LIKE
12from qmk.community_modules import module_api_list, load_module_jsons, find_module_path 12from qmk.community_modules import module_api_list, load_module_jsons, find_module_path
13 13
14 14
@@ -121,6 +121,69 @@ def _render_core_implementation(api, modules):
121 return lines 121 return lines
122 122
123 123
124def _generate_features_rules(features_dict):
125 lines = []
126 for feature, enabled in features_dict.items():
127 feature = feature.upper()
128 enabled = 'yes' if enabled else 'no'
129 lines.append(f'{feature}_ENABLE={enabled}')
130 return lines
131
132
133def _generate_modules_rules(keyboard, filename):
134 lines = []
135 modules = get_modules(keyboard, filename)
136 if len(modules) > 0:
137 lines.append('')
138 lines.append('OPT_DEFS += -DCOMMUNITY_MODULES_ENABLE=TRUE')
139 for module in modules:
140 module_path = qmk.path.unix_style_path(find_module_path(module))
141 if not module_path:
142 raise FileNotFoundError(f"Module '{module}' not found.")
143 lines.append('')
144 lines.append(f'COMMUNITY_MODULES += {module_path.name}') # use module_path here instead of module as it may be a subdirectory
145 lines.append(f'OPT_DEFS += -DCOMMUNITY_MODULE_{module_path.name.upper()}_ENABLE=TRUE')
146 lines.append(f'COMMUNITY_MODULE_PATHS += {module_path}')
147 lines.append(f'VPATH += {module_path}')
148 lines.append(f'SRC += $(wildcard {module_path}/{module_path.name}.c)')
149 lines.append(f'MODULE_NAME_{module_path.name.upper()} := {module_path.name}')
150 lines.append(f'MODULE_PATH_{module_path.name.upper()} := {module_path}')
151 lines.append(f'-include {module_path}/rules.mk')
152
153 module_jsons = load_module_jsons(modules)
154 for module_json in module_jsons:
155 if 'features' in module_json:
156 lines.append('')
157 lines.append(f'# Module: {module_json["module_name"]}')
158 lines.extend(_generate_features_rules(module_json['features']))
159 return lines
160
161
162@cli.argument('-o', '--output', arg_only=True, type=qmk.path.normpath, help='File to write to')
163@cli.argument('-q', '--quiet', arg_only=True, action='store_true', help="Quiet mode, only output error messages")
164@cli.argument('-e', '--escape', arg_only=True, action='store_true', help="Escape spaces in quiet mode")
165@cli.argument('-kb', '--keyboard', arg_only=True, type=keyboard_folder, completer=keyboard_completer, help='Keyboard to generate rules.mk for.')
166@cli.argument('filename', nargs='?', arg_only=True, type=qmk.path.FileType('r'), completer=FilesCompleter('.json'), help='A configurator export JSON to be compiled and flashed or a pre-compiled binary firmware file (bin/hex) to be flashed.')
167@cli.subcommand('Creates a community_modules_rules_mk from a keymap.json file.')
168def generate_community_modules_rules_mk(cli):
169
170 rules_mk_lines = [GPL2_HEADER_SH_LIKE, GENERATED_HEADER_SH_LIKE]
171
172 rules_mk_lines.extend(_generate_modules_rules(cli.args.keyboard, cli.args.filename))
173
174 # Show the results
175 dump_lines(cli.args.output, rules_mk_lines)
176
177 if cli.args.output:
178 if cli.args.quiet:
179 if cli.args.escape:
180 print(cli.args.output.as_posix().replace(' ', '\\ '))
181 else:
182 print(cli.args.output)
183 else:
184 cli.log.info('Wrote rules.mk to %s.', cli.args.output)
185
186
124@cli.argument('-o', '--output', arg_only=True, type=qmk.path.normpath, help='File to write to') 187@cli.argument('-o', '--output', arg_only=True, type=qmk.path.normpath, help='File to write to')
125@cli.argument('-q', '--quiet', arg_only=True, action='store_true', help="Quiet mode, only output error messages") 188@cli.argument('-q', '--quiet', arg_only=True, action='store_true', help="Quiet mode, only output error messages")
126@cli.argument('-kb', '--keyboard', arg_only=True, type=keyboard_folder, completer=keyboard_completer, help='Keyboard to generate community_modules.h for.') 189@cli.argument('-kb', '--keyboard', arg_only=True, type=keyboard_folder, completer=keyboard_completer, help='Keyboard to generate community_modules.h for.')
diff --git a/lib/python/qmk/cli/generate/rules_mk.py b/lib/python/qmk/cli/generate/rules_mk.py
index 01d71d277f..358a22fd1d 100755
--- a/lib/python/qmk/cli/generate/rules_mk.py
+++ b/lib/python/qmk/cli/generate/rules_mk.py
@@ -6,13 +6,12 @@ from dotty_dict import dotty
6from argcomplete.completers import FilesCompleter 6from argcomplete.completers import FilesCompleter
7from milc import cli 7from milc import cli
8 8
9from qmk.info import info_json, get_modules 9from qmk.info import info_json
10from qmk.json_schema import json_load 10from qmk.json_schema import json_load
11from qmk.keyboard import keyboard_completer, keyboard_folder 11from qmk.keyboard import keyboard_completer, keyboard_folder
12from qmk.commands import dump_lines, parse_configurator_json 12from qmk.commands import dump_lines, parse_configurator_json
13from qmk.path import normpath, unix_style_path, FileType 13from qmk.path import normpath, FileType
14from qmk.constants import GPL2_HEADER_SH_LIKE, GENERATED_HEADER_SH_LIKE 14from qmk.constants import GPL2_HEADER_SH_LIKE, GENERATED_HEADER_SH_LIKE
15from qmk.community_modules import find_module_path, load_module_jsons
16 15
17 16
18def generate_rule(rules_key, rules_value): 17def generate_rule(rules_key, rules_value):
@@ -56,35 +55,6 @@ def generate_features_rules(features_dict):
56 return lines 55 return lines
57 56
58 57
59def generate_modules_rules(keyboard, filename):
60 lines = []
61 modules = get_modules(keyboard, filename)
62 if len(modules) > 0:
63 lines.append('')
64 lines.append('OPT_DEFS += -DCOMMUNITY_MODULES_ENABLE=TRUE')
65 for module in modules:
66 module_path = unix_style_path(find_module_path(module))
67 if not module_path:
68 raise FileNotFoundError(f"Module '{module}' not found.")
69 lines.append('')
70 lines.append(f'COMMUNITY_MODULES += {module_path.name}') # use module_path here instead of module as it may be a subdirectory
71 lines.append(f'OPT_DEFS += -DCOMMUNITY_MODULE_{module_path.name.upper()}_ENABLE=TRUE')
72 lines.append(f'COMMUNITY_MODULE_PATHS += {module_path}')
73 lines.append(f'VPATH += {module_path}')
74 lines.append(f'SRC += $(wildcard {module_path}/{module_path.name}.c)')
75 lines.append(f'MODULE_NAME_{module_path.name.upper()} := {module_path.name}')
76 lines.append(f'MODULE_PATH_{module_path.name.upper()} := {module_path}')
77 lines.append(f'-include {module_path}/rules.mk')
78
79 module_jsons = load_module_jsons(modules)
80 for module_json in module_jsons:
81 if 'features' in module_json:
82 lines.append('')
83 lines.append(f'# Module: {module_json["module_name"]}')
84 lines.extend(generate_features_rules(module_json['features']))
85 return lines
86
87
88@cli.argument('filename', nargs='?', arg_only=True, type=FileType('r'), completer=FilesCompleter('.json'), help='A configurator export JSON to be compiled and flashed or a pre-compiled binary firmware file (bin/hex) to be flashed.') 58@cli.argument('filename', nargs='?', arg_only=True, type=FileType('r'), completer=FilesCompleter('.json'), help='A configurator export JSON to be compiled and flashed or a pre-compiled binary firmware file (bin/hex) to be flashed.')
89@cli.argument('-o', '--output', arg_only=True, type=normpath, help='File to write to') 59@cli.argument('-o', '--output', arg_only=True, type=normpath, help='File to write to')
90@cli.argument('-q', '--quiet', arg_only=True, action='store_true', help="Quiet mode, only output error messages") 60@cli.argument('-q', '--quiet', arg_only=True, action='store_true', help="Quiet mode, only output error messages")
@@ -135,8 +105,6 @@ def generate_rules_mk(cli):
135 if converter: 105 if converter:
136 rules_mk_lines.append(generate_rule('CONVERT_TO', converter)) 106 rules_mk_lines.append(generate_rule('CONVERT_TO', converter))
137 107
138 rules_mk_lines.extend(generate_modules_rules(cli.args.keyboard, cli.args.filename))
139
140 # Show the results 108 # Show the results
141 dump_lines(cli.args.output, rules_mk_lines) 109 dump_lines(cli.args.output, rules_mk_lines)
142 110
diff --git a/lib/python/qmk/info.py b/lib/python/qmk/info.py
index 93eba7376a..d95fd3d799 100644
--- a/lib/python/qmk/info.py
+++ b/lib/python/qmk/info.py
@@ -1066,23 +1066,13 @@ def get_modules(keyboard, keymap_filename):
1066 """ 1066 """
1067 modules = [] 1067 modules = []
1068 1068
1069 kb_info_json = info_json(keyboard)
1070 modules.extend(kb_info_json.get('modules', []))
1071
1069 if keymap_filename: 1072 if keymap_filename:
1070 keymap_json = parse_configurator_json(keymap_filename) 1073 keymap_json = parse_configurator_json(keymap_filename)
1071 1074
1072 if keymap_json: 1075 if keymap_json:
1073 kb = keymap_json.get('keyboard', None)
1074 if not kb:
1075 kb = keyboard
1076
1077 if kb:
1078 kb_info_json = info_json(kb)
1079 if kb_info_json:
1080 modules.extend(kb_info_json.get('modules', []))
1081
1082 modules.extend(keymap_json.get('modules', [])) 1076 modules.extend(keymap_json.get('modules', []))
1083 1077
1084 elif keyboard:
1085 kb_info_json = info_json(keyboard)
1086 modules.extend(kb_info_json.get('modules', []))
1087
1088 return list(dict.fromkeys(modules)) # remove dupes 1078 return list(dict.fromkeys(modules)) # remove dupes