Is OutputPath a required field in every PropertyGroup? - visual-studio-2010

My projects appear to all have three <PropertyGroup> items.
One:
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
Two: <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
Three: <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
FinalBuilder has been failing. When I go into the project file and add <OutputPath>bin\Debug\</OutputPath> to the first element in the .csproj file (an MSBuild file as I understand it), the build succeeds.
The remaining two elements already have <OutputPath> defined.
Is this a required field for all three elements? Why is it missing from the first element in my project files?

When MSBuild compiles a project, it takes OutputPath as an argument, to where it should place the build output.
The .csproj file has some default settings. It's in the first <PropertyGroup>.
In the conditional PropertyGroups, there are specific properties, to different configurations and platforms:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
Properties inside this node overwrites the default one, so it can specialize the build.
To hit the different PropertyGroups, MSBuild takes some argument, for example, hitting "Release|x86", the command looks like this:
msbuild /p:Configuration="Release" /p:Platform="x86"
MSBuild will use the properties from the default PropertyGroup, and overwrite/use properties from the PropertyGroups that meet the conditions, in this example "Release|x86" to compile the code.
Your problem sounds like MSBuild does not have the right arguments to evaluate the right PropertyGroups.

Related

Different `google-services.json/GoogleService-Info.plist` for iOS/Android project based on build configuration in Xamarin

So I have a requirement where my project should use different GoogleServices files for Android/iOS while using different configurations like for eg while I am using the debug configuration it should use the debug version of the file and in the release, it should use the release version.
Something similar to
Xamarin firebase different google-services,json for different build configurations
When I follow the accepted the answer I get a compile-time error saying
The command COPY /Y "$(ProjectDir)GoogleServices\google-services-development.json" "$(ProjectDir)google-services.json" exited with code 1.
I tried clean build and cleaning bin/obj nothing changed.
So I tried the other solution mentioned here and what happens is the GoogleServices files(all of them) are excluded from the project and nothing happens if I build and run. I am unsure if this is even working or not.
I have added the following lines in my csproj for release and debug respectively
<ItemGroup Condition="'$(Configuration)'=='Debug'">
<GoogleServicesJson Include="Dev\google-services.json">
<Link>google-services.json</Link>
</GoogleServicesJson>
</ItemGroup>
<ItemGroup Condition="'$(Configuration)'=='Release'">
<GoogleServicesJson Include="Prod\google-services.json">
<Link>google-services.json</Link>
</GoogleServicesJson>
</ItemGroup>
Where dev and prod are root folders in my native android project
Any suggestions are welcome.
You have to edit *.csproj file.
Using a solution to use multiple Info.plist (LogicalName tag) and Condition tag you can play with any other files all you want.
For Android I added two *.json files to Resources folder and added this snippet to my *.csproj file:
<ItemGroup Condition=" '$(Configuration)' != 'Release' ">
<GoogleServicesJson Include="Resources\dev-google-services.json">
<LogicalName>Resources\google-services.json</LogicalName>
</GoogleServicesJson>
</ItemGroup>
<ItemGroup Condition=" '$(Configuration)' == 'Release' ">
<GoogleServicesJson Include="Resources\release-google-services.json">
<LogicalName>Resources\google-services.json</LogicalName>
</GoogleServicesJson>
</ItemGroup>
In this example I use release-google-services.json for the "Release" build configuration, and dev-google-services.json for any other configurations.
Same for iOS. I added two *.plist files to root folder and added this snippet to my *.csproj file:
<ItemGroup Condition=" '$(Configuration)' != 'AppStore' ">
<BundleResource Include="Dev-GoogleService-Info.plist">
<LogicalName>GoogleService-Info.plist</LogicalName>
</BundleResource>
</ItemGroup>
<ItemGroup Condition=" '$(Configuration)' == 'AppStore' ">
<BundleResource Include="Release-GoogleService-Info.plist">
<LogicalName>GoogleService-Info.plist</LogicalName>
</BundleResource>
</ItemGroup>
This approach works for me. I guess it doesn't matter where you put these files and how you name them. Just use the LogicalName that you need.
Also, you can combine it with other variables to compose more complicated conditions. For example, in order to build two *.apk in Release configuration with different *.json files you can:
<ItemGroup Condition=" '$(Configuration)|$(DynamicConstants)' != 'Release|' ">
<GoogleServicesJson Include="Resources\dev-google-services.json">
<LogicalName>Resources\google-services.json</LogicalName>
</GoogleServicesJson>
</ItemGroup>
<ItemGroup Condition=" '$(Configuration)|$(DynamicConstants)' == 'Release|' ">
<GoogleServicesJson Include="Resources\release-google-services.json">
<LogicalName>Resources\google-services.json</LogicalName>
</GoogleServicesJson>
</ItemGroup>
Build your project like this:
msbuild MobileApp.sln /p:Configuration=Release /p:DynamicConstants=DEBUG
When you use DEBUG parameter you build Release apk with dev-google-services.json.
When you omit DEBUG parameter you build Release apk with release-google-services.json.

Post Build event with condition

