msbuildmaui.net-8.0

MAUI: Can I skip building for Android or iOS when I'm building either platform?


Basically the title says all. MAUI has a single project format for iOS and Android. When I'm debugging on iOS, I don't want MSBuild to build Android as well and vice-versa, because it gets slow. Other than creating two projects, are there no other options?


Solution

  • One way to achieve this is to add new build configurations to your solution, one for Android and one for iOS (and if you wish also the remaining platforms) and then updating the TargetFrameworks with a build condition.

    Step 1: Add new build configurations

    First, locate the configuration manager, by clicking the little triangle next to "Debug":

    Configuration Dropdown

    Then select "Configuration Manager" to see this dialog:

    Configuration Manager

    Here, you can now open the "Active solution configuration" dropdown and select "New". In the next dialog, you can then create your Android-specific configuration:

    Android-only configuration

    Repeat the same step for iOS:

    iOS-only configuration

    Then, in case you are using a Unit Test project, you need to disable building the test project with these configurations:

    Test project configuration

    Step 2: Add build conditions for TargetFrameworks

    Now, you can edit the .csproj file of your MAUI project and add the conditions to the property group at the top:

    <TargetFrameworks Condition="'$(Configuration)'=='Debug Android'">net8.0-android</TargetFrameworks>
    <TargetFrameworks Condition="'$(Configuration)'=='Debug iOS'">net8.0-ios</TargetFrameworks>
    <TargetFrameworks Condition="'$(Configuration)'=='Debug' OR '$(Configuration)'=='Release'">net8.0;net8.0-android;net8.0-ios;net8.0-maccatalyst</TargetFrameworks>
    <TargetFrameworks Condition="('$(Configuration)'=='Debug' OR '$(Configuration)'=='Release') AND $([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net8.0-windows10.0.19041.0</TargetFrameworks>
    

    Step 3: Update Test project (if you have one)

    Finally, you'll need to update the .csproj file of your test project and add conditions to the item groups so that it only builds with the supported configurations (here: Debug and Release):

    <Project Sdk="Microsoft.NET.Sdk">
    
      <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
    
        <IsPackable>false</IsPackable>
    
        <Configurations>Debug;Release;Debug Android;Debug iOS;</Configurations>
      </PropertyGroup>
    
      <ItemGroup Condition="'$(Configuration)'=='Debug' OR '$(Configuration)'=='Release'">
        <PackageReference Include="Microsoft.Maui.Dependencies" Version="6.0.547" />
        <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
        <PackageReference Include="NUnit" Version="3.13.3" />
        <PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
        <PackageReference Include="NUnit.Analyzers" Version="3.3.0" />
        <PackageReference Include="coverlet.collector" Version="3.1.2" />
      </ItemGroup>
    
      <ItemGroup Condition="'$(Configuration)'=='Debug' OR '$(Configuration)'=='Release'">
        <ProjectReference Include="..\MauiSamples\MauiSamples.csproj" />
      </ItemGroup>
    
    </Project>
    

    Final Notes

    This approach generally works, I've tried it out. However, switching between configurations sometimes leads to project load failures or failures to establish the Mac build host connection or other issues. If you don't switch between platforms very often, this approach might be suitable, otherwise, you'll have to live with how it is or manually comment/uncomment the target platform identifiers as proposed in an another answer.

    If you want to see a working example, I've created a separate branch where I've tried this in my MAUI Samples repo.