DotnetCore project IntermediateOutputPath leaves some files in the solution directory - build

In order to keep the repository clean and separated from output and build files we change corresponding paths in the project file.
For Net Framework project specifying IntermediateOutputPath redirects the obj directory to the corresponding folder.
For Net Core project (3.0) using this property is not sufficient. Whereas Debug, Release folders are indeed redirected, the obj folder is still created and it contains some file - such as
project.assets.json, .csproj.nuget.cache, .csproj.nuget.dgspec.json,.csproj.nuget.g.props, .csproj.nuget.g.targets .
Using BaseIntermediateOutputPath - doesnt help either.
Just wonder if someone can suggest how to move the whole obj directory?
Thanks
The Solution suggested by Martin works fine for Net Core projects
<Project>
<PropertyGroup>
<BuildDIrectory>C:\Temp\Build\$(Configuration)</BuildDIrectory>
<RelativePath>some arelative path which depends on location of corresponding project withing the solution</RelativePath>
<BaseIntermediateOutputPath>$(BuildDIrectory)\obj\$(RelativePath)\$(AssemblyName)\</BaseIntermediateOutputPath>
<OutputPath>$(BuildDIrectory)\out\$(RelativePath)\$(AssemblyName)\</OutputPath>
<DocumentationFile>$(BuildDIrectory)\Documentation\$(RelativePath)\$(AssemblyName).xml</DocumentationFile>
</PropertyGroup>
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
...
</Project>

BaseIntermediateOutputPath works as well, but it needs to be set very early in order to take effect.
The easiest way would be to add it to a Directory.Build.props file:
<Project>
<PropertyGroup>
<BaseIntermediateOutputPath>$(MSBuildThisFileDirectory)..\shared-obj\$(MSBuildProjectName)\</BaseIntermediateOutputPath>
</PropertyGroup>
</Project>
If you want to specify it directly in the csproj file, you cannot use the <Project Sdk=" notation since the property needs to be set before parts of the SDK are applied. However it works when using explicit SDK imports and correct ordering:
<Project>
<PropertyGroup>
<BaseIntermediateOutputPath>..\shared-obj\myprojA\</BaseIntermediateOutputPath>
</PropertyGroup>
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
<OutputType>Exe</OutputType>
</PropertyGroup>
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
</Project>

Related

How to set .vcxproj to let MSBuild compile a dll

