VS not honoring PropertyGroup Configuration Settings - visual-studio

I'm trying to compact a XML project file. The project compiles a single source file but its over 11 KB in size because of a penchant for duplicating the same settings multiple times. I'm trying to move per-source-file settings and hoisting them up into Configuration PropertyGroup with different condition statements or expressions (what does XML call them?).
If I am parsing A guide to .vcxproj and .props file structure from MSDN Blogs correctly, we can place the settings iin the property group:
<PropertyGroup Label=“Configuration“ />
<!– This property sheet (directly or via imports) defines the
default values for many tool-specific properties such as the
compiler’s Optimization, WarningLevel properties, Midl tool’s
TypeLibraryName property, etc...
However, when I check my modifications by closing VS and then re-opening it with the modified project file, none of the settings are picked up. Visual Studio appears to be using its own settings.
I have a few questions:
Is there a Visual Studio setting to tell it to stop sraying every setting into every source file? There's no reason to duplicate a setting 175x4 times for each source file crossed into each configuration.
Does Visual Studio have a compaction utility so I don't have to do this by hand? Its very tedious work.
Why is Visual Studio not picking up the settings? How do I fix it?
Here's a screen capture of a property page which includes Preprocessor Macros. The modified XML has the following, which is not reflected in Visual Studio. I've tried with and without the ClCompile.
<!-- Debug Configurations -->
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Release Configuration">
<ClCompile>
<PreprocessorDefinitions>CRYPTOPP_DLL_ONLY;%(PreprocessorDefinitions)</PreprocessorDefinitions>
...
</ClCompile>
</PropertyGroup>
Here's the compacted project file. The original can be found here. The project compiles 1 source file, and its over 11KB in size un-compacted.
My mods start at <!-- All Configurations -->, and ends at <!-- Back to Visual Studio boilerplate -->. I have not finished hoisting all the settings, but the ones that have been done, like Preprocessor Macros and Runtime Library, are not reflected under Visual Studio.
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{1974a53a-9863-41c9-886d-b2b8c2fc3c8b}</ProjectGuid>
<RootNamespace>dlltest</RootNamespace>
<PlatformToolset>v100</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<!-- All Configurations -->
<PropertyGroup Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<OutDir>$(Platform)\DLL_Output\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<CallingConvention>StdCall</CallingConvention>
<SuppressStartupBanner>true</SuppressStartupBanner>
</ClCompile>
</PropertyGroup>
<!-- Debug Configurations -->
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Debug Configuration">
<ClCompile>
<PreprocessorDefinitions>CRYPTOPP_DLL_ONLY;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Optimization>Disabled</Optimization>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<IntrinsicFunctions>true</IntrinsicFunctions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
</PropertyGroup>
<!-- Release Configurations -->
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Release Configuration">
<ClCompile>
<PreprocessorDefinitions>NDEBUG;CRYPTOPP_DLL_ONLY;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<OmitFramePointers>true</OmitFramePointers>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FunctionLevelLinking>true</FunctionLevelLinking>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
</PropertyGroup>
<!-- X86 Configurations -->
<PropertyGroup Condition="'$(Platform)'=='Win32'" Label="X86 Configuration">
<ClCompile>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
</ClCompile>
</PropertyGroup>
<!-- X64 Configurations -->
<PropertyGroup Condition="'$(Platform)'=='x64'" Label="X64 Configuration">
<ClCompile>
<!-- <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet> -->
<EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
</ClCompile>
</PropertyGroup>
<!-- Back to Visual Studio boilerplate -->
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<StringPooling>true</StringPooling>
<PrecompiledHeader />
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>cryptopp.lib;Ws2_32.lib</AdditionalDependencies>
<AdditionalLibraryDirectories>$(Platform)\DLL_Output\$(Configuration)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<StringPooling>true</StringPooling>
<PrecompiledHeader />
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>cryptopp.lib;Ws2_32.lib</AdditionalDependencies>
<AdditionalLibraryDirectories>$(Platform)\DLL_Output\$(Configuration)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader />
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>cryptopp.lib;Ws2_32.lib</AdditionalDependencies>
<AdditionalLibraryDirectories>$(Platform)\DLL_Output\$(Configuration)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader />
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>cryptopp.lib;Ws2_32.lib</AdditionalDependencies>
<AdditionalLibraryDirectories>$(Platform)\DLL_Output\$(Configuration)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="dlltest.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

