使用Visual C++和Open Folder自定义您的环境
[原文发表地址] Customizing your Environment with Visual C++ and Open Folder
[原文发表时间] 2017/11/02
自从我们支持了打开C ++代码文件夹的功能之后,社区的客户一直希望有更多地可以控制构建和编辑环境的功能。为实现这些想法,我们在Visual Studio 2017的最新版本中增加了一些新的方法可以通过使用CppProperties.json来自定义您的环境。
这个新的自定义界面使您能够使用更广泛的工具,编写更简洁的CppProperties文件,并且具有与MSBuild类似的强大的单个配置的自定义。下面的主题展示了原始C++ Open Folder文章中描述的几个概念。如果您不熟悉编辑CppProperties.json,Launch.vs.json和Tasks.vs.json,可能需要先阅读该文章。
C++ Open Folder这篇文章与我们之前发布的为CMake项目自定义您的环境相匹配,所以如果您已经阅读过了,可能会发现其中有一些内容是相似的,因为我们努力保持经验一致。而最重要的区别在于“关于Launch.vs.json和Tasks.vs.json”如何使用特定于配置的变量。
CppProperties.json的新功能
这种新的灵活性的核心在于您的项目的CppProperties.json文件,它源于两个新的概念:
- 使用“inheritEnvironments”属性来继承单个配置或一组默认全局环境变量的能力。
- 通过定义“environments”块来定义单个配置或是自定义环境变量及其值的能力。
通过使用“$ {env.VAR}”语法将这些新概念与CppProperties.json,launch.vs.json和tasks.vs.json中现有的使用环境变量的能力相结合,为创建丰富的开发环境提供了强大的机制。
我们先来看看如何使用此功能的快速示例:
1{
2 // The "environments" property is an array of key value pairs of the form
3 // { "EnvVar1": "Value1", "EnvVar2": "Value2" }
4 "environments": [
5 {
6 "INCLUDE": "${workspaceRoot}\\src\\includes"
7 }
8 ],
9
10 "configurations": [
11 {
12 "inheritEnvironments": [
13 // Inherit the MSVC 32-bit environment and toolchain.
14 "msvc_x86"
15 ],
16 "name": "x86",
17 "includePath": [
18 // Use the include path defined above.
19 "${env.INCLUDE}"
20 ],
21 "defines": [ "WIN32", "_DEBUG", "UNICODE", "_UNICODE" ],
22 "intelliSenseMode": "msvc-x86"
23 },
24 {
25 "inheritEnvironments": [
26 // Inherit the MSVC 64-bit environment and toolchain.
27 "msvc_x64"
28 ],
29 "name": "x64",
30 "includePath": [
31 // Use the include path defined above.
32 "${env.INCLUDE}"
33 ],
34 "defines": [ "WIN32", "_DEBUG", "UNICODE", "_UNICODE" ],
35 "intelliSenseMode": "msvc-x64"
36 }
37 ]
38}
为了说明这个问题,这个例子定义了两个使用Microsoft Visual C++工具链构建的配置。第一个为x86构建(因为它继承了“msvc_x86”环境),另一个为x64构建。它还定义了被两个配置同时使用的环境变量“INCLUDE”(第6行)。
请记住,“environments”(第4行)和“inheritEnvironments”(第12和第25行)属性可以在所有配置,单个配置或是两者兼有中被作为全局定义,每个配置或两者。在上面的例子中,“INCLUDE”变量是全局的,“inheritEnvironment”属性将被应用于各自的配置中。
至今以下环境可用:
- Target x86 Windows with MSVC (msvc_x86)
- Target x64 Windows with MSVC (msvc_x64)
- Target x86 Windows with the 64-bit MSVC (msvc_x64_x86)
- Target x64 Windows with the 64-bit MSVC (msvc_x64_x64)
另外,如果您安装了Linux Workload,则可以使用以下环境来远程定位Linux和WSL:
- Target x86 Linux remotely (linux_x86)
- Target x64 Linux remotely (linux_x64)
- Target ARM Linux remotely (linux_arm)
特定配置的环境变量可以覆盖全局的变量。下面的例子解释了注释中的覆盖行为:
1{
2 // The "environments" property is an array of key value pairs of the form
3 // { "EnvVar1": "Value1", "EnvVar2": "Value2" }
4 "environments": [
5 {
6 "INCLUDE": "${workspaceRoot}\\src\\includes"
7 }
8 ],
9
10 "configurations": [
11 {
12 "inheritEnvironments": [
13 // Inherit the MSVC 32-bit environment and toolchain.
14 "msvc_x86"
15 ],
16 "name": "x86",
17 "includePath": [
18 // Use the include path defined above.
19 "${env.INCLUDE}"
20 ],
21 "defines": [ "WIN32", "_DEBUG", "UNICODE", "_UNICODE" ],
22 "intelliSenseMode": "msvc-x86"
23 },
24 {
25 // The "environments" property is an array of key value pairs of the form
26 // { "EnvVar1": "Value1", "EnvVar2": "Value2" }
27 "environments": [
28 {
29 // Append 64-bit specific include path to env.INCLUDE.
30 "INCLUDE": "${env.INCLUDE};${workspaceRoot}\\src\\includes64"
31 }
32 ],
33
34 "inheritEnvironments": [
35 // Inherit the MSVC 64-bit environment and toolchain.
36 "msvc_x64"
37 ],
38 "name": "x64",
39 "includePath": [
40 // Use the include path defined above.
41 "${env.INCLUDE}"
42 ],
43 "defines": [ "WIN32", "_DEBUG", "UNICODE", "_UNICODE" ],
44 "intelliSenseMode": "msvc-x64"
45 }
46 ]
47}
如果您需要为您的构建环境声明很多变量,然后对每个配置进行少量修改,则此重写功能可以大大缩小您项目的CppProperties.json文件。
关于Launch.vs.json和Tasks.vs.json
如果您想知道是否可以在CppProperties.json文件之外使用这些变量,答案是肯定的!您在CppProperties.json中声明的所有环境变量都可以在launch.vs.json和tasks.vs.json中使用。只需将相同的“$ {env.VarName}”语法嵌入任务或启动配置中的任何属性值即可。宏语法将被扩展为它的实际值,因为它在第16行。
1{
2 "version": "0.2.1",
3 "tasks": [
4 {
5 "taskName": "build-helloworld",
6 "appliesTo": "*.cpp",
7 "contextType": "build",
8 "type": "launch",
9 "command": "${env.comspec}",
10 "workingDirectory": "${workspaceRoot}",
11 // Use environment from selected configuration, you can omit this
12 // to only use globally defined variables instead.
13 "inheritEnvironments": [ "${cpp.activeConfiguration}" ],
14 "output": "${workspaceRoot}\\bin\\helloworld.exe",
15 "args": [
16 "build.bat ${env.BUILD_ARGS}"
17 ]
18 }
19 ]
20}
如果环境变量的值是配置里面特定的,则当您尝试运行任务或调试程序时,将使用当前选定配置的值(如果将其包含在您的任务或启动配置中):
"inheritEnvironments": [ "${cpp.activeConfiguration}" ]
如果您不包括这个,只有全局定义的变量将可用。
您声明的环境变量也将由任务启动的进程继承。另一方面,正在调试的程序将不会自动继承构建环境。下面的例子展示了如何显式地将环境变量传递给启动的进程。
1{
2 "version": "0.2.1",
3 "defaults": {},
4 "configurations": [
5 {
6 "type": "native",
7 "name": "helloworld.exe",
8 // Use environment from selected configuration, you can omit this
9 // to only use globally defined variables instead.
10 "inheritEnvironments": [ "${cpp.activeConfiguration}" ],
11 "project": "bin\\helloworld.exe",
12 "args": [
13 // Use arguments defined in CppProperties.json.
14 "${env.PROG_ARGS}"
15 ] ,
16 "env": "var1=${env.var1}\u0000var2=hardcodedvalue"
17 }
18 ]
19}
您可以在第14行看到在CppProperties.json文件中引用被定义变量是可以的。第17行中的“\ u0000”是一个空字符,用于分隔变量。
高级功能
您那敏锐的眼睛可能已经注意到,“environments”和“inheritEnvironments”是CppProperties.json语法中的数组,可以声明和继承多个环境。对于典型的构建方案,您不太可能希望从多个环境中继承,但有些情况下您可能需要声明多个环境块。主要的用例是声明几个变量,您可以在任何CppProperties,Launch或者Tasks JSON中引用这些变量同时不用添加这些变量到构建环境中—例如,不在派生的构建过程继承。
以下示例显示了如何完成创建一个自定义命名空间:
1{
2 // The "environments" property is an array of key value pairs of the form
3 // { "EnvVar1": "Value1", "EnvVar2": "Value2" }
4 "environments": [
5 {
6 "INCLUDE": "${workspaceRoot}\\src\\includes"
7 },
8 {
9 // "namespace" is a reserved key that lets you put variables
10 // in namespaces other than $env.
11 "namespace": "special",
12 // SpecialVar will not be added to the environment.
13 "SpecialVar": "special"
14 }
15
16 ],
17
18 "configurations": [
19 {
20 "inheritEnvironments": [
21 // Inherit the MSVC 32-bit environment and toolchain.
22 "msvc_x86"
23 ],
24 "name": "x86",
25 "includePath": [
26 // Use the include path defined above.
27 "${env.INCLUDE}"
28 ],
29 "defines": [
30 // You can use alternative namespaces (such as special defined above)
31 // just like "${env.VAR}"
32 "${special.specialVar}",
33 "WIN32", "_DEBUG", "UNICODE", "_UNICODE"
34 ],
35 "intelliSenseMode": "msvc-x86"
36 }
37 ]
38}
您可以通过语法“$ {special.SpecialVar}”来访问任何CppProperties,Launch或Tasks JSON文件中的“SpecialVar”,如第32行所示。
发送反馈
要尝试最新的和最好的C ++功能,并给我们一些早期的反馈,请下载并安装最新的Visual Studio 2017 Preview。一如既往,我们欢迎您的反馈。欢迎通过电子邮件 visualcpp@microsoft.com,通过Twitter @visualc或Microsoft Visual Cpp的Facebook发送任何评论。
如果您遇到Visual Studio 2017的其他问题,请通过报告问题告诉我们,这个问题在安装程序和IDE本身都可用。对于建议,让我们通过UserVoice知道。