Skip to content

Commit b14dc03

Browse files
CopilotglennawatsonCopilot
authored
Modernize Sextant multi-TFM builds with OS-aware MSBuild (no .NET Framework) (#893)
Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: glennawatson <[email protected]> Co-authored-by: Copilot <[email protected]>
1 parent 2c49dae commit b14dc03

File tree

16 files changed

+134
-25
lines changed

16 files changed

+134
-25
lines changed

.github/copilot-instructions.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ Always reference these instructions first and fallback to search or bash command
3535
dotnet build Sextant.sln --configuration Release
3636
```
3737
Build time: **2-5 minutes**. Set timeout to 10+ minutes for full solution builds.
38+
39+
**Note**: The build system automatically selects appropriate target frameworks based on your OS. No manual TFM configuration needed.
3840

3941
- Individual project builds (faster for development):
4042
```bash
@@ -43,6 +45,11 @@ Always reference these instructions first and fallback to search or bash command
4345
dotnet build Sextant.Tests/Sextant.Tests.csproj --configuration Release
4446
```
4547

48+
- **Cross-platform considerations**:
49+
- Linux: Builds core .NET and Android targets
50+
- Windows: Builds all targets including Windows and Apple (via Pair-to-Mac)
51+
- macOS: Builds core .NET, Android, and Apple targets
52+
4653
### Testing
4754
- **Full test suite**:
4855
```bash
@@ -273,6 +280,30 @@ public partial class SextantNavigationService : IViewStackService
273280

274281
## Target Framework Support
275282

283+
### Centralized Multi-TFM Build System
284+
Sextant uses a centralized, OS-aware build system defined in `src/Directory.Build.props` that automatically selects appropriate target frameworks based on the host operating system:
285+
286+
#### TFM Property Groups
287+
- **`SextantModernTargets`**: `net8.0;net9.0` - Used by tests and benchmarks that don't need .NET Standard
288+
- **`SextantCoreTargets`**: `netstandard2.0;net8.0;net9.0` - Used by core libraries for broad compatibility
289+
- **`SextantMauiTargetFrameworks`**: OS-aware composition for MAUI projects including platform-specific targets
290+
291+
#### OS-Aware Target Selection
292+
- **Linux builds**: Core targets + Android (`netstandard2.0;net8.0;net9.0;net9.0-android`)
293+
- **Windows builds**: Core + Android + Windows + Apple + Tizen (supports Pair-to-Mac for iOS development)
294+
- **macOS builds**: Core + Android + Apple + Tizen
295+
296+
#### Project TFM Usage
297+
- **Core libraries** (Sextant, Sextant.Mocks): Use `$(SextantCoreTargets)` for maximum compatibility
298+
- **MAUI libraries** (Sextant.Maui, Sextant.Plugins.Popup): Use `$(SextantMauiTargetFrameworks)` for platform-specific support
299+
- **Tests/Benchmarks**: Use `$(SextantModernTargets)` since they don't need .NET Standard support
300+
301+
#### Benefits
302+
- **Cross-platform builds**: No manual TFM editing needed across different operating systems
303+
- **Consistent targeting**: Centralized TFM management reduces configuration drift
304+
- **Build optimization**: Only compiles relevant targets for each OS, reducing build time
305+
- **Maintainability**: Easy to update TFMs across entire solution from single location
306+
276307
### Supported Frameworks
277308
- **netstandard2.0** - Broad compatibility with .NET Framework and older .NET Core
278309
- **net8.0** - Modern .NET with performance improvements

Samples/Directory.Build.props

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project>
3+
<!-- Import the main Directory.Build.props from src -->
4+
<Import Project="../src/Directory.Build.props" />
5+
</Project>

Samples/SextantSample.Maui/SextantSample.Maui.csproj

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFrameworks>net9.0-android;net9.0-ios</TargetFrameworks>
5-
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net9.0-windows10.0.19041.0</TargetFrameworks>
4+
<TargetFrameworks>$(SextantMauiTargetFrameworks)</TargetFrameworks>
65
<OutputType>Exe</OutputType>
76
<UseMaui>true</UseMaui>
87
<SingleProject>true</SingleProject>

src/Benchmarks/Sextant.Benchmarks.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
33
<IsPackable>false</IsPackable>
4-
<TargetFrameworks>net462;net9.0</TargetFrameworks>
4+
<TargetFrameworks>$(SextantModernTargets)</TargetFrameworks>
55
<PlatformTarget>AnyCPU</PlatformTarget>
66
<DebugType>pdbonly</DebugType>
77
<DebugSymbols>true</DebugSymbols>

src/Directory.Build.props

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,48 @@
3232
<PublishRepositoryUrl>true</PublishRepositoryUrl>
3333
<NoWarn>$(NoWarn);CA1510;IDE0130</NoWarn>
3434
</PropertyGroup>
35+
<!-- =========================
36+
TFM Bucket Definitions
37+
========================= -->
38+
<PropertyGroup>
39+
<!-- Modern .NET TFMs only (net8/net9) - for tests/benchmarks -->
40+
<SextantModernTargets>net8.0;net9.0</SextantModernTargets>
41+
42+
<!-- Core TFMs buildable on all OSes (netstandard + modern) - for libraries -->
43+
<SextantCoreTargets>netstandard2.0;$(SextantModernTargets)</SextantCoreTargets>
44+
45+
<!-- MAUI/Platform TFMs -->
46+
<SextantAndroidTargets>net9.0-android</SextantAndroidTargets>
47+
<SextantWindowsTargets>net9.0-windows10.0.17763.0</SextantWindowsTargets>
48+
<SextantAppleTargets>net9.0-ios;net9.0-macos;net9.0-maccatalyst;net9.0-tvos</SextantAppleTargets>
49+
50+
<!-- MAUI specific targets (no netstandard) -->
51+
<SextantMauiCoreTargets>net9.0</SextantMauiCoreTargets>
52+
</PropertyGroup>
53+
54+
<!-- =========================
55+
OS-Aware Composition
56+
========================= -->
57+
<PropertyGroup>
58+
<!-- Base always-present for full framework support -->
59+
<SextantFinalTargetFrameworks>$(SextantCoreTargets)</SextantFinalTargetFrameworks>
60+
61+
<!-- Android: allowed on any OS (workload-dependent; no OS gate needed) -->
62+
<SextantFinalTargetFrameworks>$(SextantFinalTargetFrameworks);$(SextantAndroidTargets)</SextantFinalTargetFrameworks>
63+
64+
<!-- Windows MAUI/Desktop: only on Windows hosts, Windows can include "everything"-->
65+
<SextantFinalTargetFrameworks Condition="$([MSBuild]::IsOsPlatform('Windows'))">$(SextantFinalTargetFrameworks);$(SextantWindowsTargets);$(SextantAppleTargets)</SextantFinalTargetFrameworks>
66+
67+
<!-- Apple (iOS/macOS/MacCatalyst/tvOS): on macOS and on Windows (Pair-to-Mac) -->
68+
<SextantFinalTargetFrameworks Condition="$([MSBuild]::IsOsPlatform('OSX'))">$(SextantFinalTargetFrameworks);$(SextantAppleTargets)</SextantFinalTargetFrameworks>
69+
70+
<!-- MAUI specific composition (no netstandard) -->
71+
<SextantMauiTargetFrameworks>$(SextantMauiCoreTargets)</SextantMauiTargetFrameworks>
72+
<SextantMauiTargetFrameworks>$(SextantMauiTargetFrameworks);$(SextantAndroidTargets)</SextantMauiTargetFrameworks>
73+
<SextantMauiTargetFrameworks Condition="$([MSBuild]::IsOsPlatform('Windows'))">$(SextantMauiTargetFrameworks);$(SextantWindowsTargets);$(SextantAppleTargets)</SextantMauiTargetFrameworks>
74+
<SextantMauiTargetFrameworks Condition="$([MSBuild]::IsOsPlatform('OSX'))">$(SextantMauiTargetFrameworks);$(SextantAppleTargets)</SextantMauiTargetFrameworks>
75+
</PropertyGroup>
76+
3577
<PropertyGroup Condition="'$(GITHUB_ACTIONS)' == 'true'">
3678
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
3779
</PropertyGroup>

src/Sample/SextantSample.Core/SextantSample.ViewModels.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFrameworks>netstandard2.0;net8.0;net9.0</TargetFrameworks>
4+
<TargetFrameworks>$(SextantCoreTargets)</TargetFrameworks>
55
<IsPackable>false</IsPackable>
66
</PropertyGroup>
77

src/Sextant.Avalonia/Sextant.Avalonia.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
3-
<TargetFrameworks>netstandard2.0;net8.0;net9.0</TargetFrameworks>
3+
<TargetFrameworks>$(SextantCoreTargets)</TargetFrameworks>
44
<RootNamespace>Sextant.Avalonia</RootNamespace>
55
</PropertyGroup>
66
<ItemGroup>

src/Sextant.Maui/Sextant.Maui.csproj

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
3-
<TargetFrameworks>net9.0</TargetFrameworks>
4-
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net9.0-windows10.0.19041.0</TargetFrameworks>
3+
<TargetFrameworks>$(SextantMauiTargetFrameworks)</TargetFrameworks>
54
<ImplicitUsings>enable</ImplicitUsings>
65
<UseMaui>true</UseMaui>
76
</PropertyGroup>

src/Sextant.Mocks/Sextant.Mocks.csproj

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFrameworks>netstandard2.0;net9.0</TargetFrameworks>
5-
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">$(TargetFrameworks);net462;</TargetFrameworks>
4+
<TargetFrameworks>$(SextantCoreTargets)</TargetFrameworks>
65
<IsPackable>false</IsPackable>
76
</PropertyGroup>
87

src/Sextant.Plugins.Popup/Sextant.Plugins.Popup.csproj

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
3-
<TargetFrameworks>net9.0</TargetFrameworks>
4-
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net9.0-windows10.0.19041.0</TargetFrameworks>
3+
<TargetFrameworks>$(SextantMauiTargetFrameworks)</TargetFrameworks>
54
<UseMaui>true</UseMaui>
65
</PropertyGroup>
76
<ItemGroup>

0 commit comments

Comments
 (0)