Your settings are overwritten because you put them too early in the file. Do as VS does, and put them after the <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />.
update my mistake; on second sight, your settings don't have any effect whatsoever since you are defining them as properties. Do as VS does, and define them in an ItemDefinitionGroup instead of a PropertyGroup (again, in the correct location as per msbuild evaluation rules)
As for the compacting: store your settings in seperate property sheets and import those. If organized wisely this will allow you to never have to edit the project file settings itself anymore (and hence the VS populated ItemDefinitionGroups will be empty), but you'll just add/remove property sheets as needed and the project file is just a container for source/header files and property sheets. If you do the importing in the VS gui (called 'Property Manager') they will automatically end up in the correct location mentioned before, and the order will also be ok. They can also be edited in VS via the same options dialog as for the project.
Note you can create whole hierarchies of property sheets importing others, which is useful to avoid repetition. E.g. instead of manually adding Ws2_32.lib to each config/platform combo you just import a property sheet which does just that. Especially handy for libraries which have different names depending on platform/configuration etc. And suppose you have created some standard property sheets seperate for compiler/linker/... you can add them to a 'master' one. Sample:

Related

Visual Studio ignores UseDebugLibraries from .props

I have the following .props file, generated with CMake (but this does not seem to be a CMake problem):
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
</PropertyGroup>
</Project>
I have another .props file, next to this one in the .vcxproj, but it is correctly merged when i open it in Visual Studio, they look like this in the project file:
<ImportGroup Label="PropertySheets">
<Import Project="other_props_file_that_works.props;does_not_work.props" Condition="exists('other_props_file_that_works.props;does_not_work.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
Not really relevant, but the props are added like this in the CMakeLists.txt:
set_property(TARGET "${PROJECT_NAME}" PROPERTY VS_USER_PROPS ${USE_DEBUG_LIBARIES_PROPS_FILE_PATH} APPEND)

Msbuild : Error: The OutputPath property is not set for this project

I am currently trying to decouple a project and I am getting the following error
The OutputPath property is not set for project 'MyProj.vcxpro j'.
Please check to make sure that you have specified a valid combination
of Configuration and Platform for this project. Configuration=''
Platform='x64'. You may be seeing this message because you a re
trying to build a project without a solution file, and have specified
a non-default Configuration or Platform that doesn't exist for this
project. [D:\Test\MyProj.vcxproj]
I added this to my project but it is not helping
<PropertyGroup Label="Globals">
<Platform Condition="'$(Platform)' == ''">x64</Platform>
<TargetName>MyProj</TargetName>
<ResolveExportedSymbols>true</ResolveExportedSymbols>
<ProjectGuid>{xxxxx-xxxx-xxxx-xxx}</ProjectGuid>
<UsePrecompiledHeader>true</UsePrecompiledHeader>
<OutputPath>D:\MyOutput\out\</OutputPath>
</PropertyGroup>
Any suggestions ?
Please use this:
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform Condition="'$(Platform)' == ''">x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<TargetName>MyProj</TargetName>
<ResolveExportedSymbols>true</ResolveExportedSymbols>
<ProjectGuid>{xxxxx-xxxx-xxxx-xxx}</ProjectGuid>
<OutputPath>D:\MyOutput\out\</OutputPath>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
.....
</ClCompile>
</ItemDefinitionGroup>
.....
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
Then, delete any output folder like Debug and then rebuild again.

xbuild compiles without errors but dont have .exe files?

