Skip to content

Commit 0d3afe2

Browse files
First!
0 parents  commit 0d3afe2

9 files changed

+189
-0
lines changed

LICENSE.TXT

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) Michal Strehovsky
4+
5+
All rights reserved.
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy
8+
of this software and associated documentation files (the "Software"), to deal
9+
in the Software without restriction, including without limitation the rights
10+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
copies of the Software, and to permit persons to whom the Software is
12+
furnished to do so, subject to the following conditions:
13+
14+
The above copyright notice and this permission notice shall be included in all
15+
copies or substantial portions of the Software.
16+
17+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
SOFTWARE.

README.md

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# PublishAotCross
2+
3+
This is a NuGet package with an MSBuild target to aid in crosscompilation with [PublishAot](https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/). It helps resolving following error:
4+
5+
```sh
6+
$ dotnet publish -r linux-x64
7+
Microsoft.NETCore.Native.Publish.targets(59,5): error : Cross-OS native compilation is not supported.
8+
```
9+
10+
This nuget package allows using [Zig](https://ziglang.org/) as the linker/sysroot to allow crosscompiling to linux-x64/linux-arm64/linux-musl-x64/linux-musl-arm64 from a Windows machine.
11+
12+
1. [Download](https://ziglang.org/download/) an archive with Zig for your host machine, extract it and place it on your PATH. I'm using zig-windows-x86_64-0.11.0-dev.4006+bf827d0b5.zip.
13+
2. Optional: [download](https://releases.llvm.org/) LLVM. We only need llvm-objcopy executable so if you care about size, you can delete the rest. The executable needs to be on PATH - you could copy it next to the Zig executable. This step is optional and is required only to strip symbols (make the produced executables smaller). If you don't care about stripping symbols, you can skip it.
14+
3. To your project that is already using Native AOT, add a reference to this NuGet package.
15+
4. Publish for one of the newly available RIDs:
16+
* `dotnet publish -r linux-x64`
17+
* `dotnet publish -r linux-arm64`
18+
* `dotnet publish -r linux-musl-x64`
19+
* `dotnet publish -r linux-musl-arm64`
20+
21+
If you skipped the second optional step to download llvm-objcopy, you must also pass `/p:StripSymbols=false` to the publish command, or you'll see an error instructing you to do that.
22+
23+
Even though Zig allows crosscompiling for Windows as well, it's not possible to crosscompile PublishAot like this due to ABI differences (MSVC vs. MingW ABI).

global.json

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"msbuild-sdks": {
3+
"Microsoft.Build.NoTargets": "2.0.1"
4+
}
5+
}

src/Crosscompile.targets

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2+
3+
<PropertyGroup>
4+
<DisableUnsupportedError>true</DisableUnsupportedError>
5+
</PropertyGroup>
6+
7+
<UsingTask TaskName="PrependPath"
8+
TaskFactory="RoslynCodeTaskFactory"
9+
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
10+
11+
<ParameterGroup>
12+
<Value ParameterType="System.String" Required="true" />
13+
</ParameterGroup>
14+
15+
<Task>
16+
<Using Namespace="System" />
17+
<Using Namespace="System.IO" />
18+
<Code Type="Fragment" Language="cs">
19+
<![CDATA[
20+
Environment.SetEnvironmentVariable("PATH", Value + Path.PathSeparator + Environment.GetEnvironmentVariable("PATH"));
21+
]]>
22+
</Code>
23+
</Task>
24+
25+
</UsingTask>
26+
27+
<Target Name="SetPathToClang"
28+
BeforeTargets="SetupOSSpecificProps">
29+
30+
<PrependPath Value="$(MSBuildThisFileDirectory)" />
31+
32+
</Target>
33+
34+
<!-- BEGIN: Works around ILCompiler targets not detecting this as a cross compilation -->
35+
<Target Name="OverwriteTargetTriple"
36+
AfterTargets="SetupOSSpecificProps"
37+
BeforeTargets="LinkNative">
38+
39+
<PropertyGroup>
40+
<CrossCompileRid />
41+
<CrossCompileRid>$(RuntimeIdentifier)</CrossCompileRid>
42+
43+
<CrossCompileArch />
44+
<CrossCompileArch Condition="$(CrossCompileRid.EndsWith('-x64'))">x86_64</CrossCompileArch>
45+
<CrossCompileArch Condition="$(CrossCompileRid.EndsWith('-arm64'))">aarch64</CrossCompileArch>
46+
47+
<TargetTriple />
48+
<TargetTriple Condition="'$(CrossCompileArch)' != ''">$(CrossCompileArch)-linux-gnu</TargetTriple>
49+
<TargetTriple Condition="'$(CrossCompileArch)' != '' and ($(CrossCompileRid.StartsWith('linux-musl')) or $(CrossCompileRid.StartsWith('alpine')))">$(CrossCompileArch)-linux-musl</TargetTriple>
50+
</PropertyGroup>
51+
52+
<ItemGroup>
53+
<LinkerArg Include="--target=$(TargetTriple)" />
54+
</ItemGroup>
55+
56+
</Target>
57+
<!-- END: Works around ILCompiler targets not detecting this as a cross compilation -->
58+
59+
</Project>

src/PublishAotCross.nuproj

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<Project Sdk="Microsoft.Build.NoTargets">
2+
<PropertyGroup>
3+
4+
<TargetFramework>netstandard2.0</TargetFramework>
5+
6+
<PackageId>PublishAotCross</PackageId>
7+
<Version Condition="'$(Version)' == ''">42.42.42-dev</Version>
8+
<Authors>Michal Strehovsky</Authors>
9+
<Company>Michal Strehovsky</Company>
10+
<Description>MSBuild targets to aid in crosscompiling Native AOT publishing.</Description>
11+
<PackageProjectUrl>https://github.com/MichalStrehovsky/PublishAotCross</PackageProjectUrl>
12+
<PackageLicenseExpression>MIT</PackageLicenseExpression>
13+
<PackageReadmeFile>README.md</PackageReadmeFile>
14+
</PropertyGroup>
15+
16+
<ItemGroup>
17+
<None Include="PublishAotCross.targets">
18+
<Pack>true</Pack>
19+
<PackagePath>build</PackagePath>
20+
</None>
21+
<None Include="Crosscompile.targets">
22+
<Pack>true</Pack>
23+
<PackagePath>build</PackagePath>
24+
</None>
25+
<None Include="clang.cmd">
26+
<Pack>true</Pack>
27+
<PackagePath>build</PackagePath>
28+
</None>
29+
<None Include="../README.md">
30+
<Pack>true</Pack>
31+
<PackagePath>/</PackagePath>
32+
</None>
33+
</ItemGroup>
34+
</Project>

src/PublishAotCross.targets

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2+
3+
<!-- Only Windows host targeting Linux is currently supported -->
4+
<Import Project="Crosscompile.targets" Condition="$(RuntimeIdentifier.Contains('linux')) and $([MSBuild]::IsOSPlatform('Windows'))" />
5+
6+
</Project>

src/clang.cmd

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
@echo off
2+
3+
@where zig >nul 2>&1
4+
@if ERRORLEVEL 1 (
5+
echo Error: zig is not on the PATH. Install zig and make sure it's on PATH. Follow instructions at https://github.com/MichalStrehovsky/PublishAotCross.
6+
exit /B 1
7+
)
8+
9+
set args=%*
10+
11+
rem Works around zlib not being available with zig. This is not great.
12+
set args=%args:-lz =%
13+
14+
rem Work around parameters unsupported by zig. Just drop them from the command line.
15+
set args=%args:--discard-all=--as-needed%
16+
set args=%args:-Wl,-pie =%
17+
set args=%args:-pie =%
18+
19+
rem Works around zig linker dropping necessary parts of the executable.
20+
set args=-Wl,-u,__Module %args%
21+
22+
rem Run zig cc
23+
zig cc %args%

test/Hello.csproj

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<Project>
2+
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
3+
4+
<PropertyGroup>
5+
<OutputType>Exe</OutputType>
6+
<TargetFramework>net8.0</TargetFramework>
7+
<PublishAot>true</PublishAot>
8+
</PropertyGroup>
9+
10+
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
11+
12+
<Import Project="../src/PublishAotCross.targets" />
13+
</Project>

test/Program.cs

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
using System;
2+
3+
Console.WriteLine("Hello World");

0 commit comments

Comments
 (0)