Skip to content

Commit 658d777

Browse files
dicejyowl
andauthored
tweaks to enable NativeAOT-LLVM on Linux with WASI-SDK 22 (#2592)
* tweaks to enable NativeAOT-LLVM on Linux with WASI-SDK 22 Some of these changes are borrowed from #2569. Note that I had to manually copy pthread.h from the wasi-sdk-22/share/wasi-sysroot/include/wasm32-wasi-threads directory to the wasi-sdk-22/share/wasi-sysroot/include/wasm32-wasi directory as a workaround until WebAssembly/wasi-libc#501 is addressed. Signed-off-by: Joel Dice <[email protected]> * Restrict WASI SDK version check to WASI target Co-authored-by: yowl <[email protected]> --------- Signed-off-by: Joel Dice <[email protected]> Co-authored-by: yowl <[email protected]>
1 parent 838fd44 commit 658d777

File tree

15 files changed

+54
-30
lines changed

15 files changed

+54
-30
lines changed

docs/workflow/building/coreclr/nativeaot.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ The Native AOT toolchain can be currently built for Linux (x64/arm64), macOS (x6
2424
There are two kinds of binary artifacts produced by the build and needed for development: the runtime libraries and the cross-targeting compilers, ILC and RyuJit. They are built differently and separately.
2525

2626
For the runtime libraries:
27-
- Clone the [emsdk](https://github.com/emscripten-core/emsdk) repository and use the `emsdk.bat` script it comes with to [install](https://emscripten.org/docs/getting_started/downloads.html) (and optionally "activate", i. e. set the relevant environment variables permanently) the Emscripten SDK, which will be used by the native build as a sort of "virtualized" build environment. It is recommended to use the same Emscripten version that [the CI](https://github.com/dotnet/runtimelab/blob/feature/NativeAOT-LLVM/eng/pipelines/runtimelab/install-emscripten.ps1#L16-L20) uses.
27+
- To build for web browsers, clone the [emsdk](https://github.com/emscripten-core/emsdk) repository and use the `emsdk.bat` script it comes with to [install](https://emscripten.org/docs/getting_started/downloads.html) (and optionally "activate", i. e. set the relevant environment variables permanently) the Emscripten SDK, which will be used by the native build as a sort of "virtualized" build environment. It is recommended to use the same Emscripten version that [the CI](https://github.com/dotnet/runtimelab/blob/feature/NativeAOT-LLVM/eng/pipelines/runtimelab/install-emscripten.ps1#L16-L20) uses.
2828
```
2929
git clone https://github.com/emscripten-core/emsdk
3030
cd emsdk
@@ -34,7 +34,7 @@ For the runtime libraries:
3434
./emsdk install 3.1.47
3535
./emsdk activate 3.1.47
3636
```
37-
- To build for WASI, download and install the Wasi SDK from https://github.com/WebAssembly/wasi-sdk/releases (only Windows is supported currently) and set the `WASI_SDK_PATH` environment variable to the location where it is installed, e.g. `set WASI_SDK_PATH=c:\github\wasi-sdk`.
37+
- To build for WASI, download and install WASI-SDK 22 from https://github.com/WebAssembly/wasi-sdk/releases (only Windows and Linux are supported currently) and set the `WASI_SDK_PATH` environment variable to the location where it is installed, e.g. `set WASI_SDK_PATH=c:\github\wasi-sdk`. Note that WASI-SDK 22 only includes a copy of `pthread.h` for the `wasm32-wasi-threads` target, which we must copy to the include directory for the `wasm32-wasi` target, e.g. `cp $WASI_SDK\share\wasi-sysroot\include\wasm32-wasi-threads\pthread.h $WASI_SDK\share\wasi-sysroot\include\wasm32-wasi\`. This is a temporary workaround until https://github.com/WebAssembly/wasi-libc/issues/501 has been addressed and released.
3838
- Run `build clr.aot+libs -c [Debug|Release] -a wasm -os [browser|wasi]`. This will create the architecture-dependent libraries needed for linking and runtime execution, as well as the managed binaries to be used as input to ILC.
3939

4040
For the compilers:

eng/native/gen-buildsys.sh

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,17 @@ if [[ "$scan_build" == "ON" && -n "$SCAN_BUILD_COMMAND" ]]; then
9393
cmake_command="$SCAN_BUILD_COMMAND $cmake_command"
9494
fi
9595

96+
cmake_extra_defines_wasm=()
9697
if [[ "$host_arch" == "wasm" ]]; then
9798
if [[ "$target_os" == "browser" ]]; then
9899
cmake_command="emcmake $cmake_command"
99100
elif [[ "$target_os" == "wasi" ]]; then
100-
true
101+
if [[ -z $WASI_SDK_PATH ]]; then
102+
echo "Error: Should set WASI_SDK_PATH environment variable pointing to WASI SDK root."
103+
exit 1
104+
fi
105+
106+
cmake_extra_defines_wasm=("-DCLR_CMAKE_TARGET_OS=wasi" "-DCLR_CMAKE_TARGET_ARCH=wasm" "-DWASI_SDK_PREFIX=$WASI_SDK_PATH" "-DCMAKE_TOOLCHAIN_FILE=$WASI_SDK_PATH/share/cmake/wasi-sdk.cmake" "-DCMAKE_CROSSCOMPILING_EMULATOR=node --experimental-wasm-bigint --experimental-wasi-unstable-preview1")
101107
else
102108
echo "target_os was not specified"
103109
exit 1
@@ -110,6 +116,7 @@ $cmake_command \
110116
"-DCMAKE_BUILD_TYPE=$buildtype" \
111117
"-DCMAKE_INSTALL_PREFIX=$__CMakeBinDir" \
112118
$cmake_extra_defines \
119+
"${cmake_extra_defines_wasm[@]}" \
113120
$__UnprocessedCMakeArgs \
114121
-S "$1" \
115122
-B "$2"
Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
1-
Invoke-WebRequest -Uri https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20/wasi-sdk-20.0.m-mingw.tar.gz -OutFile wasi-sdk-20.0.m-mingw.tar.gz
1+
Invoke-WebRequest -Uri https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-22/wasi-sdk-22.0.m-mingw64.tar.gz -OutFile wasi-sdk-22.0.m-mingw64.tar.gz
22

3-
tar -xzf wasi-sdk-20.0.m-mingw.tar.gz
3+
tar -xzf wasi-sdk-22.0.m-mingw64.tar.gz
44

5-
mv wasi-sdk-20.0+m wasi-sdk
5+
mv wasi-sdk-22.0+m wasi-sdk
66

7+
# Temporary WASI-SDK 22 workaround: Until
8+
# https://github.com/WebAssembly/wasi-libc/issues/501 is addressed, we copy
9+
# pthread.h from the wasm32-wasi-threads include directory to the wasm32-wasi
10+
# include directory. See https://github.com/dotnet/runtimelab/issues/2598 for
11+
# the issue to remove this workaround once WASI-SDK 23 is released.
12+
13+
cp wasi-sdk/share/wasi-sysroot/include/wasm32-wasi-threads/pthread.h wasi-sdk/share/wasi-sysroot/include/wasm32-wasi/

src/coreclr/build-runtime.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,11 +177,11 @@ if [[ "$__CMakeTarget" == *"wasmjit"* ]]; then
177177

178178
if [[ "$__BuildType" == "Release" ]]; then
179179
if [[ -n $LLVM_CMAKE_CONFIG_RELEASE ]]; then
180-
LLVM_CMAKE_CONFIG="$LLVM_CMAKE_CONFIG_RELEASE"
180+
export LLVM_CMAKE_CONFIG="$LLVM_CMAKE_CONFIG_RELEASE"
181181
fi
182182
else
183183
if [[ -n $LLVM_CMAKE_CONFIG_DEBUG ]]; then
184-
LLVM_CMAKE_CONFIG="$LLVM_CMAKE_CONFIG_DEBUG"
184+
export LLVM_CMAKE_CONFIG="$LLVM_CMAKE_CONFIG_DEBUG"
185185
fi
186186
fi
187187

src/coreclr/jit/CMakeLists.txt

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -706,16 +706,11 @@ else()
706706
create_standalone_jit(TARGET clrjit_win_x86_${ARCH_HOST_NAME} OS win ARCH x86 DESTINATIONS .)
707707
endif (CLR_CMAKE_TARGET_ARCH_RISCV64)
708708

709-
# Note that we currently do not support building the LLVM Jit on Unix.
710-
# Note as well that we need this "CLR_CMAKE_BUILD_LLVM_JIT", defined by the build scripts,
709+
# Note that we need this "CLR_CMAKE_BUILD_LLVM_JIT", defined by the build scripts,
711710
# because there is no way in CMake to ask "what --target's' am I being asked to configure?".
712711
if (CLR_CMAKE_BUILD_LLVM_JIT)
713712
# The LLVM clrjit needs to be the last clrjit to use create_standalone_jit as it modifies some cmake variables.
714713
# LLVM clrjit has an extra export - registerLlvmCallbacks.
715-
set(CLRJIT_EXPORTS ${CMAKE_CURRENT_LIST_DIR}/ClrJit.Llvm.exports)
716-
set(JIT_EXPORTS_FILE ${CMAKE_CURRENT_BINARY_DIR}/ClrJit.Llvm.exports.def)
717-
preprocess_file (${CLRJIT_EXPORTS} ${JIT_EXPORTS_FILE})
718-
set(JIT_DEF_FILE ${JIT_EXPORTS_FILE})
719714

720715
# Exclude cpp files that are not required when not processing beyond rationalized LIR.
721716
# Use REGEX as this list contains the absolute paths.

src/coreclr/jit/ClrJit.Llvm.exports

Lines changed: 0 additions & 9 deletions
This file was deleted.

src/coreclr/jit/ClrJit.PAL.exports

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ jitStartup
33
getLikelyClasses
44
getLikelyMethods
55
jitBuildString
6+
registerLlvmCallbacks

src/coreclr/jit/ClrJit.exports

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ EXPORTS
77
getLikelyClasses
88
getLikelyMethods
99
jitBuildString
10+
registerLlvmCallbacks

src/coreclr/jit/ee_il_dll.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1421,3 +1421,10 @@ unsigned Compiler::eeTryGetClassSize(CORINFO_CLASS_HANDLE clsHnd)
14211421
}
14221422

14231423
#endif // !DEBUG
1424+
1425+
#ifndef TARGET_WASM
1426+
extern "C" DLLEXPORT void registerLlvmCallbacks(void** jitImports, void** jitExports)
1427+
{
1428+
// No-op stub; see llvm.cpp for the real implementation for `TARGET_WASM`
1429+
}
1430+
#endif

src/coreclr/jit/llvm.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -770,7 +770,7 @@ CORINFO_GENERIC_HANDLE Llvm::getSymbolHandleForClassToken(mdToken token)
770770
template <EEApiId Func, typename TReturn, typename... TArgs>
771771
TReturn CallEEApi(TArgs... args)
772772
{
773-
return static_cast<TReturn (*)(TArgs...)>(g_callbacks[static_cast<int>(Func)])(args...);
773+
return reinterpret_cast<TReturn (*)(TArgs...)>(g_callbacks[static_cast<int>(Func)])(args...);
774774
}
775775

776776
const char* Llvm::GetMangledMethodName(CORINFO_METHOD_HANDLE methodHandle)
@@ -866,8 +866,8 @@ extern "C" DLLEXPORT void registerLlvmCallbacks(void** jitImports, void** jitExp
866866
assert(jitExports != nullptr);
867867

868868
memcpy(g_callbacks, jitImports, static_cast<int>(EEApiId::Count) * sizeof(void*));
869-
jitExports[static_cast<int>(JitApiId::StartSingleThreadedCompilation)] = &Llvm::StartSingleThreadedCompilation;
870-
jitExports[static_cast<int>(JitApiId::FinishSingleThreadedCompilation)] = &Llvm::FinishSingleThreadedCompilation;
869+
jitExports[static_cast<int>(JitApiId::StartSingleThreadedCompilation)] = (void*)&Llvm::StartSingleThreadedCompilation;
870+
jitExports[static_cast<int>(JitApiId::FinishSingleThreadedCompilation)] = (void*)&Llvm::FinishSingleThreadedCompilation;
871871
jitExports[static_cast<int>(JitApiId::Count)] = (void*)0x1234;
872872
}
873873

src/coreclr/jit/llvmcodegen.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,6 +1118,7 @@ void Llvm::visitNode(GenTree* node)
11181118
break;
11191119
case GT_JMP:
11201120
NYI("LLVM/GT_JMP"); // Requires support for explicit tailcalls.
1121+
break;
11211122
default:
11221123
unreached();
11231124
}

src/coreclr/jit/llvmlower.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,9 @@ void Llvm::lowerFieldOfDependentlyPromotedStruct(GenTree* node)
409409
lclVar->gtFlags |= GTF_VAR_USEASG;
410410
}
411411
break;
412+
413+
default:
414+
break;
412415
}
413416

