VScode: Defining own variables in tasks.json

I’ve set up a tasks.json file for building a project on multiple platforms. All platforms see the same content of the project repository. This is done either via disk sharing, because of running another platform in a VM, or via sync with the Git repository.
So far so good, they all see the same task.json. However some command lines are rather long and those long lines are identical for most part.
for example:

"rm -rf build; mkdir build; cd build; ../configure --with-bash-malloc=no CFLAGS="-O3 -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free" LDFLAGS=-L/usr/local/lib LIBS="-ltcmalloc -lcurl" CC=clang

Similar lines are there for the different platforms.
The configure part is always the same for the different platforms, so it would be nice to factor out this common part. Thus the question is if it is possible to define your own variables, so you can use them similar to ${workspaceRoot}.

Thus define somewhere

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>"win_dir": "build_windows",
"linux_dir": "build",
"osx_dir": "build_osx",
"configure": "../configure --with-bash-malloc=no CFLAGS="-O3 -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free" LDFLAGS=-L/usr/local/lib LIBS="-ltcmalloc -lcurl" CC=clang"
</code>
<code>"win_dir": "build_windows", "linux_dir": "build", "osx_dir": "build_osx", "configure": "../configure --with-bash-malloc=no CFLAGS="-O3 -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free" LDFLAGS=-L/usr/local/lib LIBS="-ltcmalloc -lcurl" CC=clang" </code>
"win_dir": "build_windows",
"linux_dir": "build",
"osx_dir": "build_osx",
"configure": "../configure --with-bash-malloc=no CFLAGS="-O3 -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free" LDFLAGS=-L/usr/local/lib LIBS="-ltcmalloc -lcurl" CC=clang"

