How to conditionally add RuntimeIdentifiers property to Directory.Build.props when using msbuild

83 Views Asked by At

I have a cross-platform solution with multiple projects targetting iOS, Android, Mac, Windows, and Linux using Avalonia. I am using Windows Application Packaging Project to package and deploy the Windows app. The main project has reference to various library projects, all of which target NET8.0.

When try to publish the Windows packaging project, unless I add <RuntimeIdentifiers>win-x64;</RuntimeIdentifiers> to every project (including the library projects), I will get an error like this

Severity    Code    Description Project File    Line    Suppression State
Error       Assets file 'C:\Projects\Samples\AvaloniaPackagingSample\AvaloniaPackagingSample.Desktop\obj\wappublish\win-x64\project.assets.json' not found. Run a NuGet package restore to generate this file.  AvaloniaPackagingSample.Desktop.Package C:\Program Files\dotnet\sdk\8.0.101\Sdks\Microsoft.NET.Sdk\targets\Microsoft.PackageDependencyResolution.targets    267 

Instead of manually adding that build property to all projects, I have configured Directory.Build.props to apply that to all of the projects

<Project>

    <Target Name="ConfirmDirectoryBuildPropsImport" AfterTargets="PrepareForBuild">
        <Message Text="Directory.Build.props has been imported successfully" Importance="high" />
    </Target>

    <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
        <Nullable>enable</Nullable>
        <LangVersion>latest</LangVersion>
        <ImplicitUsings>enable</ImplicitUsings>
        <Version>$(Version)</Version>
        <AssemblyVersion>$(Version)</AssemblyVersion>
        <RuntimeIdentifiers>win-x64;</RuntimeIdentifiers>
    </PropertyGroup>

</Project>

The problem is that I have other targets besides the Windows and when I leave the runtime identifier Android/iOS build/publish would fail. So, I need a way to conditionally add <RuntimeIdentifiers>win-x64;</RuntimeIdentifiers>.

The idea is pretty simple - whenever I build the Windows app, indicate somehow that the runtime identifiers should be added, otherwise, skip them. I've tried adding a new variable called IsDesktop and add a conditional section to the Directory.build.props

<Project>

    <Target Name="ConfirmDirectoryBuildPropsImport" AfterTargets="PrepareForBuild">
        <Message Text="Directory.Build.props has been imported successfully" Importance="high" />
    </Target>

    <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
        <Nullable>enable</Nullable>
        <LangVersion>latest</LangVersion>
        <ImplicitUsings>enable</ImplicitUsings>
        <Version>$(Version)</Version>
        <AssemblyVersion>$(Version)</AssemblyVersion>
    </PropertyGroup>

    <PropertyGroup Condition="'$(IsDesktop)' == 'true'">
        <DefineConstants>$(DefineConstants);MY_CUSTOM_DESKTOP_CONSTANT</DefineConstants>
        <RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
    </PropertyGroup>

</Project>

And then, I execute the msbuild command against the packaging project

msbuild $packagingProjectPath `
        /nologo /nr:false `
        /p:ProjectName="$PackagingProjectPath" `
        /p:AppxBundlePlatforms="x64" `
        /p:Platform="x64" `
        /p:Configuration="Release" `
        /p:AppxPackageDir=$OutputPath `
        /p:AppxBundle=Always `
        /p:PackageCertificateThumbprint=$PackageCertificateThumbprint `
        /p:PackageCertificateKeyFile=$PackageCertificateKeyFile `
        /p:PackageCertificatePassword=$PackageCertificatePassword `
        /p:Version="$($EnvironmentSpecificVersion.VersionText)" `
        /p:IsDesktop=true `
        /v:detailed

However, the runtime identifiers are not getting added and the build fails.

2 observations

  1. Notice how I've added this piece in Directory.Build.props <Message Text="Directory.Build.props has been imported successfully" Importance="high" /> - when msbuild is executed this message does get printed, which means that Directory.Build.props is being picked up
  2. I also see MY_CUSTOM_DESKTOP_CONSTANT printed out in the build log, which means that the conditional section does get activated

But anyhow, my build still fails due to the same error I was seeing before adding the runtime identifier: ...project.assets.json' doesn't have a target for 'net8.0/win-x64'

What am I doing wrong? Perhaps, there's a different strategy for having conditional sections inside Directory.Build.props?

0

There are 0 best solutions below