28 ms·
That's spelled `dotnet publish -r ${GOOS}-${GOARCH}` with the new ahead-of-time (branded Native AOT) compilation features installed and enabled. It isn't witho
by nrr 2y ago
That's spelled `dotnet publish -r ${GOOS}-${GOARCH}` with the new ahead-of-time (branded Native AOT) compilation features installed and enabled.
It isn't without a whole list of caveats if you're used to Go's way of doing things though. See <https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/ https://learn.microsoft.com/en-us/dotnet/core/deploying/nati...> for details.
- mdaniel 2y agoYou're very kind, thank you For others wanting to play along at home: $ docker run --name net8 --rm -it mcr.microsoft.com/dotnet/sdk:8.0-jammy-arm64v8 bash -c ' cd /root dotnet new -d -o console0 console cd console0 dotnet publish --nologo --self-contained -v d -r osx-arm64 -o console0-darwin-arm64 sleep 600 ' although it didn't shake out $ docker cp net8:/root/console0/console0-darwin-arm64/console0 ./console0 $ ./console0 Killed: 9 I tried with and without --self-contained and the biggest difference was that self-contained emitted a bazillion .dll files and without just emitted the binary. I case the context isn't obvious, $(dotnet new console) is a skeleton for the infamous WriteLine("Hello, World") without doing crazy whacko stuff
- neonsunset 2y agoFor simple JIT-based but fully self-contained binaries, without adding any properties to .csproj, the command is a bit mouthful and is as follows dotnet publish -p:PublishSingleFile=true -p:PublishTrimmed=true -o {folder} (you can put -p: arguments in .csproj too as XML attrs in <PropertyGroup>...) This will give you JIT-based "trimmed" binary (other languages call it tree shaking). You don't need to specify RID explicitly unless it's different from the one you are currently using. For simple applications, publishing as AOT (without opting in the csproj for that) is dotnet publish -p:PublishAot=true -o {folder} Add -p:OptimizationPreference=Speed and -p:IlcInstructionSet=native to taste. Official docs: https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-publish#examples https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-p...
- mdaniel 2y agoYou're also very kind, and I realized that it's possible there were a bazillion "watch out"s on the docs and was just trying the <PublishAot>true trick when I saw your comment However, it seems this brings my docker experiment to an abrupt halt, and is going to be some Holy Fucking Shit to re-implement that $(for GOOS) loop in any hypothetical CI system given the resulting explosion /usr/bin/sh: 2: /tmp/MSBuildTemproot/tmp194e0a13157b47889b36abb0ce96cd2d.exec.cmd: xcodebuild: not found
- neonsunset 2y agoYou need an OS for which you are building to be able to compile an AOT binary - it depends on OS-provided tooling (MSVC on Windows, Clang on macOS and Linux, and a system-provided linker from each respective system). In fact, once ILC is done compiling IL to .a or .lib, the native linker will just link together the csharp static lib, a GC, then runtime/PAL/misc and a couple of system dependencies into a final executable (you can also make a native library with this). Cross-architecture compilation is, however, supported (but requires the same extra dependencies as e.g. Rust). If you just want to publish for every target from a single docker container (you can't easily do that with e.g. Rust as noted), then you can go with JIT+single-file using the other command. Keep in mind that Go makes concessions in order for cross-compile to work, and invested extra engineering effort in that, while .NET makes emitting "canonical" native binaries using specific system environment a priority and also cares a lot about JIT instead (there aren't that many people working on .NET compiler infrastructure, so it effectively punches above its weight bypassing Go and Java and matching C++ if optimized).