Skip to content

Commit 7b42c08

Browse files
committed
build: Auto-generation of launch.json
- Launch.json auto-generation during build configuration. - Also updated FakeIt to the latest version. - Adding mcpls configuration and other .agent files.
1 parent 9c67656 commit 7b42c08

9 files changed

Lines changed: 228 additions & 98 deletions

File tree

.agent/mcp_config.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"mcpServers": {
3+
"mcpls": {
4+
"command": "mcpls",
5+
"args": [],
6+
"env": {}
7+
},
8+
"embedded-debugger": {
9+
"command": "embedded-debugger-mcp",
10+
"args": [],
11+
"env": {
12+
"RUST_LOG": "info"
13+
}
14+
},
15+
"pdf-reader": {
16+
"command": "npx",
17+
"args": [
18+
"@sylphx/pdf-reader-mcp"
19+
],
20+
"cwd": "documentation/pdfs"
21+
}
22+
}
23+
}

.gitignore

Lines changed: 16 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# Fortran module files
2+
*.mod
3+
*.smod
4+
15
# Prerequisites
26
*.d
37

@@ -28,61 +32,35 @@
2832

2933
# Executables
3034
*.exe
35+
*.elf
3136
*.out
3237
*.app
3338

3439
# Ignore Build Output
3540
build/
3641

3742
# Ingnore Testing Output like Jlink/Ozone or GDB configuration
38-
testing/*.jdebug*
3943
testing/*.gdb
4044

45+
# Ignore Ozone outputs
46+
testing/*.jdebug
47+
testing/*.jdebug.user
48+
4149
# Ignore Python virtual environments
4250
venv/
4351
.venv/
4452

45-
$ Ignore Mac OSX Files
53+
# Ignore Mac OSX Files
4654
.DS_Store
4755
._.DS_Store
4856

4957
# Ignore user's custom settings
5058
CMakeUserPresets.json
5159

52-
# Ignore Ozone outputs
53-
*.jdebug
54-
*.jdebug.user
55-
56-
# Prerequisites
57-
*.d
58-
59-
# Compiled Object files
60-
*.slo
61-
*.lo
62-
*.o
63-
*.obj
64-
65-
# Precompiled Headers
66-
*.gch
67-
*.pch
68-
69-
# Compiled Dynamic libraries
70-
*.so
71-
*.dylib
72-
*.dll
73-
74-
# Fortran module files
75-
*.mod
76-
*.smod
77-
78-
# Compiled Static libraries
79-
*.lai
80-
*.la
81-
*.a
82-
*.lib
60+
# Agent Configuration as many have tokens in them
61+
.continue/
62+
.agents/
63+
.mcp.json
8364

84-
# Executables
85-
*.exe
86-
*.elf
87-
*.out
88-
*.app
65+
# Ignore the now autogenerated launch.json
66+
.vscode/launch.json

.vscode/launch.json

Lines changed: 0 additions & 59 deletions
This file was deleted.

CMakeLists.txt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,3 +154,29 @@ foreach(test IN LISTS LOCAL_UNITTESTS)
154154
add_subdirectory(${EMBEDDED_SUPERLOOP_PROJECT_ROOT}/modules/${test}/tests)
155155
endif()
156156
endforeach()
157+
158+
# Write the accumulated debug targets to a JSON file
159+
get_property(ACCUMULATED_DEBUG_TARGETS GLOBAL PROPERTY CROSS_DEBUG_TARGETS)
160+
string(REPLACE ";" ",\n" ACCUMULATED_TARGETS_JSON "${ACCUMULATED_DEBUG_TARGETS}")
161+
set(JSON_CONTENT "[\n${ACCUMULATED_TARGETS_JSON}\n]\n")
162+
file(WRITE "${CMAKE_BINARY_DIR}/debug_targets.json" "${JSON_CONTENT}")
163+
164+
# Generate .vscode/launch.json on configure and as a custom target
165+
add_custom_target(generate-launch-json
166+
COMMAND ${STATERATOR_PYTHON} ${CMAKE_SOURCE_DIR}/scripts/generate_launch_json.py --build-dir ${CMAKE_BINARY_DIR}
167+
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
168+
COMMENT "Generating .vscode/launch.json from build targets"
169+
)
170+
171+
if(NOT ENV{CI})
172+
# Run the generator script at configure time to automatically update launch.json
173+
execute_process(
174+
COMMAND ${STATERATOR_PYTHON} ${CMAKE_SOURCE_DIR}/scripts/generate_launch_json.py --build-dir ${CMAKE_BINARY_DIR}
175+
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
176+
RESULT_VARIABLE GENERATE_LAUNCH_JSON_RESULT
177+
)
178+
if(NOT GENERATE_LAUNCH_JSON_RESULT EQUAL 0)
179+
message(WARNING "Failed to generate .vscode/launch.json")
180+
endif()
181+
endif()
182+

build-support/share/cmake/embedded-superloop/firmware.cmake

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,10 @@ function(add_firmware)
215215
)
216216
add_custom_target(hex-${LOCAL_TARGET} ALL DEPENDS ${ARG_HEX})
217217
message(STATUS "Adding hex-${LOCAL_TARGET}")
218+
219+
# Accumulate debug target information for generate_launch_json.py
220+
set(TARGET_JSON_OBJ " {\n \"name\": \"${LOCAL_TARGET}\",\n \"device\": \"${BOARD_DEVICE}\",\n \"executable\": \"${ARG_ELF}\"\n }")
221+
append_global(CROSS_DEBUG_TARGETS "${TARGET_JSON_OBJ}")
218222
else()
219223
target_compile_definitions(${LOCAL_TARGET}.elf
220224
PUBLIC

embedded-superloop.code-workspace

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"davidanson.vscode-markdownlint",
1818
"gruntfuggly.todo-tree",
1919
"xaver.clang-format",
20+
"vadimcn.vscode-lldb",
2021
"llvm-vs-code-extensions.vscode-clangd",
2122
"ms-vscode.hexeditor"
2223
],

mcpls.toml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
[[lsp_servers]]
2+
language_id = "cpp"
3+
command = "clangd"
4+
args = [
5+
"--background-index",
6+
"--query-driver=/**/arm-none-eabi-*",
7+
"--clang-tidy",
8+
"--enable-config",
9+
"--header-insertion=iwyu",
10+
"--pretty"
11+
]
12+
file_patterns = [
13+
"**/*.cpp",
14+
"**/*.hpp",
15+
"**/*.c",
16+
"**/*.h",
17+
"**/*.inc",
18+
"**/*.ipp",
19+
"**/*.tcc",
20+
"**/*.in"
21+
]

