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

Handle non-x86 in dotnet-install.sh on *nix #4132

Merged
merged 1 commit into from
Oct 23, 2019

Conversation

omajid
Copy link
Member

@omajid omajid commented Oct 16, 2019

Here's the problem:

Tasks in arcade, such as InstallDotNetCore end up calling this script to install .NET Core for development (building and testing projects).

In certain configurations, such as how AspNetCore's global.json is setup, this dotnet-install.sh script is called multiple times to install multiple architectures of .NET Core.

This script ends up calling the CLI's dotnet-install.sh to do the heavy lifting. But it always tells it to use the same path (eg .dotnet), even for different architectures.

This works mostly okay if x64 (and x86) are the only architectures. Because x86 is ignored and only x64 gets installed on *nix. On Windows, x64 goes in .dotnet and x86 goes in .dotnet/x86.

But as soon as multiple incompatible architectures enter the picture, things start breaking down. For example, as soon as I try and add arm64 to a global.json, this is what can happen:

  1. The main bootstrap processes (executed as part of ./build.sh) installs an arm64 SDK in ~/.dotnet to run msbuild.

  2. The InstallDotNetCore tasks tries to install the versions listed in global.json in order of their appearance.

  3. This dotnet-install.sh script installs x64 in .dotnet/.

  4. InstallDotNetCore task skips x86 (because it's non-Windows platform)

  5. This dotnet-install.sh scripts calls CLI's dotnet-install.sh to install arm64 in .dotnet/

  6. CLI's dotnet-install.sh sees that the runtime and/or SDK versions are already installed in .dotnet/ and doesn't do anything.

  7. When it comes time to execute dotnet again, the .dotnet directory contains multiple versions (some from the bootstrap, some from the InstallDotNetCore task). If the version in global.json is newer than the version installed initially, the dotnet binary tries to load that latest (and incompatible) x64 hostfxr that was installed.

  8. Build blows up because an arm64 process can't load up an x64 libhostfxr.so.

This change uses the approach that the Windows build takes for x86 and x64: .NET Core for the current architecture of the machine is installed at .dotnet/. Other SDKs/Runtimes are installed at .dotnet/$OTHER_ARCH/.

This change doesn't address a larger question: does it make sense to install mutliple SDKs for different architectures? It makes sense to install x64 and x86 on x64 machines for testing. Does it make any sense to install x86 (or even x64) on arm64?

Perhaps it might better if the list in global.json was filtered by Arcade so only the architecture of the build machine and any architectures known to be compatible with it were installed.

For more background, see dotnet/aspnetcore#14790 and #2815

cc @dougbu @dagood @markwilkie @vatsan-madhavan @chcosta @tmat

@chcosta
Copy link
Member

chcosta commented Oct 16, 2019

Sounds reasonable to me. @tmat?

@tmat
Copy link
Member

tmat commented Oct 16, 2019

LGTM. It would be good to add some comments to archmap on what should be listed there.

@omajid omajid force-pushed the dotnet-install-non-x86-architectures branch from d0f41e1 to a1afcdc Compare October 16, 2019 22:20
@omajid
Copy link
Member Author

omajid commented Oct 16, 2019

It would be good to add some comments to archmap on what should be listed there.

I replaced archmap with the code style used in coreclr to determine the current architecture. Hopefully this code is more obvious now.

eng/common/dotnet-install.sh Outdated Show resolved Hide resolved
@dagood dagood self-requested a review October 18, 2019 16:36
@omajid omajid force-pushed the dotnet-install-non-x86-architectures branch from a1afcdc to 21a7fac Compare October 18, 2019 17:15
@pranavkm
Copy link
Contributor

@dagood should this PR be merged?

@dagood
Copy link
Member

dagood commented Oct 23, 2019

There's a merge conflict so it can't be at the moment--it looks @tmat and @chcosta approved via comment so good to go other than the conflict IMO.

Here's the problem:

Tasks in arcade, such as `InstallDotNetCore` end up calling this script
to install .NET Core for development (building and testing projects).

In certain configurations, such as how AspNetCore's global.json is
setup, this dotnet-install.sh script is called multiple times to install
multiple architectures of .NET Core.

This script ends up calling the CLI's dotnet-install.sh to do the heavy
work. But it always tells it to use the same path (eg .dotnet), even for
different architectures.

This works mostly okay if x64 (and x86) are the only architectures.
Because x86 is ignored and only x64 gets installed on *nix. On Windows,
x64 goes in .dotnet and x86 goes in .dotnet/x86.

But as soon as multiple incompatible architectures enter the picture,
things start breaking down. For example, as soon as I try and add arm64
to a global.json, this is what can happen:

0. The main bootstrap process (exected as part of ./build.sh) installs
   an arm64 SDK in ~/.dotnet to run msbuild.

1. The `InstallDotNetCore` tasks tries to install the versions listed in
   global.json in order of their appearance.

2. This dotnet-install.sh script installs x64 SDK and/or runtime in
   .dotnet/ (if that version is different from the boostrap SDK).

3. InstallDotNetCore task skips x86 (becuase this is a non-Windows
   platform).

4. This dotnet-install.sh scripts calls CLI's dotnet-install.sh to
   install an arm64 SDK and/or runtime in .dotnet/.

5. CLI's dotnet-install.sh sees that the runtime and/or SDK versions are
   already installed in .dotnet/ and doesn't do anything.

6. When it comes time to execute `dotnet` again, the .dotnet directory
   contains multiple versions (some from the bootstrap, some from
   `InstallDotNetCore` task) of the runtime and host. If the version in
   global.json is newer than the version installed initially, the `dotnet`
   binary tries to load that latest (and incompatible) x64 hostfxr that was
   installed.

7. Build blows up because an arm64 process can't load up an x64
   libhostfxr.

This change uses the approach that the Windows build takes for x86 and
x64: .NET Core for the current architecture of the machine is installed
at `.dotnet/`. Other SDKs/Runtimes are installed at `.dotnet/$OTHER_ARCH/`.

This change doesn't address a larger question: does it make sense to
install mutliple SDKs for different architectures? It makes sense to
install x64 and x86 on x64 machiens for testing. Does it make any sense
to install x86 (or even x64) on arm64?

Perhaps it might better if the list in global.json was filtered by
Arcade so only the architecture of the build machine and any
architectures known to be compatible with it were installed.
@omajid omajid force-pushed the dotnet-install-non-x86-architectures branch from 21a7fac to a4df442 Compare October 23, 2019 15:29
@omajid
Copy link
Member Author

omajid commented Oct 23, 2019

I have rebased the patch and fixed up the merge conflicts now.

@dagood dagood merged commit 894bd00 into dotnet:master Oct 23, 2019
@omajid
Copy link
Member Author

omajid commented Oct 23, 2019

Thanks for the review and merging this change!

omajid added a commit to omajid/dotnet-aspnetcore that referenced this pull request Oct 23, 2019
arcade uses the runtime section of global.json to decide which
architecture + runtime combination needs to be installed.

With dotnet/arcade#4132 arcade can install
foreign SDKs in separate locations correctly.

This change, suggested by @dougbu, makes arcade always install the
runtime for the local architecture (which means it should work on arm64
and x64) as well as the x86 architecture (skipped on Linux).

This gets us a working SDK/Runtime combo on arm64.
dougbu pushed a commit to dotnet/aspnetcore that referenced this pull request Nov 2, 2019
arcade uses the runtime section of global.json to decide which
architecture + runtime combination needs to be installed.

With dotnet/arcade#4132 arcade can install
foreign SDKs in separate locations correctly.

This change, suggested by @dougbu, makes arcade always install the
runtime for the local architecture (which means it should work on arm64
and x64) as well as the x86 architecture (skipped on Linux).

This gets us a working SDK/Runtime combo on arm64.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants