{"id":16565,"date":"2017-08-14T18:22:00","date_gmt":"2017-08-15T01:22:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vcblog\/?p=16565"},"modified":"2019-04-19T08:03:35","modified_gmt":"2019-04-19T08:03:35","slug":"cmake-support-in-visual-studio-customizing-your-environment","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/cmake-support-in-visual-studio-customizing-your-environment\/","title":{"rendered":"CMake Support in Visual Studio: Customizing your Environment"},"content":{"rendered":"<p>In <a href=\"https:\/\/www.visualstudio.com\/downloads\/\">Visual Studio 15.3<\/a>, there are new ways for you to apply advanced configuration to your CMake environments.<\/p>\n<p>Please\u00a0<a href=\"https:\/\/www.visualstudio.com\/downloads\/\">download the latest<\/a>\u00a0and try out the latest CMake features.\u00a0 If you are just getting started with CMake, follow the link to\u00a0<a href=\"https:\/\/aka.ms\/cmake\">learn more about CMake support in Visual Studio<\/a>.\u00a0 We are looking forward to your feedback.<\/p>\n<h3>What\u2019s new in CMakeSettings.json<\/h3>\n<p>The heart of this new flexibility is inside your project\u2019s CMakeSettings.json file and it stems from two new concepts:<\/p>\n<ol>\n<li>The ability to inherit a set of default environment variables globally or per configuration.<\/li>\n<li>The ability to define custom environment variables and their values globally or per configuration.<\/li>\n<\/ol>\n<p>Let\u2019s start with a quick example of how using this feature might look:<\/p>\n<pre class=\"lang:js decode:true\">{\r\n    \/\/ The \"environments\" property is an array of key value pairs of the form\r\n    \/\/ { \"EnvVar1\": \"Value1\", \"EnvVar2\": \"Value2\" }\r\n    \"environments\": [\r\n        {\r\n            \"BuildDir\": \"${env.USERPROFILE}\\\\CMakeBuilds\\\\${workspaceHash}\\\\build\",\r\n        }\r\n    ],\r\n    \"configurations\": [\r\n        {\r\n            \"name\": \"x86-Debug\",\r\n            \"generator\": \"Ninja\",\r\n            \"configurationType\": \"Debug\",\r\n            \/\/ Inherit the defaults for using the MSVC x86 compiler.\r\n            \"inheritEnvironments\": [\r\n                \"msvc_x86\"\r\n            ],\r\n            \"buildRoot\": \"${env.BuildDir}\\\\${name}\"\r\n        },\r\n        {\r\n            \"name\": \"x64-Debug\",\r\n            \"generator\": \"Ninja\",\r\n            \"configurationType\": \"Debug\",\r\n            \/\/ Inherit the defaults for using the MSVC x64 compiler.\r\n            \"inheritEnvironments\": [\r\n                \"msvc_x64\"\r\n            ],\r\n            \"buildRoot\": \"${env.BuildDir}\\\\${name}\"\r\n        }\r\n    ]\r\n}<\/pre>\n<p>To unpack this a bit, this example defines two configurations that use Ninja to build this CMake project.\u00a0 The first builds x86 debug while the other builds x64 debug.\u00a0 It also defines an environment variable \u201cBuildDir\u201d that it makes use of in both configurations.<\/p>\n<p>Keep in mind, both the \u201cenvironments\u201d (line 4) and \u201cinheritEnvironments\u201d (lines 16 and 24) properties can be defined globally for all configurations, per configuration, or both.\u00a0 In the example above, the \u201cBuildDir\u201d variable will be global and the \u201cinheritEnvironment\u201d property will only apply to each individual configuration.<\/p>\n<p>Configuration-specific environment variables are evaluated last, so they override global ones.\u00a0 The example below explains the override behavior in the comments:<\/p>\n<pre class=\"lang:js decode:true\">{\r\n    \/\/ The \"environments\" property is an array of key value pairs of the form\r\n    \/\/ { \"EnvVar1\": \"Value1\", \"EnvVar2\": \"Value2\" }\r\n    \"environments\": [\r\n        {\r\n            \"BuildDir\": \"${env.USERPROFILE}\\\\CMakeBuilds\\\\${workspaceHash}\",\r\n        }\r\n    ],\r\n    \"configurations\": [\r\n        {\r\n            \"name\": \"x86-Debug\",\r\n            \/\/ The syntax for this property is the same as the global one above.\r\n            \"environments\": [\r\n                {\r\n                    \/\/ Replace the global property entirely.\r\n                    \"BuildDir\": \"D:\\\\custom-builddir\",\r\n                }\r\n            ],\r\n            \"generator\": \"Ninja\",\r\n            \"configurationType\": \"Debug\",\r\n            \/\/ Inherit the defaults for using the MSVC x86 compiler.\r\n            \"inheritEnvironments\": [\r\n                \"msvc_x86\"\r\n            ],\r\n            \/\/ This will evaluate to \"D:\\custom-builddir\\x86-Debug\" due to the\r\n            \/\/ configuration-specific override.\r\n            \"buildRoot\": \"${env.BuildDir}\\\\${name}\"\r\n        },\r\n        {\r\n            \"name\": \"x64-Debug\",\r\n            \"generator\": \"Ninja\",\r\n            \"configurationType\": \"Debug\",\r\n            \/\/ Inherit the defaults for using the MSVC x64 compiler.\r\n            \"inheritEnvironments\": [\r\n                \"msvc_x64\"\r\n            ],\r\n            \/\/ Since this configuration doesn\u2019t modify BuildDir, it inherits\r\n            \/\/ from the one defined globally.\r\n            \"buildRoot\": \"${env.BuildDir}\\\\${name}\"\r\n        }\r\n    ]\r\n}<\/pre>\n<p>If you need to declare a lot of variables for your build environment and then make only minor modifications to them for each configuration, this override behavior can condense your project\u2019s CMakeSettings.json file considerably.<\/p>\n<h3>What about Launch.vs.json and Tasks.vs.json<\/h3>\n<p>In case you are wondering if you can use these variables outside of the CMakeSettings.json file, the answer is yes!\u00a0 All the environment variables you declare in your CMakeSettings.json file are available to Tasks and Launch configuration using the same syntax.\u00a0 Just embed the &#8220;${env.VarName}&#8221; syntax into any property\u2019s value in a task or launch configuration.\u00a0 The macro syntax will be expanded into its actual value, as it is on line 12 in the example below.<\/p>\n<pre class=\"lang:js decode:true\">{\r\n    \"version\": \"0.2.1\",\r\n    \"defaults\": {},\r\n    \"configurations\": [\r\n        {\r\n            \"type\": \"cppdbg\",\r\n            \"name\": \"helloworld.exe\",\r\n            \"project\": \"bin\\\\helloworld.exe\",\r\n            \"cwd\": \"${workspaceRoot}\",\r\n            \"program\": \"${debugInfo.target}\",\r\n            \"MIMode\": \"gdb\",\r\n            \"miDebuggerPath\": \"${env.MINGW_PREFIX}\\\\bin\\\\gdb.exe\",\r\n            \"externalConsole\": true\r\n        }\r\n    ]\r\n}<\/pre>\n<p>If the value of an environment variable is configuration-specific, the value for the currently selected configuration when you try to run a task or debug your program will be used.\nThe environment variables you declare will also be inherited by the processes launched by tasks. Programs being debugged, on the other hand, will not inherit the build environment.<\/p>\n<pre class=\"lang:js decode:true\">{\r\n    \"version\": \"0.2.1\",\r\n    \"defaults\": {},\r\n    \"configurations\": [\r\n        {\r\n            \"type\": \"default\",\r\n            \"project\": \"ConsoleApp2\\\\PrintEnv.csproj\",\r\n            \"name\": \"PrintEnv.csproj\",\r\n            \"env\": \"var1=${env.var1}\\u0000var2=hardcodedvalue\"\r\n        }\r\n    ]\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<p>You can see on line 0 that it is possible to reference variables defined in your CMakeSettings.json file. The \u201c\\u0000\u201d is a null character used to separate variables.<\/p>\n<h3>Advanced Features<\/h3>\n<p>Those of you with a keen eye might have noticed that \u201cenvironments\u201d and \u201cinheritEnvironments\u201d are arrays in the CMakeSettings.json syntax.\u00a0 It is possible to declare and inherit from multiple environments.\u00a0 For typical usage in CMake scenarios it is unlikely that you would want to inherit from more than one environment but there are some cases where you might want to declare more than one environment block.\u00a0 The prime use case for this, for CMake, would be to declare a few variables that you can reference in CMakeSettings\/launch.vs\/tasks.vs JSON but don\u2019t want added to the build environment itself &#8211; e.g. not inherited by spawned build processes.<\/p>\n<p>The following example shows how you accomplish this:<\/p>\n<pre class=\"lang:js decode:true \">\/\/ The \"environments\" property is an array of key value pairs of the form\r\n\/\/ { \"EnvVar1\": \"Value1\", \"EnvVar2\": \"Value2\" }\r\n\"environments\": [\r\n    {\r\n        \"BuildDir\": \"${env.USERPROFILE}\\\\CMakeBuilds\\\\${workspaceHash}\\\\build\",\r\n    },\r\n    {\r\n        \/\/ \u201cnamespace\u201d is a reserved key that lets you put variables\r\n        \/\/ in namespaces other than $env.\r\n        \"namespace\": \"special\",\r\n        \/\/ SpecialVar will not be added to the environment.\r\n        \"SpecialVar\": \"special\",\r\n    }\r\n],\r\n\"configurations\": [\r\n    {\r\n        \"name\": \"x86-Debug\",\r\n        \"generator\": \"Ninja\",\r\n        \"configurationType\": \"Debug\",\r\n        \/\/ Inherit the defaults for using the MSVC x86 compiler.\r\n        \"inheritEnvironments\": [\r\n            \"msvc_x86\"\r\n        ],\r\n        \/\/ You can use alternative namespaces (such as special defined above)\r\n        \/\/ just like \"$env.\"\r\n        \"buildRoot\": \"${env.BuildDir}\\\\${special.SpecialVar}\\\\${name}\"\r\n    },\r\n    {\r\n        \"name\": \"x64-Debug\",\r\n        \"generator\": \"Ninja\",\r\n        \"configurationType\": \"Debug\",\r\n        \/\/ Inherit the defaults for using the MSVC x64 compiler.\r\n        \"inheritEnvironments\": [\r\n            \"msvc_x64\"\r\n        ],\r\n        \"buildRoot\": \"${env.BuildDir}\\\\${name}\"\r\n    }\r\n]\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>You can access \u201cSpecialVar\u201d in any CMakeSettings, Launch, or Tasks JSON file with the syntax \u201c${special.SpecialVar}\u201d, as seen on line 25.<\/p>\n<h3>Send Us Feedback<\/h3>\n<p>To try out the latest and greatest CMake features and give us some early feedback, please download and install the latest\u00a0<a href=\"https:\/\/www.visualstudio.com\/vs\/preview\/\">Visual Studio 2017 Preview<\/a>.\u00a0 As always, we welcome your feedback.\u00a0 Feel free to send any comments through e-mail at\u00a0<a href=\"mailto:cmake@microsoft.com\">cmake@microsoft.com<\/a>, through\u00a0<a href=\"https:\/\/twitter.com\/visualc\">Twitter @visualc<\/a>, or Facebook at\u00a0<a href=\"https:\/\/www.facebook.com\/Microsoft-Visual-Cpp-222043184527264\/\">Microsoft Visual Cpp<\/a>.<\/p>\n<p>If you encounter other problems with Visual Studio 2017 please let us know via\u00a0<a href=\"https:\/\/docs.microsoft.com\/en-us\/visualstudio\/ide\/how-to-report-a-problem-with-visual-studio-2017\">Report a Problem<\/a>, which is available in both the installer and the IDE itself. \u00a0For suggestions, let us know through\u00a0<a href=\"https:\/\/visualstudio.uservoice.com\/forums\/121579-visual-studio-2015\/category\/30937-languages-c\">UserVoice<\/a>. We look forward to your feedback!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In Visual Studio 15.3, there are new ways for you to apply advanced configuration to your CMake environments. Please\u00a0download the latest\u00a0and try out the latest CMake features.\u00a0 If you are just getting started with CMake, follow the link to\u00a0learn more about CMake support in Visual Studio.\u00a0 We are looking forward to your feedback. What\u2019s new [&hellip;]<\/p>\n","protected":false},"author":326,"featured_media":35994,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[270,266],"tags":[8,140,252,233,308,6,309,316],"class_list":["post-16565","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-announcement","category-cmake","tag-announcement","tag-c","tag-cmake","tag-cross-platform","tag-existing-code","tag-ide","tag-import","tag-openfolder-edit"],"acf":[],"blog_post_summary":"<p>In Visual Studio 15.3, there are new ways for you to apply advanced configuration to your CMake environments. Please\u00a0download the latest\u00a0and try out the latest CMake features.\u00a0 If you are just getting started with CMake, follow the link to\u00a0learn more about CMake support in Visual Studio.\u00a0 We are looking forward to your feedback. What\u2019s new [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/16565","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/users\/326"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=16565"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/16565\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media\/35994"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media?parent=16565"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=16565"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=16565"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}