How/Where are the environment variables in a Visual Studio C++ project set? - visual-studio

There a lots of environment variables in my project properties that I do not understand. Clicking on macros (Is there a list of Visual Studio environment variables?) gives me a list of their values, but I am unable to figure out where some of these are set.
For example, I am trying to figure out where the variable $(IntDir) is being set.
What file is responsible for setting these variables? How can I modify them?

These are not environment variables.
They're just macros defined by the build system that you can use for setting build properties for your project. They automatically expand to things like the target platform ($(Platform)), the path to store intermediate files for your project ($(IntDir)), and the name of your project ($(ProjectName)).
You can't change them directly, but you can change them by modifying your project's properties. The project file (created automatically by Visual Studio when you create a new project) is responsible for setting them.
You already found a link to the big list of 'em, which is helpful in explaining what they are and what they do. As the documentation says, you can use them anywhere in your project's property pages that string values are accepted. They keep you from having to hard-code paths and other information, which is exceptionally useful.
Unlike environment variables, they do not persist or have any meaning independent of your build system. Once your project has been built, they go away. They're not used during debugging or deployment.

.If you want to see actual values for a specific VS instance for both 'standard' and 'custom', see if this answer helps. (Basically, you can use Process Explorer to find that out.)

Related

VisualStudio 2019 is it possible te set the build variables from CMAKE. And more generally how to set them up

I am keeping asking questions about VisualStudio but to be honest I do not understand a word from its documentation.
In the json files generated by the VS are placed build variables like ${workspaceRootFolderName}, ${workspaceRoot}, ${env.gccpath} etc etc but I do not know how to set it up.
If the the CMAKE project.
I have two questions:
Is it possible to set those variables from CMAKE files?
If not how can I set them up another way. At the moment project builds but VS generated launch files cannot evaluate the variables
There are target properties that can be used to set these kind of variables in a Visual Studio project. They all begin with VS_. I didn't see any that corresponded with these particular variables in this project.
The alternative seems to be to save them in a User props file and you can set property that incorporates that file into your project.
https://cmake.org/cmake/help/latest/prop_tgt/VS_USER_PROPS.html

How do you reference the solution folder in .targets?

I have a custom tool that I run on certain file types using the .targets mechanism in Visual Studio 2015.
Projects exist at many levels, and I want to reference this tool when the code is pulled to ANY drive/folder, including the TFS CI agent.
I tried using a relative path, but because the files are at different levels, it doesn't work for all projects.
I tried using a registry setting and environment variable, but that doesn't bode well for the CI machine which might build in a different folder each time.
Is it possible to get the solution folder of which the project/file is in, then I can use a relative path to the tool directory?
All I can find is these properties, which do not seem to help:
General MSBuild properties:
https://msdn.microsoft.com/en-us/library/bb629394.aspx
https://msdn.microsoft.com/en-us/library/ms164309.aspx
Registry and environment variables:
https://msdn.microsoft.com/en-us/library/ms171458.aspx
You can use all the standard tokens within .targets.
Just use
$(SolutionDir)
See https://msdn.microsoft.com/en-us/library/c02as0cs.aspx
Self-service answer: use visual studio's property editing for a vcxproj in preprocessor macros or include paths or such to look at a bunch of available variables. You can usually find what you need in there, by name, or by example, including the one you need here. Better than any documentation.

VS2010, MSBuild and Environment Variables

