-
Notifications
You must be signed in to change notification settings - Fork 199
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[NativeAOT-LLVM] add support for building WASI and browser debug & release on Linux #2605
Conversation
@@ -22,7 +22,7 @@ The .NET Foundation licenses this file to you under the MIT license. | |||
<_SymbolPrefix Condition="'$(_IsApplePlatform)' == 'true'">_</_SymbolPrefix> | |||
<LinkerFlavor Condition="'$(LinkerFlavor)' == '' and '$(_targetOS)' == 'freebsd'">lld</LinkerFlavor> | |||
<LinkerFlavor Condition="'$(LinkerFlavor)' == '' and '$(_linuxLibcFlavor)' == 'bionic'">lld</LinkerFlavor> | |||
<LinkerFlavor Condition="'$(LinkerFlavor)' == '' and '$(_targetOS)' == 'linux'">bfd</LinkerFlavor> | |||
<LinkerFlavor Condition="'$(LinkerFlavor)' == '' and '$(_targetOS)' == 'linux'">lld</LinkerFlavor> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should propagate from the top-level LDFLAGS set by the init-compiler.sh script. Is it getting lost somewhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume from the fact that changing this line to lld makes no difference, that it is arriving as bfd.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something up with args to init-compiler.sh maybe.
cc @dotnet/nativeaot-llvm |
# Browser WebAssembly Linux X64 | ||
|
||
- ${{ if containsValue(parameters.platforms, 'Browser_wasm_linux_x64') }}: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My preference would be to name these in a way that makes it clear that they're downstream-specific. E. g. Browser_wasm_linux_x64_naot_llvm
; and comment we're adding these because the "stock" wasi-wasm
doesn't have the build tools (that sanitizer image) we need.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
renamed
${{ if eq(parameters.container, '') }}: | ||
container: linux_x64 | ||
${{ if ne(parameters.container, '') }}: | ||
container: | ||
image: ${{ parameters.container }} | ||
registry: mcr |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would make sense to hardcode the azurelinux-3.0-cross-amd64-net9.0-sanitizer
here instead of runtimelab*
YMLs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
eng/pipelines/runtimelab.yml
Outdated
# | ||
# Build and test wasi linux with Release libraries and Release runtime with sanitzer container | ||
# |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not fold this into Build and test with Release libraries and Release runtime
above?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
|
||
Write-Host "Invoking CMake configure: 'cmake $CmakeConfigureCommandLine'" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Logging deleted intentionally?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, thanks
|
||
if [ -n "${WASM_HOST_EXECUTABLE}" ]; then | ||
shift | ||
$WASM_HOST_EXECUTABLE "$WASM_BINARY_TO_EXECUTE" $WASM_HOST_ARGS_SEPERATOR "$@" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.cmd
also logs the command it is about to run.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added log, thanks.
@@ -1275,8 +1275,12 @@ void DisplayNowayAssertMap() | |||
fout = _wfopen(strJitMeasureNowayAssertFile, W("a")); | |||
if (fout == nullptr) | |||
{ | |||
#if !defined(HOST_WINDOWS) | |||
// TODO: how do we print a `const char16_t*` portably? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do these changes need for this to compile in CI/locally? There is an upstream change pending that will resolve them; it would be better to omit them here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, locally in docker, so presumably in CI docker as well. Without these changes we cannot compile on the image:
/runtime/src/coreclr/jit/compiler.cpp:1278:83: error: length modifier 'w' results in undefined behavior or no effect with 's' conversion specifier [-Werror,-Wformat]
1278 | fprintf(jitstdout(), "Failed to open JitMeasureNowayAssertFile \"%ws\"\n",
| ~^~
/runtime/src/coreclr/jit/compiler.cpp:1279:25: error: format specifies type 'wchar_t *' but the argument has type 'LPCWSTR' (aka 'const char16_t *') [-Werror,-Wformat]
1278 | fprintf(jitstdout(), "Failed to open JitMeasureNowayAssertFile \"%ws\"\n",
| ~~~
| %s
1279 | strJitMeasureNowayAssertFile);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 errors generated.
make[3]: *** [jit/CMakeFiles/clrjit_universal_wasm32_x64.dir/build.make:189: jit/CMakeFiles/clrjit_universal_wasm32_x64.dir/compiler.cpp.o] Error 1
@@ -418,6 +418,7 @@ The .NET Foundation licenses this file to you under the MIT license. | |||
<CompileWasmArgs Condition="'$(IlcLlvmExceptionHandlingModel)' == 'cpp'">$(CompileWasmArgs) -mllvm -enable-emscripten-cxx-exceptions</CompileWasmArgs> | |||
|
|||
<ScriptExt Condition="'$(OS)' == 'Windows_NT'">.bat</ScriptExt> | |||
<ScriptExt Condition="'$(OS)' != 'Windows_NT'"></ScriptExt> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is ScriptExt
set by something upstream? If so, this variable should be renamed to something less generic (e. g. _IlcScriptExt
, or something like that).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
renamed.
- Browser_wasm_win | ||
- wasi_wasm_win | ||
- Browser_wasm_linux_x64 | ||
- wasi_wasm_linux_x64 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect this will not work as-is.
We have two things being published:
- Target packages:
browser-wasm
/wasi-wasm
.- In the current setup, these are always published and so we'll get package conflicts, since both platforms will be producing the (hopefully) identical target packages.
- Host packages.
- In the current setup, only
Browser_wasm_win
publishes host packages.
- In the current setup, only
To fix this up, we'll need to adjust the conditions that prevent package conflicts (e. g. only build target packages on Windows, only build host packages on Browser
platforms). But I would suggest leaving the official build for a follow-up change.
- Browser_wasm_win | |
- wasi_wasm_win | |
- Browser_wasm_linux_x64 | |
- wasi_wasm_linux_x64 | |
- Browser_wasm_win | |
- wasi_wasm_win |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, reverted
- script: $(Build.SourcesDirectory)/build$(scriptExt) clr.wasmjit+clr.aot -c $(buildConfigUpper) $(_officialBuildParameter) -ci -cross | ||
env: | ||
ROOTFS_DIR: /crossrootfs/x64 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think if you switch the container in the platform definition to linux_x64_sanitizer
, this explicit ROOTFS_DIR
can be dropped.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that works, thanks
- ${{ elseif eq(parameters.platform, 'wasi_wasm_linux_x64') }}: | ||
- script: | | ||
source $(Build.SourcesDirectory)/wasm-tools/emsdk/emsdk_env.sh | ||
LD_LIBRARY_PATH=/usr/local/lib:/opt/lib:/lib:/usr/lib:/crossrootfs/x64/lib/x86_64-linux-gnu/ $(Build.SourcesDirectory)/src/tests/build$(scriptExt) nativeaot $(buildConfigUpper) -arch:${{ parameters.archType }} -target-os:wasi tree nativeaot /p:LibrariesConfiguration=${{ parameters.librariesConfiguration }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is a LD_LIBRARY_PATH
like this needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because libtinfo.so.5
is only in the rootfs. The host has libtinfo.so.6
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we build the LLVM with libtinfo dependency ourselves or is that for pre-built LLVM?
If we build it ourselves, we can get rid of libtinfo dependency like this: https://github.com/dotnet/runtimelab/pull/741/files#diff-8bb555c9ef0d91e66546d2fa904a310f4d22f129e191dff6b12e4fbdfe65e321R33
nuget error |
Green, think I've got all the feedback addressed. |
@@ -35,6 +35,7 @@ extends: | |||
parameters: | |||
jobTemplate: /eng/pipelines/common/global-build-job.yml | |||
buildConfig: Release | |||
container: azurelinux-3.0-cross-amd64-net9.0-sanitizer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
container: azurelinux-3.0-cross-amd64-net9.0-sanitizer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@@ -3,7 +3,7 @@ cd /D "%1" | |||
|
|||
echo Installing Wasi SDK | |||
|
|||
powershell -NoProfile -NoLogo -ExecutionPolicy ByPass -File "%~dp0install-wasi-sdk.ps1" | |||
powershell -NoProfile -NoLogo -ExecutionPolicy ByPass -File "%~dp0install-wasi-sdk.ps1" -InstallDir . |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now unused and can be deleted?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right
@@ -0,0 +1,34 @@ | |||
[CmdletBinding(PositionalBinding=$false)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now unused and can be deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
deleted
@@ -30,12 +30,22 @@ steps: | |||
- ${{ if eq(parameters.platform, 'browser_wasm_win') }}: | |||
- script: | | |||
call $(Build.SourcesDirectory)\wasm-tools\emsdk\emsdk_env | |||
$(Build.SourcesDirectory)/src/tests/build$(scriptExt) nativeaot $(buildConfigUpper) ${{ parameters.archType }} tree nativeaot /p:LibrariesConfiguration=${{ parameters.librariesConfiguration }} | |||
$(Build.SourcesDirectory)/src/tests/build$(scriptExt) nativeaot $(buildConfigUpper) ${{ parameters.archType }} tree nativeaot /p:LibrariesConfiguration=${{ parameters.librariesConfiguration }} /p:TestWrapperTargetsWindows=true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is concerning that /p:TestWrapperTargetsWindows=true
is needed to make things work on Windows. Does that mean the local test build is broken?
- ${{ elseif in(parameters.platform, 'wasi_wasm_linux_x64_naot_llvm') }}: | ||
- script: | | ||
$(Build.SourcesDirectory)/src/tests/run$(scriptExt) --runnativeaottests ${{ parameters.archType }} $(buildConfigUpper) wasi | ||
displayName: Run WebAssembly tests in single file mode |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does need to be separate? AFAICT it is just the same as the ${{ else }}:
below, just different parameter order.
source $(Build.SourcesDirectory)/wasm-tools/emsdk/emsdk_env.sh | ||
$(Build.SourcesDirectory)/build$(scriptExt) libs.tests -test -a ${{ parameters.archType }} -os ${{ parameters.osGroup }} -lc ${{ parameters.librariesConfiguration }} -rc $(buildConfigUpper) /p:TestNativeAot=true /p:RunSmokeTestsOnly=true | ||
displayName: Build and run WebAssembly libraries tests |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this need to be separate? emsdk_env.sh
is already part of build.sh
.
src/tests/Directory.Build.props
Outdated
<TestWrapperTargetsWindows>false</TestWrapperTargetsWindows> | ||
<TestWrapperTargetsWindows Condition=" ('$(TargetsWindows)' != '' And '$(TargetsWindows)' ) OR ('$(TargetOS)' == 'android' And '$(TargetArchitecture)' == 'arm64' ) OR ($(WindowsHost) And '$(TargetArchitecture)' == 'wasm')">true</TestWrapperTargetsWindows> | ||
<TestWrapperTargetsWindows Condition="'$(TestWrapperTargetsWindows)' == ''">false</TestWrapperTargetsWindows> | ||
<TestWrapperTargetsWindows Condition=" ('$(TargetsWindows)' != '' And '$(TargetsWindows)' ) OR ('$(TargetOS)' == 'android' And '$(TargetArchitecture)' == 'arm64' )">true</TestWrapperTargetsWindows> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not clear to me any changes to TestWrapperTargetsWindows
logic are required.
Here's how the upstream condition will evaluate on Windows-targeting-WASM:
('$(TargetsWindows)' != '' And '$(TargetsWindows)' ) OR ('$(TargetOS)' == 'android' And '$(TargetArchitecture)' == 'arm64' ) OR ($(WindowsHost) And '$(TargetArchitecture)' == 'wasm')
=>true
due to(($(WindowsHost) And '$(TargetArchitecture)' == 'wasm')
.
On Not-Windows-targeting-WASM:- =>
""
(none of the Windows conditions aretrue
).
Which is how it is supposed to be.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right, it's not required. Thanks.
src/tests/build.sh
Outdated
@@ -318,6 +320,30 @@ handle_arguments_local() { | |||
fi | |||
;; | |||
|
|||
target-os*|-target-os*) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be better to structure this the same as the Windows and run.sh
script: Add wasi
/browser
arguments (possibly also wasm
, though it's not strictly required). It would make the command lines more consistent and simplify CI.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks, done.
Co-authored-by: SingleAccretion <[email protected]>
…nto linux-x64-jobs
A problem with our timers perhaps |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM modulo feedback.
Thank you 🚀!
// TODO-LLVM: This is not upstreamable and should be deleted when https://github.com/dotnet/runtimelab/pull/2614 is merged | ||
#if TARGET_WASI && !NATIVE_AOT |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you open an issue about reverting these changes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, #2666
@@ -341,7 +341,7 @@ fi | |||
<WatcherRunFile>"$CORE_ROOT/watchdog" $_WatcherTimeoutMins</WatcherRunFile> | |||
|
|||
<!-- Note that this overwrites CLRTestBashPreCommands rather than adding to it. --> | |||
<CLRTestBashPreCommands Condition="'$(CLRTestKind)' == 'BuildAndRun' and '$(TargetArchitecture)' == 'wasm'"><![CDATA[ | |||
<CLRTestBashPreCommands Condition="'$(CLRTestKind)' == 'BuildAndRun' and '$(TargetArchitecture)' == 'wasm' And '$(TargetOS)' == 'browser' And '$(RuntimeFlavor)' == 'mono'"><![CDATA[ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the '$(TargetOS)' == 'browser'
check necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, removed.
Co-authored-by: SingleAccretion <[email protected]>
Co-authored-by: SingleAccretion <[email protected]>
…nto linux-x64-jobs
Thanks for the reviews! |
Great work! Thanks a lot |
This PR adds the scripts and YML for building WASI and browser on Linux.
Takes some of the changes from Joel's work at #2614 to build on Linux. I changed some cases of
Browser
tobrowser
which seemed like the more consistent direction.Decided to pass
TestWrapperTargetsWindows
down fromruntimelab-post-build-steps.yml
to avoid troublesome inferencing.