Skip to content

Commit f478cfe

Browse files
ayakaelakoeplinger
andauthored
Mono musl support (#76500)
Co-authored-by: Alexander Köplinger <[email protected]> Fixes #76805
1 parent 1022253 commit f478cfe

File tree

11 files changed

+114
-17
lines changed

11 files changed

+114
-17
lines changed

Directory.Build.props

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@
166166
<_runtimeOS Condition="'$(TargetsMobile)' == 'true'">$(TargetOS.ToLowerInvariant())</_runtimeOS>
167167

168168
<_portableOS>linux</_portableOS>
169-
<_portableOS Condition="'$(_runtimeOS)' == 'linux-musl'">linux-musl</_portableOS>
169+
<_portableOS Condition="'$(_runtimeOS)' == 'linux-musl' or $(_runtimeOS.StartsWith('alpine'))">linux-musl</_portableOS>
170170
<_portableOS Condition="'$(_runtimeOS)' == 'linux-bionic'">linux-bionic</_portableOS>
171171
<_portableOS Condition="'$(_hostOS)' == 'osx'">osx</_portableOS>
172172
<_portableOS Condition="'$(_runtimeOS)' == 'win' or '$(TargetOS)' == 'windows'">win</_portableOS>
@@ -219,6 +219,7 @@
219219
<OutputRid Condition="'$(OutputRid)' == ''">$(PackageRID)</OutputRid>
220220
<OutputRid Condition="'$(PortableBuild)' == 'true'">$(_portableOS)-$(TargetArchitecture)</OutputRid>
221221
<TargetsLinuxBionic Condition="$(OutputRid.StartsWith('linux-bionic'))">true</TargetsLinuxBionic>
222+
<TargetsLinuxMusl Condition="'$(_portableOS)' == 'linux-musl'">true</TargetsLinuxMusl>
222223
</PropertyGroup>
223224

224225
<PropertyGroup Label="CalculateTargetOSName" Condition="'$(SkipInferTargetOSName)' != 'true'">

eng/native/tryrun.cmake

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ endmacro()
88

99
if(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/armv7-alpine-linux-musleabihf OR
1010
EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/armv6-alpine-linux-musleabihf OR
11-
EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/aarch64-alpine-linux-musl)
11+
EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/aarch64-alpine-linux-musl OR
12+
EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/s390x-alpine-linux-musl OR
13+
EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/ppc64le-alpine-linux-musl OR
14+
EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/i586-alpine-linux-musl OR
15+
EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/riscv64-alpine-linux-musl)
1216

1317
set(ALPINE_LINUX 1)
1418
elseif(EXISTS ${CROSS_ROOTFS}/bin/freebsd-version)

src/coreclr/pal/src/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,11 @@ if(CLR_CMAKE_TARGET_LINUX)
315315
target_link_libraries(coreclrpal ${UNWIND_LIBS})
316316
endif(CLR_CMAKE_USE_SYSTEM_LIBUNWIND)
317317

318+
# bundled libunwind requires using libucontext on alpine and x86 and ppc64le
319+
if(CLR_CMAKE_TARGET_ALPINE_LINUX AND (CLR_CMAKE_TARGET_ARCH_I386 OR CLR_CMAKE_TARGET_ARCH_POWERPC64))
320+
target_link_libraries(coreclrpal ucontext)
321+
endif(CLR_CMAKE_TARGET_ALPINE_LINUX AND (CLR_CMAKE_TARGET_ARCH_I386 OR CLR_CMAKE_TARGET_ARCH_POWERPC64))
322+
318323
endif(CLR_CMAKE_TARGET_LINUX)
319324

320325
if(CLR_CMAKE_TARGET_NETBSD)

src/coreclr/pal/src/misc/perfjitdump.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#include <sys/uio.h>
2626
#include <time.h>
2727
#include <unistd.h>
28-
#include <linux/limits.h>
28+
#include <limits.h>
2929

3030
#include "../inc/llvm/ELF.h"
3131

src/coreclr/vm/i386/cgenx86.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,6 +1133,7 @@ extern "C" DWORD __stdcall avx512StateSupport()
11331133

11341134
#else // !TARGET_UNIX
11351135

1136+
#if !__has_builtin(__cpuid)
11361137
void __cpuid(int cpuInfo[4], int function_id)
11371138
{
11381139
// Based on the Clang implementation provided in cpuid.h:
@@ -1143,7 +1144,9 @@ void __cpuid(int cpuInfo[4], int function_id)
11431144
: "0"(function_id)
11441145
);
11451146
}
1147+
#endif
11461148

1149+
#if !__has_builtin(__cpuidex)
11471150
void __cpuidex(int cpuInfo[4], int function_id, int subFunction_id)
11481151
{
11491152
// Based on the Clang implementation provided in cpuid.h:
@@ -1154,6 +1157,7 @@ void __cpuidex(int cpuInfo[4], int function_id, int subFunction_id)
11541157
: "0"(function_id), "2"(subFunction_id)
11551158
);
11561159
}
1160+
#endif
11571161

11581162
extern "C" DWORD __stdcall xmmYmmStateSupport()
11591163
{

src/mono/CMakeLists.txt

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,36 @@ elseif(CLR_CMAKE_HOST_OS STREQUAL "linux")
212212
# Enable the "full RELRO" options (RELRO & BIND_NOW) at link time
213213
add_link_options(-Wl,-z,relro)
214214
add_link_options(-Wl,-z,now)
215+
216+
# Detect Linux ID
217+
# TODO: Eventually merge with eng/native/configureplatform.cmake
218+
set(LINUX_ID_FILE "/etc/os-release")
219+
if(CMAKE_CROSSCOMPILING)
220+
set(LINUX_ID_FILE "${CMAKE_SYSROOT}${LINUX_ID_FILE}")
221+
endif()
222+
223+
if(EXISTS ${LINUX_ID_FILE})
224+
execute_process(
225+
COMMAND bash -c "source ${LINUX_ID_FILE} && echo \$ID"
226+
OUTPUT_VARIABLE CLR_CMAKE_LINUX_ID
227+
OUTPUT_STRIP_TRAILING_WHITESPACE)
228+
229+
execute_process(
230+
COMMAND bash -c "if strings \"${CMAKE_SYSROOT}/usr/bin/ldd\" 2>&1 | grep -q musl; then echo musl; fi"
231+
OUTPUT_VARIABLE CLR_CMAKE_LINUX_MUSL
232+
OUTPUT_STRIP_TRAILING_WHITESPACE)
233+
endif()
234+
235+
if(DEFINED CLR_CMAKE_LINUX_ID)
236+
if(CLR_CMAKE_LINUX_ID STREQUAL alpine)
237+
set(CLR_CMAKE_HOST_ALPINE_LINUX 1)
238+
set(CLR_CMAKE_HOST_OS ${CLR_CMAKE_LINUX_ID})
239+
endif()
240+
241+
if(CLR_CMAKE_LINUX_MUSL STREQUAL musl)
242+
set(CLR_CMAKE_HOST_LINUX_MUSL 1)
243+
endif()
244+
endif(DEFINED CLR_CMAKE_LINUX_ID)
215245
elseif(CLR_CMAKE_HOST_OS STREQUAL "android")
216246
set(HOST_LINUX 1)
217247
add_definitions(-D_GNU_SOURCE -D_REENTRANT)
@@ -309,7 +339,7 @@ elseif(TARGET_SYSTEM_NAME STREQUAL "ios" OR TARGET_SYSTEM_NAME STREQUAL "tvos")
309339
set(TARGET_TVOS 1)
310340
endif()
311341
set(TARGET_APPLE_MOBILE 1)
312-
elseif(TARGET_SYSTEM_NAME STREQUAL "linux")
342+
elseif(TARGET_SYSTEM_NAME STREQUAL "linux" OR TARGET_SYSTEM_NAME STREQUAL "alpine")
313343
set(TARGET_LINUX 1)
314344
elseif(TARGET_SYSTEM_NAME STREQUAL "android")
315345
set(TARGET_ANDROID 1)
@@ -592,10 +622,10 @@ if(LLVM_PREFIX)
592622
set(llvm_cxxflags "-I${LLVM_PREFIX}/include -std=c++14 -fno-exceptions -fno-rtti -D__STDC_CONSTANT_MACROS -D__STD_FORMAT_MACROS -D__STDC_LIMIT_MACROS")
593623
set(llvm_includedir "${LLVM_PREFIX}/include")
594624

595-
if(CLR_CMAKE_HOST_OS STREQUAL "linux")
625+
if(HOST_LINUX)
596626
# llvm-config --system-libs
597627
set(llvm_system_libs "-lz" "-lrt" "-ldl" "-lpthread" "-lm")
598-
elseif(CLR_CMAKE_HOST_OS STREQUAL "darwin")
628+
elseif(HOST_OSX)
599629
# llvm-config --system-libs
600630
set(llvm_system_libs "-lz" "-lm")
601631
endif()
@@ -876,6 +906,12 @@ if(HOST_IOS OR HOST_ANDROID OR HOST_MACCAT)
876906
else()
877907
set(DISABLE_DLLMAP 1)
878908
endif()
909+
910+
if(CLR_CMAKE_HOST_ALPINE_LINUX)
911+
# On Alpine Linux, we need to ensure that the reported stack range for the primary thread is
912+
# larger than the initial committed stack size.
913+
add_definitions(-DENSURE_PRIMARY_STACK_SIZE)
914+
endif()
879915
### End of OS specific checks
880916

881917
include_directories("${CLR_SRC_NATIVE_DIR}")

src/mono/mono.proj

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -633,19 +633,21 @@
633633
<MonoToolchainPrebuiltOS Condition="$([MSBuild]::IsOSPlatform('OSX'))">darwin-x86_64</MonoToolchainPrebuiltOS>
634634
<MonoToolchainPrebuiltOS Condition="'$(HostOS)' == 'windows'">windows-x86_64</MonoToolchainPrebuiltOS>
635635
<_MonoRuntimeFilePath>$(MonoObjDir)out\lib\$(MonoFileName)</_MonoRuntimeFilePath>
636-
<_LinuxAbi Condition="'$(TargetsAndroid)' != 'true' and '$(TargetsLinuxBionic)' != 'true'">gnu</_LinuxAbi>
637-
<_LinuxAbi Condition="'$(TargetsAndroid)' == 'true' or '$(TargetsLinuxBionic)' == 'true'">android</_LinuxAbi>
636+
<_LinuxAbi Condition="'$(TargetsAndroid)' != 'true' and '$(TargetsLinuxBionic)' != 'true' and '$(TargetsLinuxMusl)' != 'true'">linux-gnu</_LinuxAbi>
637+
<_LinuxAbi Condition="'$(TargetsAndroid)' != 'true' and '$(TargetsLinuxBionic)' != 'true' and '$(TargetsLinuxMusl)' == 'true'">alpine-linux-musl</_LinuxAbi>
638+
<_LinuxAbi Condition="'$(TargetsAndroid)' == 'true' or '$(TargetsLinuxBionic)' == 'true'">linux-android</_LinuxAbi>
638639
<_LinuxFloatAbi Condition="'$(TargetsAndroid)' != 'true' and '$(TargetsLinuxBionic)' != 'true'">hf</_LinuxFloatAbi>
639640
<_Objcopy>objcopy</_Objcopy>
640-
<_Objcopy Condition="'$(Platform)' == 'arm'">arm-linux-$(_LinuxAbi)eabi$(_LinuxFloatAbi)-$(_Objcopy)</_Objcopy>
641-
<_Objcopy Condition="'$(Platform)' == 'armv6'">arm-linux-$(_LinuxAbi)eabi$(_LinuxFloatAbi)-$(_Objcopy)</_Objcopy>
642-
<_Objcopy Condition="'$(Platform)' == 'arm64'">aarch64-linux-$(_LinuxAbi)-$(_Objcopy)</_Objcopy>
643-
<_Objcopy Condition="'$(Platform)' == 'riscv64'">riscv64-linux-$(_LinuxAbi)-$(_Objcopy)</_Objcopy>
644-
<_Objcopy Condition="'$(Platform)' == 's390x'">s390x-linux-$(_LinuxAbi)-$(_Objcopy)</_Objcopy>
645-
<_Objcopy Condition="'$(Platform)' == 'ppc64le'">powerpc64le-linux-$(_LinuxAbi)-$(_Objcopy)</_Objcopy>
646-
<_Objcopy Condition="'$(Platform)' == 'x64'">x86_64-linux-$(_LinuxAbi)-$(_Objcopy)</_Objcopy>
647-
<_Objcopy Condition="'$(Platform)' == 'x86'">i686-linux-$(_LinuxAbi)-$(_Objcopy)</_Objcopy>
641+
<_Objcopy Condition="'$(Platform)' == 'arm'">arm-$(_LinuxAbi)eabi$(_LinuxFloatAbi)-$(_Objcopy)</_Objcopy>
642+
<_Objcopy Condition="'$(Platform)' == 'armv6'">arm-$(_LinuxAbi)eabi$(_LinuxFloatAbi)-$(_Objcopy)</_Objcopy>
643+
<_Objcopy Condition="'$(Platform)' == 'arm64'">aarch64-$(_LinuxAbi)-$(_Objcopy)</_Objcopy>
644+
<_Objcopy Condition="'$(Platform)' == 'riscv64'">riscv64-$(_LinuxAbi)-$(_Objcopy)</_Objcopy>
645+
<_Objcopy Condition="'$(Platform)' == 's390x'">s390x-$(_LinuxAbi)-$(_Objcopy)</_Objcopy>
646+
<_Objcopy Condition="'$(Platform)' == 'ppc64le'">powerpc64le-$(_LinuxAbi)-$(_Objcopy)</_Objcopy>
647+
<_Objcopy Condition="'$(Platform)' == 'x64'">x86_64-$(_LinuxAbi)-$(_Objcopy)</_Objcopy>
648+
<_Objcopy Condition="'$(Platform)' == 'x86'">i686-$(_LinuxAbi)-$(_Objcopy)</_Objcopy>
648649
<_Objcopy Condition="'$(TargetsAndroid)' == 'true' or '$(TargetsLinuxBionic)' == 'true'">$(ANDROID_NDK_ROOT)/toolchains/llvm/prebuilt/$(MonoToolchainPrebuiltOS)/bin/llvm-objcopy</_Objcopy>
650+
<_Objcopy Condition="'$(TargetsLinuxMusl)' == 'true' and '$(CrossBuild)' != 'true'">objcopy</_Objcopy>
649651

650652
<_ObjcopyPrefix Condition="'$(MonoCrossDir)' != '' and '$(Platform)' == 'riscv64'">llvm-objcopy-</_ObjcopyPrefix>
651653
</PropertyGroup>

src/mono/mono/mini/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,10 @@ if(NOT DISABLE_SHARED_LIBS)
373373
target_compile_definitions(monosgen-objects PRIVATE -DMONO_DLL_EXPORT)
374374
endif()
375375
target_sources(monosgen-shared PRIVATE $<TARGET_OBJECTS:eglib_objects>)
376+
# Alpine Linux implements ucontext in a different library
377+
if(CLR_CMAKE_HOST_ALPINE_LINUX AND TARGET_S390X)
378+
target_link_libraries(monosgen-shared PRIVATE ucontext)
379+
endif(CLR_CMAKE_HOST_ALPINE_LINUX AND TARGET_S390X)
376380
set_target_properties(monosgen-shared PROPERTIES OUTPUT_NAME ${MONO_SHARED_LIB_NAME})
377381
target_link_libraries (monosgen-shared PRIVATE monoapi)
378382
target_include_directories (monosgen-shared PRIVATE monoapi)
@@ -534,6 +538,10 @@ if(NOT DISABLE_EXECUTABLES)
534538
set_target_properties(mono-sgen PROPERTIES OUTPUT_NAME mono-aot-cross)
535539
endif()
536540
target_link_libraries(mono-sgen PRIVATE monoapi monosgen-static ${OS_LIBS} ${LLVM_LIBS} ${ICU_LIBS} ${Z_LIBS})
541+
# Alpine Linux implements ucontext in a different library
542+
if(CLR_CMAKE_HOST_ALPINE_LINUX AND TARGET_S390X)
543+
target_link_libraries(mono-sgen PRIVATE ucontext)
544+
endif(CLR_CMAKE_HOST_ALPINE_LINUX AND TARGET_S390X)
537545
if(NOT DISABLE_COMPONENTS AND STATIC_COMPONENTS AND NOT DISABLE_LINK_STATIC_COMPONENTS)
538546
# if components are built statically, link them into runtime.
539547
target_sources(mono-sgen PRIVATE "${mono-components-objects}")

src/mono/mono/mini/mini-runtime.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4393,6 +4393,30 @@ mini_llvm_init (void)
43934393
#endif
43944394
}
43954395

