Skip to content

Commit a68cc2e

Browse files
[tool] tools/targets/vsc.py : improve compile_commands handling and w… (#11138)
[tool] tools/targets/vsc.py : improve compile_commands handling and workspace excludes - broaden source file extension detection to include C++ and asm - resolve compile_commands path to absolute and pass its directory to clangd - limit excludes scan to rt-thread/packages and always include board/linker_scripts
1 parent b3c71a6 commit a68cc2e

File tree

1 file changed

+41
-10
lines changed

1 file changed

+41
-10
lines changed

tools/targets/vsc.py

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ def extract_source_dirs(compile_commands):
8888
for entry in compile_commands:
8989
file_path = os.path.abspath(entry['file'])
9090

91-
if file_path.endswith('.c'):
91+
file_ext = os.path.splitext(file_path)[1].lower()
92+
if file_ext in ('.c', '.cc', '.cpp', '.cxx', '.s', '.asm'):
9293
dir_path = os.path.dirname(file_path)
9394
source_dirs.add(dir_path)
9495
# command or arguments
@@ -126,6 +127,26 @@ def is_path_in_tree(path, tree):
126127
return False
127128

128129

130+
def should_force_include(path, root_path):
131+
rel_path = os.path.relpath(path, root_path).replace('\\', '/')
132+
return (
133+
rel_path == 'board/linker_scripts' or
134+
rel_path.startswith('board/linker_scripts/')
135+
)
136+
137+
def limit_excludes_to_root_dirs(root_path, names):
138+
allowed = set(os.path.normpath(os.path.join(root_path, name)) for name in names)
139+
return [p for p in allowed if os.path.isdir(p)]
140+
141+
def is_under_roots(path, root_path, names):
142+
norm = os.path.normpath(path)
143+
for name in names:
144+
root = os.path.normpath(os.path.join(root_path, name))
145+
if norm == root or norm.startswith(root + os.path.sep):
146+
return True
147+
return False
148+
149+
129150
def generate_code_workspace_file(source_dirs,command_json_path,root_path):
130151
current_working_directory = os.getcwd()
131152
current_folder_name = os.path.basename(current_working_directory)
@@ -139,7 +160,13 @@ def generate_code_workspace_file(source_dirs,command_json_path,root_path):
139160
continue
140161

141162
root_rel_path = os.path.relpath(root_path, current_working_directory)
142-
command_json_path = os.path.relpath(current_working_directory, root_path) + os.sep
163+
command_json_abs_path = command_json_path
164+
if not os.path.isabs(command_json_abs_path):
165+
command_json_abs_path = os.path.abspath(
166+
os.path.join(current_working_directory, command_json_abs_path)
167+
)
168+
command_json_dir = os.path.dirname(command_json_abs_path)
169+
command_json_dir = os.path.relpath(command_json_dir, root_path)
143170
workspace_data = {
144171
"folders": [
145172
{
@@ -148,7 +175,7 @@ def generate_code_workspace_file(source_dirs,command_json_path,root_path):
148175
],
149176
"settings": {
150177
"clangd.arguments": [
151-
f"--compile-commands-dir={command_json_path}",
178+
f"--compile-commands-dir={command_json_dir}",
152179
"--header-insertion=never"
153180
],
154181
"files.exclude": {dir.replace('\\','/'): True for dir in sorted(relative_dirs)}
@@ -161,8 +188,11 @@ def generate_code_workspace_file(source_dirs,command_json_path,root_path):
161188
print(f'Workspace file {workspace_filename} created.')
162189

163190
def command_json_to_workspace(root_path,command_json_path):
164-
165-
with open('build/compile_commands.json', 'r') as f:
191+
command_json_abs_path = command_json_path
192+
if not os.path.isabs(command_json_abs_path):
193+
command_json_abs_path = os.path.abspath(command_json_abs_path)
194+
195+
with open(command_json_abs_path, 'r') as f:
166196
compile_commands = json.load(f)
167197

168198
source_dirs = extract_source_dirs(compile_commands)
@@ -182,17 +212,19 @@ def command_json_to_workspace(root_path,command_json_path):
182212
# os.chdir(root_path)
183213
# 轮询root文件夹下面的每一个文件夹和子文件夹
184214
for root, dirs, files in os.walk(root_path):
215+
if not is_under_roots(root, root_path, ('rt-thread', 'packages')):
216+
continue
185217
# 检查当前root是否在filtered_tree中
186-
if not is_path_in_tree(root, filtered_tree):
218+
if not is_path_in_tree(root, filtered_tree) and not should_force_include(root, root_path):
187219
exclude_fold.add(root)
188220
dirs[:] = [] # 不往下轮询子文件夹
189221
continue
190222
for dir in dirs:
191223
dir_path = os.path.join(root, dir)
192-
if not is_path_in_tree(dir_path, filtered_tree):
224+
if not is_path_in_tree(dir_path, filtered_tree) and not should_force_include(dir_path, root_path):
193225
exclude_fold.add(dir_path)
194226

195-
generate_code_workspace_file(exclude_fold,command_json_path,root_path)
227+
generate_code_workspace_file(exclude_fold,command_json_abs_path,root_path)
196228

197229
def delete_repeatelist(data):
198230
temp_dict = set([str(item) for item in data])
@@ -245,8 +277,7 @@ def GenerateCFiles(env):
245277
Generate vscode.code-workspace files by build/compile_commands.json
246278
"""
247279
if os.path.exists('build/compile_commands.json'):
248-
249-
command_json_to_workspace(env['RTT_ROOT'],'build/compile_commands.json')
280+
command_json_to_workspace(os.getcwd(), 'build/compile_commands.json')
250281
return
251282
"""
252283
Generate vscode.code-workspace files

0 commit comments

Comments
 (0)