Having the need to add a condition to the Post Build event in my Visual Studio 2013 project, I ended up with the following:
<PropertyGroup Condition=" '$(OS)' == 'Windows_NT' ">
<PostBuildEvent>"$(SolutionDir)..\Deploy\Build\sign-bin.cmd"</PostBuildEvent>
</PropertyGroup>
I've added the condition Condition=" '$(OS)' == 'Windows_NT' " manually with a text editor to the CSPROJ file.
This works as expected, my solution builds successfully both in Visual Studio as well as in Travis CI.
What doesn't work:
When editing the Post Build event inside Visual Studio in the graphical editor, it seems to ignore the condition and simply stores the event twice:
<PropertyGroup Condition=" '$(OS)' == 'Windows_NT' ">
<PostBuildEvent>"$(SolutionDir)..\Deploy\Build\sign-bin.cmd"</PostBuildEvent>
</PropertyGroup>
<PropertyGroup>
<PostBuildEvent>"$(SolutionDir)..\Deploy\Build\sign-bin.cmd"</PostBuildEvent>
</PropertyGroup>
It doesn't matter whether I add the condition to the <PropertyGroup> node or the <PostBuildEvent> node.
In both cases the nodes are duplicated by Visual Studio upon saving.
My questions:
Any chance to somehow add the ability to ignore my Post Build event (which is the reason for the condition) on Travis?
Any chance to somehow tell Visual Studio to not duplicate the node with condition upon saving?

creating a targeted OBJ folder for a project in Visual Studio

Is it possible to create a targeted OBJ file path much like you can do for a BIN folder? You can set the output path in the Project's properties. Example paths would be:
Bin\Debug\Windows Phone 7\
Bin\Debug\NETMF\
Bin\Debug....\
A use case here is if I have multiple projects that target different platforms. On compiling, the OBJ file is shared instead of separated out like the bin folders are. When compiling, you hit race conditions where the OBJ folder is being leveraged at the same time and errors are thrown.
Here we're talking about MSBUILD, and you have the option of setting BaseIntermediaryOutputPath in your project. If you open the project (.csproj, I am assuming) with an XML editor, you will see configuration blocks for different debug/release config combos.
So something like this (edit for each config option separately):
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{A35097D8-80BC-4FA5-BECD-FF045C5566EC}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>WorkApplication</RootNamespace>
<AssemblyName>WorkApplication</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<BaseIntermediateOutputPath>E:\OBJ-TEST</BaseIntermediateOutputPath>
<WarningLevel>4</WarningLevel>
</PropertyGroup>

Disable Code Analysis for Some Projects using MSBuild

I have inherited a solution file that uses a MSBuild script to compile multiple solutions. The majority of projects are configured with analysis and rulesets and I have a few unit-test projects that don't.
Projects with analysis turned on:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<DefineConstants>CODE_ANALYSIS;DEBUG;TRACE</DefineConstants>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<PlatformTarget>x86</PlatformTarget>
<CodeAnalysisRuleSet>..\OurRules.ruleset</CodeAnalysisRuleSet>
<RunCodeAnalysis>true</RunCodeAnalysis>
</PropertyGroup>
Projects with analysis turned off:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<PlatformTarget>x86</PlatformTarget>
<RunCodeAnalysis>false</RunCodeAnalysis>
</PropertyGroup>
When I run my build script, it looks like some projects are not respecting the project settings:
msbuild.exe BuildScript.proj /p:SolutionRoot=%cd%; /p:Configuration=Debug /p:Platform:x86 /p:RunCodeAnalysis=True
When I check the output folder, I see coverage analysis xml outputs for projects that have the RunCodeAnalysis flag set to false. Can someone help me understand what's going on here?
I figured this out shortly after posting it.
Team Build supports the following values for RunCodeAnalysis: Always, Default, Never.
In contrast, locally MSBuild supports True or False for RunCodeAnalysis.
Why are they different? In looking at the Microsoft.TeamFoundation.Build.targets file, the following appears:
<Target Name="CoreCompileSolution">
<PropertyGroup>
<CodeAnalysisOption Condition=" '$(RunCodeAnalysis)'=='Always'">RunCodeAnalysis=true</CodeAnalysisOption>
<CodeAnalysisOption Condition=" '$(RunCodeAnalysis)'=='Never'">RunCodeAnalysis=false</CodeAnalysisOption>
...
</PropertyGroup>
...
</Target>
These settings are then passed onto the msbuild process when it compiles the solution file.
So in other words:
Always tells MSBuild to compile all projects with RunCodeAnalysis=True
Never tells MSBuild to suppress code analysis (RunCodeAnalysis=False) on all projects.
...and not specifying a value for RunCodeAnalysis means that MSBuild will respect the RunCodeAnalysis setting in the project file. Hence, the default setting.
Simply removing the /p:RunCodeAnalysis from my original question had the correct result. Projects that have analysis turned on will run code analysis. Projects without the setting don't perform any extra work.
More information about this is available here: http://www.bryancook.net/2011/06/build-server-code-analysis-settings.html
Change:
<RunCodeAnalysis>false</RunCodeAnalysis>
To:
<RunCodeAnalysis>Never</RunCodeAnalysis>
... and see if that solves your problem. Valid values for RunCodeAnalysis are either {Default,Always,Never} or {True,False}, depending on how you build.
See: Item 12 of How to: Edit a Build Type for more info.
Also, see this article for inconsistencies in the settings of RunCodeAnalysis, depending on how you build: Inconsistent RunCodeAnalysis values

How do I change the build folders in VS2010?

I'm getting an error in a VS2010 DB project that indicates I have too many charachters in my build path.
How can I change my default build path for all project types?
Something like
c:\build\$(projectname)\......
Thanks!
EDIT:
I've moved my project to the root of the C: drive and I still get the error with my DB project. I get this error when I try to right click the project and select properties
An error occurred trying to load the project properties window. Close the window and try again.
Cannot evaluate the item metadata "%(FullPath)". The item metadata "%(FullPath)" cannot be applied to the path "obj\Debug|Any CPU\TASS.DB.dbschema". Illegal characters in path. C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets
The first thing that jumps out to me here is that your platform and configuration are being fused together to form "Debug|Any CPU" and a string is being made from that--the pipe is the character it's referencing there when it says there are illegal characters. I'm not sure how much your database project really differs with respect to debug/release and for architecture, but you may not even need to include them in the path.
Since you can't open the project property pages, you'll need to edit the msbuild directly by unloading it and selecting "Edit..." from the context menu (sorry if you know this already).
From there, assuming you're realling running up on the windows path length ceiling, you could use some msbuild trickery to maximize your headroom in there. Specifically, doing something similar to what you suggest: use the C:\ drive wherever possible.
To do this, look inside the PropertyGroups with the conditions for your Configuration & Platform configurations, and inside them replace the OutputPath and IntermediateOutputPath properties so that they're as short as possible, for example:
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<OutputPath>$(SystemDrive)\D\A</OutputPath>
<IntermediateOutputPath>$(SystemDrive)\o\D\A</IntermediateOutputPath>
</PropertyGroup>
This saves some valuable characters in that instead of "Debug" you're using "D", "A" for "AnyCPU" and "o" for "obj".
Probably most importantly you're using C:\o\ for the intermediate build directory instead of C:\whatever-the-whole-path-is-to-your-project-file\obj. As well, this property isn't configurable from the property pages, from what I recall.
Some added flexibility there using SystemDrive instead of a hard-coded C:, not that I would really expect it to be different.
Finally, concerning your property pages load problem, I don't know how the Debug|AnyCPU got in your path (I don't know of any properties that store the concatenated flavor like that), but you should be able to pick it out pretty easily once you open up the file. Hopefully it's similar to load errors in something like the winforms designer where you change one line and suddenly the whole thing works again.
Hope this helps!
I don't think it's possible to set a default build path for all projects, only the standard Debug/Release folders within the project itself. The only suggestion I would have is to simply move the project folder to location with a shorter path.
EDIT: As per the new edit, have a look here:
http://connect.microsoft.com/VisualStudio/feedback/details/594333/database-project-template-files-corrupt
I updated a project from VS 2005 to VS 2010 and got the same error message.
"The item metadata "%(Filename)" cannot be applied to the path "obj\Debug|x86\Debug\DemoCSharp.pdb". Illegal characters in path." The problem is that Visual Studio 2010 fails in converting the csproj file to the new format, but it does not tell us where exactly the error is.
In my VS 2005 csproj file there is the following XML code:
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">Debug|x86</Platform>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{05F88317-0CA7-4FE5-8520-35422402941A}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>DemoCSharp</RootNamespace>
<AssemblyName>DemoCSharp</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\output32\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<OutputPath>..\output32\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\output64\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
<OutputPath>..\output64\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
Visual Studio does NOT tell us which line produces the problem. But I found it by "try and error".
The cause of the error message is clearly a bug in the Visual Studio conversion wizard because VS 2005 has no problem loading this csproj file while VS 2010 fails to convert it.
So you have to manually edit and fix this file and then load it anew in VS2010.
In my case the line that triggers the bug is the 3. line with <Platform Condition. The bug is that VS tries to take the value ("Debug|x86") of this platform condition XML node and embed it into a path on disk (like "...\obj\Debug|x86\..."). But as pipe characters are illegal in paths, it later complains and aborts the conversion.
So how to solve the problem ?
I simply replaced the third line
<Platform Condition=" '$(Platform)' == '' ">Debug|x86</Platform>
with
<Platform Condition=" '$(Platform)' == '' ">Debug</Platform>
which eliminates the pipe character and the project converted without errors.
NOTE: It is also possible to completely delete this line.
ATTENTION:
It is possible that in YOUR case the same error messages needs another fix than in my case. Please study the csproj file and look for the pipe characters, then find out with try and error how to modify it. This error can even appear in other conditions than converting a project.
But what they all have in common is that this is a Visual Studio bug (or in case of 'littlechris' a software extension bug) that tries to embed a pipe character into the path.
XML node: "Debug|x86" -> path "...\obj\Debug|x86\..."
I received this messeage because the absolute path of one of the files in my project exceeded 260 characters. Once I reduced the path length, I was able to build the project.

Resources