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

[build.ps1] Set the default architecture using an environment variable #104474

Closed
wants to merge 4 commits into from
Closed
Changes from 1 commit
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
16 changes: 14 additions & 2 deletions eng/build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Param(
[switch]$coverage,
[string]$testscope,
[switch]$testnobuild,
[ValidateSet("x86","x64","arm","arm64","wasm")][string[]][Alias('a')]$arch = @([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture.ToString().ToLowerInvariant()),
[ValidateSet("x86","x64","arm","arm64","wasm")][string[]][Alias('a')]$arch,
[switch]$cross = $false,
[string][Alias('s')]$subset,
[ValidateSet("Debug","Release","Checked")][string][Alias('rc')]$runtimeConfiguration,
Expand All @@ -27,11 +27,19 @@ Param(
[Parameter(ValueFromRemainingArguments=$true)][String[]]$properties
)

function Get-Default-Arch() {
if ($env:DOTNET_RUNTIME_DEFAULT_ARCH) {
return $env:DOTNET_RUNTIME_DEFAULT_ARCH
}

return [System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture.ToString().ToLowerInvariant()
}

function Get-Help() {
Write-Host "Common settings:"
Write-Host " -arch (-a) Target platform: x86, x64, arm, arm64, or wasm."
Write-Host " Pass a comma-separated list to build for multiple architectures."
Write-Host (" [Default: {0} (Depends on your console's architecture.)]" -f [System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture.ToString().ToLowerInvariant())
Write-Host (" [Default: {0} (Depends on your console's architecture or the DOTNET_RUNTIME_DEFAULT_ARCH environment variable.)]" -f @(Get-Default-Arch))
Copy link
Member

Choose a reason for hiding this comment

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

This covers for the top level build.sh1, but it does not cover other entrypoints into the dev workflow. For example, it does not cover running dotnet build .... directly that is part of number of documented dev workflows. If we want to go with the environment variables as the solution for overriding defaults, should it be respected for all entrypoints into the dev workflow?

Copy link
Member Author

Choose a reason for hiding this comment

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

The peculiarity of build.sh1 is that it resolves the default architecture from the process architecture of the calling shell. The architecture of dotnet build ... is controlled by what SDKs you have installed and the PATH environment variable. I've never had issues running the correct sdk from a 32-bit shell.

Copy link
Member

Choose a reason for hiding this comment

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

The peculiarity of build.sh1 is that it resolves the default architecture from the process architecture of the calling shell.

build.ps1 resolves the default architecture from the process architecture of the calling powershell.exe. It sounds like that you have the x64 powershell.exe on the PATH in your environment, but you actually want to have the arm64 powershell.exe. Is there arm64 powershell on Windows Arm64?

Copy link
Member Author

Choose a reason for hiding this comment

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

Windows Arm does have native builds for Powershell, however I'm using mingw which only has x64 builds at the moment. A similar issue with SSH connections to Windows arm devices.

Copy link
Member

Choose a reason for hiding this comment

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

Would it be better to workaround the problem by changing the path in your mingw environment to point to native powershell? It would cover this and all other powershell.exe invocations.

Copy link
Member Author

Choose a reason for hiding this comment

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

Even if you run it as %windir%\sysnative\cmd.exe ?

That folder doesn't exist on ARM builds. Similar to powershell.exe it's the same executable that adapts depending on the parent architecture:

image

The non-native shells keep you on non-native architecture. It has been always the case.

I understand that this is the case, however like I said this does create problems in the workflows for those that do rely on tools that aren't arm64 native yet. While creating a wrapper script does technically resolve the issue, the dev loop workflow largely relies on muscle memory: I work on x64 and arm64 machines interchangeably so even with the workaround I have to explicitly remember that the current machine is arm64 to make sure the right script/arch parameter is being used. If I don't, I will have lost > 5 minutes waiting on a build that was targeting the wrong architecture. This has been happening frequently enough to me for it to be a problem.

Copy link
Member

Choose a reason for hiding this comment

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

That folder doesn't exist on ARM builds.

That's surprising. It has been a virtual folder that only exists on non-native contexts. It has been the escape hatch to get back to native context. For example, this is how you can relaunch native x64 cmd from the emulated x86 cmd on Windows x64:

C:\Windows>set PROCESSOR_ARCHITECTURE
PROCESSOR_ARCHITECTURE=x86

C:\Windows>%windir%\sysnative\cmd.exe
Microsoft Windows [Version 10.0.22631.3810]
(c) Microsoft Corporation. All rights reserved.

C:\Windows>set PROCESSOR_ARCHITECTURE
PROCESSOR_ARCHITECTURE=AMD64

Is it really the case that these same steps do not work in emulated x64 cmd on Windows arm64?

Copy link
Member Author

Choose a reason for hiding this comment

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

Assuming there existed a build of cmd.exe or powershell.exe that consistently launched an arm64 process, then it would solve my issue. The only copy of cmd.exe I could find other than the System32 one is the one at SysWOW64 which launches as an x86 process.

Copy link
Member

Choose a reason for hiding this comment

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

You are right. I have done some reading on this topic. The system .exes are multi-arch on Windows Arm, and so there is no way to control the system process architecture by selecting different .exes. Instead, the process launching the .exe controls the process architecture.

For example, start command allows you to set the desired process architecture.start /B /WAIT /MACHINE arm64 %windir%\System32\cmd.exe should always launch native cmd prompt on Windows arm64.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks, the /machine parameter seems to work for me. By installing the following script called powershell in my PATH:

#!/usr/bin/env bash
start //b //wait //machine arm64 powershell.exe "$@"

I'm able to force native powershell process from the mingw environment. This solves the problem using build.sh as the entrypoint, but not for the build.cmd entrypoint.

Write-Host " -binaryLog (-bl) Output binary log."
Write-Host " -configuration (-c) Build configuration: Debug, Release or Checked."
Write-Host " Checked is exclusive to the CLR subset. It is the same as Debug, except code is"
Expand Down Expand Up @@ -143,6 +151,10 @@ if ($subset -eq 'help') {
exit 0
}

if (-not $arch) {
$arch = Get-Default-Arch
}

# Lower-case the passed in OS string.
if ($os) {
$os = $os.ToLowerInvariant()
Expand Down
Loading