Skip to content

Commit 4aed0e9

Browse files
committed
[tools] Add workspace generation for RT-Thread root directory.
1 parent b91a131 commit 4aed0e9

File tree

1 file changed

+101
-8
lines changed

1 file changed

+101
-8
lines changed

tools/targets/vsc.py

Lines changed: 101 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
# 2018-05-30 Bernard The first version
2323
# 2023-03-03 Supperthomas Add the vscode workspace config file
2424
# 2024-12-13 Supperthomas covert compile_commands.json to vscode workspace file
25+
# 2025-07-05 Bernard Add support for generating .vscode/c_cpp_properties.json
26+
# and .vscode/settings.json files
2527
"""
2628
Utils for VSCode
2729
"""
@@ -63,7 +65,7 @@ def build_tree(paths):
6365
tree = {}
6466
current_working_directory = os.getcwd()
6567
current_folder_name = os.path.basename(current_working_directory)
66-
#过滤异常和不存在的路径
68+
# Filter out invalid and non-existent paths
6769
relative_dirs = []
6870
for path in paths:
6971
normalized_path = os.path.normpath(path)
@@ -90,7 +92,7 @@ def extract_source_dirs(compile_commands):
9092
if file_path.endswith('.c'):
9193
dir_path = os.path.dirname(file_path)
9294
source_dirs.add(dir_path)
93-
# command 或者arguments
95+
# command or arguments
9496
command = entry.get('command') or entry.get('arguments')
9597

9698
if isinstance(command, str):
@@ -105,7 +107,7 @@ def extract_source_dirs(compile_commands):
105107
elif part.startswith('/I'):
106108
include_dir = part[2:] if len(part) > 2 else parts[i + 1]
107109
source_dirs.add(os.path.abspath(include_dir))
108-
#print(f"Source Directories: {source_dirs}")
110+
109111
return sorted(source_dirs)
110112

111113

@@ -114,8 +116,7 @@ def is_path_in_tree(path, tree):
114116
current_level = tree
115117
found_first_node = False
116118
root_key = list(tree.keys())[0]
117-
#print(root_key)
118-
#print(path)
119+
119120
index_start = parts.index(root_key)
120121
length = len(parts)
121122
try:
@@ -155,7 +156,6 @@ def generate_code_workspace_file(source_dirs,command_json_path,root_path):
155156
}
156157
}
157158
workspace_filename = f'{current_folder_name}.code-workspace'
158-
# print(workspace_data)
159159
with open(workspace_filename, 'w') as f:
160160
json.dump(workspace_data, f, indent=4)
161161

@@ -193,8 +193,6 @@ def command_json_to_workspace(root_path,command_json_path):
193193
if not is_path_in_tree(dir_path, filtered_tree):
194194
exclude_fold.add(dir_path)
195195

196-
#print("Excluded Folders:")
197-
#print(exclude_fold)
198196
generate_code_workspace_file(exclude_fold,command_json_path,root_path)
199197

200198
def delete_repeatelist(data):
@@ -340,6 +338,51 @@ def GenerateVSCode(env):
340338

341339
return
342340

341+
import os
342+
343+
def find_rtconfig_dirs(bsp_dir, project_dir):
344+
"""
345+
Search for subdirectories containing 'rtconfig.h' under 'bsp_dir' (up to 4 levels deep), excluding 'project_dir'.
346+
347+
Args:
348+
bsp_dir (str): The root directory to search (absolute path).
349+
project_dir (str): The subdirectory to exclude from the search (absolute path).
350+
351+
Returns
352+
list: A list of absolute paths to subdirectories containing 'rtconfig.h'.
353+
"""
354+
355+
result = []
356+
project_dir = os.path.normpath(project_dir)
357+
358+
# list the bsp_dir to add result
359+
list = os.listdir(bsp_dir)
360+
for item in list:
361+
item = os.path.join(bsp_dir, item)
362+
363+
# if item is a directory
364+
if not os.path.isdir(item):
365+
continue
366+
367+
# print(item, project_dir)
368+
if not project_dir.startswith(item):
369+
result.append(os.path.abspath(item))
370+
371+
parent_dir = os.path.dirname(project_dir)
372+
373+
if parent_dir != bsp_dir:
374+
list = os.listdir(parent_dir)
375+
for item in list:
376+
item = os.path.join(parent_dir, item)
377+
rtconfig_path = os.path.join(item, 'rtconfig.h')
378+
if os.path.isfile(rtconfig_path):
379+
abs_path = os.path.abspath(item)
380+
if abs_path != project_dir:
381+
result.append(abs_path)
382+
383+
# print(result)
384+
return result
385+
343386
def GenerateVSCodeWorkspace(env):
344387
"""
345388
Generate vscode.code files
@@ -349,6 +392,26 @@ def GenerateVSCodeWorkspace(env):
349392
# get the launch directory
350393
cwd = GetLaunchDir()
351394

395+
# get .vscode/workspace.json file
396+
workspace_file = os.path.join(cwd, '.vscode', 'workspace.json')
397+
if not os.path.exists(workspace_file):
398+
print('Workspace file not found, skip generating.')
399+
return
400+
401+
try:
402+
# read the workspace file
403+
with open(workspace_file, 'r') as f:
404+
workspace_data = json.load(f)
405+
406+
# get the bsp directories from the workspace data, bsps/folder
407+
bsp_dir = os.path.join(cwd, workspace_data.get('bsps', {}).get('folder', ''))
408+
if not bsp_dir:
409+
print('No BSP directories found in the workspace file, skip generating.')
410+
return
411+
except Exception as e:
412+
print('Error reading workspace file, skip generating.')
413+
return
414+
352415
# check if .vscode folder exists, if not, create it
353416
if not os.path.exists(os.path.join(cwd, '.vscode')):
354417
os.mkdir(os.path.join(cwd, '.vscode'))
@@ -391,6 +454,36 @@ def GenerateVSCodeWorkspace(env):
391454
vsc_file.write(json.dumps(json_obj, ensure_ascii=False, indent=4))
392455
vsc_file.close()
393456

457+
# generate .vscode/settings.json
458+
vsc_settings = {}
459+
settings_path = os.path.join(cwd, '.vscode/settings.json')
460+
if os.path.exists(settings_path):
461+
with open(settings_path, 'r') as f:
462+
# read the existing settings file and load to vsc_settings
463+
vsc_settings = json.load(f)
464+
465+
vsc_file = open(settings_path, 'w')
466+
if vsc_file:
467+
vsc_settings['files.exclude'] = {
468+
"**/__pycache__": True,
469+
"tools/kconfig-frontends": True,
470+
}
471+
472+
result = find_rtconfig_dirs(bsp_dir, os.getcwd())
473+
if result:
474+
# sort the result
475+
result = sorted(result, key=lambda x: x.lower())
476+
for item in result:
477+
# make the path relative to the current working directory
478+
rel_path = os.path.relpath(item, cwd)
479+
# add the path to files.exclude
480+
vsc_settings['files.exclude'][rel_path] = True
481+
482+
vsc_settings['search.exclude'] = vsc_settings['files.exclude']
483+
# write the settings to the file
484+
vsc_file.write(json.dumps(vsc_settings, ensure_ascii=False, indent=4))
485+
vsc_file.close()
486+
394487
print('Done!')
395488

396489
return

0 commit comments

Comments
 (0)