Above All
To save your time from reading a lot, Thanks to CristiFati and here is the answer:
If you use "Library" in "ConfigurationType" like me, you'll get an .obj file instead of .dll.
The right keyword is "DynamicLibrary" instead of "Library". That is:
<ConfigurationType>DynamicLibrary</ConfigurationType>
Then you'll have the .dll you want.
[supplement] From CMake Documents, thanks to Botje's guiding, it appears that a "Library" is actually like a sub-directory under the root project. Thus it's different with how dll work.
Short Story:
I need to compile a dll with MSbuild, without any IDE.
I followed instruction on Microsoft Doc to create app build project.
No webpage indicates how to create dll build project is found yet. Thus I edit .vcxproj according to similar google info.
BUILD SUCCESS!
But the result only contain a .obj file. No dll in sight.
Need help about how to modify a .vcxproj to build a dll.
Detailed Story:
I need to compile a dll.
My company didn't buy any commercial license thus I cannot use any IDE for this.
However MSBuild is safe to use.
I'm following this page to create a C++ project which could be compiled with MSBuild only.
https://learn.microsoft.com/en-us/cpp/build/walkthrough-using-msbuild-to-create-a-visual-cpp-project?view=vs-2017
You don't need actually read that page because I'll paste the project file below.
First, Following that page, I got this application type project file
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.default.props" />
<PropertyGroup>
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ItemGroup>
<ClCompile Include="helloworld.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="helloworld.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Targets" />
</Project>
I tested the build. And got my .exe file successfully. And my helloworld.exe printed "HelloWorld" as predicted. Then...
Second, Following this page:
https://learn.microsoft.com/en-us/cpp/build/walkthrough-creating-and-using-a-dynamic-link-library-cpp?view=vs-2017
I'm sure the header and cpp file is good to go
#pragma once
#ifdef HELLOWORLD_EXPORTS
#define HELLOWORLD_API __declspec(dllexport)
#else
#define HELLOWORLD_API __declspec(dllimport)
#endif
extern "C" HELLOWORLD_API void helloworld();
Third, Switch this project from application mode to library mode...
Actually I'm not sure how to do this. So I googled some info and try to do what they did.
I change the Debug mode to Release mode.
Then change the Application output to Library.
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.default.props" />
<PropertyGroup>
<ConfigurationType>Library</ConfigurationType>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ItemGroup>
<ClCompile Include="helloworld.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="helloworld.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Targets" />
</Project>
Finally, I let msbuild do its work:
msbuild helloworld.vcxproj /p:configuration=Release
And the build is success!
But when I head to Release folder under my root directory, I find only a "helloworld.obj" file and a "vc141.pdb" along a folder names "helloworld.tlog".
Well this is not right. I think the right result will be a "helloworld.dll" in here.
So, that should be my .vcxproj file's problem I guess.
So, could anybody kindly give a guide for creating a dll project from scratch?
Thanks!
Although using the IDE is prohibited by licensing purposes, listing [MS.Docs]: Walkthrough: Create and use your own Dynamic Link Library (C++) anyway.
The keypoint is:
3. From the filtered list of project types, select Dynamic-link Library (DLL), and then choose Next.
Behind the scenes, that maps to: [MS.Docs]: ConfigurationTypes Enum:
Fields
typeApplication             1      Application (.exe)
typeDynamicLibrary      2      Dynamic Library (.dll)
typeGeneric                 10      Makefile, displays makefile toolset (NMake)
typeStaticLibrary           4      Static Library (.dll)
typeUnknown                0      Utility
Translated to .vcxproj structure, the ConfigurationType node:
<ConfigurationType>Application</ConfigurationType>
should be converted to:
<ConfigurationType>DynamicLibrary</ConfigurationType>
But, as (#Botje's) comments rightly pointed out, you should move towards free build tools (there are a number of alternatives, and CMake seems to be the best one).

Custom Build Files changes do not trigger project rebuild in VS 2017

In my C++ VS project I added a custom target to compile shader files and set it as a initial target. This is the project xml
<Project InitialTargets="CompileShaders" DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
..... Normal Default VS C++ content here ......
<ItemGroup>
<GLSLShader Include="SPIR-V\canvas2D.vert" />
<GLSLShader Include="SPIR-V\canvas2D.frag" />
</ItemGroup>
<Target Name="CompileShaders" Inputs="#(GLSLShader)" Outputs="SPIR-V\shaders_bytecode.h" >
<PropertyGroup>
<OriginalFileName>%(GLSLShader.Filename)%(GLSLShader.Extension)</OriginalFileName>
</PropertyGroup>
<Message Text="Start Compiling GSLANG #(GLSLShader) " />
<Message Condition="'$(VULKAN_SDK)'==''" Text="Error, cant find environment variable VULKAN_SDK, Make sure that the Lunar Vulkan SDK is installed" />
<Message Condition="'$(VULKAN_SDK)'!=''" Text="$(VULKAN_SDK)\Bin\glslangValidator.exe %(GLSLShader.Filename)%(GLSLShader.Extension) -V --vn $([System.String]::Copy('%(GLSLShader.Filename)%(GLSLShader.Extension)').Replace('.','_')) -o %(GLSLShader.Filename)%(GLSLShader.Extension).h" />
<Exec Condition="'$(VULKAN_SDK)'!=''" Command="$(VULKAN_SDK)\Bin\glslangValidator.exe %(GLSLShader.Filename)%(GLSLShader.Extension) -V --vn $([System.String]::Copy('%(GLSLShader.Filename)%(GLSLShader.Extension)').Replace('.','_')) -o %(GLSLShader.Filename)%(GLSLShader.Extension).h" WorkingDirectory="$(ProjectDir)\SPIR-V" />
<Exec Condition="'$(VULKAN_SDK)'!=''" Command="del shaders_bytecode.h" WorkingDirectory="$(ProjectDir)\SPIR-V" />
<Exec Condition="'$(VULKAN_SDK)'!=''" Command="type %(GLSLShader.Filename)%(GLSLShader.Extension).h >> shaders_bytecode.h" WorkingDirectory="$(ProjectDir)\SPIR-V" />
<Exec Condition="'$(VULKAN_SDK)'!=''" Command="del %(GLSLShader.Filename)%(GLSLShader.Extension).h" WorkingDirectory="$(ProjectDir)\SPIR-V" />
</Target>
</Project>
if I change any .cpp .h file and build the solution, the shaders are compiled together with the rest of the project, but if I change only the shader files (i.e SPIR-V\canvas2D.vert) the project is not built. VS says that the project is up to date.
Now the strange thing, If I run the project using msbuild on the terminal ouside VS, the shader files changes are enough to trigger the rebuild. Go figure....!!!
It looks like something related to how VS build projects. It is outside the msbuild.
Aha!! Found it in this article. It turns out visual studio bypass msbuild and uses some other criteria to verify if a project is up to date or not. If the criteria fails it then runs the msbuild on that project.
To override the visual studio behavior set the property DisableFastUpToDateCheck as true in the Globals property group of your project's xml:
<PropertyGroup Label="Globals">
<!-- Other Global Property Settings -->
<DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
</PropertyGroup>
And it is done... I wonder if there is a away to tell Visual Studio FastUpToDateCheck Mechanism to also pay attention to the custom build files ????? The solution above will suffice for now.

Missing NuGet packages when used on project within a solution

I've looked at this answer:
Editing the .csproj file and correcting the relative path to the
solution folder (which contains the packages folder) solved the
problem for me.
but I'm not sure what to edit.
I'm making a C++ project in Visual Studio 2013. I have one solution with three projects. One of the projects needs a NuGet package.
I used Manage NuGet packages for solution on my solution to install the NuGet package. From there I selected the one project which needs the package. I also used Enable NuGet Package Restore.
By doing this I end up with a .nuget and packages folder in the solution directory.
When I try to build the project requiring the package I get the error:
This project references NuGet package(s) that are missing on this
computer. Enable NuGet Package Restore to download them. For more
information, see http://go.microsoft.com/fwlink/?LinkID=322105. The
missing file is
....\packages\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.targets.
If I follow the mentioned path, assuming that the directory it is relative from is the project directory of the project, the "missing file" is there.
The project having this problem, was a project I used alone (with its own solution) before, and has been copy pasted to this solution with three projects.
That's why I mentioned the answer of an another question and the top of the post. That answer suggest editing a project file. If I open my .vcxproj file I see this:
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\packages\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.targets" Condition="Exists('..\packages\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.targets')" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<Import Project="..\..\packages\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.targets" Condition="Exists('..\..\packages\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.targets')" />
<Import Project="..\..\packages\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.targets" Condition="Exists('..\..\packages\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
<Error Condition="!Exists('..\..\packages\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.targets'))" />
<Error Condition="!Exists('..\..\packages\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.targets'))" />
<Error Condition="!Exists('..\..\packages\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.targets'))" />
</Target>
I'm very unsure what to edit.
I can guess that maybe some of the paths should be changed from being relative of the project directory, to being relative of the solution directory. But by editing to:
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="packages\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.targets" Condition="Exists('packages\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.targets')" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<Import Project="packages\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.targets" Condition="Exists('packages\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.targets')" />
<Import Project="packages\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.targets" Condition="Exists('packages\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
<Error Condition="!Exists('packages\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.targets'))" />
<Error Condition="!Exists('packages\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.targets'))" />
<Error Condition="!Exists('packages\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.targets'))" />
</Target>
Visual studio will give me an error stating: An item with the same key has already been added. The project is then marked as (load failed) in the solution browser.
What am I doing wrong here?
I found my solution through this answer.
In the .vcxproj file I removed the following:
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
<Error Condition="!Exists('packages\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.targets'))" />
<Error Condition="!Exists('packages\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.targets'))" />
<Error Condition="!Exists('packages\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.targets'))" />
</Target>
and I can now build the project.
It is probably not the best solution, as there is a reason for these Error Conditions to exist. But editing the paths did not help.

Include path relative to props file in visual studio

I'm trying to create property file with include path to use in all my c++ project.
Here is repository structure.
/
/Libs
/Libs2
A.h
B.h
/Sln1
Sln1.sln
Proj1.vcxproj
Sln2.sln
Proj2.vcxproj
Props.props
I want use property file (Props.props) to add the following include path to both projects ( C:\\Libs;C:\\Libs\Libs2).
Currently I have macro in my property file:
Name Value
ProjRoot C:\<path to rep root>
And I use it in include string: $(ProjRoot)\Libs;$(ProjRoot)\Libs\Libs2
The problem with this solution is hardcoded absolute path in macro value. If my repository will be cloned on another drive I will have to change it manually.
Can I use path relative to property file in macro value?
I.e.:
Name Value
ProjRoot ./
Where ./ will resolve to path of Props.props file in all projects which will use this property file.
I cannot use $(SolutionDir) and $(ProjectDir) because there are may solutions and projects in different nesting level so path relative to them would not work.
Thank you.
Do do this one should manually edit props file and include the following:
<PropSheetPath>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)'))</PropSheetPath>
This will create property PropSheetPath with property file folder.
Found the answer here:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/2817cae7-3a71-4701-839a-9bf47af7c498/property-sheets-macro-to-reference-location-of-property-sheet?forum=vcgeneral
Just to improve previous answer... Here how it looks as a full example (I'm using a bunch of small property sheets to add third party libraries in a modular way). This is an example for adding paths to include folders for C++ compiler and library folders for linker to add CEGUI library into project (debug version, I use separate prop sheet for Release).
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros">
<PropSheetPath>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)'))</PropSheetPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Language)'=='C++'">
<CAExcludePath>$(PropsheetPath)..\..\install\windows\Debug\include\cegui-0;$(CAExcludePath)</CAExcludePath>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<PreprocessorDefinitions>CEGUI_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(PropsheetPath)..\..\install\windows\Debug\include\cegui-0;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>$(PropsheetPath)..\..\install\windows\Debug\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>DbgHelp.lib;CEGUIBase-0_Static_d.lib;CEGUICommonDialogs-0_Static_d.lib;CEGUICoreWindowRendererSet_Static_d.lib;CEGUIExpatParser_Static_d.lib;CEGUIOpenGLRenderer-0_Static_d.lib;CEGUITGAImageCodec_Static_d.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup />
</Project>

