roybj roybj - 1 month ago 7
C++ Question

View effective properties in VS C++ project when using MSBuild targets file?

I am importing MSBuild targets file to set properties to a VS C++ project - namely the include and libs folders.
(I am using Nuget for native packages, and this is how it is done there).
I couldn't find a way to view in the IDE, the effective properties values that the project get from the properties file.
when I look at the project properties (e.g. include folders), they are empty.
but the targets file is working, since I am able to use the include, lib folders that are specified there successfully.

How can I view the values from the IDE?

Here are the rest of the details:
I installed the
Microsoft.Azure.C.SharedUtility (1.0.19) Nuget package in an empty C++ project. this results in the following sections added to the vcxproj file:

<ImportGroup Label="ExtensionTargets">
<Import Project="..\packages\Microsoft.Azure.C.SharedUtility.1.0.19\build\native\Microsoft.Azure.C.SharedUtility.targets" Condition="Exists('..\packages\Microsoft.Azure.C.SharedUtility.1.0.19\build\native\Microsoft.Azure.C.SharedUtility.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use 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('..\packages\Microsoft.Azure.C.SharedUtility.1.0.19\build\native\Microsoft.Azure.C.SharedUtility.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Azure.C.SharedUtility.1.0.19\build\native\Microsoft.Azure.C.SharedUtility.targets'))" />
</Target>


