Skip to content
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] Build on Linux #2574

Merged
merged 22 commits into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion eng/common/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ prepare_machine=false
verbosity='minimal'
runtime_source_feed=''
runtime_source_feed_key=''
host_arch=''
target_os=''

Choose a reason for hiding this comment

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

Are these only required for NATIVEAOT_CI_WASM_BUILD_EMSDK_PATH? It's not clear what they're for.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Its to avoid

/home/scott/github/runtimelab/eng/common/build.sh: line 245: host_arch: unbound variable

${host_arch-''} might be another way to solve it, or make it a mandatory parameter.

Choose a reason for hiding this comment

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

But the only uses of host_arch that I see look to be new (added in this change). My suggestion is delete them - or are they needed for something?


properties=''
while [[ $# > 0 ]]; do
Expand Down Expand Up @@ -185,7 +187,15 @@ while [[ $# > 0 ]]; do
runtime_source_feed=$2
shift
;;
-runtimesourcefeedkey)
-arch)
host_arch=$2
shift
;;
-os)
target_os=$2
shift
;;
-runtimesourceyeedkey)
runtime_source_feed_key=$2
shift
;;
Expand All @@ -207,6 +217,14 @@ if [[ "$ci" == true ]]; then
if [[ "$exclude_ci_binary_log" == false ]]; then
binary_log=true
fi

# This is a bit of a workaround for the fact that the pipelines do not have a great
# way of preserving the environment between scripts. Set by install-emscripten.sh.
if [[ "$host_arch" == "wasm" && "$target_os" == "browser" ]]; then
if [[ -n "$NATIVEAOT_CI_WASM_BUILD_EMSDK_PATH" ]]; then
source $NATIVEAOT_CI_WASM_BUILD_EMSDK_PATH/emsdk_env.sh
fi
fi
fi

. "$scriptroot/tools.sh"
Expand All @@ -226,6 +244,12 @@ function Build {
if [[ ! -z "$projects" ]]; then
properties="$properties /p:Projects=$projects"
fi
if [[ ! -z "$host_arch" ]]; then
properties="$properties -arch $host_arch"
fi
if [[ ! -z "$target_os" ]]; then
properties="$properties -os $target_os"
fi

local bl=""
if [[ "$binary_log" == true ]]; then
Expand Down
18 changes: 14 additions & 4 deletions eng/pipelines/common/global-build-job.yml
Original file line number Diff line number Diff line change
Expand Up @@ -206,13 +206,23 @@ jobs:
df -h
displayName: Disk Usage before Build

# 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
# Install Wasm dependencies on Windows: emscripten, LLVM, NodeJS
- ${{ if and(eq(parameters.hostedOs, 'windows'), and(eq(parameters.runtimeFlavor, 'coreclr'), eq(parameters.archType, 'wasm'))) }}:
- 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 }}
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

# Install Wasm dependencies on Linux: emscripten, LLVM, NodeJS.
- ${{ if and(eq(parameters.hostedOs, 'linux'), and(eq(parameters.runtimeFlavor, 'coreclr'), eq(parameters.archType, 'wasm'))) }}:

Choose a reason for hiding this comment

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

Can we collapse the Windows/Linux into one section now (will require putting Emscripten on the same pwsh plan)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, done

- script: pwsh $(Build.SourcesDirectory)/eng/pipelines/runtimelab/install-emscripten.ps1 $(Build.SourcesDirectory)/wasm-tools
displayName: Install/activate emscripten
- script: pwsh $(Build.SourcesDirectory)/eng/pipelines/runtimelab/install-llvm.ps1 -Configs ${{ parameters.buildConfig }} -CI

Choose a reason for hiding this comment

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

parameters.buildConfig can be Checked, to the normalization of of Config in install-llvm.cmd needs to be moved into install-llvm.ps1.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

workingDirectory: $(Build.SourcesDirectory)/wasm-tools
displayName: Install/build LLVM
- 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 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(
[string]$InstallDir
)

New-Item -ItemType Directory -Force -ErrorAction SilentlyContinue -Path (Split-Path -Path $InstallDir -Parent) -Name (Split-Path -Path $InstallDir -Leaf)

Choose a reason for hiding this comment

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

Does this really need to be this elaborate?

I just tried:

/home/singleaccretion> New-Item /home/singleaccretion/test/xyz/dir -Force -ItemType Directory

And it created the nested directory as expected.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Its ok on Linux, but with a drive letter it fails. We could strip the drive letter and assume we are "in" that drive, but it probably isn't much easier to read.