414417
lclVar->SetLclNum(varDsc->lvParentLcl);

src/coreclr/jit/llvmlssa.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1482,7 +1482,7 @@ class ShadowStackAllocator
14821482
{
14831483
if (block != m_currentBlock)
14841484
{
1485-
m_actions.Push({AllocationActionKind::Block, m_currentBlockIndex++});
1485+
m_actions.Push({AllocationActionKind::Block, {m_currentBlockIndex++}});
14861486
m_currentBlock = block;
14871487
}
14881488
}
@@ -1636,6 +1636,10 @@ class ShadowStackAllocator
16361636
template <typename... TArgs>
16371637
void PrintFormatted(char** pBuffer, const char* format, TArgs... args)
16381638
{
1639+
#ifdef __clang__
1640+
#pragma clang diagnostic push
1641+
#pragma clang diagnostic ignored "-Wformat-security"
1642+
#endif // __clang__
16391643
if (pBuffer == nullptr)
16401644
{
16411645
printf(format, args...);
@@ -1644,6 +1648,9 @@ class ShadowStackAllocator
16441648
{
16451649
*pBuffer += sprintf(*pBuffer, format, args...);
16461650
}
1651+
#ifdef __clang__
1652+
#pragma clang diagnostic pop
1653+
#endif // __clang__
16471654
}
16481655

16491656
void PrintAction(const AllocationAction& action, char** pBuffer = nullptr)

src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -388,9 +388,11 @@ The .NET Foundation licenses this file to you under the MIT license.
388388

389389
<Target Name="CheckWasmSdks">
390390
<Error Text="Emscripten not found, not compiling to WebAssembly. To enable WebAssembly compilation, install Emscripten and ensure the EMSDK environment variable points to the directory containing upstream/emscripten/emcc.bat"
391-
Condition="'$(EMSDK)' == ''" />
391+
Condition="'$(EMSDK)' == '' and '$(_targetOS)' == 'browser'" />
392392
<Error Text="Wasi SDK not found, not compiling to WebAssembly. To enable WebAssembly compilation, install Wasi SDK and ensure the WASI_SDK_PATH environment variable points to the directory containing share/wasi-sysroot"
393393
Condition="'$(WASI_SDK_PATH)' == '' and '$(_targetOS)' == 'wasi'" />
394+
<Warning Text="The WASI SDK version is too low. Please use WASI SDK 22 or newer with a 64 bit Clang."
395+
Condition="!Exists('$(WASI_SDK_PATH)/VERSION') and '$(_targetOS)' == 'wasi'" />
394396
</Target>
395397

396398
<Target Name="CompileWasmObjects"
@@ -420,8 +422,7 @@ The .NET Foundation licenses this file to you under the MIT license.
420422
<CompileWasmArgs>$(CompileWasmArgs) -fvisibility=default -mllvm -combiner-global-alias-analysis=false -mllvm -disable-lsr --sysroot=&quot;$(WASI_SDK_PATH)/share/wasi-sysroot&quot; -target $(IlcLlvmTarget)</CompileWasmArgs>
421423

422424
<ExeExt Condition="'$(OS)' == 'Windows_NT'">.exe</ExeExt>
423-
<!-- using Emscripten's clang++ because of a crash in wasi-sdk's clang++ (https://github.com/WebAssembly/wasi-sdk/issues/326) -->
424-
<WasmCompilerPath>&quot;$(EMSDK)/upstream/bin/clang++$(ExeExt)&quot;</WasmCompilerPath>
425+
<WasmCompilerPath>&quot;$(WASI_SDK_PATH)/bin/clang++$(ExeExt)&quot;</WasmCompilerPath>
425426
<WasmLinkerPath>&quot;$(WASI_SDK_PATH)/bin/clang&quot;</WasmLinkerPath>
426427
</PropertyGroup>
427428

src/native/libs/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ if (CLR_CMAKE_TARGET_UNIX OR CLR_CMAKE_TARGET_BROWSER OR CLR_CMAKE_TARGET_WASI)
3232
set(CMAKE_INSTALL_PREFIX $ENV{__CMakeBinDir})
3333
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -Wno-declaration-after-statement")
3434

35+
# TODO-LLVM: remove once upstream moves to WASI SDK 22 as well (or otherwise fixes these warnings).
36+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-switch-default")
37+
3538
add_compile_options(-I${CMAKE_CURRENT_SOURCE_DIR}/Common)
3639
add_compile_options(-I${CMAKE_CURRENT_BINARY_DIR}/Common)
3740

0 commit comments

Comments
 (0)