Hello,
I've made simple NMake Project that I modify to launch a batch file inside a specific SDK Folder. This batch file use xtensa-elf to built ESP8266 MCU Chip (future, i will support atmel MCU). I use this tutorial to perform Custom UI. But I've problem with conditional parameter and I don't think that I've the proper form.
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> was also removed. That's mean that I can't add element inside project. For the moment the batch file scan for files inside folder, instead scanning inside project structure.
My structure miss a lot of flexibility, actually each conditional configuration was a modified copy and paste from first. That's mean, if I will modify general properties, I need two modify two files. Also, when I will separate inside few file, I get some problem to parse command line.
ParseConfig.targets(39,5): warning : Querying file E:\Home\Visual Studio 2015\ESPBUILDER\Template\ESPBuilder.props did not return any usable configuration properties.
ParseConfig.targets, Build Target andConditionalPropertyPageSchema in .VCXProj
<ImportGroup Label="ExtensionTargets"><Import Project="$(ESPBuilderFolder)Template\ParseConfig.targets" /></ImportGroup><Target Name="Build"><MSBuild Projects="$(MSBuildProjectFullPath)" Properties="PropertyPageSchema=%(PropertyPageSchema.Identity);Name=ESPRAM" Condition="'%(PropertyPageSchema.Context)'=='Project'" Targets="ParseConfig"><Output PropertyName="ESP-Options" TaskParameter="TargetOutputs" /></MSBuild><MSBuild Projects="$(MSBuildProjectFullPath)" Properties="PropertyPageSchema=%(PropertyPageSchema.Identity);Name=General_Sheet" Condition="'%(PropertyPageSchema.Context)'=='Project'" Targets="ParseConfig"><Output PropertyName="Config-Options" TaskParameter="TargetOutputs" /></MSBuild><MSBuild Projects="$(MSBuildProjectFullPath)" Properties="PropertyPageSchema=%(PropertyPageSchema.Identity);Name=Linker" Condition="'%(PropertyPageSchema.Context)'=='Project'" Targets="ParseConfig"><Output PropertyName="Linker-Options" TaskParameter="TargetOutputs" /></MSBuild><Message Text="ESP Option : $(ESP-Options)" Importance="high" /><Message Text="Config Option : $(Config-Options)" Importance="high" /><Message Text="Linker Option : $(Linker-Options)" Importance="high" /><Exec Command=""$(VisualStudioDir)\ESPBUILDER\bin\build" /p $(ESP-options) Module="user;driver" Proj="$(MSBuildProjectName)" ProjFolder="$(MSBuildProjectDirectory)" ESPBuilderFolder="$(VisualStudioDir)\ESPBUILDER\" IOTSDKPath="$(ESPBuilderFolder)SDK\" COMPILE=gcc Path="$(ESPBuilderFolder)bin;$(ESPBuilderFolder)xtensa106\bin;$(ESPBuilderFolder)Python27;%Path%" " /></Target><!-- Target Rebuild & Target Clean --><ItemGroup Condition="'$(ESPBoot)'=='None'"><PropertyPageSchema Include="$(ESPBuilderFolder)Template\ESPBuilderFlash.props"><Context>Project</Context></PropertyPageSchema><ProjectTools Include="General_Sheet" /><ProjectTools Include="ESPRAM" /><ProjectTools Include="Linker" /></ItemGroup><ItemGroup Condition="'$(ESPBoot)'!='None'"><PropertyPageSchema Include="$(ESPBuilderFolder)Template\ESPBuilderBoot.props"><Context>Project</Context></PropertyPageSchema><ProjectTools Include="General_Sheet" /><ProjectTools Include="ESPRAM" /><ProjectTools Include="Linker" /></ItemGroup></Project>
Config Line result
1> ESP Option : ESPBootNum=0 ESPBoot=None ESPBin=0 SPISpeed=15 SPIMODE=2 SPISIZE=0 ESPRAM=512 USERRAM=512 USERADDR=0x40000 1> Config Option : "fsddf" "E:\Home\Visual Studio 2015\ESPBuilder\sdk\include\json" "E:\Home\Visual Studio 2015\ESPBuilder\sdk\include" 1> Linker Option : -l"audio" -l"video" -l"mousecompond"
CustomUI
<?xml version="1.0" encoding="utf-8"?><ProjectSchemaDefinitions xmlns="http://schemas.microsoft.com/build/2009/properties" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib"><Rule Name="ESPRAM" DisplayName="ESP Ram" PageTemplate="generic" SwitchPrefix="" Description="ESP Ram property sheet" Order="200" xmlns="http://schemas.microsoft.com/build/2009/properties"><Rule.Categories><Category Name="ESPRAMConfig" DisplayName="ESP Ram Configuration" /></Rule.Categories><Rule.DataSource><DataSource Persistence="ProjectFile" HasConfigurationCondition="true" /></Rule.DataSource><EnumProperty Name="ESPBoot" DisplayName="ESP Boot Mode" Description="Select version of ESP Boot Mode." Category="ESPRAMConfig"><EnumValue Name="None" DisplayName="No boot" Description="Using Eagle mode .flash and .irom0text" Switch="ESPBootNum=0 ESPBoot=None"/><EnumValue Name="Old" DisplayName="Version 1.1" Description="Using boot mode version 1.1" Switch="ESPBootNum=1 ESPBoot=Old"/><EnumValue Name="New" DisplayName="Version 1.2+" Description="Using boot mode version 1.2 or more" Switch="ESPBootNum=2 ESPBoot=New"/></EnumProperty><EnumProperty Name="ESPBin" DisplayName="ESP Bin Mode" Description="Select ESP Bin version." Category="ESPRAMConfig"><EnumValue Name="User1" DisplayName="User1.bin" Description="Using User 1 slot" Switch="ESPBin=1"/><EnumValue Name="User2" DisplayName="User2.bin" Description="Using User 2 slot" Switch="ESPBin=2"/></EnumProperty><EnumProperty Name="SPISpeed" DisplayName="ESP SPI Speed Mode" Description="Select SPI Speed." Category="ESPRAMConfig"><EnumValue Name="SPI20" DisplayName="20 Mhz - Frequence Div 0" Description="20 Mhz speed mode" Switch="SPISpeed=0"/><EnumValue Name="SPI26" DisplayName="26.7 Mhz - Frequence Div 1" Description="26.7 Mhz speed mode" Switch="SPISpeed=1"/><EnumValue Name="SPI40" DisplayName="40 Mhz - Frequence Div 2" Description="40 Mhz speed mode" Switch="SPISpeed=2"/><EnumValue Name="SPI80" DisplayName="80 Mhz - Frequence Div 15" Description="80 Mhz speed mode" Switch="SPISpeed=15"/></EnumProperty><EnumProperty Name="SPIMode" DisplayName="ESP SPI Transfert Mode" Description="Select SPI transfert Mode." Category="ESPRAMConfig"><EnumValue Name="SPIQIO" DisplayName="QIO" Description="QIO Transfert Mode" Switch="SPIMODE=0"/><EnumValue Name="SPIQOUT" DisplayName="QOUT" Description="QOUT Transfert Mode" Switch="SPIMODE=1"/><EnumValue Name="SPIDIO" DisplayName="DIO" Description="DIO Transfert Mode" Switch="SPIMODE=2"/><EnumValue Name="SPIDOUT" DisplayName="DOUT" Description="DOUT Transfert Mode" Switch="SPIMODE=3"/></EnumProperty><EnumProperty Name="SPISize" DisplayName="ESP SPI Size" Description="Select SPI Size." Category="ESPRAMConfig"><EnumValue Name="2" DisplayName="1024KB [512KB + 512KB]" Description="Total [User1 + User2]" Switch="SPISIZE=2 ESPRAM=1024 USERRAM=1024 USERADDR=0x81000"/><EnumValue Name="3" DisplayName="2048KB [512KB + 512KB]" Description="Total [User1 + User2]" Switch="SPISIZE=3 ESPRAM=2048 USERRAM=1024 USERADDR=0x81000"/><EnumValue Name="4" DisplayName="4096KB [512KB + 512KB]" Description="Total [User1 + User2]" Switch="SPISIZE=4 ESPRAM=4096 USERRAM=1024 USERADDR=0x81000"/><EnumValue Name="5" DisplayName="2048KB [1024KB + 1024KB]" Description="Total [User1 + User2]" Switch="SPISIZE=5 ESPRAM=2048 USERRAM=2048 USERADDR=0x101000"/><EnumValue Name="6" DisplayName="4096KB [1024KB + 1024KB]" Description="Total [User1 + User2]" Switch="SPISIZE=6 ESPRAM=4096 USERRAM=2048 USERADDR=0x101000"/></EnumProperty></Rule><Rule Name="General_Sheet" DisplayName="General" PageTemplate="generic" SwitchPrefix="" Description="ESP General property sheet" Order="100" xmlns="http://schemas.microsoft.com/build/2009/properties"><Rule.Categories><Category Name="General" DisplayName="General" /><Category Name="Directory" DisplayName="Directory" /></Rule.Categories><Rule.DataSource><DataSource Persistence="ProjectFile" HasConfigurationCondition="true" /></Rule.DataSource><StringProperty Name="OutputFolder" DisplayName="Output Folder" Description="Output generation folder" Category="General" /><StringListProperty Name="IncludeFolder" DisplayName="Include" Description="Include Folder" Category="Directory" Subtype="folder" /></Rule><Rule Name="Linker" DisplayName="Linker" PageTemplate="generic" SwitchPrefix="" Description="ESP Linker property sheet" Order="300" xmlns="http://schemas.microsoft.com/build/2009/properties"><Rule.Categories><Category Name="Link" DisplayName="Linker" /></Rule.Categories><Rule.DataSource><DataSource Persistence="ProjectFile" /></Rule.DataSource><StringListProperty Name="LibMod" DisplayName="Lib module" Description="Lib Module" Category="Link"/></Rule></ProjectSchemaDefinitions>
ParseConfig.target "IN CASE"
<!-- *********************************************************************************************** WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have created a backup copy. Incorrect changes to this file will make it impossible to load or build your projects from the command-line or the IDE. Copyright (C) Eugene Sadovoi. All rights reserved. *********************************************************************************************** --><Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"><Target Name="ParseConfig" Outputs="@(options, ' ');" ><Error ContinueOnError="false" Condition="'$(PropertyPageSchema)'==''" Text="Property 'PropertyPageSchema' is missing. Please provide file to process [PropertyPageSchema=property_shecma_file.xml]." /><Error ContinueOnError="false" Condition="!Exists('$(PropertyPageSchema)')" Text="File '$(PropertyPageSchema)' is missing. Please provide correct path." /><PropertyGroup><PrefixQuery Condition="'$(Name)'==''" >/ns:Rule/@SwitchPrefix|/ns:ProjectSchemaDefinitions/ns:Rule/@SwitchPrefix</PrefixQuery><PrefixQuery Condition="'$(Name)'!=''" >/ns:Rule[@Name='$(Name)']/@SwitchPrefix|/ns:ProjectSchemaDefinitions/ns:Rule[@Name='$(Name)']/@SwitchPrefix</PrefixQuery><DataQuery Condition="'$(Name)'==''" >/ns:ProjectSchemaDefinitions/ns:Rule/node()[not(contains(@IncludeInCommandLine, 'false')) and contains(local-name(), 'Property')]|</DataQuery><DataQuery Condition="'$(Name)'==''" >$(DataQuery)/ns:Rule/node()[not(contains(@IncludeInCommandLine, 'false')) and contains(local-name(), 'Property')]</DataQuery><DataQuery Condition="'$(Name)'!=''" >/ns:ProjectSchemaDefinitions/ns:Rule[@Name='$(Name)']/node()[not(contains(@IncludeInCommandLine, 'false')) and contains(local-name(), 'Property')]|</DataQuery><DataQuery Condition="'$(Name)'!=''" >$(DataQuery)/ns:Rule[@Name='$(Name)']/node()[not(contains(@IncludeInCommandLine, 'false')) and contains(local-name(), 'Property')]</DataQuery></PropertyGroup><XmlPeek Namespaces="<Namespace Prefix='ns' Uri='http://schemas.microsoft.com/build/2009/properties'/>" XmlInputPath="$(PropertyPageSchema)" Query="$(PrefixQuery)"><Output TaskParameter="Result" PropertyName="DefaultSwitchPrefix" /></XmlPeek><XmlPeek Namespaces="<Namespace Prefix='ns' Uri='http://schemas.microsoft.com/build/2009/properties'/>" XmlInputPath="$(PropertyPageSchema)" Query="$(DataQuery)"><Output TaskParameter="Result" ItemName="Peeked" /></XmlPeek><Warning Condition="'@(Peeked)'==''" Text="Querying file $(PropertyPageSchema) did not return any usable configuration properties." /><ItemGroup Label="Parse XML"><Properties Remove="@(Properties)" /><Properties Include="@(Peeked -> '%(Identity)')"><Type>$([System.Text.RegularExpressions.Regex]::Match(%(Identity), (?<=<)(.*?)(?=\s)))</Type><Name>$([System.Text.RegularExpressions.Regex]::Match(%(Identity), (?<=Name=")(.*?)(?=")))</Name><Prefix>$([System.Text.RegularExpressions.Regex]::Match(%(Identity), (?<=SwitchPrefix=")(.*?)(?=")))</Prefix><Prefix Condition="'$([System.Text.RegularExpressions.Regex]::Match(%(Identity), (?<=SwitchPrefix=")(.*?)(?=")))'==''">$(DefaultSwitchPrefix)</Prefix><Switch>$([System.Text.RegularExpressions.Regex]::Match(%(Identity), (?<=Switch=")(.*?)(?=")))</Switch><ReverseSwitch>$([System.Text.RegularExpressions.Regex]::Match(%(Identity), (?<=ReverseSwitch=")(.*?)(?=")))</ReverseSwitch><Separator>$([System.Text.RegularExpressions.Regex]::Match(%(Identity), (?<=\sSeparator=")(.*?)(?=")))</Separator><Divider>$([System.Text.RegularExpressions.Regex]::Match(%(Identity), (?<=ValueSeparator=")(.*?)(?=")))</Divider><Children>$([System.Text.RegularExpressions.Regex]::Matches(%(Identity), EnumValue\s(.*?)>))</Children><Preamble>$([System.Text.RegularExpressions.Regex]::Match(%(Identity), (?<=Switch=")(.*?)(?=")))$([System.Text.RegularExpressions.Regex]::Match(%(Identity), (?<=\sSeparator=")(.*?)(?=")))</Preamble><Subtype>$([System.Text.RegularExpressions.Regex]::Match(%(Identity), (?<=Subtype=")(.*?)(?=")))</Subtype></Properties><!--StringProperty--><options Label="Simple StringProperty" Condition="'%(Properties.Type)' == 'StringProperty' And '$(%(Properties.Name))'!=''" Include="%(Properties.Prefix)%(Properties.Switch)%(Properties.Separator)"$(%(Properties.Name))"" /><!--StringListProperty--><list-outer-join Condition="'$(%(Properties.Name))'!='' And '%(Properties.Type)'=='StringListProperty' And '%(Properties.Divider)'==''" Include="$(%(Properties.Name))" ><Prefix>%(Properties.Prefix)%(Properties.Switch)%(Properties.Separator)</Prefix></list-outer-join><options Label="No Divider" Condition="'@(list-outer-join)'!=''" Include="%(list-outer-join.Prefix)"%(list-outer-join.Identity)"" /><options Label="Divider present" Condition="'%(Properties.Type)' == 'StringListProperty' And '$(%(Properties.Name))' != '' And '%(Properties.Divider)'!=''" Include="%(Properties.Prefix)%(Properties.Preamble)"$([System.String]::Copy('$(%(Properties.Name))').Replace(';', '%(Properties.Divider)').TrimEnd('%(Properties.Divider)').Replace('%(Properties.Divider)', '"%(Properties.Divider)"'))"" /><!--BoolProperty--><options Condition="'$(%(Properties.Name))'=='true' And '%(Properties.Type)'=='BoolProperty' And '%(Properties.Switch)'!=''" Include="%(Properties.Prefix)%(Properties.Switch)" /><options Condition="'$(%(Properties.Name))'=='false' And '%(Properties.Type)'=='BoolProperty' And '%(Properties.ReverseSwitch)'!=''" Include="%(Properties.Prefix)%(Properties.ReverseSwitch)" /><!--IntProperty--><options Condition="'$(%(Properties.Name))'!='' And '%(Properties.Type)'=='IntProperty'" Include="%(Properties.Prefix)%(Properties.Switch)%(Properties.Separator)$(%(Properties.Name))" /><!--DynamicEnumProperty--><options Condition="'$(%(Properties.Name))'!='' And '%(Properties.Type)'=='DynamicEnumProperty'" Include="%(Properties.Prefix)%(Properties.Switch)" /><!--EnumProperty--><enum-values Condition="'%(Properties.Type)'=='EnumProperty'" Include="%(Properties.Children)" ><Name>%(Properties.Name)</Name><Prefix>%(Properties.Prefix)</Prefix></enum-values><options Condition="'$(%(enum-values.Name))'!='' And '$(%(enum-values.Name))'=='$([System.Text.RegularExpressions.Regex]::Match(%(Identity), (?<=Name=")(.*?)(?=")))'" Include="%(enum-values.Prefix)$([System.Text.RegularExpressions.Regex]::Match(%(Identity), (?<=Switch=")(.*?)(?=")))" /></ItemGroup></Target></Project>
Question:
How configure.VCXProj and Custom Properties to remove redundant and have a structured form (with import or include parameter whatever... if is more flexible and professional)
Does a way to parse Command line without using ParseConfig.targets... Like a Microsoft File (.props or .targets) inside MSBUILD folder (like more standard, less modified) or another way to retrive switch command line?
Thanks