-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathvscode_workspace.lua
More file actions
246 lines (226 loc) · 6.13 KB
/
Copy pathvscode_workspace.lua
File metadata and controls
246 lines (226 loc) · 6.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
--
-- Name: vscode_workspace.lua
-- Purpose: Generate a vscode file.
-- Author: Ryan Pusztai
-- Modified by: Andrea Zanellato
-- Manu Evans
-- Yehonatan Ballas
-- Created: 2013/05/06
-- Copyright: (c) 2008-2020 Jason Perkins and the Premake project
--
local p = premake
local project = p.project
local workspace = p.workspace
local tree = p.tree
local vscode = p.modules.vscode
vscode.workspace = {}
local m = vscode.workspace
function m.getcompiler(cfg)
local toolset = p.tools[_OPTIONS.cc or cfg.toolset or p.CLANG]
if not toolset then
error("Invalid toolset '" + (_OPTIONS.cc or cfg.toolset) + "'")
end
return toolset
end
--
-- Generate a vscode file
--
function m.generate(wks)
p.utf8()
p.w('{"folders": [')
-- workspace should be first for clangd to use it as the working directory
p.w('{')
p.w('"path": "."')
p.w('},')
--
-- Project list
--
local root_src_dirs = {}
local tr = workspace.grouptree(wks)
tree.traverse(tr, {
onleaf = function(n)
local prj = n.project
if prj.workspace.location ~= prj.location then
local prjpath = path.getrelative(prj.workspace.location, prj.location)
p.w('{')
p.w('"path": "%s"', prjpath)
p.w('},')
end
-- add root source file directories
local non_root_path = '' -- used to remove the non root part from the end of a leaf node's path
local tr = project.getsourcetree(prj)
tree.traverse(tr, {
onbranchenter = function(node, depth)
if depth ~= 0 then
non_root_path = non_root_path .. '/' .. node.name
end
end,
onbranchexit = function(node, depth)
if depth ~= 0 then
non_root_path = non_root_path:sub(1, non_root_path:len()-(node.name:len()+1))
end
end,
onleaf = function(node, depth)
if node.relpath == nil then
return
end
non_root_path = non_root_path ..'/'.. node.name
local rel_root_path = node.relpath:sub(1, node.relpath:len()-(non_root_path:len()))
non_root_path = non_root_path:sub(1, non_root_path:len()-(node.name:len()+1))
root_src_dirs[rel_root_path] = true
end
})
end,
})
for src_dir_rel in pairs(root_src_dirs) do
print(src_dir_rel)
p.w('{')
p.w('"path": "%s"', src_dir_rel)
p.w('},')
end
-- for clangd to find compile_commands.json in the build dir
p.w('],')
p.w('"settings":{')
p.w('"clangd.arguments":[')
p.w('"--compile-commands-dir=.",')
p.w('"--background-index",')
p.w('"--header-insertion=never"')
p.w(']}')
p.w('}')
--TODO wks.startproject
end
function m.generate_tasks(wks)
p.utf8()
_p('{')
_p(1, '"version": "2.0.0",')
_p(1, '"tasks": [')
local tr = workspace.grouptree(wks)
tree.traverse(tr, {
onleaf = function(n)
local prj = n.project
_p(1, '{')
_p(2, '"type": "shell",')
_p(2, '"label": "build %s",', prj.name)
-- check if ninja is used, otherwise default to make.
if os.isfile(prj.location .. '/build.ninja') then
_p(2, '"command": "clear && time ninja",')
else
_p(2, '"command": "clear && time make %s -r -j$(nproc)",', prj.name)
end
_p(2, '"args": [],')
_p(2, '"options": {')
_p(3, '"cwd": "${workspaceFolder}/"')
_p(2, '},')
_p(2, '"problemMatcher": [')
_p(3, '"$gcc"')
_p(2, '],')
_p(2, '"group": {')
_p(3, '"kind": "build",')
_p(3, '"isDefault": true')
_p(2, '},')
_p(1, '},')
end,
})
_p(1, ']')
_p('}')
end
function m.generate_launch(wks)
p.utf8()
_p('{')
_p(1, '"configurations": [')
local first_cfg = true
local tr = workspace.grouptree(wks)
tree.traverse(tr, {
onleaf = function(n)
local prj = n.project
for cfg in project.eachconfig(prj) do
if first_cfg then
first_cfg = false
_p(1, '{')
else
_p(1, ',{')
end
_p(2, '"name": "%s: Build and debug",', prj.name)
--_p(2, '"type": "cppdbg",') -- microsoft's C++ extension. TODO detect which is used and choose it?
_p(2, '"type": "lldb",') -- CodeLLVM
--_p(2, '"type": "lldb-dap",') -- LLVM's LLDB DAP
_p(2, '"request": "launch",')
_p(2, '"program": "%s/%s",', cfg.buildtarget.directory, prj.name)
_p(2, '"args": [],')
--_p(2, '"stopAtEntry": false,')
_p(2, '"cwd": "${workspaceFolder}/",')
--_p(2, '"externalConsole": false,')
-- _p(2, '"MIMode": "gdb",')
-- _p(2, '"setupCommands": [')
-- _p(3, '{')
-- _p(3, '"description": "Enable pretty-printing for gdb",')
-- _p(3, '"text": "-enable-pretty-printing",')
-- _p(3, '"ignoreFailures": true')
-- _p(3, '},')
-- _p(3, '{')
-- _p(3, '"description": "Enable break on all-exceptions",')
-- _p(3, '"text": "catch throw",')
-- _p(3, '"ignoreFailures": true')
-- _p(3, '}')
-- _p(2, '],')
-- _p(2, '"miDebuggerPath": "/usr/bin/gdb",')
_p(2, '"preLaunchTask": "build %s"', prj.name)
_p(1, '}')
end
end,
})
_p(1, ']')
_p('}')
end
function m.c_cpp_properties(wks)
_p('{')
_p(1, '"configurations": [')
local first_cfg = true
local tr = workspace.grouptree(wks)
tree.traverse(tr, {
onleaf = function(n)
local prj = n.project
for cfg in project.eachconfig(prj) do
if first_cfg then
first_cfg = false
_p(1, '{')
else
_p(1, ',{')
end
_p(2, '"name": "%s %s",', prj.name, cfg.name)
_p(2, '"includePath": [')
_p(3, '"${workspaceFolder}/**"')
for _, includedir in ipairs(cfg.includedirs) do
_p(3, ',"%s"', includedir)
end
_p(2, '],')
_p(2, '"defines": [')
if #cfg.defines > 0 then
_p(3, '"%s"', cfg.defines[1]:gsub('"','\\"'))
for i = 2,#cfg.defines do
_p(3, ',"%s"', cfg.defines[i]:gsub('"','\\"'))
end
end
_p(2, '],')
_p(2, '"compilerPath": "/usr/bin/g++",') --TODO premake toolset
if cfg.cdialect ~= nil then
_p(2, '"cStandard": "%s",', cfg.cdialect:lower())
end
if cfg.cppdialect ~= nil then
_p(2, '"cppStandard": "%s",', cfg.cppdialect:lower())
end
_p(2, '"intelliSenseMode": "gcc-x64",') --TODO premake toolset
_p(2, '"compilerArgs": [')
-- force includes
local toolset = m.getcompiler(cfg)
local forceincludes = toolset.getforceincludes(cfg)
_p(3, '"' .. table.concat(forceincludes, ";") .. '"')
_p(2, ']')
_p(1, '}')
end
end,
})
_p(1, '],')
_p(1, '"version": 4')
_p('}')
end