diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 71828f1e3..1f11d52b3 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -80,11 +80,9 @@ jobs:
os: [ubuntu-latest, macos-latest, windows-latest]
# moonbit removed from language matrix for now - causing CI failures
lang: [c, rust, csharp, cpp, go]
- exclude:
- # For now csharp doesn't work on macos, so exclude it from testing.
- - os: macos-latest
- lang: csharp
runs-on: ${{ matrix.os }}
+ env:
+ RUNTIMELAB_COMMIT: '4cac3ab5c8e97fda69c23dfca41ace964babc05e'
steps:
- uses: actions/checkout@v4
with:
@@ -103,7 +101,14 @@ jobs:
uses: actions/setup-dotnet@v4
with:
dotnet-version: '9.x'
- if: matrix.lang == 'csharp'
+ if: matrix.lang == 'csharp' && runner.os != 'macOS'
+
+ - name: Setup .NET 10 (macOS)
+ uses: actions/setup-dotnet@v4
+ with:
+ dotnet-version: '10.x'
+ dotnet-quality: 'preview'
+ if: matrix.lang == 'csharp' && runner.os == 'macOS'
- name: Setup Go
uses: actions/setup-go@v5
@@ -125,6 +130,57 @@ jobs:
shell: powershell
if: matrix.os == 'windows-latest' && matrix.lang == 'moonbit'
+ # macOS C# requires locally-built ILC packages since no osx-arm64
+ # packages are published on NuGet.
+ - name: Cache runtimelab ILC packages
+ id: cache-runtimelab
+ uses: actions/cache@v4
+ with:
+ path: runtimelab-packages
+ key: runtimelab-macos-arm64-${{ env.RUNTIMELAB_COMMIT }}
+ if: runner.os == 'macOS' && matrix.lang == 'csharp'
+
+ - name: Install LLVM 18 for runtimelab build
+ if: runner.os == 'macOS' && matrix.lang == 'csharp' && steps.cache-runtimelab.outputs.cache-hit != 'true'
+ run: brew install llvm@18
+
+ - name: Checkout runtimelab
+ uses: actions/checkout@v4
+ with:
+ repository: dotnet/runtimelab
+ ref: ${{ env.RUNTIMELAB_COMMIT }}
+ path: runtimelab
+ if: runner.os == 'macOS' && matrix.lang == 'csharp' && steps.cache-runtimelab.outputs.cache-hit != 'true'
+
+ - name: Build runtimelab ILC packages
+ if: runner.os == 'macOS' && matrix.lang == 'csharp' && steps.cache-runtimelab.outputs.cache-hit != 'true'
+ run: |
+ cd runtimelab
+ ln -sf $WASI_SDK_PATH src/mono/wasi/wasi-sdk
+ mkdir -p src/mono/wasi/include
+
+ # Build wasi libs and packages
+ ./build.sh clr.aot+libs -c Release -a wasm -os wasi /p:NuGetAudit=false
+ ./build.sh nativeaot.packages -c Release -a wasm -os wasi /p:NuGetAudit=false
+
+ # Build host compiler, libs, WASM JIT, and packages
+ ./build.sh clr.aot -c Release /p:NuGetAudit=false
+ ./build.sh libs -c Release /p:NuGetAudit=false
+ LLVM_CMAKE_CONFIG_RELEASE=$(brew --prefix llvm@18)/lib/cmake/llvm \
+ src/coreclr/build-runtime.sh -arm64 -release -os osx -outputrid osx-arm64 -component llvmjit
+ cp artifacts/bin/coreclr/osx.arm64.Release/libclrjit_universal_llvm32_arm64.dylib artifacts/bin/coreclr/osx.arm64.Release/ilc-published/
+ cp artifacts/bin/coreclr/osx.arm64.Release/libjitinterface_arm64.dylib artifacts/bin/coreclr/osx.arm64.Release/ilc-published/
+ ./build.sh nativeaot.packages -c Release /p:NuGetAudit=false
+
+ mkdir -p ../runtimelab-packages
+ cp artifacts/packages/Release/Shipping/*.nupkg ../runtimelab-packages/
+
+ - name: Set ILC env vars for macOS C#
+ if: runner.os == 'macOS' && matrix.lang == 'csharp'
+ run: |
+ echo "ILC_VERSION=10.0.0-dev" >> $GITHUB_ENV
+ echo "ILC_PACKAGES_PATH=${{ github.workspace }}/runtimelab-packages" >> $GITHUB_ENV
+
# Run all codegen tests for this language
- run: |
cargo run test --languages ${{ matrix.lang }} tests/codegen \
diff --git a/crates/csharp/src/csproj.rs b/crates/csharp/src/csproj.rs
index 1d9d86aaa..c94b39064 100644
--- a/crates/csharp/src/csproj.rs
+++ b/crates/csharp/src/csproj.rs
@@ -1,5 +1,5 @@
use anyhow::Result;
-use std::{fs, path::PathBuf};
+use std::{env, fs, path::PathBuf};
use heck::ToUpperCamelCase;
@@ -103,21 +103,36 @@ impl CSProjectLLVMBuilder {
let os = match std::env::consts::OS {
"windows" => "win",
"linux" => std::env::consts::OS,
+ "macos" => "osx",
other => todo!("OS {} not supported", other),
};
+ let arch = match std::env::consts::ARCH {
+ "aarch64" => "arm64",
+ "x86_64" => "x64",
+ other => todo!("ARCH {} not supported", other),
+ };
+
+ let ilc_version = env::var("ILC_VERSION").unwrap_or_else(|_| "10.0.0-*".to_string());
+
csproj.push_str(
&format!(
r#"
-
-
+
+
"#),
);
+ let local_source = match env::var("ILC_PACKAGES_PATH") {
+ Ok(path) => format!(r#""#),
+ Err(_) => String::new(),
+ };
+
fs::write(
self.dir.join("nuget.config"),
- r#"
+ format!(
+ r#"
@@ -126,11 +141,12 @@ impl CSProjectLLVMBuilder {
+ {local_source}
-
- "#,
+ "#
+ ),
)?;
}
diff --git a/crates/test/src/csharp.rs b/crates/test/src/csharp.rs
index 8e11ca7f7..692221e02 100644
--- a/crates/test/src/csharp.rs
+++ b/crates/test/src/csharp.rs
@@ -99,6 +99,7 @@ impl LanguageMethods for Csharp {
let os = match std::env::consts::OS {
"windows" => "win",
"linux" => std::env::consts::OS,
+ "macos" => "osx",
other => todo!("OS {} not supported", other),
};