Define a conditional constant for all builds in Visual Studio - c#

I have a project with some code. I want to determine is RyuJIT is used and if so then write RyuJIT otherwise LegacyJIT.
I write:
#if RuyJIT
Console.WriteLine("RyuJIT");
#else
Console.WriteLine("LegacyJIT");
#endif
then I'm trying to define a constant. So i open my .csproj in notepad and write following:
<PropertyGroup>
<DefineConstants Condition=" $(TargetFrameworkVersion.Replace('v', '')) >= 4.6 ">RyuJIT</DefineConstants>
</PropertyGroup>
But it doesn't work: constant is not defined thus second line is always compiled for any target framework. What am I doing wrong? How can I share this constant between builds?

Solved with Choose node. Additionaly, now I'm able to reference .Net 4.6-only dlls.
<Choose>
<When Condition=" $(TargetFrameworkVersion.Replace('v', '')) >= 4.6 ">
<ItemGroup>
<Reference Include="System.Numerics" />
<Reference Include="System.Numerics.Vectors, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Numerics.Vectors.4.1.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<PropertyGroup>
<DefineConstants>SIMD</DefineConstants>
</PropertyGroup>
</When>
</Choose>
I replaced RyuJIT with SIMD because it's more suitable

Related

use .net core sdk in MSBuild project

I have a PCL-project with different functions and classes for each platform. I want to implement .net core support now. But I cant use controls like UserControl because the Microsoft.NET.Sdk.WindowsDesktop SDK isn't referenced. The .net framework is easy to implement because I only have to reference each assembly... But in .net core, I can't reference the assembly...
<Project Sdk="MSBuild.Sdk.Extras">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;xamarin.ios10;xamarin.mac20;xamarin.tvos10;monoandroid10.0;tizen40</TargetFrameworks>
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">uap10.0.17763;net472;netcoreapp3.1;$(TargetFrameworks)</TargetFrameworks>
</PropertyGroup>
<ItemGroup Condition=" $(TargetFramework.StartsWith('net4')) And '$(OS)' == 'Windows_NT' ">
...
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System.Xaml" />
</ItemGroup>
<ItemGroup Condition=" $(TargetFramework.StartsWith('netcoreapp3')) And '$(OS)' == 'Windows_NT' ">
...
<SDKReference Include="Microsoft.NET.Sdk.WindowsDesktop" />
</ItemGroup>
That's my executable app, referencing the PCL-project above;
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<UseWPF>true</UseWPF>
</PropertyGroup>
<ItemGroup>
<ProjectReference ...... />
</ItemGroup>
</Project>
I already tried this to reference the SDK but its not working.
<SDKReference Include="Microsoft.NET.Sdk.WindowsDesktop" />
I want to implement .net core support now. But I cant use controls
like UserControl because the Microsoft.NET.Sdk.WindowsDesktop SDK
isn't referenced. The .net framework is easy to implement because I
only have to reference each assembly... But in .net core, I can't
reference the assembly..
After doing a deep research, I found that Microsoft.NET.Sdk.WindowsDesktop cannot be used by SDKReference.
As a suggestion, you could create a custom targets file and then import it into your PCL-project to use the Net Core SDK.
1) create a file called custom.targets in your PCL project folder.
2) Then add these in custom.targets:
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<UseWPF>true</UseWPF>
</PropertyGroup>
</Project>
3) import this in xxx.csproj file of PCL-Project.
<Import Project="$(ProjectDir)custom.targets" Condition=" $(TargetFramework.StartsWith('netcoreapp3')) And '$(OS)' == 'Windows_NT' "/>
4) Then restart your project. Although there are some warnings that reminds you that some sdks are repeatedly quoted, you can ignore them and it will not have any impact on your project.
You can check this, which works well in my side.

Use Project Reference in Debug and Nuget in Release