I have a question about MSBuild.exe and Environment Variables. First, the development environment:
The code is mostly C++ with some C#. There are over 5,000 classes, 340 projects and 200 solutions arranged in a deep source tree. There is a solution at the root of the tree and at various other points in the tree. We use TFS and maintain multiple active branches for a series of future releases. Each developer uses a local view to modify and test code. Some developers work on multiple branches concurrently. Sometimes developers build solutions from different TFS branches concurrently.
We use about 70 environment variables for locating shared header files, libraries, etc. In VS2008 we used a file with the same base name as the solution file and an extension of .slnenv for defining the environment variables. All variables are defined relative to the base of the source tree. This .slnenv file is read by a custom VS2008 AddIn that creates Environment Variables in the VS2008 process space, i.e.
MyProjectDir=$(SolutionDir)\..\..
MyRoot=$(MyProjectDir)\..\..
MyInstallDir=$(MyRoot)\Install
MySourceDir=$(MyRoot)\Source
MyUnmanagedSourceDir=$(MySourceDir)\My\Unmanaged
MyIncludeDirs=$(MyProjectDir);$(MyUnmanagedSourceDir)
This AddIn does not work correctly with VS2010 because MSBuild does not inherit the environment variables that are created after the solution is loaded.
My question is how do I get these environment variables to MSBuild? I have found two methods that work, but are not as convenient as the AddIn we had been using.
VS2010 can be started with a command script that first sets Environment Variables in the process space and then starts VS2010. MSBuild does inherit these Environment Variables. This is unsatisfactory because the scripts would need to be customized for the various points where a solution can be loaded.
The second method I have tried is defining the Environment Variables as Properties in property sheets and .vcxproj files. We have a base property sheet that all .vcxproj files load. In that property sheet:
<PropertyGroup>
<MyRoot>$(MyProjectDir)\..\..</MyRoot>
<MyInstallDir>$(MyRoot)\Install</MyInstallDir>
<MySourceDir>$(MyRoot)\Source</MySourceDir>
<MyUnmanagedSourceDir>$(MySourceDir)\My\Unmanaged</MyUnmanagedSourceDir>
<MyIncludeDirs>$(MyProjectDir);$(MyUnmanagedSourceDir)</MyIncludeDirs>
</PropertyGroup>
Then I can define the base directory in each .vcxproj file:
<PropertyGroup>
<MyProjectDir>..\..</MyProjectDir>
</PropertyGroup>
This method uses relative path names where the AddIn resolved all Environment Variables to absolute path names. I'd rather not have to edit 340 .vcxproj files where the definition of "MyProjectDir" would vary depending on how far from the source root the project file exists. So far I've tried this method in just one project.
I have tried to modify the AddIn to create Properties rather than Environment Variables. I tried using ENV2.get_Properties(), but that seems to work only for Properties that are defined in VS2010, not for Properties I've defined.
Thank you,
Dan Kary
After discussion via email, we figured what were Dan needs and following message helps him with question issue. He agrees that this could be helpfull to other SO members:
Aha, I get it now.
As I did understand from that topic - you really need all that stuff only for build step (paths for include clause, paths to built tool to resolve dll\exe dependency), and no regular developer activities depends on it.
It's good, cause we don't need to fight VStudio about not reinitializing env vars after first load. We just need somehow edit and implement your solution for huge amount of proj files ;) Task become much easier :D
Small disclaimer - I'm writing this on the road and have no access to fully fledged dev env to check and bulletproof all further recomendations, so take my apologizes in advance for any mistakes I will make ;)
I would like to bring your attention to some msbuild features:
http://msdn.microsoft.com/en-us/library/ms164309.aspx
You have predefined properties, that available for all scripts and projects, it looks like this will help you solve first issue - absolute paths instead of relative. This is small excerpt from the link for further reference
$(MSBuildProjectDirectory) -
The absolute path of the directory where the project file is located, for example, C:\MyCompany\MyProduct.
$(MSBuildProjectFile) -
The complete file name of the project file, including the file name extension, for example,
MyApp.proj.
$(MSBuildProjectExtension)
The file name extension of the project file, including the period, for example, .proj.
$(MSBuildProjectFullPath)
The absolute path and complete file name of the project file, for example, C:\MyCompany\MyProduct\MyApp.proj.
$(MSBuildProjectName)
The file name of the project file without the file name extension, for example, MyApp.
So you should be able to use this defined properties in your Property sheets.
Now, with msbuild 4.0 toolset (toolset defined by attribute ToolsVersion="" on the root script element) there is interesting trick
Microsoft.Common.Targets define 2 variables to conditionally import custom msbuild script before or after itself
CustomBeforeMicrosoftCommonTargets and CustomAfterMicrosoftCommonTargets
You can use it the following way ( I think it will possible help you to avoid editing of all proj files or at least - reduce editing to very simplified copy-paste part)
Define it using relative path to include your property sheet files
<CustomBeforeMicrosoftCommonTargets>$(MSBuildProjectFile)\ConcreteProjectCustomProperties.propz</CustomBeforeMicrosoftCommonTargets>
Take a note that CustomBeforeMicrosoftCommonTargets should be global scoped property to be inherited by all secondary
And if you properly define your ConcreteProjectCustomProperties.propz I think you could achieve what you need.
"Properly" is that you will include there your global properties file (with relative or absolute path) and then define all your project-level properties.
NB:
Also take a note that later defined properties not available for reference to early defined
Your example defines $(MyIncludeDirs) with reference to $(MyProjectDir), but $(MyProjectDir) declared and defined a bit later.
It could be due to "exampling" and fast churning that code, but if you define your vars same way in production - it could lead to subtle error.
I hope I got your problem properly and my explanations will help you to quickly move all your properties from custom add-on to simpler and native msbuild script ;)