And the targets file itself is:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" InitialTargets="Microsoft_Azure_C_SharedUtil_Init">
<PropertyGroup Label="Default initializers for properties">
<Linkage-Microsoft_Azure_C_SharedUtil_Init Condition="'$(Linkage-Microsoft_Azure_C_SharedUtil_Init)' == ''">static</Linkage-Microsoft_Azure_C_SharedUtil_Init>
<CallingConvention-Microsoft_Azure_C_SharedUtil Condition="'$(CallingConvention-Microsoft_Azure_C_SharedUtil)' == ''">cdecl</CallingConvention-Microsoft_Azure_C_SharedUtil>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)../../build/native/include/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<ResourceCompile>
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)../../build/native/include/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Label="Win32Debug" Condition="(( $(Configuration.ToLower().IndexOf('debug')) &gt; -1 ) And ('$(Platform)' == 'Win32' ) )">
<Link>
<AdditionalDependencies>Secur32.lib;Ws2_32.lib;$(MSBuildThisFileDirectory)../../build/native/Win32/Debug/aziotsharedutil.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Label="Win32Release" Condition="(( $(Configuration.ToLower().IndexOf('debug')) == -1 ) And ('$(Platform)' == 'Win32' ) )">
<Link>
<AdditionalDependencies>Secur32.lib;Ws2_32.lib;$(MSBuildThisFileDirectory)../../build/native/Win32/Release/aziotsharedutil.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Label="Win64Debug" Condition="(( $(Configuration.ToLower().IndexOf('debug')) &gt; -1 ) And ('$(Platform)' == 'x64' ) )">
<Link>
<AdditionalDependencies>Secur32.lib;Ws2_32.lib;$(MSBuildThisFileDirectory)../../build/native/x64/Debug/aziotsharedutil.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Label="Win64Release" Condition="(( $(Configuration.ToLower().IndexOf('debug')) == -1 ) And ('$(Platform)' == 'x64' ) )">
<Link>
<AdditionalDependencies>Secur32.lib;Ws2_32.lib;$(MSBuildThisFileDirectory)../../build/native/x64/Release/aziotsharedutil.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Label="ARMDebug" Condition="(( $(Configuration.ToLower().IndexOf('debug')) &gt; -1 ) And ('$(Platform)' == 'ARM' ) )">
<Link>
<AdditionalDependencies>Secur32.lib;Ws2_32.lib;$(MSBuildThisFileDirectory)../../build/native/arm/Debug/aziotsharedutil.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Label="ARMRelease" Condition="(( $(Configuration.ToLower().IndexOf('debug')) == -1 ) And ('$(Platform)' == 'ARM' ) )">
<Link>
<AdditionalDependencies>Secur32.lib;Ws2_32.lib;$(MSBuildThisFileDirectory)../../build/native/arm/Release/aziotsharedutil.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Label="ARM64Debug" Condition="(( $(Configuration.ToLower().IndexOf('debug')) &gt; -1 ) And ('$(Platform)' == 'ARM64' ) )">
<Link>
<AdditionalDependencies>Secur32.lib;Ws2_32.lib;$(MSBuildThisFileDirectory)../../build/native/arm64/Debug/aziotsharedutil.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Label="ARM64Release" Condition="(( $(Configuration.ToLower().IndexOf('debug')) == -1 ) And ('$(Platform)' == 'ARM64' ) )">
<Link>
<AdditionalDependencies>Secur32.lib;Ws2_32.lib;$(MSBuildThisFileDirectory)../../build/native/arm64/Release/aziotsharedutil.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<UsingTask TaskName="Microsoft_Azure_Shared_Util_Contains" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" TaskFactory="CodeTaskFactory">
<ParameterGroup>
<Text Output="false" ParameterType="System.String" />
<Library Output="false" Required="true" ParameterType="System.String" />
<Value Output="false" Required="true" ParameterType="System.String" />
<Result Output="true" ParameterType="System.String" />
</ParameterGroup>
<Task>
<Code>Result = ((Text ?? "").Split(';').Contains(Library) ) ? Value : String.Empty;</Code>
</Task>
</UsingTask>
<Target Name="Microsoft_Azure_C_SharedUtil_Init">
<Microsoft_Azure_Shared_Util_Contains Text="Linkage-dynamic" Library="Microsoft_Azure_Shared_Util" Value="dynamic" Condition="'$(Linkage-Microsoft_Azure_C_SharedUtil_Init)'==''">
<Output TaskParameter="Result" PropertyName="Linkage-Microsoft_Azure_C_SharedUtil_Init" />
</Microsoft_Azure_Shared_Util_Contains>
<Microsoft_Azure_Shared_Util_Contains Text="Linkage-static" Library="Microsoft_Azure_Shared_Util" Value="static" Condition="'$(Linkage-Microsoft_Azure_C_SharedUtil_Init)'==''">
<Output TaskParameter="Result" PropertyName="Linkage-Microsoft_Azure_C_SharedUtil_Init" />
</Microsoft_Azure_Shared_Util_Contains>
<Microsoft_Azure_Shared_Util_Contains Text="Linkage-ltcg" Library="Microsoft_Azure_Shared_Util" Value="ltcg" Condition="'$(Linkage-Microsoft_Azure_C_SharedUtil_Init)'==''">
<Output TaskParameter="Result" PropertyName="Linkage-Microsoft_Azure_C_SharedUtil_Init" />
</Microsoft_Azure_Shared_Util_Contains>
<Microsoft_Azure_Shared_Util_Contains Text="Linkage-sxs" Library="Microsoft_Azure_Shared_Util" Value="sxs" Condition="'$(Linkage-Microsoft_Azure_C_SharedUtil_Init)'==''">
<Output TaskParameter="Result" PropertyName="Linkage-Microsoft_Azure_C_SharedUtil_Init" />
</Microsoft_Azure_Shared_Util_Contains>
<Microsoft_Azure_Shared_Util_Contains Text="CallingConvention-cdecl" Library="Microsoft_Azure_Shared_Util" Value="cdecl" Condition="'$(CallingConvention-Microsoft_Azure_Shared_Util)'==''">
<Output TaskParameter="Result" PropertyName="CallingConvention-Microsoft_Azure_Shared_Util" />
</Microsoft_Azure_Shared_Util_Contains>
<Microsoft_Azure_Shared_Util_Contains Text="CallingConvention-stdcall" Library="Microsoft_Azure_Shared_Util" Value="stdcall" Condition="'$(CallingConvention-Microsoft_Azure_Shared_Util)'==''">
<Output TaskParameter="Result" PropertyName="CallingConvention-Microsoft_Azure_Shared_Util" />
</Microsoft_Azure_Shared_Util_Contains>
<Microsoft_Azure_Shared_Util_Contains Text="CallingConvention-fastcall" Library="Microsoft_Azure_Shared_Util" Value="fastcall" Condition="'$(CallingConvention-Microsoft_Azure_Shared_Util)'==''">
<Output TaskParameter="Result" PropertyName="CallingConvention-Microsoft_Azure_Shared_Util" />
</Microsoft_Azure_Shared_Util_Contains>
<Microsoft_Azure_Shared_Util_Contains Text="CallingConvention-thiscall" Library="Microsoft_Azure_Shared_Util" Value="thiscall" Condition="'$(CallingConvention-Microsoft_Azure_Shared_Util)'==''">
<Output TaskParameter="Result" PropertyName="CallingConvention-Microsoft_Azure_Shared_Util" />
</Microsoft_Azure_Shared_Util_Contains>
<Microsoft_Azure_Shared_Util_Contains Text="CallingConvention-clrcall" Library="Microsoft_Azure_Shared_Util" Value="clrcall" Condition="'$(CallingConvention-Microsoft_Azure_Shared_Util)'==''">
<Output TaskParameter="Result" PropertyName="CallingConvention-Microsoft_Azure_Shared_Util" />
</Microsoft_Azure_Shared_Util_Contains>
</Target>
<Target Name="Microsoft_Azure_Shared_Util_redist_AfterBuild" AfterTargets="AfterBuild" />
<Target Name="Microsoft_Azure_Shared_Util_redist_AfterBuild_Win32_and_Debug" Label="Win32 and Debug" Condition="'$(Platform.ToLower())' == 'win32' And ( $(Configuration.ToLower().IndexOf('debug')) &gt; -1 )" AfterTargets="Microsoft_Azure_Shared_Util_redist_AfterBuild">
</Target>
<Target Name="Microsoft_Azure_Shared_Util_redist_AfterBuild_Win32_and_Release" Label="Win32 and Release" Condition="'$(Platform.ToLower())' == 'win32' And ( $(Configuration.ToLower().IndexOf('debug')) == -1 )" AfterTargets="Microsoft_Azure_Shared_Util_redist_AfterBuild">
</Target>
<Target Name="Microsoft_Azure_Shared_Util_redist_AfterBuild_Win64_and_Debug" Label="Win64 and Debug" Condition="'$(Platform.ToLower())' == 'x64' And ( $(Configuration.ToLower().IndexOf('debug')) &gt; -1 )" AfterTargets="Microsoft_Azure_Shared_Util_redist_AfterBuild">
</Target>
<Target Name="Microsoft_Azure_Shared_Util_redist_AfterBuild_Win64_and_Release" Label="Win64 and Release" Condition="'$(Platform.ToLower())' == 'x64' And ( $(Configuration.ToLower().IndexOf('debug')) == -1 )" AfterTargets="Microsoft_Azure_Shared_Util_redist_AfterBuild">
</Target>
<Target Name="Microsoft_Azure_Shared_Util_redist_AfterBuild_ARM_and_Debug" Label="ARM and Debug" Condition="'$(Platform.ToLower())' == 'ARM' And ( $(Configuration.ToLower().IndexOf('debug')) &gt; -1 )" AfterTargets="Microsoft_Azure_Shared_Util_redist_AfterBuild">
</Target>
<Target Name="Microsoft_Azure_Shared_Util_redist_AfterBuild_ARM_and_Release" Label="ARM and Release" Condition="'$(Platform.ToLower())' == 'ARM' And ( $(Configuration.ToLower().IndexOf('debug')) == -1 )" AfterTargets="Microsoft_Azure_Shared_Util_redist_AfterBuild">
</Target>
<Target Name="Microsoft_Azure_Shared_Util_redist_AfterBuild_ARM64_and_Debug" Label="ARM64 and Debug" Condition="'$(Platform.ToLower())' == 'ARM64' And ( $(Configuration.ToLower().IndexOf('debug')) &gt; -1 )" AfterTargets="Microsoft_Azure_Shared_Util_redist_AfterBuild">
</Target>
<Target Name="Microsoft_Azure_Shared_Util_redist_AfterBuild_ARM64_and_Release" Label="ARM64 and Release" Condition="'$(Platform.ToLower())' == 'ARM64' And ( $(Configuration.ToLower().IndexOf('debug')) == -1 )" AfterTargets="Microsoft_Azure_Shared_Util_redist_AfterBuild">
</Target>
</Project>


The project works fine, includes from the right folders and references the right libs, but I cannot see the effective values in the IDE.

Thanks,
Roy.

Answer

As said in the comment, this looks like a bug (or maybe feature) in VS: for some reason when the imported file is imported after the project's own ItemDefinitionGroups where it has the compiler/linker settings, it's content isn't reflected in the IDE even though it is used in the build, as per standard msbuild evaluation rules.

The workaround is simple enough: move the Import higher in the project file. In fact as you can see the Import is now in an ImportGroup labelled 'ExtensionTargets' but higher in the file there's also a group labelled 'ExtensionSettings' which seems tailored for usage like this - and VS will show the resulting settings properly, and they can be overrided by user settings when needed via the standard project property system.

Arguably (though I can't find documentation to back it up) the most sensible thing to do here is to provide 2 imports: the actual targets file which as the name implies contains msbuild Targets, imported under 'ExtensionTargets', and a seperate file with compiler/linker settings imported under 'ExtensionSettings'. The latter wouldn't have a .targets extension but a .props extension as that is the convention used most.

Comments