In our team is an old developer, who likes Debug-Message-Boxes. Not for just the current debugging session, no, forever. So when running the program in debugging mode, the boxes are nagging all the other developers. But we are not allowed to remove the boxes.
So, is there a possibility to define a DEFINE deepened on user / computer? So, we can do this:
#ifdef _DEBUG
#ifndef NONAG
MessageBox(...);
#endif
#endif
-> and now, we can define "NONAG" and have more fun..
Thanks
With a standard setup, a {ProjectName}.vcxproj.user props file will be created next to your normal project.
Its a standard props file which shouldn't be checked into source control and so lets each individual user set personal project settings including preprocessor macros. So change that file to be something like:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemDefinitionGroup>
<ClCompile>
<PreprocessorDefinitions>NONAG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
</Project>
Alternatively you can setup custom props file by including something like in your project or common props file:
<ImportGroup Label="PropertySheets">
<Import Project="{some custom props file path}" Condition="exists('{some custom props file path}')"/>
</ImportGroup>
Related
Using Visual Studio 2017, in the solution explorer, I right-click on a C# .Net Core project and select "Publish...". I create a publish profile that publishes the app to a folder or file share. The result is a profile whose default target location is an absolute path "[project directory]\bin\Release\netcoreapp2.1\publish\", such as in the following snippet.
Visual Studio generates a .pubxml file to store that publish profile, where the target location is stored in a <PublishDir> tag. For example:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PublishProtocol>FileSystem</PublishProtocol>
<Configuration>Release</Configuration>
<Platform>Any CPU</Platform>
<TargetFramework>netcoreapp2.1</TargetFramework>
<PublishDir>F:\work\foo\bin\Release\netcoreapp2.1\publish\</PublishDir>
</PropertyGroup>
</Project>
What I would prefer is to use a variable in the value of the <PublishDir> tag, such as the $(SolutionDir) variable. I can manually edit the .pubxml file to inject a variable. For example:
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
...
<PublishDir>$(SolutionDir)\publish\</PublishDir>
</PropertyGroup>
</Project>
However, when I next load the project in Visual Studio, that variable is either ignored, or has a empty value, such as in the following snippet.
Is there a way to use variables in the publish profile?
Had a similar problem using VS2019. Only things that worked for me where environment variables like $(windir) and Properties in the pubxml above the line where they are needed e.g.
<!-- removed some properties from xml -->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<PublishProvider>FileSystem</PublishProvider>
<TargetFramework>netcoreapp3.1</TargetFramework>
<PublishUrl>$(WINDIR)\$(PublishProvider)\$(WebPublishMethod)\$(LastUsedBuildConfiguration)_$(TargetFramework)</PublishUrl>
<WebPublishMethod>FileSystem</WebPublishMethod>
</PropertyGroup>
</Project>
The resulting PublishUrl was
C:\Windows\FileSystem\\Release_netcoreapp3.1
WebPublishMethod is not part of PublishUrl because it's below PublishUrl.
Don't know about F:\work\foo\bin\ but you could try Configuration and TargetFramework for Release\netcoreapp2.1
After some research, to get VisualStudio to build a project's object files in parallel, one must ensure that project properties MinimalRebuild is off and MultiProcessorCompilation is on. I can configure this in the project file, but is there a way to override these project settings on the command line using msbuild?
In other words, using msbuild from the command line, how would I override MinimalRebuild (/Gm-) to be false and MultiProcessorCompilation (/MP) to be true? The following doesn't seem to work
msbuild /m:7 /p:CL_MPCount=7 /p:MinimalRebuild=false /p:MultiProcessorCompilation=true
As an aside, is /p:CL_MPCOUNT redundant with the MultiProcessorCompilation property? Overall, I'm having trouble finding documentation on what fits the /p option.
In other words, using msbuild from the command line, how would I
override MinimalRebuild (/Gm-) to be false and
MultiProcessorCompilation (/MP) to be true?
CL_MPCount can be overrided by /p:xxx=xxx but MultiProcessorCompilation and MinimalRebuild are not. Just to be clear, It can only be overridden by /p:xxx=xxx(p means property) if it is a property of MSBuild. And the Property usually can be called by $. So I do some tests:
Edit
Test
1)CL_MPCount
This value means Maximum Number of concurrent C++ compilations in VS IDE.You can refer to this.
So I have assigned a value by VS IDE by(Debug->Options->Projects and Solutions->VC++ Project Solutions and set the Maximum Number of concurrent C++ compilations to 2.)
write a custom target like
<Target Name ="Test" AfterTargets="Build">
<Message Importance="high" Text="CL_MPCount is= $(CL_MPCount)">
</Message>
</Target>
Then Build and it shows;
From this we can see that this is a property that belongs to MSBuild.
2)MinimalRebuild
Usually, it means /GM and it usually set in the Properties in a c++ project. l have set it to True by (Right-click on the project-->Properties-->C/C++-->Code Generation-->set Enable Minimal Rebuild to True).
Custom target like
<Target Name ="Test" AfterTargets="Build">
<Message Importance="high" Text="MinimalRebuild is= $(MinimalRebuild)">
</Message>
</Target>
The result is like
From it, the value which set in the VS IDE cannot be available by $(MinimalRebuild) which means it is not a property of MSBuild.
3) MultiProcessorCompilation
It also means /MP and from the document we will find that it is an option of the the compiler not a property of MSBuild. Besides, l did the same as the MinimalRebuild and it is not being output. So it is also not a property of MSBuild.
In addition, l thought MinimalRebuild and MultiProcessorCompilation are the options of MSBuild before. So I type MSBuild -help in Command Line and found that it did not list these parameters at all. So I think these two parameters have nothing to do with MSBuild at all, but are just some of the compiler's options.
Hope it could help you.
I found a way to override both properties at User level. Anyway you may find them helpful (for example for Build host where incremental build is not meaningful at all).
Create these two properties files:
%USERPROFILE%\AppData\Local\Microsoft\MSBuild\v4.0\Microsoft.Cpp.Win32.user.props
%USERPROFILE%\AppData\Local\Microsoft\MSBuild\v4.0\Microsoft.Cpp.x64.user.props
with following content:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup>
<ClCompile>
<MinimalRebuild>false</MinimalRebuild>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<ProcessorNumber>2</ProcessorNumber>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup />
</Project>
Feel free to customize ProcessorNumber to suit your hardware.
Now MSBUild will use above values for all projects.
In my C++ project Visual Studio (2017) fails to detect changes in a property value when I trigger a "build" (e.g. via F5 requesting a debugger start).
I want to be able to use the property pages dialog in visual studio to specify a path variable to another library.
The simplified versions are here. First I use a .targets file:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<PropertyPageSchema Include="$(MSBuildThisFileDirectory)\overrideSettings.xml" />
</ItemGroup>
<PropertyGroup Condition="'$(myDir)' == ''">
<__my_IncludeDir>somewhere\include\</__my_IncludeDir>
</PropertyGroup>
<PropertyGroup Condition="'$(myDir)' != ''">
<__my_IncludeDir>somewhere_else\include\</__my_IncludeDir>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(__my_IncludeDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<ResourceCompile>
<AdditionalIncludeDirectories>$(__my_IncludeDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
</Project>
And an .xml file for the settings:
<?xml version="1.0" encoding="utf-8"?>
<ProjectSchemaDefinitions xmlns="clr-namespace:Microsoft.Build.Framework.XamlTypes;assembly=Microsoft.Build.Framework">
<Rule Name="ProjectSettings_NugetDevOverride" PageTemplate="tool" DisplayName="Nuget Development Override" SwitchPrefix="/" Order="1">
<Rule.Categories>
<Category Name="myTest" DisplayName="myTest" />
</Rule.Categories>
<Rule.DataSource>
<DataSource Persistence="UserFile" ItemType="" />
</Rule.DataSource>
<StringProperty Name="myDir" Category="myTest" />
</Rule>
</ProjectSchemaDefinitions>
Now, this does work to some extent.
However, Visual Studio fails to correctly detect changes in the property variable defined on the property page.
I build the project -> 1 succeeded
I build the project again (F5) -> 1 up-to-date
I change the variable myDir using the property page; making it empty or setting a value, so that the other property group in the .targets file is triggered.
I build the project again (F5) -> 1 up-to-date This is wrong!
I re-build the project -> 1 succeeded with correctly used new property value.
Where is the problem in my setup? Can I explicitly add myDir as property to be checked before the build is marked as up-to-date?
I found one workaround: DisableFastUpToDateCheck
https://stackoverflow.com/a/36004494/552373
But this is horrible, since my real project is very large and the fast-up-to-date-check really helps.
Update 20171128:
I now also tried the following:
I build the project -> 1 succeeded
I build the project again (F5) -> 1 up-to-date
I change the variable myDir using the property page; making it empty or setting a value, so that the other property group in the .targets file is triggered.
I close Visual Studio and open it again. No file-save dialog popped up.
I build the project again (F5) -> 1 up-to-date This is wrong!
The fact, that even this does not work, points at a real problem with the FastUpToDateCheck in Visual Studio.
Does anyone have a further idea?
I'm tyring to refactor my code using include-what-you-use, but I need to figure out exactly which directories VS is looking in.
How do I get a listing of all include paths visible to files in my project?
If I add an incorrect include, something like "#include " I get the listing I want, but I can't copy and paste the damn thing! (and OCR doesn't seem to work).
How do I get this list?
Copy/pasting from the dialog is ok if you want to do this once manually but doesn't scale well. Since you tagged this msbuild, here's a solution using it. Create a file names showincludes.targets and paste this msbuild code:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="ShowIncludes">
<Message Text="$(Include);%(ClCompile.AdditionalIncludeDirectories)"/>
</Target>
</Project>
Now to get the list of includes for any project file use
msbuild \path\to\vcxproj /p:ForceImportAfterCppTargets=\path\to\showincludes.targets /t:ShowIncludes
This will import said file into the project give, so it has access to all properties, and print out the value of the INCLUDE environment variable which is by default used by the compiler, and also the value of AdditionalIncludeDirectories which is passed to the compiler by msbuild.
I'm managing a C++ project in VS2010 and want to have ALL .cpp files run through an external tool before going to the C++ compiler. All signs seem to indicate this is possible. See, for example, here.
Since this will happen over multiple projects, it makes sense to put this functionality in a property sheet and then just importing this property sheet everywhere. Before I touched the property sheet, it looked like this in its entirety:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<ExtensionsToDeleteOnClean>...</ExtensionsToDeleteOnClean>
<CustomBuildBeforeTargets>ClCompile</CustomBuildBeforeTargets>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>...</AdditionalIncludeDirectories>
<ForcedIncludeFiles>%(ForcedIncludeFiles)</ForcedIncludeFiles>
</ClCompile>
<Link>
<AdditionalDependencies>...</AdditionalDependencies>
</Link>
<Outputs>...</Outputs>
</CustomBuildStep>
</ItemDefinitionGroup>
</Project>
As per the above linked document, I have added the following lines:
<Project>
<PropertyGroup>
...
<CustomBuildBeforeTargets>ClCompile</CustomBuildBeforeTargets>
</PropertyGroup>
...
<ItemGroup>
<CustomBuild Include="*.cpp">
<Message>Running Custom Build Step</Message>
<Command>dummy</Command>
<Outputs>dummy</Outputs>
</CustomBuild>
</ItemGroup>
</Project>
This appears to have no effect, and my custom build tool never runs before ClCompile. I have tried various ways of moving things around and renaming tags (the Xml editor complains that CustomBuild isn't even valid according to the schema, for example), but nothing works.
What am I doing wrong?
Although this is a very old question, I will attempt to answer it.
The Include attribute expects to find *.cpp files in the Project directory. If there are no .cpp files in the Project directory, then this CustomBuild "Task" will never kick in.
What the OP could have done was
<CustomBuild Include="**\*.cpp">
<Message>Custombuild kicking in</Message>
<Command>echo %(Identity)</Command>
<Outputs>dummy</Outputs>
</CustomBuild>
instead of
<CustomBuild Include="*.cpp">
...
and he would have performed the CustomBuild action on all the .cpp files in all the subdirectories of the project directory, and not just the .cpp files waiting to be compiled.
If the .cpp files are not availble under the Project directory (can happen when such a project directory structure is used) then the OP must explicitly point to the right "root" directory.
Alternatively you can save yourself wildcard usage by simply running an Exec task on every included ClCompile.
<Target Name="ProcessClCompileFiles" BeforeTargets="ClCompile" Condition="'#(ClCompile)'!=''">
<Message Text="== Starting processing cpp files ==" Importance="High"/>
<Exec Command="echo processing %(ClCompile.filename)%(ClCompile.extension) & ////YOUR COMMAND HERE////" />
</Target>
As a note. This requires the ClCompile itemgroup to be initialised before this Target. if you were to create a target that dynamically adds ClCompile, you'd have to ensure that this happens before this Target is called.
Another note is that these Exec tasks will always run if there are any items in the ClCompile itemgroup. If you have a condition where it should skip them (eg, already processed), use Condition="A=B"
For easy reference, here's how to validate it hasn't created a file and if it created a file; if the file is out of date:
Condition="!Exists('$(OutDir)%(Filename)%(Extension)') OR ($([System.DateTime]::Parse('%(ClCompile.ModifiedTime)').Ticks) > $([System.IO.File]::GetLastWriteTime('$(OutDir)%(Filename)%(Extension)').Ticks))"