Skip to content

Haiku: Initial NativeAOT and Crossgen2 support#127431

Open
trungnt2910 wants to merge 4 commits intodotnet:mainfrom
trungnt2910:dev/trungnt2910/haiku-nativeaot
Open

Haiku: Initial NativeAOT and Crossgen2 support#127431
trungnt2910 wants to merge 4 commits intodotnet:mainfrom
trungnt2910:dev/trungnt2910/haiku-nativeaot

Conversation

@trungnt2910
Copy link
Copy Markdown
Contributor

Add the required configuration to support NativeAOT and Crossgen2 for Haiku targets.

This includes:

  • Enabling NativeAOT and Crossgen2 for Haiku in MSBuild scripts,
  • Adding "Haiku" to relevant enumerations and switch blocks,
  • Defining correct linker flags for Haiku targets,
  • Adding 0x0B05 as the PE native image type constant for Haiku
    • This is a reference to Haiku's origins as "OpenBeOS".

Part of #55803.

Copilot AI review requested due to automatic review settings April 26, 2026 03:31
@trungnt2910
Copy link
Copy Markdown
Contributor Author

c/c @am11

@dotnet-policy-service dotnet-policy-service Bot added the community-contribution Indicates that the PR has been added by a community member label Apr 26, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds initial Haiku support for NativeAOT and Crossgen2 by wiring Haiku through build/configuration logic and the CoreCLR toolchain’s target/OS metadata.

Changes:

  • Enables Crossgen2/R2R and NativeAOT support paths for Haiku in MSBuild/build subsets.
  • Adds Haiku to target OS enums/switches/help text across AOT tooling (crossgen2/ilc/r2rdump/perfmap).
  • Defines Haiku-specific PE native image OS override constant and adjusts NativeAOT Unix link settings for Haiku.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Runtime.CoreCLR.sfxproj Stops disabling R2R/crossgen for Haiku in runtime pack SFX build.
src/coreclr/tools/r2rdump/Program.cs Adds Haiku OS mapping for TargetDetails when producing PDB/perfmap metadata.
src/coreclr/tools/aot/crossgen2/Crossgen2RootCommand.cs Adds haiku to --targetos extended help list.
src/coreclr/tools/aot/ILCompiler/ILCompilerRootCommand.cs Adds haiku to --targetos extended help list.
src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TrimmingDriver.cs Detects Haiku at runtime to compute default TargetOS in trimming tests.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs Introduces Haiku OS override constant in R2R reader OS enum.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/TargetExtensions.cs Adds Haiku machine OS override mapping for R2R object writer.
src/coreclr/tools/aot/ILCompiler.Diagnostics/ReadyToRunDiagnosticsConstants.cs Adds Haiku perfmap OS token.
src/coreclr/tools/aot/ILCompiler.Diagnostics/PerfMapWriter.cs Maps TargetOS.Haiku to the new perfmap OS token.
src/coreclr/tools/Common/TypeSystem/Common/TargetDetails.cs Adds Haiku to TargetOS enum.
src/coreclr/tools/Common/Compiler/ObjectWriter/PETargetExtensions.cs Adds Haiku machine OS override mapping for PE writer.
src/coreclr/tools/Common/CommandLineHelpers.cs Adds Haiku detection and parsing for --targetos.
src/coreclr/nativeaot/Runtime/unix/PalUnix.cpp Treats Haiku like Linux/Android for pthread TLS key-based shutdown notifications.
src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets Adds Haiku target triple and tweaks linker/system library args for Haiku.
src/coreclr/inc/pedecoder.h Defines Haiku PE native image OS override constant (0x0B05).
src/coreclr/crossgen-corelib.proj Stops disabling R2R/crossgen for Haiku in crossgen-corelib flow.
eng/Subsets.props Marks Haiku as a supported OS for NativeAOT subset gating.

Comment thread src/coreclr/tools/r2rdump/Program.cs Outdated
Comment on lines +507 to 509
#if defined(TARGET_LINUX) || defined(TARGET_ANDROID) || defined(TARGET_HAIKU)
static pthread_key_t key;
#endif
Copy link
Copy Markdown
Contributor Author

@trungnt2910 trungnt2910 Apr 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like this should be a configure-time check.

Maybe check for pthread_key_create if we prefer that, or run a check for __cxa_thread_atexit in the OS's default libc, or run a behavior check for TLS destructors (it will likely fail and crash on Haiku)?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that'd be better:

diff --git a/src/coreclr/nativeaot/Runtime/unix/PalUnix.cpp b/src/coreclr/nativeaot/Runtime/unix/PalUnix.cpp
index dec55db8290..0fd3f622d03 100644
--- a/src/coreclr/nativeaot/Runtime/unix/PalUnix.cpp
+++ b/src/coreclr/nativeaot/Runtime/unix/PalUnix.cpp
@@ -504,7 +504,7 @@ void InitializeCurrentProcessCpuCount()
     g_RhNumberOfProcessors = count;
 }
 