And then write

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>"tasks": [
{
"taskName": "configure",
"command": "bash",
"windows": {
"args": ["-c", "rm -rf ${win_dir}; mkdir ${win_dir}; cd ${win_dir}; ${configure}"]
},
"linux": {
"args": ["-c", "rm -rf ${linux_dir}; mkdir ${linux_dir}; cd ${linux_dir}; ${configure}"]
},
"osx": {
"args": ["-c", "rm -rf ${osx_dir}; mkdir ${osx_dir}; cd ${osx_dir}; ${configure}"]
},
"isBuildCommand": true,
"problemMatcher": "$make-compile"
},
... others tasks using the variables
</code>
<code>"tasks": [ { "taskName": "configure", "command": "bash", "windows": { "args": ["-c", "rm -rf ${win_dir}; mkdir ${win_dir}; cd ${win_dir}; ${configure}"] }, "linux": { "args": ["-c", "rm -rf ${linux_dir}; mkdir ${linux_dir}; cd ${linux_dir}; ${configure}"] }, "osx": { "args": ["-c", "rm -rf ${osx_dir}; mkdir ${osx_dir}; cd ${osx_dir}; ${configure}"] }, "isBuildCommand": true, "problemMatcher": "$make-compile" }, ... others tasks using the variables </code>
"tasks": [
    {
        "taskName": "configure",
        "command": "bash",
        "windows": {
            "args": ["-c", "rm -rf ${win_dir}; mkdir ${win_dir}; cd ${win_dir}; ${configure}"]
        },
        "linux": {
            "args": ["-c", "rm -rf ${linux_dir}; mkdir ${linux_dir}; cd ${linux_dir}; ${configure}"]
        },
        "osx": {
            "args": ["-c", "rm -rf ${osx_dir}; mkdir ${osx_dir}; cd ${osx_dir}; ${configure}"]
        },
        "isBuildCommand": true,
        "problemMatcher": "$make-compile"
    },
    ... others tasks using the variables

When making changes to the build directory or arguments passed to configure etc, then the tasks.json file needs only editing at one place, instead of many.

Perhaps it is already possible but I’m unable to find out how. I tried to do something with the declares block, but that seems to be hard tied to problemMatcher. You can find some examples, but I could not find clear documentation of of the elements of the tasks.json file and how they interact.

Perhaps I’m missing something, please educate me!

1

Adam Parkin’s answer won’t work because, at least on windows, the shell will not substitute environment variables given as arguments. ${env:...} variables as suggested in a comment on that answer won’t be substituted using environment variables set in tasks.json itself, only preexisting ones. You can however add custom settings in settings.json, and reference those in tasks.json using ${config:...}.

e.g. settings.json:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>{
"win_dir": "build_windows",
"linux_dir": "build",
"osx_dir": "build_osx",
"configure": "../configure --with-bash-malloc=no CFLAGS="-O3 -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free" LDFLAGS=-L/usr/local/lib LIBS="-ltcmalloc -lcurl" CC=clang"
}
</code>
<code>{ "win_dir": "build_windows", "linux_dir": "build", "osx_dir": "build_osx", "configure": "../configure --with-bash-malloc=no CFLAGS="-O3 -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free" LDFLAGS=-L/usr/local/lib LIBS="-ltcmalloc -lcurl" CC=clang" } </code>
{
    "win_dir": "build_windows",
    "linux_dir": "build",
    "osx_dir": "build_osx",
    "configure": "../configure --with-bash-malloc=no CFLAGS="-O3 -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free" LDFLAGS=-L/usr/local/lib LIBS="-ltcmalloc -lcurl" CC=clang"
}

in tasks.json:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>{
"tasks": [
{
"taskName": "configure",
"command": "bash",
"windows": {
"args": ["-c", "rm -rf ${config:win_dir}; mkdir ${config:win_dir}; cd ${config:win_dir}; ${config:configure}"]
},
"linux": {
"args": ["-c", "rm -rf ${config:linux_dir}; mkdir ${config:linux_dir}; cd ${config:linux_dir}; ${config:configure}"]
},
"osx": {
"args": ["-c", "rm -rf ${config:osx_dir}; mkdir ${config:osx_dir}; cd ${config:osx_dir}; ${config:configure}"]
},
"isBuildCommand": true,
"problemMatcher": "$make-compile"
},
// ... other tasks using the variables
]
}
</code>
<code>{ "tasks": [ { "taskName": "configure", "command": "bash", "windows": { "args": ["-c", "rm -rf ${config:win_dir}; mkdir ${config:win_dir}; cd ${config:win_dir}; ${config:configure}"] }, "linux": { "args": ["-c", "rm -rf ${config:linux_dir}; mkdir ${config:linux_dir}; cd ${config:linux_dir}; ${config:configure}"] }, "osx": { "args": ["-c", "rm -rf ${config:osx_dir}; mkdir ${config:osx_dir}; cd ${config:osx_dir}; ${config:configure}"] }, "isBuildCommand": true, "problemMatcher": "$make-compile" }, // ... other tasks using the variables ] } </code>
{
    "tasks": [
        {
            "taskName": "configure",
            "command": "bash",
            "windows": {
                "args": ["-c", "rm -rf ${config:win_dir}; mkdir ${config:win_dir}; cd ${config:win_dir}; ${config:configure}"]
            },
            "linux": {
                "args": ["-c", "rm -rf ${config:linux_dir}; mkdir ${config:linux_dir}; cd ${config:linux_dir}; ${config:configure}"]
            },
            "osx": {
                "args": ["-c", "rm -rf ${config:osx_dir}; mkdir ${config:osx_dir}; cd ${config:osx_dir}; ${config:configure}"]
            },
            "isBuildCommand": true,
            "problemMatcher": "$make-compile"
        },
        // ... other tasks using the variables
    ]
}

2

Use tasks.options.env to set per-task environment

As documented in the VSCode custom tasks page, environment variables can be set either at the task level or the file level, depending on how broadly those values should be applied.

Task-level Example:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>{
"version": "2.0.0",
"tasks": [
{
"label": "Test with passing variable",
"type": "shell",
"options": {
"env": {
"GREETING_VAR": "Hello"
}
},
"command": "echo ${GREETING_VAR}, World!"
}
]
}
</code>
<code>{ "version": "2.0.0", "tasks": [ { "label": "Test with passing variable", "type": "shell", "options": { "env": { "GREETING_VAR": "Hello" } }, "command": "echo ${GREETING_VAR}, World!" } ] } </code>
{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "Test with passing variable",
            "type": "shell",
            "options": {
                "env": {
                    "GREETING_VAR": "Hello"
                }
            },
            "command": "echo ${GREETING_VAR}, World!"
        }
    ]
}

File-level Example:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>{
"version": "2.0.0",
"options": {
"env": {
"GREETING_VAR": "Hello"
}
},
"tasks": [
{
"label": "Test with passing variable",
"type": "shell",
"command": "echo ${GREETING_VAR}, World!"
}
]
}
</code>
<code>{ "version": "2.0.0", "options": { "env": { "GREETING_VAR": "Hello" } }, "tasks": [ { "label": "Test with passing variable", "type": "shell", "command": "echo ${GREETING_VAR}, World!" } ] } </code>
{
    "version": "2.0.0",
    "options": {
         "env": {
              "GREETING_VAR": "Hello"
         }
    },
    "tasks": [
        {
            "label": "Test with passing variable",
            "type": "shell",
            "command": "echo ${GREETING_VAR}, World!"
        }
    ]
}

More details regarding options in tasks may be found here.

1

Thus the question is if it is possible to define your own variables, so you can use them similar to ${workspaceRoot}.

You could define environment variables in your tasks.json:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"options": {
"env": {
"win_dir": "build_windows",
"linux_dir": "build",
"osx_dir": "build_osx",
"configure": "../configure --with-bash-malloc=no CFLAGS="-O3 -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free" LDFLAGS=-L/usr/local/lib LIBS="-ltcmalloc -lcurl" CC=clang"
}
},
"tasks": [
{
"label": "Example",
"type": "shell",
"command": "echo win_dir is $env:win_dir"
},
]
}
</code>
<code>{ // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format "version": "2.0.0", "options": { "env": { "win_dir": "build_windows", "linux_dir": "build", "osx_dir": "build_osx", "configure": "../configure --with-bash-malloc=no CFLAGS="-O3 -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free" LDFLAGS=-L/usr/local/lib LIBS="-ltcmalloc -lcurl" CC=clang" } }, "tasks": [ { "label": "Example", "type": "shell", "command": "echo win_dir is $env:win_dir" }, ] } </code>
{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "options": {
        "env": {
            "win_dir": "build_windows",
            "linux_dir": "build",
            "osx_dir": "build_osx",
            "configure": "../configure --with-bash-malloc=no CFLAGS="-O3 -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free" LDFLAGS=-L/usr/local/lib LIBS="-ltcmalloc -lcurl" CC=clang"
        }
    },
    "tasks": [
        {
            "label": "Example",
            "type": "shell",
            "command": "echo win_dir is $env:win_dir"
        },
    ]
}

With that, you could then also use the environment matching to refer to the relevant environment variables.

3

I am taking a different approach.

tasks.json

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>{
"version": "2.0.0",
"params":{
"git_version":"2.30.0",
"node_version":"14.13.6",
"python_version":"3.8"
},
"tasks": [
{
"label":"Process Task.json",
"type":"shell",
"command":"python process_tasks.py",
"group":"build",
"isBackground":true
},
{
"label":"Test process_tasks.py",
"type":"shell",
"command":"echo $[params.git_version]",
"group":"test",
"presentation": {
"reveal": "always"
}
}
]
}
</code>
<code>{ "version": "2.0.0", "params":{ "git_version":"2.30.0", "node_version":"14.13.6", "python_version":"3.8" }, "tasks": [ { "label":"Process Task.json", "type":"shell", "command":"python process_tasks.py", "group":"build", "isBackground":true }, { "label":"Test process_tasks.py", "type":"shell", "command":"echo $[params.git_version]", "group":"test", "presentation": { "reveal": "always" } } ] } </code>
{
    "version": "2.0.0",
    "params":{
        "git_version":"2.30.0",
        "node_version":"14.13.6",
        "python_version":"3.8"
    },
    "tasks": [
        {
            "label":"Process Task.json",
            "type":"shell",
            "command":"python process_tasks.py",
            "group":"build",
            "isBackground":true
        },
        {
            "label":"Test process_tasks.py",
            "type":"shell",
            "command":"echo $[params.git_version]",
            "group":"test",
            "presentation": {
                "reveal": "always"
            }
        }
     ]
}

Rather than making env variables, we can follow the flowing steps:

Step 1:

Make a task in tasks.json as follows

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>{
"label":"Process Task.json",
"type":"shell",
"command":"python process_tasks.py",
"group":"build",
"isBackground":true
},
</code>
<code>{ "label":"Process Task.json", "type":"shell", "command":"python process_tasks.py", "group":"build", "isBackground":true }, </code>
{
    "label":"Process Task.json",
    "type":"shell",
    "command":"python process_tasks.py",
    "group":"build",
    "isBackground":true
},

Step 2:

process_tasks.py is a Python file that will replace variables in tasks.json with the actual value:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>import json
import os
import re
if __name__ == "__main__":
# Get the path to the JSON file
json_path = os.path.join(".vscode/tasks.json")
with open(json_path, "r") as f:
data = json.load(f)
with open(json_path, "r") as f:
lines = f.readlines()
new_lines = []
#regex to find text between $[]
regex = re.compile(r"$[(.*?)]")
for line in lines:
#regex in line:
match = regex.search(line)
if match:
#get the text between $[]
text = match.group(1)
keys = text.split(".")
buffer_data = data
for key in keys:
buffer_data = buffer_data[key]
#replace the text with the value of the environment variable
line = line.replace(f"$[{text}]", buffer_data)
new_lines.append(line)
with open(json_path, "w") as f:
f.writelines(new_lines)
</code>
<code>import json import os import re if __name__ == "__main__": # Get the path to the JSON file json_path = os.path.join(".vscode/tasks.json") with open(json_path, "r") as f: data = json.load(f) with open(json_path, "r") as f: lines = f.readlines() new_lines = [] #regex to find text between $[] regex = re.compile(r"$[(.*?)]") for line in lines: #regex in line: match = regex.search(line) if match: #get the text between $[] text = match.group(1) keys = text.split(".") buffer_data = data for key in keys: buffer_data = buffer_data[key] #replace the text with the value of the environment variable line = line.replace(f"$[{text}]", buffer_data) new_lines.append(line) with open(json_path, "w") as f: f.writelines(new_lines) </code>
import json
import os
import re

if __name__ == "__main__":
    # Get the path to the JSON file
    json_path = os.path.join(".vscode/tasks.json")

    with open(json_path, "r") as f:
        data = json.load(f)

    with open(json_path, "r") as f:
        lines = f.readlines()

        new_lines = []

        #regex to find text between $[]
        regex = re.compile(r"$[(.*?)]")

        for line in lines:
            #regex in line:
            match = regex.search(line)
            if match:
                #get the text between $[]

                text = match.group(1)

                keys = text.split(".")

                buffer_data = data

                for key in keys:
                    buffer_data = buffer_data[key]

                #replace the text with the value of the environment variable
                line = line.replace(f"$[{text}]", buffer_data)

            new_lines.append(line)

    with open(json_path, "w") as f:
        f.writelines(new_lines)

Step 3:

Add a test task to verify your result

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>{
"label":"Test process_tasks.py",
"type":"shell",
"command":"echo $[params.git_version]",
"group":"test",
"presentation": {
"reveal": "always"
}
},
</code>
<code>{ "label":"Test process_tasks.py", "type":"shell", "command":"echo $[params.git_version]", "group":"test", "presentation": { "reveal": "always" } }, </code>
{
    "label":"Test process_tasks.py",
    "type":"shell",
    "command":"echo $[params.git_version]",
    "group":"test",
    "presentation": {
        "reveal": "always"
    }
},

Note:

Making this “Process Task.json” as a global task and adding the correct path of the process.py file in the build task will reduce a lot of work.

Thus we can define our own variables inside tasks.json and access them using $[params.git_version].

After executing the “Process Task.json” task, all variables in $[] format will be replaced by its corresponding value.

0

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật