How to set "When Conditions" in C# application - premake

I'm trying to convert an existing C# to premake. I'm using premake5 alpha 6. In my C# project, there are "When conditions" that set the reference include depending on the build configuration if it's release|x86, Debug|x86..etc. How do I set the When Condition= in premake?
In my existing project file:
<When Condition=" ('$(Configuration)|$(Platform)' == 'Release|AnyCPU' Or ('$(Configuration)|$(Platform)' == 'Release|x86') ">
<ItemGroup>
<Reference Include="Project_v100">
<HintPath>..\..\bin\x86\Project_v100.dll</HintPath>
</Reference>
</ItemGroup>
</When>
I know that if i do this in premake the result will be something like the below.
In Premake:
links "Project_v100.dll"
In project file:
<Reference Include="Project_v100">
<HintPath>..\..\bin\x86\Project_v100.dll</HintPath>
<Private>False</Private>
</Reference>

I think that you're looking for filter : https://github.com/premake/premake-core/wiki/filter

More specifically:
filter "configurations:Release"
links "Project_v100"
Here is the user guide page on filters, and as Citron already mentioned, the reference manual page.

Related

How to get net-core projects to include auto generated code file?

I have a .net core project file (*.csproj) like this:
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
<!-- Create RS.cs -->
<ItemGroup>
<ResourceGeneratorInputs Include="strings.resx" />
<ResourceGeneratorOutputs Include="RS.cs" />
</ItemGroup>
<Target Name="GenerateTheResourceFile"
BeforeTargets="PrepareForBuild"
Inputs="#(ResourceGeneratorInputs)"
Outputs="#(ResourceGeneratorOutputs)">
<Exec Command="ResourceStringGenerator.exe strings.resx RS.cs " />
</Target>
</Project>
This projects has a target that generates a csharp code file called RS.cs, which also must be compiled.
The problem is the file is generated too late. The build engine has already read the list of files in the project directory, and the RS.cs file gets ignored.
I have tried changing the BeforeTargets attribute to various other Targets with no luck at all. (Described here: https://learn.microsoft.com/en-us/dotnet/core/tools/csproj#build-events)
I've tried turning off automatic inclusion of files too:
<PropertyGroup>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
</PropertyGroup>
and making my own list of files to compile. But that didn't work either. The RS.cs file was still generated too late.
The new project file format seems to be so eager to get the list of files, that it seems to leave no room for auto-generated files.
What is the work-around here?
The static portion of a project file is always evaluated before targets run.
However, you can also add items inside your target:
<Target Name="GenerateTheResourceFile"
BeforeTargets="PrepareForBuild"
Inputs="#(ResourceGeneratorInputs)"
Outputs="#(ResourceGeneratorOutputs)">
<Exec Command="ResourceStringGenerator.exe strings.resx RS.cs " />
<ItemGroup>
<EmbeddedResource Include="strings.resx" Exclude="#(EmbeddedResource)" />
<Compile Include="RS.cs" Exclude="#(Compile)" />
</ItemGroup>
</Target>
The "exclude" part ensures that the file isn't added twice if it was already picked up during static evaluation (i.e. additional builds)

"Duplicate compile items" error when generating code from "Add Web Reference" in Rider

I'm creating a .NET core API that consumes a web service with the Rider IDE.
I created a new csproj FooBar.Service, and added the web reference. The FooBar.Service.csproj file is as follow:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<WCFMetadata Include="Service References" />
</ItemGroup>
<ItemGroup>
<WCFMetadataStorage Include="Service References\FooBar" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="Service References\FooBar\FooBar.svcmap">
<Generator>WCF Proxy Generator</Generator>
<LastGenOutput>FooBar.cs</LastGenOutput>
</None>
<None Include="Service References\FooBar\FooBar.webref" />
<None Include="Service References\FooBar\FooBar.wsdl" />
</ItemGroup>
<ItemGroup>
<Compile Include="Service References\FooBar\FooBar.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>FooBar.svcmap</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<Reference Include="System.ServiceModel" />
</ItemGroup>
</Project>
The generated code seems correct, but I have this error:
Duplicate 'Compile' items were included. The .NET SDK includes 'Compile' items from your project directory by default. You can either remove these items from your project file, or set the 'EnableDefaultCompileItems' property to 'false' if you want to explicitly include them in your project file. For more information, see https://aka.ms/sdkimplicititems. The duplicate items were: 'Service References\FooBar\FooBar.cs'
I've read the other question about this issue: the answer is that there are 2 compile items with the same name. If I understand the error message, the file is firstly added by default because it is in the folder of the .csproj, and it is added again by the <Compile Include="Service References\FooBar\FooBar.cs"> item.
I guess that this is a bug of the Rider web service code generation, but what could be a workaround without messing up with the automaticaly generated code? I know that I can deactivate the EnableDefaultCompileItems flag, but I'd prefer not to because I prefer this behavior.
I tried to replace the Include with an Update as seen in this answer, but then I have a bunch of compile error that says: The type or namespace name 'ServiceModel' does not exist in the namespace 'System' (are you missing an assembly reference?) although it is included.

How to exclude APP_DATA directory from publishing using custom target "PublishToFileSystem"

I am using a custom target for publishing my web site to a local folder.
The target (found here) looks like:
<Target Name="PublishToFileSystem"
DependsOnTargets="PipelinePreDeployCopyAllFilesToOneFolder">
<Error Condition="'$(PublishDestination)'==''"
Text="The PublishDestination property must be set to the intended publishing destination." />
<MakeDir Condition="!Exists($(PublishDestination))"
Directories="$(PublishDestination)" />
<ItemGroup>
<PublishFiles Include="$(_PackageTempDir)\**\*.*" />
</ItemGroup>
<Copy SourceFiles="#(PublishFiles)"
DestinationFiles="#(PublishFiles->'$(PublishDestination)\%(RecursiveDir)%(Filename)%(Extension)')"
SkipUnchangedFiles="True" />
</Target>
The corresponding msbuild command looks like:
msbuild projectfile.csproj /p:DeployOnBuild=true /p:VisualStudioVersion=14.0 /p:configuration=Release /p:PublishDestination=C:\inetpub\wwwroot\WebSite /T:PublishToFileSystem
That works fine so far. However, I would like to exclude the APP_DATA directory from publishing.
So, is there a way to exclude the APP_DATA directory from publishing? Maybe by excluding it from the file set defined with <PublishFiles Include="$(_PackageTempDir)\**\*.*" />?
Environment:
Visual Studio 2015
MSBuild Tools 2015
The easiest way I found is to set this inside the publish profile.
<ExcludeApp_Data>False</ExcludeApp_Data>
You can do it from solution property. Just right click on solution and choose its property. You will get Package/Publish tab there you just need to check "Exclude files from the App_Data Folder". You can check at attached screen shot.
Hope this can help you.
It is possible to set the option (suggested by #Vipin Rathore) within the project file:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<ExcludeFoldersFromDeployment>APP_DATA</ExcludeFoldersFromDeployment>
</PropertyGroup>

Cirrius.Mvvmcross.Community.Plugins.SQLite.WindowsStore needs platform-specific dlls for X86 and ARM

In order to create a Windows Store app that uses SQLite, it is necessary to create platform-specific variants (nominally X86 and ARM). The nuget package only provides the X86 version. To work around this, I have included the SQLite plugin projects in my solution, so when I change the target to ARM, it creates the appropriate ARM executables for all of the necessary projects. My question is, am I missing something in the use of the nuget package that would allow me to access the different DLLs, or is this a limitation of the nuget package?
The nuget package does contain all 3 assemblies - but the nuspec nuget core doesn't understand the different assembly configurations. There are some powershell and .targets way around this - but not implemented by Mvx (yet).
There's some more info on this on https://nuget.codeplex.com/discussions/446656 and https://github.com/MvvmCross/MvvmCross/issues/307
While waiting for some hero to make a full solution, the workaround is to manually edit you .csproj file with conditionals like in https://nuget.codeplex.com/discussions/446656:
<Choose>
<When Condition=" '$(Platform)' == 'ARM' ">
<ItemGroup>
<Reference Include="Cirrious.MvvmCross.Plugins.Sqlite.WinRT.dll">
<HintPath>..\..\packages\...\x86\Cirrious.MvvmCross.Plugins.Sqlite.WinRT.dll</HintPath>
</Reference>
</ItemGroup>
</When>
</Choose>
<Choose>
<When Condition=" '$(Platform)' == 'x64' ">
<ItemGroup>
<Reference Include="Cirrious.MvvmCross.Plugins.Sqlite.WinRT.dll">
<HintPath>..\..\packages\...\x64\Cirrious.MvvmCross.Plugins.Sqlite.WinRT.dll</HintPath>
</Reference>
</ItemGroup>
</When>
</Choose>
<Choose>
<When Condition=" '$(Platform)' == 'x86' ">
<ItemGroup>
<Reference Include="Cirrious.MvvmCross.Plugins.Sqlite.WinRT.dll">
<HintPath>..\..\packages\...\x86\Cirrious.MvvmCross.Plugins.Sqlite.WinRT.dll</HintPath>
</Reference>
</ItemGroup>
</When>
</Choose>

Web Deployment Project AfterBuild path problems

I'm currently in the process of setting up a build server for a web project. I'm using Web Deployment Project to create a deployable package and I want to do some simple file administration (copy webDeploy.config -> web.config and delete .csproj files).
My target looks as follows:
<Target Name="AfterBuild">
<Delete Files="$(OutputPath)\*.csproj" />
</Target>
However, inspecting the output of the WDP gives me this
Target "AfterBuild" in file "C:\project\Deployment\Project.Deployment.wdproj":
Task "Delete"
File ".\Debug\*.*" doesn't exist. Skipping.
Done executing task "Delete".
Done building target "AfterBuild" in project "Project.Deployment.wdproj".
The Deployment path does indeed contain a Debug path. What am I doing wrong?
If you want to use wildcards you will have do so in an item list. The item list will take care of expanding the wild cards for you. So in your case:
<Target Name="AfterBuild">
<ItemGroup>
<FilesToDelete Include="$(OutputPath)\*.csproj" />
</ItemGroup>
<Delete Files="#(FilesToDelete)" />
</Target>
I tried it myself and was stunned but the explanation is simple: You cannot use wildcards (MSBuild Team Blog).
Sample:
<ItemGroup>
<ProjectConfigFiles Include="$(OutputPath)\*.csproj" />
</ItemGroup>
<Target Name="AfterBuild">
<Delete Files="#(ProjectConfigFiles)" />
</Target>

Resources