VirtualBox

source: vbox/trunk/tools/bin/gen-vscode-workspace.sh@ 95721

Last change on this file since 95721 was 95580, checked in by vboxsync, 2 years ago

tools/bin/gen-slickedit-workspace.sh,gen-vscode-workspace.sh: Put common code in common-gen-workspace.inc.sh. Fixed a few bugs in gen-vscode-workspace.sh so it 'works' on windows.

  • Property svn:eol-style set to LF
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 20.0 KB
Line 
1# !kmk_ash
2# $Id: gen-vscode-workspace.sh 95580 2022-07-09 19:28:19Z vboxsync $
3## @file
4# Script for generating a Visual Studio Code (vscode) workspace.
5#
6# This is derived from gen-slickedit-workspace.sh, so fixes may apply to both.
7#
8
9#
10# Copyright (C) 2009-2022 Oracle Corporation
11#
12# This file is part of VirtualBox Open Source Edition (OSE), as
13# available from http://www.virtualbox.org. This file is free software;
14# you can redistribute it and/or modify it under the terms of the GNU
15# General Public License (GPL) as published by the Free Software
16# Foundation, in version 2 as it comes in the "COPYING" file of the
17# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
18# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
19#
20
21#
22# Include code we share with gen-slickedit-workspace.sh
23#
24MY_SCRIPT_DIR=.
25case "$0" in
26 */*|*\\*)
27 MY_SCRIPT_DIR=$(echo "$0" | kmk_sed -e 's,[/\][^/\][^/\]*$,,')
28 ;;
29esac
30. "${MY_SCRIPT_DIR}/common-gen-workspace.inc.sh"
31
32
33#
34# Globals.
35#
36MY_PROJECT_FILES=""
37
38
39#
40# Parameters w/ defaults.
41#
42MY_VSCODE_DIR=".vscode"
43MY_VSCODE_FILE_DOT_EXT=".json"
44MY_OUT_DIR=${MY_VSCODE_DIR}
45MY_PRJ_PRF="VBox-"
46MY_WS_NAME="virtualbox.vscode-workspace" ## @todo v1.69 wants to open *.code-workspace...
47MY_DBG=""
48MY_WINDOWS_HOST=""
49MY_OPT_MINIMAL=""
50MY_OPT_USE_WILDCARDS="yes"
51
52
53##
54# Function generating an (intermediate) project task.
55#
56# @param $1 The project file name.
57# @param $2 Build config name.
58# @param $3 Task group to assign task to.
59# @param $4 kBuild extra args.
60# @param $5 kBuild working directory to set.
61# If empty, the file's directory will be used.
62# @param $6 kBuild per-task options.
63# Leave empty if not being used.
64my_generate_project_task()
65{
66 MY_FILE="${1}";
67 MY_CFG_NAME="${2}";
68 MY_TASK_GROUP="${3}";
69 MY_KMK_EXTRAS="${4}";
70 MY_KMK_CWD="${5}";
71 MY_KMK_TASK_ARGS="${6}";
72 shift; shift; shift; shift; shift; shift;
73
74 if [ -z "$MY_KMK_CWD" ]; then
75 MY_KMK_CWD='${fileDirname}'
76 fi
77
78 MY_TASK_LABEL="${MY_TASK_GROUP}: ${MY_CFG_NAME}"
79
80 echo ' {' >> "${MY_FILE}"
81 echo ' "type": "shell",' >> "${MY_FILE}"
82 echo ' "label": "'${MY_TASK_LABEL}'",' >> "${MY_FILE}"
83 echo ' "command": "'${MY_KMK_CMD}'",' >> "${MY_FILE}"
84 echo ' "args": [' >> "${MY_FILE}"
85 echo ' ' ${MY_KMK_ARGS} ',' >> "${MY_FILE}"
86 if [ -n "${MY_KMK_EXTRAS}" ]; then
87 echo ' '${MY_KMK_EXTRAS}' ,' >> "${MY_FILE}"
88 fi
89 echo ' "-C",' >> "${MY_FILE}"
90 echo ' "'${MY_KMK_CWD}'"' >> "${MY_FILE}"
91 if [ -n "${MY_KMK_TASK_ARGS}" ]; then
92 echo ' ', ${MY_KMK_TASK_ARGS} >> "${MY_FILE}"
93 fi
94 echo ' ],' >> "${MY_FILE}"
95 echo ' "options": {' >> "${MY_FILE}"
96 echo ' "cwd": "'${MY_KMK_CWD}'"' >> "${MY_FILE}"
97 echo ' },' >> "${MY_FILE}"
98 echo ' "problemMatcher": [' >> "${MY_FILE}"
99 echo ' "$gcc"' >> "${MY_FILE}"
100 echo ' ],' >> "${MY_FILE}"
101 echo ' "presentation": {' >> "${MY_FILE}"
102 echo ' "reveal": "always",' >> "${MY_FILE}"
103 echo ' "clear": true,' >> "${MY_FILE}"
104 echo ' "panel": "dedicated"' >> "${MY_FILE}"
105 echo ' },' >> "${MY_FILE}"
106 echo ' "detail": "compiler: /bin/clang++-9"' >> "${MY_FILE}"
107 echo ' },' >> "${MY_FILE}"
108}
109
110##
111# Function generating a project build config.
112#
113# @param $1 The project file name.
114# @param $2 Build config name.
115# @param $3 Extra kBuild command line options, variant 1.
116# @param $4 Extra kBuild command line options, variant 2.
117# @param $4+ Include directories.
118# @param $N --end-includes
119my_generate_project_config()
120{
121 MY_FILE="${1}";
122 MY_CFG_NAME="${2}";
123 MY_KMK_EXTRAS1="${3}";
124 MY_KMK_EXTRAS2="${4}";
125 MY_KMK_EXTRAS3="${5}";
126 MY_KMK_EXTRAS4="${6}";
127 shift; shift; shift; shift; shift; shift;
128
129 ## @todo Process includes.
130 while test $# -ge 1 -a "${1}" != "--end-includes";
131 do
132 for f in $1;
133 do
134 my_abs_dir ${f}
135 #echo "Includes: ${MY_ABS_DIR}/"
136 done
137 shift
138 done
139 shift
140
141 #
142 # Build tasks.
143 #
144 MY_TASK_CWD='${fileDirname}'
145 MY_TASK_ARGS='"-o", "${file}"'
146 my_generate_project_task "${MY_FILE}" "${MY_CFG_NAME}" "Compile1" "${MY_KMK_EXTRAS1}" \
147 "${MY_TASK_CWD}" "${MY_TASK_ARGS}"
148 if test -n "${MY_KMK_EXTRAS2}"; then
149 my_generate_project_task "${MY_FILE}" "${MY_CFG_NAME}" "Compile2" "${MY_KMK_EXTRAS2}" \
150 "${MY_TASK_CWD}" "${MY_TASK_ARGS}"
151 fi
152 if test -n "${MY_KMK_EXTRAS3}"; then
153 my_generate_project_task "${MY_FILE}" "${MY_CFG_NAME}" "Compile3" "${MY_KMK_EXTRAS3}" \
154 "${MY_TASK_CWD}" "${MY_TASK_ARGS}"
155 fi
156 if test -n "${MY_KMK_EXTRAS4}"; then
157 my_generate_project_task "${MY_FILE}" "${MY_CFG_NAME}" "Compile4" "${MY_KMK_EXTRAS4}" \
158 "${MY_TASK_CWD}" "${MY_TASK_ARGS}"
159 fi
160 MY_TASK_CWD='${workspaceFolder}'
161 MY_TASK_ARGS=""
162 my_generate_project_task "${MY_FILE}" "${MY_CFG_NAME}" "Build1" "${MY_KMK_EXTRAS1}" \
163 "${MY_TASK_CWD}" "${MY_TASK_ARGS}"
164 if test -n "${MY_KMK_EXTRAS2}"; then
165 my_generate_project_task "${MY_FILE}" "${MY_CFG_NAME}" "Build2" "${MY_KMK_EXTRAS2}" \
166 "${MY_TASK_CWD}" "${MY_TASK_ARGS}"
167 fi
168 if test -n "${MY_KMK_EXTRAS3}"; then
169 my_generate_project_task "${MY_FILE}" "${MY_CFG_NAME}" "Build3" "${MY_KMK_EXTRAS3}" \
170 "${MY_TASK_CWD}" "${MY_TASK_ARGS}"
171 fi
172 if test -n "${MY_KMK_EXTRAS4}"; then
173 my_generate_project_task "${MY_FILE}" "${MY_CFG_NAME}" "Build4" "${MY_KMK_EXTRAS4}" \
174 "${MY_TASK_CWD}" "${MY_TASK_ARGS}"
175 fi
176
177 MY_TASK_CWD='${workspaceFolder}'
178 MY_TASK_ARGS='"rebuild"'
179 my_generate_project_task "${MY_FILE}" "${MY_CFG_NAME}" "Rebuild1" "${MY_KMK_EXTRAS1}" \
180 "${MY_TASK_CWD}" "${MY_TASK_ARGS}"
181 if test -n "${MY_KMK_EXTRAS2}"; then
182 my_generate_project_task "${MY_FILE}" "${MY_CFG_NAME}" "Rebuild2" "${MY_KMK_EXTRAS2}" \
183 "${MY_TASK_CWD}" "${MY_TASK_ARGS}"
184 fi
185 if test -n "${MY_KMK_EXTRAS3}"; then
186 my_generate_project_task "${MY_FILE}" "${MY_CFG_NAME}" "Rebuild3" "${MY_KMK_EXTRAS3}" \
187 "${MY_TASK_CWD}" "${MY_TASK_ARGS}"
188 fi
189 if test -n "${MY_KMK_EXTRAS4}"; then
190 my_generate_project_task "${MY_FILE}" "${MY_CFG_NAME}" "Rebuild4" "${MY_KMK_EXTRAS4}" \
191 "${MY_TASK_CWD}" "${MY_TASK_ARGS}"
192 fi
193
194 #
195 # Generate compound tasks that invokes all needed sub tasks.
196 #
197 # Note: We include "VBox" in the label so that the command is easier to find
198 # in the command pallette.
199 #
200 echo ' {' >> "${MY_FILE}"
201 echo ' "label": "VBox Compile: '${MY_CFG_NAME}'",' >> "${MY_FILE}"
202 echo ' "dependsOrder": "sequence",' >> "${MY_FILE}"
203 echo ' "dependsOn": [ "Compile1: '${MY_CFG_NAME}'"' >> "${MY_FILE}"
204 if test -n "${MY_KMK_EXTRAS2}"; then
205 echo ' , "Compile2: '${MY_CFG_NAME}'"' >> "${MY_FILE}"
206 fi
207 if test -n "${MY_KMK_EXTRAS3}"; then
208 echo ' , "Compile3: '${MY_CFG_NAME}'"' >> "${MY_FILE}"
209 fi
210 if test -n "${MY_KMK_EXTRAS4}"; then
211 echo ' , "Compile4: '${MY_CFG_NAME}'"' >> "${MY_FILE}"
212 fi
213 echo ' ]' >> "${MY_FILE}"
214 echo ' },' >> "${MY_FILE}"
215 echo ' {' >> "${MY_FILE}"
216 echo ' "label": "VBox Build: '${MY_CFG_NAME}'",' >> "${MY_FILE}"
217 echo ' "dependsOrder": "sequence",' >> "${MY_FILE}"
218 echo ' "dependsOn": [ "Build1: '${MY_CFG_NAME}'"' >> "${MY_FILE}"
219 if test -n "${MY_KMK_EXTRAS2}"; then
220 echo ' , "Build2: '${MY_CFG_NAME}'"' >> "${MY_FILE}"
221 fi
222 if test -n "${MY_KMK_EXTRAS3}"; then
223 echo ' , "Build3: '${MY_CFG_NAME}'"' >> "${MY_FILE}"
224 fi
225 if test -n "${MY_KMK_EXTRAS4}"; then
226 echo ' , "Build4: '${MY_CFG_NAME}'"' >> "${MY_FILE}"
227 fi
228 echo ' ],' >> "${MY_FILE}"
229 echo ' "group": {' >> "${MY_FILE}"
230 echo ' "kind": "build",' >> "${MY_FILE}"
231 echo ' "isDefault": true' >> "${MY_FILE}"
232 echo ' }' >> "${MY_FILE}"
233 echo ' },' >> "${MY_FILE}"
234 echo ' {' >> "${MY_FILE}"
235 echo ' "label": "VBox Rebuild: '${MY_CFG_NAME}'",' >> "${MY_FILE}"
236 echo ' "dependsOrder": "sequence",' >> "${MY_FILE}"
237 echo ' "dependsOn": [ "Rebuild1: '${MY_CFG_NAME}'"' >> "${MY_FILE}"
238 if test -n "${MY_KMK_EXTRAS2}"; then
239 echo ' , "Rebuild2: '${MY_CFG_NAME}'"' >> "${MY_FILE}"
240 fi
241 if test -n "${MY_KMK_EXTRAS3}"; then
242 echo ' , "Rebuild3: '${MY_CFG_NAME}'"' >> "${MY_FILE}"
243 fi
244 if test -n "${MY_KMK_EXTRAS4}"; then
245 echo ' , "Rebuild4: '${MY_CFG_NAME}'"' >> "${MY_FILE}"
246 fi
247 echo ' ]' >> "${MY_FILE}"
248 echo ' },' >> "${MY_FILE}"
249}
250
251
252##
253# Function generating a project.
254#
255# @param $1 The project file name.
256# @param $2 The project working directory.
257# @param $3 Dummy separator.
258# @param $4+ Include directories.
259# @param $N --end-includes
260# @param $N+1 Directory sub-trees and files to include in the project.
261#
262my_generate_project()
263{
264 MY_PRJ_NAME=${1}
265 MY_WRK_DIR="${MY_FILE_ROOT_DIR}/${2}"
266 MY_FILE_PATH="${MY_WRK_DIR}/.vscode"
267 shift
268 shift
269 shift
270
271 # Make sure that the .vscode project dir exists. But do *NOT* create the
272 # parent dir, it must already exist. Duh!
273 test -d "${MY_FILE_PATH}" || ${MY_MKDIR} "${MY_FILE_PATH}"
274
275 MY_FILE="${MY_FILE_PATH}/c_cpp_properties${MY_VSCODE_FILE_DOT_EXT}";
276 echo "Generating ${MY_FILE}..."
277
278 # Add it to the project list for workspace construction later on.
279 MY_PROJECT_FILES="${MY_PROJECT_FILES} ${MY_PRJ_NAME}:${MY_WRK_DIR}"
280
281 #
282 # Generate the C/C++ bits.
283 ## @todo Might needs tweaking a bit more as stuff evolves.
284 #
285 echo '{' > "${MY_FILE}"
286 echo ' "configurations": [' >> "${MY_FILE}"
287 echo ' {' >> "${MY_FILE}"
288 echo ' "name": "Linux",' >> "${MY_FILE}"
289 echo ' "includePath": [' >> "${MY_FILE}"
290 echo ' "${workspaceFolder}/**"' >> "${MY_FILE}"
291 echo ' ],' >> "${MY_FILE}"
292 echo ' "defines": [],' >> "${MY_FILE}"
293 echo ' "cStandard": "c17",' >> "${MY_FILE}"
294 echo ' "cppStandard": "c++14",' >> "${MY_FILE}"
295 echo ' "intelliSenseMode": "linux-gcc-x64",' >> "${MY_FILE}"
296 echo ' "compilerPath": "/usr/bin/gcc"' >> "${MY_FILE}"
297 echo ' }' >> "${MY_FILE}"
298 echo ' ],' >> "${MY_FILE}"
299 echo ' "version": 4' >> "${MY_FILE}"
300 echo '}' >> "${MY_FILE}"
301
302 MY_FILE="${MY_FILE_PATH}/tasks${MY_VSCODE_FILE_DOT_EXT}";
303 echo "Generating ${MY_FILE}..."
304
305 #
306 # Tasks header.
307 #
308 echo '{' > "${MY_FILE}"
309 echo ' "version": "2.0.0",' >> "${MY_FILE}"
310 echo ' "tasks": [' >> "${MY_FILE}"
311
312 my_generate_project_config "${MY_FILE}" "Default" "" "" "" "" $*
313 my_generate_project_config "${MY_FILE}" "Debug + hardening" \
314 '"KBUILD_TYPE=debug", "VBOX_WITH_HARDENING=1"' \
315 "" "" "" $*
316 my_generate_project_config "${MY_FILE}" "Release + hardening" \
317 '"KBUILD_TYPE=release", "VBOX_WITH_HARDENING=1"' \
318 "" "" "" $*
319 my_generate_project_config "${MY_FILE}" "Debug+Release + hardening" \
320 '"KBUILD_TYPE=debug", "VBOX_WITH_HARDENING=1"' \
321 '"KBUILD_TYPE=release", "VBOX_WITH_HARDENING=1"' \
322 "" "" $*
323 my_generate_project_config "${MY_FILE}" "Debug w/o hardening" \
324 '"KBUILD_TYPE=debug", "VBOX_WITHOUT_HARDENING=1"' \
325 "" "" "" $*
326 my_generate_project_config "${MY_FILE}" "Release w/o hardening" \
327 '"KBUILD_TYPE=release", "VBOX_WITHOUT_HARDENING=1"' \
328 "" "" "" $*
329 my_generate_project_config "${MY_FILE}" "Debug+Release w/o hardening" \
330 '"KBUILD_TYPE=debug", "VBOX_WITHOUT_HARDENING=1"' \
331 '"KBUILD_TYPE=release", "VBOX_WITHOUT_HARDENING=1"' \
332 "" "" $*
333 my_generate_project_config "${MY_FILE}" "Debug+Release with and without hardening" \
334 '"KBUILD_TYPE=debug", "VBOX_WITH_HARDENING=1"' \
335 '"KBUILD_TYPE=release", "VBOX_WITH_HARDENING=1"' \
336 '"KBUILD_TYPE=debug", "VBOX_WITHOUT_HARDENING=1"' \
337 '"KBUILD_TYPE=release", "VBOX_WITHOUT_HARDENING=1"' \
338 $*
339
340 #
341 # Tasks footer.
342 #
343 echo ' ]' >> "${MY_FILE}"
344 echo '}' >> "${MY_FILE}"
345
346 while test $# -ge 1 -a "${1}" != "--end-includes";
347 do
348 shift;
349 done;
350 shift;
351
352 return 0
353}
354
355
356##
357# Generate the workspace
358#
359my_generate_workspace()
360{
361 MY_FILE="${MY_FILE_ROOT_DIR}/${MY_WS_NAME}"
362 echo "Generating ${MY_FILE}..."
363 echo '{' > "${MY_FILE}"
364 echo ' "folders": [' >> "${MY_FILE}"
365 for i in ${MY_PROJECT_FILES};
366 do
367 MY_PRJ_NAME=$(echo $i | ${MY_SED} -e 's/:.*$//')
368 MY_PRJ_PATH=$(echo $i | ${MY_SED} -e 's/^.*://')
369 echo ' {' >> "${MY_FILE}"
370 echo ' "name": "'"${MY_PRJ_NAME}"'",' >> "${MY_FILE}"
371 echo ' "path": "'"${MY_PRJ_PATH}"'",' >> "${MY_FILE}"
372 echo ' },' >> "${MY_FILE}"
373 done
374 echo ' ],' >> "${MY_FILE}"
375 echo ' "settings": {},' >> "${MY_FILE}"
376 echo ' "extensions": {' >> "${MY_FILE}"
377 echo ' "recommendations": ["ms-vscode.cpptools"]' >> "${MY_FILE}"
378 echo ' },' >> "${MY_FILE}"
379 echo '}' >> "${MY_FILE}"
380 return 0
381}
382
383
384#
385# Parse arguments.
386#
387while test $# -ge 1;
388do
389 ARG=$1
390 shift
391 case "$ARG" in
392
393 --rootdir)
394 if test $# -eq 0; then
395 echo "error: missing --rootdir argument." 1>&2
396 exit 1;
397 fi
398 MY_ROOT_DIR="$1"
399 shift
400 ;;
401
402 --outdir)
403 if test $# -eq 0; then
404 echo "error: missing --outdir argument." 1>&2
405 exit 1;
406 fi
407 MY_OUT_DIR="$1"
408 shift
409 ;;
410
411 --project-base)
412 if test $# -eq 0; then
413 echo "error: missing --project-base argument." 1>&2
414 exit 1;
415 fi
416 MY_PRJ_PRF="$1"
417 shift
418 ;;
419
420 --workspace)
421 if test $# -eq 0; then
422 echo "error: missing --workspace argument." 1>&2
423 exit 1;
424 fi
425 MY_WS_NAME="$1"
426 shift
427 ;;
428
429 --windows-host)
430 MY_WINDOWS_HOST=1
431 ;;
432
433 --minimal)
434 MY_OPT_MINIMAL=1
435 ;;
436
437 # usage
438 --h*|-h*|-?|--?)
439 echo "usage: $0 [--rootdir <rootdir>] [--outdir <outdir>] [--project-base <prefix>] [--workspace <name>] [--minimal]"
440 echo ""
441 echo "If --outdir is specified, you must specify a --rootdir relative to it as well."
442 exit 1;
443 ;;
444
445 # default
446 *)
447 echo "error: Invalid parameter '$ARG'" 1>&2
448 exit 1;
449
450 esac
451done
452
453
454#
455# From now on everything *MUST* succeed.
456#
457set -e
458
459
460#
461# Make sure the output directory exists, is valid and clean.
462#
463## @todo r=bird: The above statement is *extremely* misleading. This script will
464# create .vscode subdirs all over the place, and the root one doesn't seem to
465# have any special purpose compared to the rest. Guess this is just fluff
466# inherited from gen-slickedit-workspace.sh.
467${MY_RM} -f \
468 "${MY_OUT_DIR}"*.json \
469 "${MY_OUT_DIR}/${MY_ROOT_DIR}/${MY_WS_NAME}"
470${MY_MKDIR} -p "${MY_OUT_DIR}"
471
472# Enter the directory (or ${MY_ROOT_DIR} + my_abs_dir won't work) and save the absolute root path.
473cd "${MY_OUT_DIR}"
474my_abs_dir "."
475MY_FILE_ROOT_DIR=${MY_ABS_DIR} ## @todo r=bird: 'FILE' or 'DIR'? ;-)
476
477
478#
479# Determine the invocation to conjure up kmk.
480#
481my_abs_dir "tools"
482if test -n "${MY_WINDOWS_HOST}"; then
483 MY_KMK_CMD="cscript.exe"
484 MY_KMK_ARGS='"/Nologo", "'${MY_ABS_DIR}/envSub.vbs'", "--quiet", "--", "kmk.exe"'
485else
486 MY_KMK_CMD="/usr/bin/env"
487 MY_KMK_ARGS='"LANG=C", "'${MY_ABS_DIR}/env.sh'", "--quiet", "--no-wine", "kmk"'
488fi
489
490
491#
492# Generate the projects (common code) and workspace.
493#
494my_generate_all_projects # in common-gen-workspace-projects.inc.sh
495my_generate_workspace
496
497
498echo "done"
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette