I have a working solution, might need some tweaking on POSIX systems unless you have Powershell installed.
As you can see everything is defined in the c_cpp_properties.json and then the variables are referenced as inputs in the tasks.json
Not as elegant as i'd have liked but it works for having a single source of truth.
c_cpp_properties.json
{
"env": {
"linkers": [],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE"
],
"app_title": "App Title",
"app_exe": "app_exe_name",
"common_library": "${workspaceFolder}/../Common-Lib/src",
"windows_sdk_path": "C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0",
"mingw_path": "C:/Users/User Name/Documents/Environment/Apps/mingw64",
"self_include": "${workspaceFolder}/src",
"common_library_include": "${workspaceFolder}/../Common-Lib/src",
"mingw_include": "${mingw_path}/include",
"windows_sdk_ucrt_include": "${windows_sdk_path}/ucrt",
"windows_sdk_shared_include": "${windows_sdk_path}/shared",
"windows_sdk_um_include": "${windows_sdk_path}/um",
"windows_sdk_winrt_include": "${windows_sdk_path}/winrt",
"windows_sdk_cppwinrt_include": "${windows_sdk_path}/cppwinrt",
"commonIncludePath": [
"${self_include}/**",
"${common_library_include}/**"
],
"windowsIncludePath": [
"${mingw_include}/**",
"${windows_sdk_ucrt_include}/**",
"${windows_sdk_shared_include}/**",
"${windows_sdk_um_include}/**",
"${windows_sdk_winrt_include}/**",
"${windows_sdk_cppwinrt_include}/**"
]
},
"configurations": [
{
"name": "Win32",
"customConfigurationVariables": {
"app_title": "${app_title}",
"app_exe": "${app_exe}",
"mingw_path": "${mingw_path}"
},
"includePath": [
"${commonIncludePath}",
"${windowsIncludePath}"
],
"defines": ["${defines}", "_WINDOWS"],
"compilerPath": "${mingw_path}/bin/gcc.exe",
"cStandard": "c23",
"cppStandard": "c++23",
"intelliSenseMode": "windows-gcc-x64",
"mergeConfigurations": true
}
],
"version": 4,
"enableConfigurationSquiggles": true
}
tasks.json
{
"version": "2.0.0",
"problemMatcher": [
"$gcc"
],
"options": {
"cwd": "${workspaceFolder}/bin",
"env": {
"MINGW_PATH": "${input:mingw_path}"
}
},
"presentation": {
"echo": true,
"reveal": "always",
"focus": true,
"panel": "new",
"showReuseMessage": true,
"clear": true
},
"isBuildCommand": true,
"inputs": [
{
"id": "app_exe",
"type": "command",
"command": "cpptools.activeConfigCustomVariable",
"args": "app_exe"
},
{
"id": "app_title",
"type": "command",
"command": "cpptools.activeConfigCustomVariable",
"args": "app_title"
},
{
"id": "mingw_path",
"type": "command",
"command": "cpptools.activeConfigCustomVariable",
"args": "mingw_path"
},
{
"id": "self_include",
"type": "command",
"command": "cpptools.activeConfigCustomVariable",
"args": "self_include"
},
{
"id": "common_library_include",
"type": "command",
"command": "cpptools.activeConfigCustomVariable",
"args": "common_library_include"
},
{
"id": "mingw_include",
"type": "command",
"command": "cpptools.activeConfigCustomVariable",
"args": "mingw_include"
},
{
"id": "windows_sdk_ucrt_include",
"type": "command",
"command": "cpptools.activeConfigCustomVariable",
"args": "windows_sdk_ucrt_include"
},
{
"id": "windows_sdk_shared_include",
"type": "command",
"command": "cpptools.activeConfigCustomVariable",
"args": "windows_sdk_shared_include"
},
{
"id": "windows_sdk_um_include",
"type": "command",
"command": "cpptools.activeConfigCustomVariable",
"args": "windows_sdk_um_include"
},
{
"id": "windows_sdk_winrt_include",
"type": "command",
"command": "cpptools.activeConfigCustomVariable",
"args": "windows_sdk_winrt_include"
},
{
"id": "windows_sdk_cppwinrt_include",
"type": "command",
"command": "cpptools.activeConfigCustomVariable",
"args": "windows_sdk_cppwinrt_include"
}
],
"tasks": [
{
"type": "cppbuild",
"label": "C Build (Windows)",
"detail": "Build Non Debug.",
"command": "gcc",
"args": [
"-g",
"${workspaceFolder}/src/main.c",
"-o",
"${workspaceFolder}/bin/${input:app_exe}.exe",
"-Ofast",
"-lgdi32",
"-ldwmapi",
"-luxtheme",
"-fdiagnostics-color=always",
"-I", "${input:self_include}", "-I", "${input:common_library_include}",
"-I", "${input:mingw_include}", "-I", "${input:windows_sdk_ucrt_include}", "-I", "${input:windows_sdk_shared_include}",
"-I", "${input:windows_sdk_um_include}", "-I", "${input:windows_sdk_winrt_include}", "-I", "${input:windows_sdk_cppwinrt_include}"
],
"group": {
"kind": "build",
"isDefault": false
}
},
{
"type": "cppbuild",
"label": "C Build Debug (Windows)",
"detail": "Build With Debugging.",
"command": "gcc",
"args": [
"-g",
"${workspaceFolder}/src/main.c",
"-o",
"${workspaceFolder}/bin/${input:app_exe}-debug.exe",
"-DDEBUG",
"-Ofast",
"-lgdi32",
"-ldwmapi",
"-luxtheme",
"-lruntimeobject",
"-fdiagnostics-color=always",
"-I", "${input:self_include}", "-I", "${input:common_library_include}",
"-I", "${input:mingw_include}", "-I", "${input:windows_sdk_ucrt_include}", "-I", "${input:windows_sdk_shared_include}",
"-I", "${input:windows_sdk_um_include}", "-I", "${input:windows_sdk_winrt_include}", "-I", "${input:windows_sdk_cppwinrt_include}"
],
"group": {
"kind": "build",
"isDefault": false
}
},
{
"type": "cppbuild",
"label": "C Build Debug (POSIX)",
"detail": "Build With Debugging.",
"command": "gcc",
"args": [
"-g",
"${workspaceFolder}/src/main.c",
"-o",
"${workspaceFolder}/bin/${input:app_exe}-debug.exe",
"-DDEBUG",
"-Ofast",
"-lrt",
"-fdiagnostics-color=always",
"-I", "${input:self_include}", "-I", "${input:common_library_include}"
],
"group": {
"kind": "build",
"isDefault": false
}
},
{
"type": "cppbuild",
"label": "C Build Active file (Windows)",
"detail": "Build Current File.",
"command": "gcc",
"args": [
"-g",
"${workspaceFolder}/src/${fileBasenameNoExtension}.c",
"-o",
"${workspaceFolder}/bin/${fileBasenameNoExtension}.o",
"-DDEBUG",
"-Ofast",
"-lgdi32",
"-ldwmapi",
"-luxtheme",
"-fdiagnostics-color=always",
"-I", "${input:self_include}", "-I", "${input:common_library_include}",
"-I", "${input:mingw_include}", "-I", "${input:windows_sdk_ucrt_include}", "-I", "${input:windows_sdk_shared_include}",
"-I", "${input:windows_sdk_um_include}", "-I", "${input:windows_sdk_winrt_include}", "-I", "${input:windows_sdk_cppwinrt_include}"
],
"group": {
"kind": "build",
"isDefault": false
}
}
]
}
And as a bonus you can also pass values into launch.json
{
"version": "0.2.0",
"inputs": [
{
"id": "app_exe",
"type": "command",
"command": "cpptools.activeConfigCustomVariable",
"args": "app_exe"
},
{
"id": "app_title",
"type": "command",
"command": "cpptools.activeConfigCustomVariable",
"args": "app_title"
},
{
"id": "mingw_path",
"type": "command",
"command": "cpptools.activeConfigCustomVariable",
"args": "mingw_path"
}
],
"configurations": [
{
"name": "Debug",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/bin/${input:app_exe}-debug.exe",
"cwd": "${workspaceFolder}/bin",
"args": [
"--title",
"Debug Title",
"--message",
"Debugging Notification",
"/DEBUG",
"/test"
],
"stopAtEntry": false,
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "${input:mingw_path}/bin/gdb.exe",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "C Build Debug (Windows)"
},
{
"name": "Launch",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/bin/${input:app_exe}.exe",
"cwd": "${workspaceFolder}/bin",
"args": [
],
"stopAtEntry": false,
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "${input:mingw_path}/bin/gdb.exe",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "C Build (Windows)"
}
]
}