-#if defined(TARGET_LINUX) || defined(TARGET_ANDROID)
+#if HAVE_PTHREAD_KEY_CREATE
 static pthread_key_t key;
 #endif
 
@@ -548,7 +548,7 @@ bool PalInit()
     }
 #endif
 
-#if defined(TARGET_LINUX) || defined(TARGET_ANDROID)
+#if HAVE_PTHREAD_KEY_CREATE
     if (pthread_key_create(&key, RuntimeThreadShutdown) != 0)
     {
         return false;
@@ -558,7 +558,7 @@ bool PalInit()
     return true;
 }
 
-#if !defined(TARGET_LINUX) && !defined(TARGET_ANDROID)
+#if !HAVE_PTHREAD_KEY_CREATE
 struct TlsDestructionMonitor
 {
     void* m_thread = nullptr;
@@ -604,7 +604,7 @@ FCIMPLEND
 //  thread        - thread to attach
 void PalAttachThread(void* thread)
 {
-#if defined(TARGET_LINUX) || defined(TARGET_ANDROID)
+#if HAVE_PTHREAD_KEY_CREATE
     if (pthread_setspecific(key, thread) != 0)
     {
         _ASSERTE(!"pthread_setspecific failed");
diff --git a/src/coreclr/nativeaot/Runtime/unix/config.h.in b/src/coreclr/nativeaot/Runtime/unix/config.h.in
index 3a5e1ef87b5..1a13cff7cf1 100644
--- a/src/coreclr/nativeaot/Runtime/unix/config.h.in
+++ b/src/coreclr/nativeaot/Runtime/unix/config.h.in
@@ -10,6 +10,7 @@
 #cmakedefine01 HAVE_PTHREAD_GETATTR_NP
 #cmakedefine01 HAVE_PTHREAD_CONDATTR_SETCLOCK
 #cmakedefine01 HAVE_PTHREAD_GETTHREADID_NP
+#cmakedefine01 HAVE_PTHREAD_KEY_CREATE
 
 #cmakedefine01 HAVE_CLOCK_NANOSLEEP
 #cmakedefine01 HAVE_SYSCTLBYNAME
diff --git a/src/coreclr/nativeaot/Runtime/unix/configure.cmake b/src/coreclr/nativeaot/Runtime/unix/configure.cmake
index 7cd0bf8ef75..2d15fccaef4 100644
--- a/src/coreclr/nativeaot/Runtime/unix/configure.cmake
+++ b/src/coreclr/nativeaot/Runtime/unix/configure.cmake
@@ -32,6 +32,7 @@ check_library_exists(${PTHREAD_LIBRARY} pthread_attr_get_np "" HAVE_PTHREAD_ATTR
 check_library_exists(${PTHREAD_LIBRARY} pthread_getattr_np "" HAVE_PTHREAD_GETATTR_NP)
 check_library_exists(${PTHREAD_LIBRARY} pthread_condattr_setclock "" HAVE_PTHREAD_CONDATTR_SETCLOCK)
 check_library_exists(${PTHREAD_LIBRARY} pthread_getthreadid_np "" HAVE_PTHREAD_GETTHREADID_NP)
+check_library_exists(${PTHREAD_LIBRARY} pthread_key_create "" HAVE_PTHREAD_KEY_CREATE)
 
 check_function_exists(clock_nanosleep HAVE_CLOCK_NANOSLEEP)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would that be a good idea?

I think the C++ TLS solution would be preferable here, since it is mandated by the standard and has no limitations I am aware of.

Meanwhile, pthread_setspecific is limited by PTHREAD_KEYS_MAX.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it's fine. pthread_key_create in this file runs exactly once, during PalInit, which is called once per process at startup. It is never called again.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied the changes, let's see how it goes.

which is called once per process at startup. It is never called again.

It is still one fewer key for the rest of the process though.

Comment on lines +265 to +266
<LinkerArg Include="-pie -Wl,-pie" Condition="'$(_IsApplePlatform)' != 'true' and '$(_targetOS)' != 'haiku' and '$(NativeLib)' == '' and '$(StaticExecutable)' != 'true' and '$(PositionIndependentExecutable)' != 'false'" />
<LinkerArg Include="-Wl,-no-pie" Condition="'$(_IsApplePlatform)' != 'true' and '$(_targetOS)' != 'haiku' and '$(NativeLib)' == '' and '$(StaticExecutable)' != 'true' and '$(PositionIndependentExecutable)' == 'false'" />
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to yesterday's patch https://github.com/dotnet/runtime/pull/127392/changes#diff-0ed6f3997357a6ff6652a7509482b05370b67e8e3041eecfd89f9556e7b59313R495 -pie should work on Haiku, -fPIE was supposed to be replaced with -fPIC for executables. What was the error? I think you want to keep -Wl,-pie and -Wl,-no-pie (linker options) and separate out -pie if compiler is complaining.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have the exact error here, but it had something to do with -fPIE not working with -shared.

-shared should be passed by default by the toolchain since all Haiku executables are built as shared objects for some reason.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, during the build, it should've published crossgen2 and ilc binaries as AOT. You can copy them from published directory on Haiku machine and run <path> --help, if it prints help without any error, we are good here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

~/Desktop> crossgen2 --help
The application to execute does not exist: '/boot/home/Desktop/crossgen2.dll'.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

~/Desktop/crossgen2/native> ./crossgen2 --help
--------------------------------------------------
Debug Assertion Violation

Message: m_pCodeManager->FindMethodInfo(m_ControlPC, &m_methodInfo)

Expression: 'ASSERT_UNCONDITIONALLY'

File: /home/runner/dotnet-runtime/src/coreclr/nativeaot/Runtime/StackFrameIterator.cpp, Line: 2194
--------------------------------------------------
Abort

This is interesting.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I'm waiting for the other PRs (especially the approved ones) to get merged before continuing. Right now I'm running it on disposable GitHub Actions machines and it's becoming cherry-pick hell.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most are passing, except:

Running /boot/home/Desktop/haiku.x64.Debug/nativeaot/SmokeTests/HardwareIntrinsics/X64Avx512/native/X64Avx512...

The current CPU is missing one or more of the required instruction sets.
Abort
Kill Thread
/boot/home/Desktop/haiku.x64.Debug/nativeaot/SmokeTests/HardwareIntrinsics/X64Avx512/native/X64Avx512 failed with exit code 149
Running /boot/home/Desktop/haiku.x64.Debug/nativeaot/SmokeTests/HardwareIntrinsics/X64Avx512_VectorT512/native/X64Avx512_VectorT512...

The current CPU is missing one or more of the required instruction sets.
Abort
Kill Thread
/boot/home/Desktop/haiku.x64.Debug/nativeaot/SmokeTests/HardwareIntrinsics/X64Avx512_VectorT512/native/X64Avx512_VectorT512 failed with exit code 149

My CPU is:

~/Desktop/haiku.x64.Debug/nativeaot> sysinfo
Kernel name: kernel_x86_64 built on: Apr 25 2026 06:15:18 version 0x901
4 Intel 11th Gen Core™ i7-1165G7, revision 806c1 running at 1689MHz

CPU #0: "11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz"
        Frequency: 1689.601
        Signature: 0x0806c1; Type 0, family 6, model 140, stepping 1
        Features: 0x1f8bfbff
                FPU, VME, DE, PSE, TSC, MSR, PAE, MCE, CX8, APIC, SEP, MTRR, PGE, MCA, CMOV, PAT
                PSE36, CFLUSH, MMX, FXSTR, SSE, SSE2, SS, HTT
        Extended Features (0x00000001): 0xfffa3203
                SSE3, PCLMULDQ, SSSE3, FMA, CX16, PCID, SSE4.1, SSE4.2, x2APIC, MOVEB, POPCNT, TSC-DEADLINE, AES, XSAVE, OSXSAVE, AVX
                F16C, RDRND, HYPERVISOR
        Extended Features (0x80000001): 0x2c100800
                SCE, NX, GBPAGES, RDTSCP, 64
        Extended Features (0x00000007): 0xf1bf27eb 0x18405fce 0xbc000510
                FSGSBASE, IA32_TSC_ADJUST, BMI1, AVX2, FDP_EXCPTN_ONLY, SMEP, BMI2, Enhanced REP MOVSB/STOSB, INVPCID, No FPU DS/CS, AVX512F, AVX512DQ, RDSEED, ADX, SMAP, AVX512_IFMA
                CLFLUSHOPT, CLWB, AVX512CD, SHA, AVX512BW, AVX512VL
                AVX512_VBMI, UMIP, PKU, AVX512_VBMI2, CET_SS, GFNI, VAES, VPCLMULQDQ, AVX512_VNNI, AVX512_BITALG, AVX512_VPOPCNTDQ, RDPID, MOVDIRI, MOVDIR64B
                Fast Short REP MOV, AVX512_VP2INTERSECT, MD_CLEAR, IBRS/IBPB, STIBP, L1D_FLUSH, IA32_ARCH_CAPABILITIES, SSBD

        L2 Data cache fully associative, 1 lines/tag, 64 bytes/line
        L2 cache: 256 KB, 8-way set associative, 0 lines/tag, 64 bytes/line

        Unknown cache descriptor 0xfe
        64-byte Prefetching

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is fine, you can ignore that test. Those tests are specifically publishing with explicit <IlcInstructionSet> option. The default is SSE4.2 which covers all x64 machines manufactured since 2008. We can set <IlcInstructionSet>native</IlcInstructionSet> in csproj if aim is to run app on the same machine.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems a bit suspicious though, since I ran this on a i7-1165G7, which should support AVX-512 according to Intel.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to GDB it is due to this returning 0:

uint32_t eax;
__asm(" xgetbv\n" \
: "=a"(eax) /*output in eax*/\
: "c"(0) /*inputs - 0 in ecx*/\
: "edx" /* registers that are clobbered*/
);
// check OS has enabled XMM, YMM and ZMM state support
return ((eax & 0xE6) == 0x0E6) ? 1 : 0;

So it's a Haiku issue, not an issue with this PR.

Comment thread src/coreclr/tools/Common/CommandLineHelpers.cs
Comment thread src/coreclr/tools/Common/CommandLineHelpers.cs Outdated
Copilot AI review requested due to automatic review settings April 26, 2026 09:04
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds initial Haiku enablement across the CoreCLR toolchain and build integration to allow NativeAOT and Crossgen2/ReadyToRun flows to recognize and target Haiku, including a new Haiku OS override constant (0x0B05) and Haiku-specific linker/system library handling.

Changes:

  • Enable Haiku for Crossgen2/NativeAOT in MSBuild subset gating and project configuration.
  • Extend target OS enumerations/switches (TargetOS, perfmap tokens, PE OS override) to include Haiku (0x0B05).
  • Add Haiku-specific NativeAOT cross-compilation triple and adjust Unix linker/system library flags.

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Runtime.CoreCLR.sfxproj Stops disabling R2R publish for Haiku in the runtime sfx packaging project.
src/coreclr/tools/r2rdump/Program.cs Updates OS mapping logic used for PDB/perfmap emission from R2R images.
src/coreclr/tools/aot/crossgen2/Crossgen2RootCommand.cs Adds haiku to --targetos help text for crossgen2.
src/coreclr/tools/aot/ILCompiler/ILCompilerRootCommand.cs Adds haiku to --targetos help text for ilc.
src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TrimmingDriver.cs Adds runtime OS detection for Haiku in trimming test harness defaults.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs Adds OperatingSystem.Haiku = 0x0B05 for R2R header parsing.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/TargetExtensions.cs Adds Haiku to PE OS override mapping for ReadyToRun object writer.
src/coreclr/tools/aot/ILCompiler.Diagnostics/ReadyToRunDiagnosticsConstants.cs Introduces a perfmap OS token for Haiku.
src/coreclr/tools/aot/ILCompiler.Diagnostics/PerfMapWriter.cs Maps TargetOS.Haiku to the new perfmap OS token.
src/coreclr/tools/Common/TypeSystem/Common/TargetDetails.cs Adds TargetOS.Haiku to the shared type system target OS enum.
src/coreclr/tools/Common/Compiler/ObjectWriter/PETargetExtensions.cs Adds Haiku to PE OS override mapping for the common object writer.
src/coreclr/tools/Common/CommandLineHelpers.cs Switches OS parsing to Enum.TryParse and adds Haiku OS detection.
src/coreclr/nativeaot/Runtime/unix/configure.cmake Adds CMake feature detection for pthread_key_create.
src/coreclr/nativeaot/Runtime/unix/config.h.in Adds HAVE_PTHREAD_KEY_CREATE define to generated config header.
src/coreclr/nativeaot/Runtime/unix/PalUnix.cpp Uses HAVE_PTHREAD_KEY_CREATE for thread shutdown registration path selection.
src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets Adds Haiku target triple and Haiku-specific system library/linker flag conditioning.
src/coreclr/inc/pedecoder.h Defines Haiku PE native OS override constant under __HAIKU__.
src/coreclr/crossgen-corelib.proj Stops disabling R2R crossgen for Haiku in corelib crossgen project.
eng/Subsets.props Enables NativeAOT supported-OS gating for Haiku.

Comment thread src/coreclr/tools/r2rdump/Program.cs Outdated
}

#if defined(TARGET_LINUX) || defined(TARGET_ANDROID)
#if HAVE_PTHREAD_KEY_CREATE
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is valid feedback. pthread_key_create is available on all Unixes, so this is effectively turning the more efficient path that uses thread_local into a dead code.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would defeat the entire purpose of the check wouldn't it?

I think the real discussion should be here, where I am suggesting a configure-time thread_local check instead.

#127431 (comment)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does not need to be a configure-time check. You can add a local define so that the full condition does not need to duplicated

#if defined(TARGET_LINUX) || defined(TARGET_ANDROID) || defined(TARGET_HAIKU)
// thread_local with a destructor brings in undesirable dependency on C++ runtime on some platforms.
// Switch to pthread_key_t on those platforms.
#define USE_PTHREAD_KEY 1
#endif

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue here was to prevent having to hard-code the list of OSes, not the duplication.

Guess I will revert the current changes and add that block.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All other pthread APIs are config driven in src/coreclr/nativeaot/Runtime/unix/config.h.in. osx-arm64 smoke tests are passing locally for me, not sure why we wana exclude them. I checked corert discussion when it was initially introduced and didn't find anything specific.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All other pthread APIs are config driven in src/coreclr/nativeaot/Runtime/unix/config.h.in

These other pthread APIs are not universally available.

pthread_key_create is universally available, so there is no point in checking for it.

pthread_key path is a fallback in this code. We want to use thread_local if possible.

Comment on lines +76 to +82
if (!Enum.TryParse<TargetOS>(token, ignoreCase: true, out TargetOS os))
{
"linux" => TargetOS.Linux,
"win" or "windows" => TargetOS.Windows,
"osx" => TargetOS.OSX,
"freebsd" => TargetOS.FreeBSD,
"maccatalyst" => TargetOS.MacCatalyst,
"iossimulator" => TargetOS.iOSSimulator,
"ios" => TargetOS.iOS,
"tvossimulator" => TargetOS.tvOSSimulator,
"tvos" => TargetOS.tvOS,
"browser" => TargetOS.Browser,
"wasi" => TargetOS.Wasi,
_ => throw new CommandLineException($"Target OS '{token}' is not supported")
};
if (token.ToLowerInvariant() == "win") return TargetOS.Windows;

throw new CommandLineException($"Target OS '{token}' is not supported");
}
return os;
Copilot AI review requested due to automatic review settings April 26, 2026 09:15
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds initial Haiku OS support for NativeAOT/Crossgen2 across the CoreCLR toolchain and build integration, enabling R2R/AOT flows to recognize Haiku targets and emit the correct OS override metadata.

Changes:

  • Enables Haiku in R2R/Crossgen2/ILCompiler target OS handling (enums, parsing, help text) and PE OS override constants.
  • Updates NativeAOT Unix build/link integration for Haiku (target triple + Haiku-specific system libs/linker args) and makes PAL TLS shutdown detection feature-probed.
  • Lifts existing build-time gating that previously disabled NativeAOT/Crossgen2 for Haiku.

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Runtime.CoreCLR.sfxproj Stops disabling PublishReadyToRun for Haiku (enables R2R in SFX packaging).
src/coreclr/tools/r2rdump/Program.cs Makes OS mapping more flexible (Apple special-case + enum parsing).
src/coreclr/tools/aot/crossgen2/Crossgen2RootCommand.cs Adds haiku to documented --targetos values.
src/coreclr/tools/aot/ILCompiler/ILCompilerRootCommand.cs Adds haiku to documented --targetos values.
src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TrimmingDriver.cs Detects Haiku at runtime to select TargetOS defaults for trimming tests.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs Introduces Haiku PE OS override token (0x0B05) in R2R reader enum.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/TargetExtensions.cs Adds Haiku to MachineOSOverride + TargetOS→override mapping for R2R writing.
src/coreclr/tools/aot/ILCompiler.Diagnostics/ReadyToRunDiagnosticsConstants.cs Adds Haiku to perfmap OS tokens.
src/coreclr/tools/aot/ILCompiler.Diagnostics/PerfMapWriter.cs Maps TargetOS.Haiku to perfmap constants.
src/coreclr/tools/Common/TypeSystem/Common/TargetDetails.cs Adds TargetOS.Haiku to the shared target OS enum.
src/coreclr/tools/Common/Compiler/ObjectWriter/PETargetExtensions.cs Adds Haiku to MachineOSOverride + TargetOS→override mapping for PE writing.
src/coreclr/tools/Common/CommandLineHelpers.cs Switches target OS parsing to enum parsing and adds Haiku runtime detection.
src/coreclr/nativeaot/Runtime/unix/configure.cmake Feature-probes for pthread_key_create availability.
src/coreclr/nativeaot/Runtime/unix/config.h.in Adds HAVE_PTHREAD_KEY_CREATE configuration define.
src/coreclr/nativeaot/Runtime/unix/PalUnix.cpp Uses HAVE_PTHREAD_KEY_CREATE to select TLS shutdown mechanism.
src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets Adds Haiku cross target triple and adjusts Haiku link libraries/flags.
src/coreclr/inc/pedecoder.h Defines Haiku PE native OS override constant under __HAIKU__.
src/coreclr/crossgen-corelib.proj Stops disabling PublishReadyToRun for Haiku (enables crossgen2 for corelib).
eng/Subsets.props Marks Haiku as supported for NativeAOT OS gating.

Comment on lines +76 to +82
if (!Enum.TryParse<TargetOS>(token, ignoreCase: true, out TargetOS os))
{
"linux" => TargetOS.Linux,
"win" or "windows" => TargetOS.Windows,
"osx" => TargetOS.OSX,
"freebsd" => TargetOS.FreeBSD,
"maccatalyst" => TargetOS.MacCatalyst,
"iossimulator" => TargetOS.iOSSimulator,
"ios" => TargetOS.iOS,
"tvossimulator" => TargetOS.tvOSSimulator,
"tvos" => TargetOS.tvOS,
"browser" => TargetOS.Browser,
"wasi" => TargetOS.Wasi,
_ => throw new CommandLineException($"Target OS '{token}' is not supported")
};
if (token.ToLowerInvariant() == "win") return TargetOS.Windows;

throw new CommandLineException($"Target OS '{token}' is not supported");
}
return os;
OperatingSystem.FreeBSD => TargetOS.FreeBSD,
OperatingSystem.NetBSD => TargetOS.FreeBSD,
_ => throw new NotImplementedException(r2r.OperatingSystem.ToString()),
_ when Enum.TryParse(osToken, ignoreCase: true, out TargetOS parsedOs) => parsedOs,
Add the required configuration to support NativeAOT and Crossgen2 for
Haiku targets.

This includes:
- Enabling NativeAOT and Crossgen2 for Haiku in MSBuild scripts,
- Adding "Haiku" to relevant enumerations and switch blocks,
- Defining correct linker flags for Haiku targets,
- Adding `0x0B05` as the PE native image type constant for Haiku
  - This is a reference to Haiku's origins as "**O**pen**B**e**OS**".
- Ensuring that .NET's `llvm-libunwind` works correctly on Haiku.
  - `llvm-libunwind` needs to pull in `libbsd` for `dl_iterate_phdr`.
  Otherwise, basic functionality will not work.
Use `Enum` parsing instead of `switch` statements to avoid having to
manually add new OSes in the future.

This also fixes a typo where NetBSD is mapped to FreeBSD.
Check for `pthread_key_create` and prioritize using that to detect the
end of thread lifetimes.

This removes a dependency on `libstdc++` for UNIX platforms.
Copilot AI review requested due to automatic review settings April 26, 2026 12:38
@trungnt2910 trungnt2910 force-pushed the dev/trungnt2910/haiku-nativeaot branch from f46311d to ea0ecb3 Compare April 26, 2026 12:38
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds initial Haiku target enablement across the NativeAOT/Crossgen2 toolchain and related build infrastructure, including wiring Haiku through target OS enums and PE/R2R OS override constants.

Changes:

  • Enable Crossgen2/ReadyToRun publishing for Haiku in installer/coreclr build projects and in tool help/OS parsing paths.
  • Add Haiku to target OS enumerations and OS-override constants (including 0x0B05) used by R2R/PE writers and diagnostics (perfmap).
  • Adjust NativeAOT Unix build integration for Haiku (target triple, system libs, and TLS/thread-shutdown detection via pthread_key_create probing).

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Runtime.CoreCLR.sfxproj Enables ReadyToRun publishing for Haiku by removing it from the disabled OS list.
src/coreclr/tools/r2rdump/Program.cs Makes OS mapping more flexible via Enum.TryParse, with explicit Apple→OSX mapping.
src/coreclr/tools/aot/crossgen2/Crossgen2RootCommand.cs Adds haiku to --targetos help text list.
src/coreclr/tools/aot/ILCompiler/ILCompilerRootCommand.cs Adds haiku to --targetos help text list.
src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TrimmingDriver.cs Detects Haiku at runtime for trimming test defaults.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs Adds Haiku OS override constant (0x0B05) to R2R reader OS enum.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/TargetExtensions.cs Adds Haiku to machine OS override emission for R2R object writing.
src/coreclr/tools/aot/ILCompiler.Diagnostics/ReadyToRunDiagnosticsConstants.cs Adds Haiku token to perfmap OS token enum.
src/coreclr/tools/aot/ILCompiler.Diagnostics/PerfMapWriter.cs Maps TargetOS.Haiku to the new perfmap OS token.
src/coreclr/tools/Common/TypeSystem/Common/TargetDetails.cs Adds TargetOS.Haiku to the shared target OS enum.
src/coreclr/tools/Common/Compiler/ObjectWriter/PETargetExtensions.cs Adds Haiku to machine OS override emission for PE object writing.
src/coreclr/tools/Common/CommandLineHelpers.cs Updates --targetos parsing to use Enum.TryParse and adds runtime Haiku detection.
src/coreclr/nativeaot/Runtime/unix/configure.cmake Probes for pthread_key_create availability.
src/coreclr/nativeaot/Runtime/unix/config.h.in Adds HAVE_PTHREAD_KEY_CREATE configuration define.
src/coreclr/nativeaot/Runtime/unix/PalUnix.cpp Uses HAVE_PTHREAD_KEY_CREATE to select pthread TLS key vs thread-local destruction monitoring.
src/coreclr/nativeaot/Runtime/CMakeLists.txt Adds Haiku-specific libunwind configuration define.
src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets Adds Haiku target triple and Haiku-specific link/system-library adjustments.
src/coreclr/inc/pedecoder.h Defines Haiku IMAGE_FILE_MACHINE_NATIVE_OS_OVERRIDE constant (0x0B05).
src/coreclr/crossgen-corelib.proj Enables ReadyToRun publishing for Haiku by removing it from the disabled OS list.
eng/Subsets.props Marks Haiku as a supported OS for NativeAOT subset gating.

"browser" => TargetOS.Browser,
"wasi" => TargetOS.Wasi,
"win" => TargetOS.Windows,
_ when Enum.TryParse(token, ignoreCase: true, out TargetOS os) => os,
<LinkerArg Include="-pie -Wl,-pie" Condition="'$(_IsApplePlatform)' != 'true' and '$(NativeLib)' == '' and '$(StaticExecutable)' != 'true' and '$(PositionIndependentExecutable)' != 'false'" />
<LinkerArg Include="-Wl,-no-pie" Condition="'$(_IsApplePlatform)' != 'true' and '$(NativeLib)' == '' and '$(StaticExecutable)' != 'true' and '$(PositionIndependentExecutable)' == 'false'" />
<LinkerArg Include="-pie -Wl,-pie" Condition="'$(_IsApplePlatform)' != 'true' and '$(_targetOS)' != 'haiku' and '$(NativeLib)' == '' and '$(StaticExecutable)' != 'true' and '$(PositionIndependentExecutable)' != 'false'" />
<LinkerArg Include="-Wl,-no-pie" Condition="'$(_IsApplePlatform)' != 'true' and '$(_targetOS)' != 'haiku' and '$(NativeLib)' == '' and '$(StaticExecutable)' != 'true' and '$(PositionIndependentExecutable)' == 'false'" />
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to yesterday's patch https://github.com/dotnet/runtime/pull/127392/changes#diff-0ed6f3997357a6ff6652a7509482b05370b67e8e3041eecfd89f9556e7b59313R495 -pie should work on Haiku, -fPIE was supposed to be replaced with -fPIC for executables.

So should this be in sync with what was done in #127392 ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am pretty sure -pic is a no-op in Haiku since any binary (including executables) can be loaded at any address.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Therefore, replacing -fPIE with -fPIC (or passing -fPIC at all) on Haiku is redundant. If synchronization between this and #127392 is mandatory, I believe we should change the other file to not pass anything for Haiku targets instead.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, I think @jkotas point is to keep them in sync so it can be reasoned about. If it works without those flags, then omitting on both sides sounds good. We can validate build.sh clr+libs --os haiku --cross --bootstrap with and without -gcc (it publishes crossgen2/ilc and other stuff which you can copy to vm and run --help as before to make sure binaries are executing).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See: #127443.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, with the argument, it works without -gcc.

With -gcc, it fails before even calling the linker:

gcc-13 : error : unrecognized command-line option ‘--target=x86_64-unknown-haiku’ [/home/trung/dotnet-runtime/src/coreclr/tools/aot/ILCompiler/ILCompiler_publish.csproj]
/home/trung/dotnet-runtime/artifacts/bin/coreclr/haiku.x64.Debug/build/Microsoft.NETCore.Native.targets(370,5): error MSB3073: The command ""/usr/bin/gcc-13" "/home/trung/dotnet-runtime/artifacts/obj/coreclr/ILCompiler_publish/haiku.x64.Debug/native/ilc.o" -o "/home/trung/dotnet-runtime/artifacts/bin/ILCompiler_publish/x64/Debug/native/ilc" -Wl,--version-script="/home/trung/dotnet-runtime/artifacts/obj/coreclr/ILCompiler_publish/haiku.x64.Debug/native/ilc.exports" -Wl,--export-dynamic -gz=zlib /home/trung/dotnet-runtime/artifacts/bootstrap/haiku-x64/microsoft.netcore.app/lib/runtimes/haiku-x64/native/libSystem.Native.a /home/trung/dotnet-runtime/artifacts/bootstrap/haiku-x64/microsoft.netcore.app/lib/runtimes/haiku-x64/native/libSystem.IO.Compression.Native.a /home/trung/dotnet-runtime/artifacts/bootstrap/haiku-x64/microsoft.netcore.app/lib/runtimes/haiku-x64/native/libSystem.Net.Security.Native.a /home/trung/dotnet-runtime/artifacts/bootstrap/haiku-x64/microsoft.netcore.app/lib/runtimes/haiku-x64/native/libSystem.Security.Cryptography.Native.OpenSsl.a /home/trung/dotnet-runtime/artifacts/bootstrap/haiku-x64/aotsdk/libbootstrapper.o /home/trung/dotnet-runtime/artifacts/bootstrap/haiku-x64/aotsdk/libRuntime.ServerGC.a /home/trung/dotnet-runtime/artifacts/bootstrap/haiku-x64/aotsdk/libeventpipe-enabled.a /home/trung/dotnet-runtime/artifacts/bootstrap/haiku-x64/aotsdk/libRuntime.VxsortEnabled.a /home/trung/dotnet-runtime/artifacts/bootstrap/haiku-x64/aotsdk/libstandalonegc-disabled.a /home/trung/dotnet-runtime/artifacts/bootstrap/haiku-x64/aotsdk/libaotminipal.a /home/trung/dotnet-runtime/artifacts/bootstrap/haiku-x64/aotsdk/libstdc++compat.a /home/trung/dotnet-runtime/artifacts/bootstrap/haiku-x64/microsoft.netcore.app/lib/runtimes/haiku-x64/native/libz.a /home/trung/dotnet-runtime/artifacts/bootstrap/haiku-x64/microsoft.netcore.app/lib/runtimes/haiku-x64/native/libbrotlienc.a /home/trung/dotnet-runtime/artifacts/bootstrap/haiku-x64/microsoft.netcore.app/lib/runtimes/haiku-x64/native/libbrotlidec.a /home/trung/dotnet-runtime/artifacts/bootstrap/haiku-x64/microsoft.netcore.app/lib/runtimes/haiku-x64/native/libbrotlicommon.a /home/trung/dotnet-runtime/artifacts/bootstrap/haiku-x64/microsoft.netcore.app/lib/runtimes/haiku-x64/native/libzstd.a --sysroot="/home/trung/dotnet-rootfs" --target=x86_64-unknown-haiku -g -Wl,--build-id=sha1 -Wl,--as-needed -lm -lbsd -lnetwork -Wl,-z,relro -Wl,-z,now -Wl,--eh-frame-hdr -Wl,--discard-all -Wl,--gc-sections" exited with code 1. [/home/trung/dotnet-runtime/src/coreclr/tools/aot/ILCompiler/ILCompiler_publish.csproj]

Build FAILED.

gcc-13 : error : unrecognized command-line option ‘--target=x86_64-unknown-haiku’ [/home/trung/dotnet-runtime/src/coreclr/tools/aot/ILCompiler/ILCompiler_publish.csproj]
/home/trung/dotnet-runtime/artifacts/bin/coreclr/haiku.x64.Debug/build/Microsoft.NETCore.Native.targets(370,5): error MSB3073: The command ""/usr/bin/gcc-13" "/home/trung/dotnet-runtime/artifacts/obj/coreclr/ILCompiler_publish/haiku.x64.Debug/native/ilc.o" -o "/home/trung/dotnet-runtime/artifacts/bin/ILCompiler_publish/x64/Debug/native/ilc" -Wl,--version-script="/home/trung/dotnet-runtime/artifacts/obj/coreclr/ILCompiler_publish/haiku.x64.Debug/native/ilc.exports" -Wl,--export-dynamic -gz=zlib /home/trung/dotnet-runtime/artifacts/bootstrap/haiku-x64/microsoft.netcore.app/lib/runtimes/haiku-x64/native/libSystem.Native.a /home/trung/dotnet-runtime/artifacts/bootstrap/haiku-x64/microsoft.netcore.app/lib/runtimes/haiku-x64/native/libSystem.IO.Compression.Native.a /home/trung/dotnet-runtime/artifacts/bootstrap/haiku-x64/microsoft.netcore.app/lib/runtimes/haiku-x64/native/libSystem.Net.Security.Native.a /home/trung/dotnet-runtime/artifacts/bootstrap/haiku-x64/microsoft.netcore.app/lib/runtimes/haiku-x64/native/libSystem.Security.Cryptography.Native.OpenSsl.a /home/trung/dotnet-runtime/artifacts/bootstrap/haiku-x64/aotsdk/libbootstrapper.o /home/trung/dotnet-runtime/artifacts/bootstrap/haiku-x64/aotsdk/libRuntime.ServerGC.a /home/trung/dotnet-runtime/artifacts/bootstrap/haiku-x64/aotsdk/libeventpipe-enabled.a /home/trung/dotnet-runtime/artifacts/bootstrap/haiku-x64/aotsdk/libRuntime.VxsortEnabled.a /home/trung/dotnet-runtime/artifacts/bootstrap/haiku-x64/aotsdk/libstandalonegc-disabled.a /home/trung/dotnet-runtime/artifacts/bootstrap/haiku-x64/aotsdk/libaotminipal.a /home/trung/dotnet-runtime/artifacts/bootstrap/haiku-x64/aotsdk/libstdc++compat.a /home/trung/dotnet-runtime/artifacts/bootstrap/haiku-x64/microsoft.netcore.app/lib/runtimes/haiku-x64/native/libz.a /home/trung/dotnet-runtime/artifacts/bootstrap/haiku-x64/microsoft.netcore.app/lib/runtimes/haiku-x64/native/libbrotlienc.a /home/trung/dotnet-runtime/artifacts/bootstrap/haiku-x64/microsoft.netcore.app/lib/runtimes/haiku-x64/native/libbrotlidec.a /home/trung/dotnet-runtime/artifacts/bootstrap/haiku-x64/microsoft.netcore.app/lib/runtimes/haiku-x64/native/libbrotlicommon.a /home/trung/dotnet-runtime/artifacts/bootstrap/haiku-x64/microsoft.netcore.app/lib/runtimes/haiku-x64/native/libzstd.a --sysroot="/home/trung/dotnet-rootfs" --target=x86_64-unknown-haiku -g -Wl,--build-id=sha1 -Wl,--as-needed -lm -lbsd -lnetwork -Wl,-z,relro -Wl,-z,now -Wl,--eh-frame-hdr -Wl,--discard-all -Wl,--gc-sections" exited with code 1. [/home/trung/dotnet-runtime/src/coreclr/tools/aot/ILCompiler/ILCompiler_publish.csproj]
    0 Warning(s)
    2 Error(s)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-crossgen2-coreclr community-contribution Indicates that the PR has been added by a community member os-haiku

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants