Skip to content

Commit

Permalink
[NativeAOT-LLVM] Build on Linux (#2574)
Browse files Browse the repository at this point in the history
* Enable linux builds

* move NATIVEAOT_CI_WASM_BUILD_EMSDK_PATH to be inline with windows

* just use pwsh for installing node.  Delete the .cmd

* normalize checked for llvm config

* use powershell only for emscripten install

* use pwsh inline with node

* do not search system paths for LLVM

* feedback tidy

* do not use __ExtraCmakeArgs

* Update src/coreclr/build-runtime.sh

Co-authored-by: SingleAccretion <62474226+SingleAccretion@users.noreply.github.com>

* Update src/coreclr/jit/CMakeLists.txt

Co-authored-by: SingleAccretion <62474226+SingleAccretion@users.noreply.github.com>

* Ensure Powershell on linux

Remove wasm build options
add cmake to path on windows
Use more Powershell where possible
Simplify New-Item use
Feedback

* feedback, move tool installations to correct place.

---------

Co-authored-by: SingleAccretion <62474226+SingleAccretion@users.noreply.github.com>
  • Loading branch information
yowl and SingleAccretion authored May 21, 2024
1 parent e5a0829 commit 07ff833
Show file tree
Hide file tree
Showing 16 changed files with 148 additions and 80 deletions.
2 changes: 1 addition & 1 deletion docs/using-nativeaot/prerequisites.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ The following pre-requisites need to be installed for building .NET projects wit
## Emscripten SDK

* Install and activate Emscripten. See [Install Emscripten](https://emscripten.org/docs/getting_started/downloads.html#installation-instructions-using-the-emsdk-recommended).
* We strongly recommend using the same version that we test against. Look for it here: [install-emscripten.cmd](https://github.com/dotnet/runtimelab/blob/feature/NativeAOT-LLVM/eng/pipelines/runtimelab/install-emscripten.cmd).
* We strongly recommend using the same version that we test against. Look for it here: [install-emscripten.ps1](https://github.com/dotnet/runtimelab/blob/feature/NativeAOT-LLVM/eng/pipelines/runtimelab/install-emscripten.ps1).
```
./emsdk install <version>
./emsdk activate <version>
Expand Down
2 changes: 1 addition & 1 deletion docs/workflow/building/coreclr/nativeaot.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ The Native AOT toolchain can be currently built for Linux (x64/arm64), macOS (x6
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.

For the runtime libraries:
- 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.cmd#L14-L18) uses.
- 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.
```
git clone https://github.com/emscripten-core/emsdk
cd emsdk
Expand Down
17 changes: 9 additions & 8 deletions eng/pipelines/common/global-build-job.yml
Original file line number Diff line number Diff line change
Expand Up @@ -208,11 +208,17 @@ jobs:
# Install Wasm dependencies: emscripten, LLVM, NodeJS
- ${{ if and(eq(parameters.runtimeFlavor, 'coreclr'), eq(parameters.archType, 'wasm')) }}:
- script: call $(Build.SourcesDirectory)/eng/pipelines/runtimelab/install-emscripten.cmd $(Build.SourcesDirectory)\wasm-tools
- script: pwsh $(Build.SourcesDirectory)/eng/pipelines/runtimelab/install-emscripten.ps1 $(Build.SourcesDirectory)/wasm-tools
displayName: Install/activate emscripten
- script: call $(Build.SourcesDirectory)/eng/pipelines/runtimelab/install-llvm.cmd $(Build.SourcesDirectory)\wasm-tools $(Build.SourcesDirectory) ${{ parameters.buildConfig }}
- script: call $(Build.SourcesDirectory)/eng/pipelines/runtimelab/set-cmake-path.cmd
displayName: Set CMake path
# Install Powershell on OSes that don't come with it by default
- ${{ if ne(parameters.hostedOs, 'windows') }}:
- script: $(Build.SourcesDirectory)/eng/pipelines/runtimelab/install-pwsh.sh $(Build.SourcesDirectory)/wasm-tools
displayName: Install Powershell 7
- script: pwsh $(Build.SourcesDirectory)/eng/pipelines/runtimelab/install-llvm.ps1 -CI -InstallDir $(Build.SourcesDirectory)\wasm-tools -Configs ${{ parameters.buildConfig }}
displayName: Install/build LLVM
- script: call $(Build.SourcesDirectory)/eng/pipelines/runtimelab/install-nodejs.cmd $(Build.SourcesDirectory)\wasm-tools
- script: pwsh $(Build.SourcesDirectory)/eng/pipelines/runtimelab/install-nodejs.ps1 $(Build.SourcesDirectory)\wasm-tools
displayName: Install NodeJS

- ${{ if and(eq(parameters.runtimeFlavor, 'coreclr'), eq(parameters.platform, 'wasi_wasm_win')) }}:
Expand All @@ -222,11 +228,6 @@ jobs:
- script: call $(Build.SourcesDirectory)/eng/pipelines/runtimelab/install-wasmer.cmd $(Build.SourcesDirectory)\wasm-tools
displayName: Install wasmer

- ${{ if and(eq(parameters.osGroup, 'windows'), eq(parameters.archType, 'x64')) }}:
# Install LLVM for the win-x64 build as it will build the clrjit for browser_wasm cross compilation
- script: call $(Build.SourcesDirectory)/eng/pipelines/runtimelab/install-llvm.cmd $(Build.SourcesDirectory)\wasm-tools $(Build.SourcesDirectory) ${{ parameters.buildConfig }}
displayName: Install/build LLVM

- ${{ if or(eq(parameters.platform, 'browser_wasm_win'), and(eq(parameters.platform, 'wasi_wasm_win'), not(eq(parameters.runtimeFlavor, 'coreclr')))) }}:
# Update machine certs
- task: PowerShell@2
Expand Down
4 changes: 1 addition & 3 deletions eng/pipelines/runtimelab.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ extends:
helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml
buildConfig: debug
platforms:
# - linux_x64
- osx_x64
- windows_x64
- Browser_wasm_win
Expand All @@ -81,7 +80,6 @@ extends:
helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml
buildConfig: checked
platforms:
# - linux_x64
- windows_x64
jobParameters:
timeoutInMinutes: 300
Expand All @@ -101,7 +99,7 @@ extends:
helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
buildConfig: release
platforms:
# - linux_x64
- linux_x64
- osx_x64
- windows_x64
- Browser_wasm_win
Expand Down
25 changes: 0 additions & 25 deletions eng/pipelines/runtimelab/install-emscripten.cmd

This file was deleted.

23 changes: 23 additions & 0 deletions eng/pipelines/runtimelab/install-emscripten.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
param(
$InstallDir
)

$ErrorActionPreference="Stop"

New-Item -ItemType Directory -Force -Path $InstallDir

Set-Location -Path $InstallDir

git clone https://github.com/emscripten-core/emsdk.git

Set-Location -Path emsdk

# Checkout a specific commit to avoid unexpected issues
git checkout 37b85e9

./emsdk install 3.1.47

./emsdk activate 3.1.47

# Set a variable for later use (used in common/build.ps1)
Write-Host "##vso[task.setvariable variable=NATIVEAOT_CI_WASM_BUILD_EMSDK_PATH]$PWD"
22 changes: 0 additions & 22 deletions eng/pipelines/runtimelab/install-llvm.cmd

This file was deleted.

39 changes: 33 additions & 6 deletions eng/pipelines/runtimelab/install-llvm.ps1
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
[CmdletBinding(PositionalBinding=$false)]
param(
[ValidateSet("Debug","Release")][string[]]$Configs = @("Debug","Release"),
$InstallDir,
[ValidateSet("Debug","Release","Checked")][string[]]$Configs = @("Debug","Release"),
[switch]$CI,
[switch]$NoClone,
[switch]$NoBuild
)


$ErrorActionPreference="Stop"

New-Item -ItemType Directory -Path $InstallDir -Force
Set-Location -Path $InstallDir

# Set IsWindows if the version of Powershell does not already have it.
if (!(Test-Path variable:global:IsWindows))
{
$IsWindows = [Environment]::OSVersion.Platform -eq [PlatformID]::Win32NT
}

if (!(gcm git -ErrorAction SilentlyContinue))
{
Write-Error "Unable to find 'git' in PATH"
Expand All @@ -31,27 +42,43 @@ elseif (!(Test-Path llvm-project))
exit 1
}

foreach ($Config in $Configs)
# There is no [C/c]hecked LLVM config, so change to Debug
foreach ($Config in $Configs | % { if ($_ -eq "Checked") { "Debug" } else { $_ } } | Select-Object -Unique)
{
pushd llvm-project
$BuildDirName = "build-$($Config.ToLower())"
mkdir $BuildDirName -Force
New-Item -ItemType Directory $BuildDirName -Force

$BuildDirPath = "$pwd/$BuildDirName"
$SourceDirName = "$pwd/llvm"
popd

$CmakeConfigureCommandLine = "-G", "Visual Studio 17 2022", "-DLLVM_INCLUDE_BENCHMARKS=OFF", "-Thost=x64"
if ($IsWindows)
{
$CmakeGenerator = "Visual Studio 17 2022"
}
else
{
$CmakeGenerator = "Unix Makefiles"
}

$CmakeConfigureCommandLine = "-G", "$CmakeGenerator", "-DLLVM_INCLUDE_BENCHMARKS=OFF"
$CmakeConfigureCommandLine += "-S", $SourceDirName, "-B", $BuildDirPath
if ($Config -eq "Release")
{
$LlvmConfig = "Release"
$CmakeConfigureCommandLine += "-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded"
if ($IsWindows)
{
$CmakeConfigureCommandLine += "-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded", "-Thost=x64"
}
}
else
{
$LlvmConfig = "Debug"
$CmakeConfigureCommandLine += "-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDebug"
if ($IsWindows)
{
$CmakeConfigureCommandLine += "-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDebug", "-Thost=x64"
}
}
$CmakeConfigureCommandLine += "-DCMAKE_BUILD_TYPE=$LlvmConfig"

Expand Down
9 changes: 0 additions & 9 deletions eng/pipelines/runtimelab/install-nodejs.cmd

This file was deleted.

30 changes: 26 additions & 4 deletions eng/pipelines/runtimelab/install-nodejs.ps1
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
$InstallPath = $Args[0]
$NodeJSVersion = "v20.2.0"
$NodeJSInstallName = "node-$NodeJSVersion-win-x64"
$NodeJSZipName = "$NodeJSInstallName.zip"

if (!(Test-Path variable:global:IsWindows))
{
$IsWindows = [Environment]::OSVersion.Platform -eq [PlatformID]::Win32NT
}

if ($IsWIndows)
{
$NodeJSInstallName = "node-$NodeJSVersion-win-x64"
$NodeJSZipName = "$NodeJSInstallName.zip"
}
else
{
$NodeJSInstallName = "node-$NodeJSVersion-linux-x64"
$NodeJSZipName = "$NodeJSInstallName.tar.xz"
}

if (!(Test-Path $InstallPath))
{
Expand Down Expand Up @@ -33,9 +47,17 @@ if ($RetryCount -le 0)
exit 1
}

Expand-Archive -LiteralPath "$InstallPath\$NodeJSInstallName.zip" -DestinationPath $InstallPath -Force
if ($IsWindows)
{
Expand-Archive -LiteralPath "$InstallPath\$NodeJSZipName" -DestinationPath $InstallPath -Force
$NodeJSExePath = "$InstallPath\$NodeJSInstallName\node.exe"
}
else
{
tar xJf $InstallPath/$NodeJSZipName -C $InstallPath
$NodeJSExePath = "$InstallPath/$NodeJSInstallName/bin/node"
}

$NodeJSExePath = "$InstallPath\$NodeJSInstallName\node.exe"
if (!(Test-Path $NodeJSExePath))
{
Write-Error "Did not find NodeJS at: '$NodeJSExePath'"
Expand Down
19 changes: 19 additions & 0 deletions eng/pipelines/runtimelab/install-pwsh.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env bash

mkdir -p $1

cd $1

curl -L -o powershell.tar.gz https://github.com/PowerShell/PowerShell/releases/download/v7.3.12/powershell-7.3.12-linux-x64.tar.gz

# Create the target folder where powershell will be placed
mkdir powershell7

# Expand powershell to the target folder
tar zxf powershell.tar.gz -C powershell7

# Set execute permissions
chmod +x powershell7/pwsh

echo setting PATH
echo ##vso[task.setvariable variable=PATH]$PATH:$1/powershell7
10 changes: 10 additions & 0 deletions eng/pipelines/runtimelab/set-cmake-path.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Save the current PATH because init-vs-env.cmd will add enough to the PATH that calling it twice
# will exceed the command length limit.
set OLD_PATH=%PATH%
call "%RepoRoot%eng\native\init-vs-env.cmd" wasm || exit /b 1

call set CMakeDir=%%CMakePath:\cmake.exe=%%

echo CMakeDir is %CMakeDir%
echo Setting PATH to %OLD_PATH%;%CMakeDir%
echo ##vso[task.setvariable variable=PATH]%OLD_PATH%;%CMakeDir%
20 changes: 20 additions & 0 deletions src/coreclr/build-runtime.sh
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,26 @@ if [[ -n "$__RequestedBuildComponents" ]]; then
__CMakeTarget=" $__RequestedBuildComponents "
__CMakeTarget="${__CMakeTarget// paltests / paltests_install }"
fi

if [[ "$__CMakeTarget" == *"wasmjit"* ]]; then
__CMakeArgs="$__CMakeArgs -DCLR_CMAKE_BUILD_LLVM_JIT=1"

if [[ "$__BuildType" == "Release" ]]; then
if [[ -n $LLVM_CMAKE_CONFIG_RELEASE ]]; then
LLVM_CMAKE_CONFIG="$LLVM_CMAKE_CONFIG_RELEASE"
fi
else
if [[ -n $LLVM_CMAKE_CONFIG_DEBUG ]]; then
LLVM_CMAKE_CONFIG="$LLVM_CMAKE_CONFIG_DEBUG"
fi
fi

if [[ -z "$LLVM_CMAKE_CONFIG" ]]; then
echo The LLVM_CMAKE_CONFIG environment variable pointing to llvm-build-dir/lib/cmake/llvm must be set. 1>&2
exit 1
fi
fi

if [[ -z "$__CMakeTarget" ]]; then
__CMakeTarget="install"
fi
Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/jit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ function(create_standalone_jit)
# We'll be linking against LLVM built without /guard:ehcont, so disable it.
set_target_properties(${TARGETDETAILS_TARGET} PROPERTIES CLR_EH_CONTINUATION OFF)

find_package(LLVM REQUIRED CONFIG PATHS $ENV{LLVM_CMAKE_CONFIG})
# Only look at "our" LLVM with LLVM_CMAKE_CONFIG.
find_package(LLVM REQUIRED CONFIG PATHS $ENV{LLVM_CMAKE_CONFIG} NO_DEFAULT_PATH)
target_include_directories(${TARGETDETAILS_TARGET} PRIVATE ${LLVM_INCLUDE_DIRS})
separate_arguments(LLVM_DEFINITIONS)
target_compile_definitions(${TARGETDETAILS_TARGET} PRIVATE ${LLVM_DEFINITIONS})
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/nativeaot/Runtime/unix/UnixContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
// WASM has no thread state contexts.
#ifndef HOST_WASM

#include <ucontext.h>

// Convert Unix native context to PAL_LIMITED_CONTEXT
void NativeContextToPalContext(const void* context, PAL_LIMITED_CONTEXT* palContext);
// Redirect Unix native context to the PAL_LIMITED_CONTEXT and also set the first two argument registers
Expand Down
1 change: 1 addition & 0 deletions src/native/libs/build-native.sh
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ __usePThreads=0
source "$__RepoRootDir"/eng/native/build-commons.sh

# Set cross build
EMSDK_PATH=$EMSDK
if [[ "$__TargetOS" == browser ]]; then
if [[ -z "$EMSDK_PATH" ]]; then
if [[ -d "$__RepoRootDir"/src/mono/browser/emsdk/ ]]; then
Expand Down

0 comments on commit 07ff833

Please sign in to comment.