PS C:\Users\scott> new-item -ItemType Directory -Force -Name c:/tmp/1/2
new-item : The given path's format is not supported.
At line:1 char:1
+ new-item -ItemType Directory -Force -Name c:/tmp/1/2
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [New-Item], NotSupportedException
    + FullyQualifiedErrorId : System.NotSupportedException,Microsoft.PowerShell.Commands.NewItemCommand

PS C:\Users\scott> new-item -ItemType Directory -Force -Name /tmp/1/2


    Directory: C:\Users\scott\tmp\1


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----        11/05/2024     16:54                2

Choose a reason for hiding this comment

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

new-item -ItemType Directory -Force -Name c:/tmp/1/2

I think this should use -Path. I tried:

PS C:\Users\Accretion\AppData\Local\Temp> new-item -Force -ItemKind Directory -Path C:\Users\Accretion\AppData\Local\Temp/xyz/rot/tot

    Directory: C:\Users\Accretion\AppData\Local\Temp\xyz\rot

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----          13.05.2024    00:22                tot


$ErrorActionPreference="Stop"

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

python ./emsdk.py install 3.1.47

./emsdk activate 3.1.47

Choose a reason for hiding this comment

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

We have install-emscripten.cmd referenced in docs/using-nativeaot/prerequisites.md and also docs/workflow/building/coreclr/nativeaot.md, these need to be updated now.

Also, it is odd that the first line calls .py directly while the second goes through the wrapper script.


# Set a variable for later use (used in common/build.ps1)
Write-Host "##vso[task.setvariable variable=NATIVEAOT_CI_WASM_BUILD_EMSDK_PATH]$PWD"
3 changes: 0 additions & 3 deletions eng/pipelines/runtimelab/install-llvm.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ call "%RepoRoot%eng\native\init-vs-env.cmd" wasm || exit /b 1
echo Using CMake at "%CMakePath%"
set PATH=%PATH%;%CMakePath%

:: There is no [C/c]hecked LLVM config, so change to Debug
if /I %LlvmBuildConfig% EQU checked set LlvmBuildConfig=Debug

powershell -NoProfile -NoLogo -ExecutionPolicy ByPass -File "%~dp0install-llvm.ps1" -Configs %LlvmBuildConfig% -CI
if %errorlevel% NEQ 0 goto fail
exit /b 0
Expand Down
34 changes: 28 additions & 6 deletions eng/pipelines/runtimelab/install-llvm.ps1
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
[CmdletBinding(PositionalBinding=$false)]
param(
[ValidateSet("Debug","Release")][string[]]$Configs = @("Debug","Release"),
[ValidateSet("Debug","Release","Checked")][string[]]$Configs = @("Debug","Release"),
[switch]$CI,
[switch]$NoClone,
[switch]$NoBuild
)

# 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
}

$ErrorActionPreference="Stop"

if (!(gcm git -ErrorAction SilentlyContinue))
Expand All @@ -31,27 +37,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

Choose a reason for hiding this comment

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

Suggested change
$IsWindows=[environment]::OSVersion.Platform -eq [PlatformID]::Win32NT
$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"
Comment on lines +52 to +53

Choose a reason for hiding this comment

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

Does Expand-Archive not work on Linux (it's a bit surprising)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It does, but doesn't support gz which is gzip, or xz which is some LZMA I think.

Copy link
Contributor Author

@yowl yowl May 10, 2024

Choose a reason for hiding this comment

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

And those are our options for linux https://nodejs.org/dist/v9.9.0/

}
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
22 changes: 21 additions & 1 deletion 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 All @@ -185,7 +205,7 @@ fi

eval "$__RepoRootDir/eng/native/version/copy_version_files.sh"

build_native "$__HostOS" "$__HostArch" "$__ProjectRoot" "$__IntermediatesDir" "$__CMakeTarget" "$__CMakeArgs" "CoreCLR component"
build_native "$__HostOS" "$__HostArch" "$__ProjectRoot" "$__IntermediatesDir" "$__CMakeTarget" "$__CMakeArgs $__ExtraCmakeArgs" "CoreCLR component"
yowl marked this conversation as resolved.
Show resolved Hide resolved

# Build complete

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})
# Prefer the version specified in LLVM_CMAKE_CONFIG over the "system" installed version
find_package(LLVM REQUIRED CONFIG PATHS $ENV{LLVM_CMAKE_CONFIG} NO_DEFAULT_PATH)
yowl marked this conversation as resolved.
Show resolved Hide resolved
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