I would like to work in my project (A) and a dependent Nuget package (B) at the same time, without the need to release the nuget package on each change.
Is it possible to do a project-reference the Nuget project (B) from the Solution (A) when building Debug. And when building Release use the Nuget package from Source?
One way is to manually edit the csproj file.
If you have currently referenced the NuGet package, you will have a part in the csproj file like this:
....
<ItemGroup>
<Reference Include="log4net, Version=2.0.8.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\packages\log4net.2.0.8\lib\net45-full\log4net.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
....
In this example, log4net is used. For your NuGet package, the public key token, version and so on is different.
You can no change it to:
<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<Reference Include="log4net">
<HintPath>Debug\log4net.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Reference Include="log4net, Version=2.0.8.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\packages\log4net.2.0.8\lib\net45-full\log4net.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
The Condition attribute in the ItemGroup element is doing the job between debug and release.
Is it possible to do a project-reference the Nuget project (B) from the Solution (A) when building Debug. And when building Release use the Nuget package from Source?
Certainly, but there are some restrictions you need to know.
First, the ID of the NuGet package should different from the name of the reference project, otherwise, the reference from NuGet will replace the project reference.(For example, TestProjectReferenceForDebug is the name of the project reference, if you want to use project reference and NuGet package at the same time, you could not use this project to create the NuGet package directly, so I created a same project with different name to create the NuGet package "TestNuGetForRelease"):
Second, you should use Condition attribute in the ItemGroup element, otherwise, there is an ambiguous reference between 'TestProjectReferenceForDebug' and 'TestNuGetForRelease', so we need add the Condition attribute in the ItemGroup element
<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
<Reference Include="TestNuGetForRelease, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL" >
<HintPath>..\packages\TestNuGetForRelease.1.0.0\lib\net462\TestNuGetForRelease.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<ProjectReference Include="..\TestProjectReferenceForDebug\TestProjectReferenceForDebug.csproj">
<Project>{90424b17-2231-4d7d-997b-608115d9f4d9}</Project>
<Name>TestProjectReferenceForDebug</Name>
</ProjectReference>
</ItemGroup>
Third, after we add the Condition attribute in the ItemGroup element with debug and release, we could use project reference in Debug and Nuget in Release, however, if we use those namespace in one .cs file at same time, we need to add those two namespace, then you will get an error "The referenced component 'xxx' could not be found". That because VS could not find those two namespace only in the "Release" or "Debug" model:
To resolve this error, we have to annotate the namespace which in another configuration model when you change the configuration model from Debug to Release.

can't open vs2010 csproj file in vs2012

Goal:
doing xna with winforms.
Way
getting the code and how from their programmer, Microsoft from this link, which contains a solution with three projects in it, the form project, the Content and the ContentLibrary project.
Projects explanation:
The ContentLibrary project builds a dll which the form project references(but it doesn't seem to have anything and I don't know why).
It references the Content project in a bizzare way I have never seen.
The Content project contains a picture file, nothing else and I don't know what does it build.
Finally the form project which contains the main form which have many controls including user defined ones, one abstract which inherits xna control, and others to implement this control(these will do the drawing).
Problem:
could not open the ContentLibrary project.
the error message I get:
C:\Program Files(x86)\MSBuild\Microsoft\XNA Game Studio\Microsoft.Xna.GameStudio.targets was not found confirm that the path in the declaration is correct and that the file exists on disk
My Try:
opening the ContentLibrary project file(.csproj one) with notepad and here's what I found:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{396ADBE6-FB16-4DBA-8C70-C16A46B448EA}</ProjectGuid>
<ProjectTypeGuids>{6D335F3A-9D43-41b4-9D22-F6F17C4BE596};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} </ProjectTypeGuids>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ContentLibrary</RootNamespace>
<AssemblyName>ContentLibrary</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
<XnaFrameworkVersion>v4.0</XnaFrameworkVersion>
<XnaPlatform>Windows</XnaPlatform>
<XnaProfile>Reach</XnaProfile>
<XnaCrossPlatformGroupID>e0c073d9-a61b-474a-bda0-a8ada2c89669</XnaCrossPlatformGroupID>
<XnaOutputType>Library</XnaOutputType>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\x86\Debug</OutputPath>
<DefineConstants>DEBUG;TRACE;WINDOWS</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoStdLib>true</NoStdLib>
<UseVSHostingProcess>false</UseVSHostingProcess>
<PlatformTarget>x86</PlatformTarget>
<XnaCompressContent>false</XnaCompressContent>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\x86\Release</OutputPath>
<DefineConstants>TRACE;WINDOWS</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoStdLib>true</NoStdLib>
<UseVSHostingProcess>false</UseVSHostingProcess>
<PlatformTarget>x86</PlatformTarget>
<XnaCompressContent>true</XnaCompressContent>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Xna.Framework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Xna.Framework.Game, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Xna.Framework.Graphics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Xna.Framework.GamerServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Xna.Framework.Xact, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Xna.Framework.Video, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Xna.Framework.Avatar, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Xna.Framework.Net, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Xna.Framework.Storage, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
<Private>False</Private>
</Reference>
<Reference Include="mscorlib">
<Private>False</Private>
</Reference>
<Reference Include="System">
<Private>False</Private>
</Reference>
<Reference Include="System.Xml">
<Private>False</Private>
</Reference>
<Reference Include="System.Core">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
<Private>False</Private>
</Reference>
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
<Private>False</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Content\Content.contentproj">
<Project>{618DED89-9BA8-44D7-83A0-163041666FAC}</Project>
<Name>Content</Name>
<XnaReferenceType>Content</XnaReferenceType>
</ProjectReference>
</ItemGroup>
<ItemGroup />
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA Game Studio\Microsoft.Xna.GameStudio.targets" />
<!--
To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
Optional information:
in case needed, I'm running Windows 8 x64.
I found a solution here:
https://bitbucket.org/rbwhitaker/xna-beyond-vs-2010/downloads
The link given contains a script file which is launched by PowerShell(similar to command prompt). If you run Windows 7 or later you have PowerShell, if not use this link:
http://www.microsoft.com/en-us/download/details.aspx?id=40855
When you're ready follow these steps:
Open PowerShell.
Navigate to where you put the script by using cd command.
Run the following command: Set-ExecutionPolicy Unrestricted. This is because PowerShell doesn't activate script files by default to protect your computer, you can change it back when finished by typing: Set-ExecutionPolicy Restricted
Run the script using this command: .\XnaFor2013.ps1
Wait, it takes some time, on my computer it took about 15 minutes. It may take longer on slower computers. (I had windows 8 64 bit.)
If you want to know what this script does scroll down to the end of this page:
http://rbwhitaker.wikidot.com/setting-up-xna
Excerpt to prevent link rot:
First, it downloads the XNA installer from Microsoft.
It turns out that the XNA installer is just a self-extracting archive
that contains about seven other installers. So the next thing the
script does is unpack those "internal" installers.
Six of the seven do exactly what you want them to do, out of the box,
so the script runs them each in turn.
The other one is the installer that places files in the right place in
Visual Studio. Unfortunately, it's looking for Visual Studio 2010,
while you've got a newer version (2012 or 2013 both work with the
script). So the script tells this installer to just place the files in
a temporary location.
These files are built for Visual Studio 2010 and require some changes,
so the script makes the changes and places them in the appropriate
place for your version of Visual Studio. (In fact, it does it for all
versions of Visual Studio you've got installed, regardless of whether
it's 2012 or 2013, and regardless of if it's a paid version or Express
for Windows Desktop.)
Unfortunately, Visual Studio doesn't automatically check for new
add-ons. (Actually, that's a good thing because it would take too long
to check all the time, but in this case, it's bad because we need it
to check.) To make it check for new addons, the script deletes the
extension cache and has Visual Studio rebuild it. Rebuilding the cache
takes most of the time that the script runs for. (Several minutes.)
Once it's rebuilt, everything is ready to go, and the script deletes
the temporary files that it created.

Conditional references in .NET project, possible to get rid of warning?