Custom macros for configuring a build in Visual C++

Hopefully this isn't a duplicate. I tried to search for an answer to my question, but the word 'macro' just has too many different applications to filter the search results very effectively.
Anyway, I recently noticed in another Visual C++ (VS2010) project that custom macros were used to set up VC++ directories (include, lib) or link libraries. Something like this: "libjpeg-$(JPEG_LIB_VERSION)-static.lib", etc.
How does one go about doing that? I can't remember in what project I saw that technique, so I haven't been able to find it again to investigate, but this would be very useful when building against local builds or particular versions of widely-distributed software (say, Boost, for instance).
There's this (Visual C++ Express and setting env variables solution wide), which I suppose kinda-sorta answers the question, but not really.
The macro being used may be an environment variable, or it may indeed be a custom macro.
If it is an environment variable, you could follow the documentation as mentioned in this MSDN document How to: Use Environment Variables in a Build
However, if it is not an environment variable and you want to create your own, there is another MSDN document for that How to: Add New Property Sheets to C++ Projects
For additional references on creating a custom macro, please see How to add environmental variable to VS solution (.sln )
For additional references on using an environment, please see Macros/Environment variable in .sln and .vcproj files for Visual studio

How to set PlatformToolset from custom property sheet in Visual Studio 2010

I am moving now from VS 2005 to VS 2010 with products consisting of few solutions with numerous projects each. I wanted to make use of the property sheets system so our numerous configurations would be easier to maintain.
One of the issues is that we want to use Windows SDK 7.1 (as we need BaseClasses sample - and if we have to use that sample that why not the entire SDK)? But this requires me to change PlatformToolset on each and every single project in all the solutions. Also we will have to remember to change that value for newly added projects. Rather bad idea.
So I wanted to set this (among other things) from a custom property sheet. There is no such option directly from dialog shown when setting properties on property sheet. Adding entries manually to the XML file didn't help as well (but I haven't also seen any error or warning message).
Then how am I supposed to set default PlatformToolset value? At best in a configuration file which can be committed to repository. But if it could be done in some computer local settings then it would be acceptable too.
(Note that I know that I can use BaseClasses differently and avoid that problem at all but I think it is interesting issue in itself.)
I also asked this question at MSDN Formus.
PlatformToolset must be set in project properties at the begin of the file before inclusion of other files so that it can be later used to set up some defaults. If non is set then those inclusions will set it up to some default value.
Resetting it later even if works is pointless as everything was already included/set up. So to change the default value to a different SDK it seems VS configuration files (those which are included) should be changed appropriately.
But this does not have to be a good thing because it is local for the machine.
There is also an option of manual inclusion of property file which sets the PlatformToolset before default inclusions. However MS warns that if project file does not keep proper order (and this would spoil the order) VS GUI tools for project set up might not work properly.
In the end I just manually changed all projects. New projects also have to be changed to the new PlatformToolset.

Resources