Visual Studio 2013 Project with Multiple Property Sheets

I am working on a project using Visual Studio 2013 on Windows 10. Basically I am writing a few MEX files using C++, and I'm using a few libraries that I use often: OpenCV and MATLAB's extern libraries. For each library, I have saved property sheets (.props files) with all of the necessary information. The gist of it is that I am trying to add both my opencv.props file and my matlab.props file to the project.
My current problem arises when I try to add multiple property sheets to the property configuration in "Property Manager." For each, I click "Add existing property sheet" and voila! I am supposed to get the proper settings. When I only use a single property sheet, everything works fine. When I try adding multiple sheets, only the most recent addition seems to be registering.
Any idea where I'm going wrong?
I've pasted the contents of the .props files below since they're both pretty short and simple:
matlab.props
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(MATLAB_DIR)\extern\include</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup />
</Project>
opencv.props
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_PropertySheetDisplayName>OpenCV_debug</_PropertySheetDisplayName>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(OPENCV_DIR)\..\..\include</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>$(OPENCV_DIR)\lib</AdditionalLibraryDirectories>
<AdditionalDependencies>opencv_calib3d$(OPENCV_VERSION)d.lib;opencv_contrib$(OPENCV_VERSION)d.lib;opencv_core$(OPENCV_VERSION)d.lib;opencv_features2d$(OPENCV_VERSION)d.lib;opencv_flann$(OPENCV_VERSION)d.lib;opencv_gpu$(OPENCV_VERSION)d.lib;opencv_highgui$(OPENCV_VERSION)d.lib;opencv_imgproc$(OPENCV_VERSION)d.lib;opencv_legacy$(OPENCV_VERSION)d.lib;opencv_ml$(OPENCV_VERSION)d.lib;opencv_nonfree$(OPENCV_VERSION)d.lib;opencv_objdetect$(OPENCV_VERSION)d.lib;opencv_ocl$(OPENCV_VERSION)d.lib;opencv_photo$(OPENCV_VERSION)d.lib;opencv_stitching$(OPENCV_VERSION)d.lib;opencv_superres$(OPENCV_VERSION)d.lib;opencv_ts$(OPENCV_VERSION)d.lib;opencv_video$(OPENCV_VERSION)d.lib;opencv_videostab$(OPENCV_VERSION)d.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup />
</Project>
In general, properties in a property sheet overwrite previously set properties. To retain previous settings, you have to add them explicitly (using the %(<prop>) macro syntax).
For example, in your opencv.props file you need to replace
<AdditionalIncludeDirectories>$(MATLAB_DIR)\extern\include</AdditionalIncludeDirectories>
with
<AdditionalIncludeDirectories>$(MATLAB_DIR)\extern\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
Apply the same changes to the <AdditionalLibraryDirectories> property; the <AdditionalDependencies> is already correct.