Only For educational purposes.
Basically I am trying to compile Juicy Potato exploit. I found a visual studio project from github and Now I am trying to compile it using mono xbuild, Although it compiles without any errors but I can't find the binary or .exe files.
see below:
>>>> xbuild tool is deprecated and will be removed in future updates, use msbuild instead <<<<
XBuild Engine Version 14.0
Mono, Version 5.18.0.240
Copyright (C) 2005-2013 Various Mono authors
Build started 2019-10-10 3:30:02 PM.
__________________________________________________
/home/HTB/Json/10.10.10.158/nmap/juicy_potato/juicy-potato/JuicyPotato/JuicyPotato.sln: warning : Ignoring vcproj 'JuicyPotato'.
/home/HTB/Json/10.10.10.158/nmap/juicy_potato/juicy-potato/JuicyPotato/JuicyPotato.sln: warning : Failed to find project 4164003e-ba47-4a95-8586-d5aac399c050
/home/HTB/Json/10.10.10.158/nmap/juicy_potato/juicy-potato/JuicyPotato/JuicyPotato.sln: warning : Don't know how to handle GlobalSection ExtensibilityGlobals, Ignoring.
Project "/home/HTB/Json/10.10.10.158/nmap/juicy_potato/juicy-potato/JuicyPotato/JuicyPotato.sln" (default target(s)):
Target ValidateSolutionConfiguration:
Building solution configuration "Debug|x64".
Done building project "/home/HTB/Json/10.10.10.158/nmap/juicy_potato/juicy- potato/JuicyPotato/JuicyPotato.sln".
Build succeeded.
Warnings:
/home/HTB/Json/10.10.10.158/nmap/juicy_potato/juicy-potato/JuicyPotato/JuicyPotato.sln: warning : Ignoring vcproj 'JuicyPotato'.
/home/HTB/Json/10.10.10.158/nmap/juicy_potato/juicy-potato/JuicyPotato/JuicyPotato.sln: warning : Failed to find project 4164003e-ba47-4a95-8586-d5aac399c050
/home/HTB/Json/10.10.10.158/nmap/juicy_potato/juicy-potato/JuicyPotato/JuicyPotato.sln: warning : Don't know how to handle GlobalSection ExtensibilityGlobals, Ignoring.
3 Warning(s)
0 Error(s)
Time Elapsed 00:00:00.1375220
root#kali:/home/HTB/Json/10.10.10.158/nmap/juicy_potato/juicy-potato/JuicyPotato# ls
JuicyPotato JuicyPotato.sdf JuicyPotato.sln
root#kali:/home/HTB/Json/10.10.10.158/nmap/juicy_potato/juicy-potato/JuicyPotato# uname -a
Linux kali 4.19.0-kali3-amd64 #1 SMP Debian 4.19.20-1kali1 (2019-02-14) x86_64 GNU/Linux
my .vcxproj
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{4164003E-BA47-4A95-8586-D5AAC399C050}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>JuicyPotato</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
<ProjectName>JuicyPotato</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>```
Bottom:
```<PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;MSFROTTENPOTATO_EXPORTS;_CRT_SECURE_NO_WARNINGS;% (PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>secur32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<BuildLog>
<Path>$(SolutionDir)$(Configuration)\$(Platform)\$(MSBuildProjectName).log</Path>
</BuildLog>
</ItemDefinitionGroup>
<ItemGroup>
<Text Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="BlockingQueue.h" />
<ClInclude Include="IStorageTrigger.h" />
<ClInclude Include="LocalNegotiator.h" />
<ClInclude Include="MSFRottenPotato.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp">
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
</PrecompiledHeader>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
</PrecompiledHeader>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
</PrecompiledHeader>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
</PrecompiledHeader>
</ClCompile>
<ClCompile Include="IStorageTrigger.cpp" />
<ClCompile Include="LocalNegotiator.cpp" />
<ClCompile Include="JuicyPotato.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>```
Architecture:
Linux kali 4.19.0-kali3-amd64 #1 SMP Debian 4.19.20-1kali1 (2019-02-14) x86_64 GNU/Linux

Passing properties to MSBUILD Task

I am trying to call msbuild task for all the project files with properties. I call the msbuild task four times with hardcoded configurations and platform combination. Something like
<MSBuild Projects="$(MSBuildProjectFile)" Targets="Build" Properties="Configuration=Debug;Platform=Win32" BuildInParallel="true"/>
<MSBuild Projects="$(MSBuildProjectFile)" Targets="Build" Properties="Configuration=Debug;Platform=x64" BuildInParallel="true"/>
<MSBuild Projects="$(MSBuildProjectFile)" Targets="Build" Properties="Configuration=Release;Platform=Win32" BuildInParallel="true"/>
<MSBuild Projects="$(MSBuildProjectFile)" Targets="Build" Properties="Configuration=Release;Platform=x64" BuildInParallel="true"/>
But I want to provide this property as ItemGroup something like this
Configuration=%(BUILD_CONFIG.Identity);Platform=%(BUILD_PLATFORM.Identity)
Code sample
MyProject.vcxproj
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="BuildAll" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="BuildAllConfiguration.vcxproj"/>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{E6B6F967-3BE3-428F-9288-3F838B8E726A}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>MyProject</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
...
Similar Configuration Details for release and Platforms x64
This project file includes BuildAllConfiguration.vcxproj
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<BUILD_PLATFORMS>Win32;x64</BUILD_PLATFORMS>
<BUILD_CONFIGURATION>Debug;Release</BUILD_CONFIGURATION>
</PropertyGroup>
<Target Name="BuildAll">
<ItemGroup>
<CONFIGURATION Include="$(BUILD_CONFIGURATION.Split(';'))"/>
<PLATFORM Include="$(BUILD_PLATFORMS.Split(';'))"/>
<ProjectToBuild Include="$(MSBuildProjectFile)">
<Properties>Configuration=%(CONFIGURATION.Identity);Platform=%(PLATFORM.Identity)</Properties>
<Targets>Build</Targets>
</ProjectToBuild>
</ItemGroup>
<Message Text="MSBUILD TASK input #(ProjectToBuild)"/>
<MSBuild Projects="#(ProjectToBuild)" />
</Target>
</Project>
This project will call MyProject.vcxproj with Target Build and Properties which is not getting wellformed. My expectation is that the properties goes as following
Properties=Configuration=Debug;Platform=Win32
Properties=Configuration=Release;Platform=Win32
Properties=Configuration=Debug;Platform=x64
Properties=Configuration=Release;Platform=x64
Instead the properties are passed as following
Properties=Configuration=Debug;Platform=
Properties=Configuration=Release;Platform=
Properties=Configuration=;Platform=Win32
Properties=Configuration=;Platform=x64
You need a cross-product here, if you search for that you should find plenty of answers, though I reckon if you don't know it's called that it might be hard to find. Something like this:
<Target Name="BuildAll">
<ItemGroup>
<CONFIGURATION Include="$(BUILD_CONFIGURATION.Split(';'))"/>
<PLATFORM Include="$(BUILD_PLATFORMS.Split(';'))"/>
<!-- cross product of both -->
<ConfigAndPlatform Include="#(CONFIGURATION)">
<Platform>%(PLATFORM.Identity)</Platform>
</ConfigAndPlatform>
<ProjectToBuild Include="$(MSBuildProjectFile)"/>
</ItemGroup>
<MSBuild Projects="#(ProjectToBuild)" Properties="Configuration=%(ConfigAndPlatform.Identity);Platform=%(ConfigAndPlatform.Platform)" />
</Target>
Some notes: capitals make things harder to read, maybe don't use them? Also if you put your configurations/platforms in an ItemGroup instead of a PropertyGroup you don't need extra splitting logic:
<ItemGroup>
<Configuration Include="Debug;Release"/>
<Platform Include="Win32;x64"/>
<ItemGroup>

How to programmatically create a VC++ project with C#?

I want to to create a VC++ project with C#. I see this MSDN article about creating C# and VB console application projects. But how to do with VC++ project?
ADD 1
I had exactly the same issue as below thread. And its solution is to manipulate the raw XML, which is miserable... Is there some kind of API that I can work with?
How can an Empty Visual C++ project be created programmatically?
ADD 2
And besides creating a .vcxproj fie. I want to programmatically create a solution .sln file. Because my codebase are separated into many projects.
OK. I solved this problem by manipulating the *.sln and *.vcxproj files directly.
Details:
For *.vcxproj file, I created the following template:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
__SM_C_FILES__
</ItemGroup>
<ItemGroup>
__SM_H_FILES__
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>__SM_PROJECT_GUID__</ProjectGuid>
<RootNamespace>__SM_PROJECT_ROOTNS__</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>__SM_ADDITIONAL_INCLUDE_DIRS_DEBUG__</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>__SM_ADDITIONAL_INCLUDE_DIRS_RELEASE__</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
The __SM_C_FILES__ contains sub-template like this:
<ClCompile Include="__SM_C_FILE__" />
The __SM_H_FILES__ contains sub-template like this:
<ClInclude Include="__SM_H_FILE__" />
For *.sln file, I created a template as below:
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.40629.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "__SM_PROJ_NAME__", "__SM_PROJ_FILE_PATH__", "__SM_PROJ_GUID__"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{__SM_PROJ_GUID__}.Debug|Win32.ActiveCfg = Debug|Win32
{__SM_PROJ_GUID__}.Debug|Win32.Build.0 = Debug|Win32
{__SM_PROJ_GUID__}.Release|Win32.ActiveCfg = Release|Win32
{__SM_PROJ_GUID__}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
Note the __SM_*__parts, I replace them with the project-specific content using the plain string replacement, which is pretty straight-forward.
And in the *.sln file, if you have multiple projects, you may need to generated multiple parts of the Project sections.
The {8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942} is a well-known GUID that represents the VC++ project type. A comprehensive list can be found here.
Thus, I avoided manipulating the XML.
Unlike this similar thread, I didn't create the *.vcxproj.filters file. Though it looks a bit ugly, but I can live with that for now.

Resources