scripts/generate_launch_json.py

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
#!/usr/bin/env python3
2+
import argparse
3+
import json
4+
import os
5+
import re
6+
import sys
7+
from pathlib import Path
8+
9+
def main():
10+
parser = argparse.ArgumentParser(
11+
description="Generate VS Code launch.json from configured CMake build targets."
12+
)
13+
parser.add_argument(
14+
"--build-dir",
15+
type=str,
16+
required=True,
17+
help="Path to the active CMake build directory.",
18+
)
19+
args = parser.parse_args()
20+
21+
workspace_root = Path(__file__).resolve().parent.parent
22+
build_dir = Path(args.build_dir).resolve()
23+
24+
if not build_dir.exists():
25+
print(f"Error: Build directory {build_dir} does not exist.", file=sys.stderr)
26+
sys.exit(1)
27+
28+
# 1. Read targets from debug_targets.json inside build_dir
29+
json_path = build_dir / "debug_targets.json"
30+
if not json_path.exists():
31+
print(f"No debug_targets.json found in {build_dir}. Skipping generation.", file=sys.stderr)
32+
sys.exit(0)
33+
34+
try:
35+
targets = json.loads(json_path.read_text(encoding="utf-8"))
36+
except Exception as e:
37+
print(f"Error reading/parsing {json_path}: {e}", file=sys.stderr)
38+
sys.exit(1)
39+
40+
new_configs = []
41+
42+
for target in targets:
43+
name = target.get("name")
44+
device = target.get("device")
45+
exec_path_str = target.get("executable")
46+
47+
if not name or not device or not exec_path_str:
48+
continue
49+
50+
exec_path = Path(exec_path_str)
51+
52+
# Derive SVD file path
53+
rel_svd = ""
54+
if device.startswith("STM32"):
55+
# The naming convention for SVDs is STM32 + first 4 chars of model + .svd
56+
# e.g., STM32F407VE -> STM32F407.svd
57+
svd_name = f"{device[:9]}.svd"
58+
svd_path = workspace_root / "modules" / "stm32" / "scripts" / svd_name
59+
if svd_path.exists():
60+
rel_svd = "${workspaceFolder}/" + str(svd_path.resolve().relative_to(workspace_root.resolve()))
61+
62+
# Convert absolute paths to workspace-relative using VS Code variable
63+
try:
64+
rel_exec = "${workspaceFolder}/" + str(exec_path.resolve().relative_to(workspace_root.resolve()))
65+
except ValueError:
66+
rel_exec = str(exec_path)
67+
68+
# Create launch configuration
69+
config = {
70+
"name": f"Cortex-Debug (JLink): {name}",
71+
"cwd": "${workspaceFolder}",
72+
"executable": rel_exec,
73+
"request": "launch",
74+
"type": "cortex-debug",
75+
"servertype": "jlink",
76+
"interface": "swd",
77+
"runToEntryPoint": "reset_entry",
78+
"device": device,
79+
"internalConsoleOptions": "openOnSessionStart",
80+
"showDevDebugOutput": "both",
81+
"preLaunchCommands": [
82+
"set mem inaccessible-by-default off"
83+
],
84+
"preResetCommands": [
85+
"monitor reset 0"
86+
],
87+
}
88+
89+
if rel_svd:
90+
config["svdFile"] = rel_svd
91+
92+
new_configs.append(config)
93+
94+
print(f"Generated {len(new_configs)} debug configurations for build directory {build_dir.name}.")
95+
96+
# 2. Read existing launch.json, filter/merge, and write back
97+
launch_json_path = workspace_root / ".vscode" / "launch.json"
98+
existing_launch = {"version": "0.2.0", "configurations": []}
99+
100+
if launch_json_path.exists():
101+
try:
102+
raw_content = launch_json_path.read_text(encoding="utf-8")
103+
# Strip comments and trailing commas to parse with standard json
104+
clean_content = re.sub(r'//.*', '', raw_content)
105+
clean_content = re.sub(r',\s*([\]}])', r'\1', clean_content)
106+
existing_launch = json.loads(clean_content)
107+
except Exception as e:
108+
print(f"Warning: Could not parse existing launch.json ({e}). Overwriting.", file=sys.stderr)
109+
110+
# Filter out existing cortex-debug configurations to avoid duplication/stale entries
111+
non_cortex_configs = [
112+
c for c in existing_launch.get("configurations", [])
113+
if c.get("type") != "cortex-debug"
114+
]
115+
116+
# Merge
117+
merged_configs = non_cortex_configs + new_configs
118+
existing_launch["configurations"] = merged_configs
119+
120+
# Ensure .vscode dir exists
121+
launch_json_path.parent.mkdir(parents=True, exist_ok=True)
122+
123+
# Write back
124+
try:
125+
with open(launch_json_path, "w", encoding="utf-8") as f:
126+
f.write("// Auto-generated debug configurations. Do not edit manually.\n")
127+
f.write("// Run CMake configure to update.\n")
128+
json.dump(existing_launch, f, indent=4)
129+
f.write("\n")
130+
print(f"Successfully updated {launch_json_path}")
131+
except Exception as e:
132+
print(f"Error: Could not write to {launch_json_path} ({e})", file=sys.stderr)
133+
sys.exit(1)
134+
135+
if __name__ == "__main__":
136+
main()

third-party/FakeIt

Submodule FakeIt updated 67 files

0 commit comments

Comments
 (0)