4396+
#ifdef ENSURE_PRIMARY_STACK_SIZE
4397+
/*++
4398+
Function:
4399+
EnsureStackSize
4400+
4401+
Abstract:
4402+
This fixes a problem on MUSL where the initial stack size reported by the
4403+
pthread_attr_getstack is about 128kB, but this limit is not fixed and
4404+
the stack can grow dynamically. The problem is that it makes the
4405+
functions ReflectionInvocation::[Try]EnsureSufficientExecutionStack
4406+
to fail for real life scenarios like e.g. compilation of corefx.
4407+
Since there is no real fixed limit for the stack, the code below
4408+
ensures moving the stack limit to a value that makes reasonable
4409+
real life scenarios work.
4410+
4411+
--*/
4412+
static MONO_NO_OPTIMIZATION MONO_NEVER_INLINE void
4413+
ensure_stack_size (size_t size)
4414+
{
4415+
volatile uint8_t *s = (uint8_t *)g_alloca(size);
4416+
*s = 0;
4417+
}
4418+
#endif // ENSURE_PRIMARY_STACK_SIZE
4419+
43964420
void
43974421
mini_add_profiler_argument (const char *desc)
43984422
{
@@ -4554,6 +4578,11 @@ mini_init (const char *filename)
45544578
mono_w32handle_init ();
45554579
#endif
45564580

4581+
#ifdef ENSURE_PRIMARY_STACK_SIZE
4582+
// TODO: https://github.com/dotnet/runtime/issues/72920
4583+
ensure_stack_size (5 * 1024 * 1024);
4584+
#endif // ENSURE_PRIMARY_STACK_SIZE
4585+
45574586
mono_thread_info_runtime_init (&ticallbacks);
45584587

45594588
if (g_hasenv ("MONO_DEBUG")) {

src/mono/mono/utils/mono-context.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@
1111
#ifndef __MONO_MONO_CONTEXT_H__
1212
#define __MONO_MONO_CONTEXT_H__
1313

14+
/*
15+
* Handle non-gnu libc versions with nothing in features.h
16+
* We have no idea what they're compatible with, so always fail.
17+
*/
18+
#ifndef __GLIBC_PREREQ
19+
# define __GLIBC_PREREQ(x,y) 0
20+
#endif
21+
1422
#include "mono-compiler.h"
1523
#include "mono-sigcontext.h"
1624
#include "mono-machine.h"

0 commit comments

Comments
 (0)