I have two references to a SQLite assembly, one for 32-bit and one for 64-bit, which looks like this (this is a test project to try to get rid of the warning, don't get hung up on the paths):
<Reference Condition=" '$(Platform)' == 'x64' " Include="System.Data.SQLite, Version=1.0.61.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=AMD64">
<SpecificVersion>True</SpecificVersion>
<HintPath>..\..\LVK Libraries\SQLite3\version_1.0.65.0\64-bit\System.Data.SQLite.DLL</HintPath>
</Reference>
<Reference Condition=" '$(Platform)' == 'x86' " Include="System.Data.SQLite, Version=1.0.65.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=x86">
<SpecificVersion>True</SpecificVersion>
<HintPath>..\..\LVK Libraries\SQLite3\version_1.0.65.0\32-bit\System.Data.SQLite.DLL</HintPath>
</Reference>
This produces the following warning:
Warning 1 The referenced component 'System.Data.SQLite' could not be found.
Is it possible for me to get rid of this warning?
One way I've looked at it to just configure my project to be 32-bit when I develop, and let the build machine fix the reference when building for 64-bit, but this seems a bit awkward and probably prone to errors.
Any other options?
The reason I want to get rid of it is that the warning is apparently being picked up by TeamCity and periodically flagged as something I need to look into, so I'd like to get completely rid of it.
Edit: Per the answer, I tried this:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
...
<SqlitePath>..\..\LVK Libraries\SQLite3\version_1.0.65.0\32-bit</SqlitePath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
...
<SqlitePath>..\..\LVK Libraries\SQLite3\version_1.0.65.0\32-bit</SqlitePath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
...
<SqlitePath>..\..\LVK Libraries\SQLite3\version_1.0.65.0\64-bit</SqlitePath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
...
<SqlitePath>..\..\LVK Libraries\SQLite3\version_1.0.65.0\64-bit</SqlitePath>
</PropertyGroup>
and then in my reference:
<Reference Include="System.Data.SQLite">
<SpecificVersion>False</SpecificVersion>
<HintPath>$(SqlitePath)\System.Data.SQLite.DLL</HintPath>
</Reference>
This got rid of the warning, but is it correct?
If there is no "AnyCPU" assembly for SQL Lite you are stuck with separate builds.
To do separate builds create a property that gives the correct path in a conditional property group and then use that property to have a single reference (i.e. move the conditional outside the references items group). There is an example of using such a property (for a custom FXCop extension) here, you can see lots of conditional properties being defined at the start of the .csproj file.
(Summary: VS doesn't handle all of the possibilities MSBuild does.)
As I see it, the problem with your original project was that you had <SpecificVersion>True</SpecificVersion> specifying System.Data.SQLite, Version=1.0.61.0, whereas the actual assembly was version 1.0.65. Fixing version in the assembly name in Reference ought to help.

Visual Studio Project: How to include a reference for one configuration only?

Env.: VS2008 C# project
I need to build my app for use in 2 different environments. In one of those environments, I need to use a 3rd party DLL assembly.
I could isolate the code that uses this DLL using #if blocks. But how do I conditionally include the reference to the DLL in the CS project file?
Edit: womp has a good point in his comment. I turned into a separate question: Will the referenced DLL be loaded at all if it's never called?
TIA,
Unload the project and open it as .XML
Locate the reference item tag and add a Condition attribute.
For instance:
<ItemGroup>
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Xml" />
<Reference Include="MyUtilities.Debug"
Condition="'$(Configuration)'=='Debug'"/>
</ItemGroup>
Notice the last reference now has a condition.
I know this is an old post, but in case anyone else finds it before they find the answer, like I did, it's this: you need to use the "Choose" element in the project file:
link
You can define both conditional references and conditional compilation in one place, so you don't have to use #if's in your code.
It works in SharpDevelop, and since it's MS's documentation I assume it works in Visual Studio.
The following, in the csproj file references itemgroup works in vs 2008 for me:-
<Reference Include="DRLClasses, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL" Condition=" '$(Configuration)' == 'Debug' ">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\Visual Studio User Library\Debug\DRLClasses.dll</HintPath>
</Reference>
<Reference Include="DRLClasses, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL" Condition=" '$(Configuration)' == 'Release' ">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\Visual Studio User Library\Release\DRLClasses.dll</HintPath>
</Reference>
Inspired by the question and answer shown here, you can add <Choose> and <When Condition> commands around the part you want to be conditionally run. For example:
<Choose>
<When Condition="$(USEDLL) == true">
<ItemGroup>
<EmbeddedResource Include="test.dll">
<LogicalName>test.dll</LogicalName>
</EmbeddedResource>
</ItemGroup>
</When>
</Choose>
Then in the CLI, simply use the /p property in MSBuild like this:
MSBuild "C:\myproject\myproject.sln" /p:USEDLL=true
...or if you don't want the DLL, simply:
MSBuild "C:\myproject\myproject.sln" /p:USEDLL=false

Categories