Architecture in a .net core app

Hi,

If I create a .net core library and set the architecture to something other than anycpu what does it do ? Also if I set publish to true, I get a runtimes folder. Does the architecture influence that ?

I was looking at the deps.json file for a project created using dotnet and it has

"runtimeTarget": {
    "name": ".NETCoreApp,Version=v6.0/linux-x64",
    "signature": ""
  },

Whatever architecture I select in Fire I always get

  "runtimeTarget": {
    "name": ".NETCoreApp,Version=v6.0",
    "signature": ""
  },

and the runtimes folder never seems to change. Should it only have the architecture I selected ?
This is what it always contains
Screenshot 2022-12-28 at 9.08.12 PM
Cheers,
John

Not much, I believe, aside from setting a flag in the .exe that forces it to run only on that architecture (at least that’s what classic did. Essentially you could force an .exe to always run 32-bit, even on 674-bit systems. or to never run on 32-bit, by setting). This is useful eg you have a native dependency .dll that you only have one arch for.

I don’t believe so. Note there’s a separate RuntimeIdentifiers setting that you can use to say what runtime(s) to build for (as "architecture is rather vague, for something targeting multiple OSs). Normally, your project is built for the local runtime (e.g. “win-x86_64”), when building on Windows, but you can use that to build for all (or an arbitrary subset) of rutimes, including non-local OSs. We use that e.g. to build Ebuild and the compiler for all platforms, on our Windows build machine.

    <RuntimeIdentifiers>win-arm64;win-arm;win-x86;win-x64;osx-x64;osx-arm64;linux-x64</RuntimeIdentifiers>

I suppose I could look at limiting this, yeah. But again, Architecture is probably the wrong thing to use here, rather than the runtime (else, if you set x86_64, would you expect win-x86_64 and linux-x86_64 and osx-x86_64, but not win-i386? that seems counter-intuitive).

I’ll check with Carlo next week to see if the Architecture setting has any relevance on the Core side of things, still.

Follow-up Qs:

this is when building on linux-x64, i assume? or are you setting that as a target but building elsewhere with dotnet. I suppose i can look at always adding that, but im not sure what the benefit would be. if it ain’t broke…

You have a test-case handy for me? WIll any project do, with Publish=true?

I can try and create a test case.

Im trying to create a lambda function for aws. I got a simple example running with anycpu but when I tried with more code and assemblies I ran into problems.

One of the things I see in the aws logs is “Unknown application error occurred Runtime.Unknown” so i was comparing what the official tools generate compared to what Im generating using elements.

In the aws documentation it has

"Lambda provides a choice of instruction set architectures:

  • arm64 – 64-bit ARM architecture, for the AWS Graviton2 processor.
  • x86_64 – 64-bit x86 architecture, for x86-based processors. x86_64 is the default architecture. "

The first thing I found was that difference in the generated deps.json

1 Like

If you manually tweak the json to match dotnet before uploading, does that change anything?

thanx!

A simple project indeed does not hit this, as there’s no runtime folders involved.

If I specify the os when calling the dotnet command ie

dotnet build --os linux
or
dotnet publish -os linux

Then the deps.json is updated

  "runtimeTarget": {
    "name": ".NETCoreApp,Version=v6.0/linux-arm64",
    "signature": ""
  },

os is shorthand for --target in .net 6

the aws tool is doing this

… dotnet publish “/Users/JohnMoshakis/Documents/develop/sam-hello-world/lambda-dotnet6/src/HelloWorld” --output “/Users/JohnMoshakis/Documents/develop/sam-hello-world/lambda-dotnet6/src/HelloWorld/bin/Release/net6.0/publish” --configuration “Release” --framework “net6.0” --runtime linux-x64 /p:GenerateRuntimeConfigurationFiles=true --self-contained False

It does. It seems quite promising. I now get errors about missing assemblies.

Its a bit strange, I get

Amazon.Lambda.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.
Unhandled exception. System.IO.FileNotFoundException: Could not load file or assembly 'Amazon.Lambda.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.

but Im using v2.1.0 and been deployed.

Ok, I’ll look at adding this, then.

Strange indeed, but i’d need more context/details to comment more. are all your (non-system) package references set to Copy Local?

What happens if you build for more than one OS? there’s only a single .deps.json, even in that case (only the stub .exe gets duplicated)…

Do you mean dotnet ?

The strange thing is Im still building elements using anycpu, maybe thats causing a problem ? If I want to build for linux-x64 on my mac what would I chose in in elements?

K, so first change i made, if and only if exactly one value is set in RuntimeIdentifiers, then I will add this value to the runtime target name:

{
  "runtimeTarget": {
    "name": ".NETCoreApp,Version=v7.0/win-arm64",
    "signature": ""
  },

This will not happen if NONE are set (because it’s assumed that this app will/should run on any os/arch, nor if more than one is set.

Looking at the second issue (too many runtimes), the issue I see is that just looking across the packages in my local cache, these runtime names ar every varied and confusing.

The go from simple os named (win, osx, linux - but also “unix”), to expected combos (“win-aem64”) to more elaborate ones (“linux-musl-x64”), and specific linux distros even (“debian.8-x64”).

So I’m unsure what the exact logic should be.

Obviously, “win”, “osx”, “linux”, and versions with an architecture, I can handle easily.

What about “unix”.macOS is unix, so should a mac build get the “unix” folder or nor (is it only for other unix variants, wich we don’t actively support, and I didn’t think ,NET Core did either).

What’s “musl”, and should a “linux-x64” build get the “linux-musl-x64” runtime folder?

What about “debian-…” and “fedora-” folders?

For now I’ll fix it so that you only get the runtimes that either exactly match a target (eg “linux-x64”) or match an os "eg “win”), and we take it from there?

I’d still appreciate a testcase or a sample reference that adds the ones you screenshotted above, so I can test this more thoroughly.

There is this .NET Runtime Identifier (RID) catalog | Microsoft Learn ?

I think it makes sense to match the targets

Im still working on the example, I have to work out which reference is using the runtimes.

ugh.

just give me the list of package references your project has (ideally copied from the .elemehts so I can just paste them all in in one go)

Is this ok ?

ConsoleApplication4.zip (49.1 KB)

1 Like

i love how this docs aren’t even correct.

[os].[version]-[architecture]-[additional qualifiers]

doesn’t match

linux-musl-x64

:see_no_evil:

There is also this on supported targets https://github.com/dotnet/runtime/blob/main/src/libraries/Microsoft.NETCore.Platforms/src/runtime.js

404

sorry I missed the on