Skip to content

Commit

Permalink
feat: support linux musl targets
Browse files Browse the repository at this point in the history
  • Loading branch information
YOU54F committed Sep 24, 2024
1 parent 8f98cb5 commit 5a45405
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 46 deletions.
45 changes: 44 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,51 @@ jobs:
name: nupkgs
path: ./dist/*.*

build-dotnet-containers:
runs-on: ubuntu-latest
name: ${{ matrix.arch }}-${{ matrix.distro }}-build-dotnet-container
strategy:
fail-fast: false
matrix:
arch:
- amd64
# - arm64
distro:
- "mcr.microsoft.com/dotnet/sdk:8.0"
- "mcr.microsoft.com/dotnet/sdk:8.0-alpine"

steps:
- uses: actions/checkout@v4

- name: Docker dependencies
id: docker_commands
shell: bash
run: |
if [[ ${{ matrix.distro }} == *"alpine"* ]]; then
echo "deps=apk add --no-cache curl bash gzip && " >> "$GITHUB_OUTPUT"
else
echo "deps=" >> "$GITHUB_OUTPUT"
fi
- name: Restore, Build & Test
run: |
docker run \
--rm \
-v $(pwd):/${{ github.workspace }} \
-w ${{ github.workspace }} \
--platform linux/${{ matrix.arch }} \
--entrypoint /bin/sh \
${{ matrix.distro }} \
-c '${{ steps.docker_commands.outputs.deps }} \
build/download-native-libs.sh && \
dotnet restore && dotnet build --no-restore && \
dotnet test --no-build --verbosity normal'
release:
needs: build-dotnet
needs: [
build-dotnet,
build-dotnet-containers
]
if: github.ref_type == 'tag'
runs-on: ubuntu-latest
steps:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ Due to using a shared native library instead of C# for the main Pact logic only
| Linux (libc) | ARM | ❌ No |
| Linux (libc) | x86 | ❌ No |
| Linux (libc) | x64 | ✔️ Yes |
| Linux (musl) | Any | [No](https://github.com/pact-foundation/pact-net/issues/374) |
| Linux (musl) | Any | ✔️ Yes |
| OSX | x64 | ✔️ Yes |
| OSX | ARM (M1/M2) | ✔️ Yes |

Expand Down
20 changes: 19 additions & 1 deletion build/download-native-libs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,23 @@ download_native() {
if [[ "$OSTYPE" == "darwin"* ]]; then
shasum -a 256 --check --quiet "$src_sha"
else
sha256sum --check --quiet "$src_sha"
if [[ "$OSTYPE" == "linux"* ]]; then
if ldd /bin/ls >/dev/null 2>&1; then
ldd_output=$(ldd /bin/ls)
case "$ldd_output" in
*musl*)
sha256sum -c -s "$path/$dest_file.sha256"
;;
*)
sha256sum --check --quiet "$src_sha"
;;
esac
else
sha256sum --check --quiet "$path/$dest_file.sha256"
fi
else
sha256sum --check --quiet "$path/$dest_file.sha256"
fi
fi

echo -e "${GREEN}OK${CLEAR}"
Expand All @@ -66,5 +82,7 @@ download_native "pact_ffi" "windows" "x86_64" "dll"
download_native "libpact_ffi" "linux" "x86_64" "so"
download_native "libpact_ffi" "macos" "x86_64" "dylib"
download_native "libpact_ffi" "macos" "aarch64" "dylib"
download_native "libpact_ffi" "linux" "x86_64-musl" "so"
download_native "libpact_ffi" "linux" "aarch64-musl" "so"

echo "Successfully downloaded FFI libraries"
128 changes: 85 additions & 43 deletions src/PactNet/PactNet.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk" InitialTargets="build_libs">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
Expand All @@ -9,49 +9,91 @@
</PropertyGroup>

<Import Project="../NuGet.targets" />
<Target Name="build_libs">
<!-- musl detection notes -->
<!-- Main fallback behaviour is to default to glibc flavour, ensuring miminal impact on existing supported targets -->
<!-- ContinueOnError True and Fallback to IsLinuxX64 / IsLinuxArm64 -->
<!-- 1. Check host is Linux - IsLinux -->
<!-- 2. Check if supported arch specific musl lib exists - IsLinuxMuslX64LibFound/IsLinuxMuslArm64LibFound -->
<!-- 3. Check if musl is the loaded libc -->
<!-- 3a. glibc hosts could have musl cross libs installed, in the standard musl location -->
<!-- 3b. use ldd on a well known binary such as /bin/sh and grep for musl -->
<!-- 3c. note ldd may not be available on all musl targets -->
<PropertyGroup>
<IsLinux>False</IsLinux>
<IsLinux Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'True'">True</IsLinux>
<IsLinuxMuslX64LibFound Condition="$([System.IO.File]::Exists('/lib/ld-musl-x86_64.so.1')) == 'True'">True</IsLinuxMuslX64LibFound>
<IsLinuxMuslArm64LibFound Condition="$([System.IO.File]::Exists('/lib/ld-musl-aarch64.so.1')) == 'True'">True</IsLinuxMuslArm64LibFound>
</PropertyGroup>
<!-- only run this check if linux and the musl shared libs were found -->
<Exec Command="ldd /bin/sh | grep musl" ConsoleToMSBuild="true" StandardOutputImportance="low" ContinueOnError="true" Condition="$(IsLinux) == 'True' And ($(IsLinuxMuslX64LibFound) == 'True' Or $(IsLinuxMuslArm64LibFound) == 'True')">
<Output TaskParameter="ExitCode" PropertyName="IsLinuxMuslLoaded"/>
</Exec>
<PropertyGroup>
<IsWindows>False</IsWindows>
<IsOSX>False</IsOSX>
<IsWindows Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'True'">True</IsWindows>
<IsOSX Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'True'">True</IsOSX>
<IsArm64>False</IsArm64>
<IsArm64 Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture)' == 'Arm64'">True</IsArm64>
<IsLinuxX64 Condition="'$(IsLinux)' == 'True' And '$(IsArm64)' == 'False'">True</IsLinuxX64>
<IsLinuxArm64 Condition="'$(IsLinux)' == 'True' And '$(IsArm64)' == 'True'">True</IsLinuxArm64>
<IsLinuxMuslX64 Condition="'$(IsLinux)' == 'True' And '$(IsLinuxMuslLoaded)' == '0' And '$(IsArm64)' == 'False'">True</IsLinuxMuslX64>
<IsLinuxMuslArm64 Condition="'$(IsLinux)' == 'True' And '$(IsLinuxMuslLoaded)' == '0' And '$(IsArm64)' == 'True'">True</IsLinuxMuslArm64>
</PropertyGroup>

<PropertyGroup>
<IsWindows>False</IsWindows>
<IsLinux>False</IsLinux>
<IsOSX>False</IsOSX>
<IsArm64>False</IsArm64>
<IsWindows Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'True'">True</IsWindows>
<IsLinux Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'True'">True</IsLinux>
<IsOSX Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'True'">True</IsOSX>
<IsArm64 Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture)' == 'Arm64'">True</IsArm64>
</PropertyGroup>

<ItemGroup>
<Content Include="$(MSBuildProjectDirectory)\..\..\build\windows\x86_64\pact_ffi.dll">
<Link>pact_ffi.dll</Link>
<PackagePath>runtimes/win-x64/native</PackagePath>
<Pack>true</Pack>
<CopyToOutputDirectory Condition="'$(IsWindows)'">PreserveNewest</CopyToOutputDirectory>
<Visible>false</Visible>
</Content>
<Content Include="$(MSBuildProjectDirectory)\..\..\build\linux\x86_64\libpact_ffi.so">
<Link>libpact_ffi.so</Link>
<PackagePath>runtimes/linux-x64/native</PackagePath>
<Pack>true</Pack>
<CopyToOutputDirectory Condition="'$(IsLinux)'">PreserveNewest</CopyToOutputDirectory>
<Visible>false</Visible>
</Content>
<Content Include="$(MSBuildProjectDirectory)\..\..\build\macos\x86_64\libpact_ffi.dylib">
<Link>libpact_ffi.dylib</Link>
<PackagePath>runtimes/osx-x64/native</PackagePath>
<Pack>true</Pack>
<CopyToOutputDirectory Condition="'$(IsOSX)' == 'True' And '$(IsArm64)' == 'False'">PreserveNewest</CopyToOutputDirectory>
<Visible>false</Visible>
</Content>
<Content Include="$(MSBuildProjectDirectory)\..\..\build\macos\aarch64\libpact_ffi.dylib">
<Link>libpact_ffi.dylib</Link>
<PackagePath>runtimes/osx-arm64/native</PackagePath>
<Pack>true</Pack>
<CopyToOutputDirectory Condition="'$(IsOSX)' == 'True' And '$(IsArm64)' == 'True'">PreserveNewest</CopyToOutputDirectory>
<Visible>false</Visible>
</Content>
</ItemGroup>

<ItemGroup>
<Content Include="$(MSBuildProjectDirectory)\..\..\build\windows\x86_64\pact_ffi.dll">
<Link>pact_ffi.dll</Link>
<PackagePath>runtimes/win-x64/native</PackagePath>
<Pack>true</Pack>
<CopyToOutputDirectory Condition="'$(IsWindows)'">PreserveNewest</CopyToOutputDirectory>
<Visible>false</Visible>
</Content>
<Content Include="$(MSBuildProjectDirectory)\..\..\build\linux\x86_64\libpact_ffi.so">
<Link>libpact_ffi.so</Link>
<PackagePath>runtimes/linux-x64/native</PackagePath>
<Pack>true</Pack>
<CopyToOutputDirectory Condition="'$(IsLinuxX64)' == 'True'">PreserveNewest</CopyToOutputDirectory>
<Visible>false</Visible>
</Content>
<Content Include="$(MSBuildProjectDirectory)\..\..\build\linux\aarch64\libpact_ffi.so">
<Link>libpact_ffi.so</Link>
<PackagePath>runtimes/linux-arm64/native</PackagePath>
<Pack>true</Pack>
<CopyToOutputDirectory Condition="'$(IsLinuxArm64)' == 'True'">PreserveNewest</CopyToOutputDirectory>
<Visible>false</Visible>
</Content>
<Content Include="$(MSBuildProjectDirectory)\..\..\build\linux\x86_64-musl\libpact_ffi.so">
<Link>libpact_ffi.so</Link>
<PackagePath>runtimes/linux-x64-musl/native</PackagePath>
<Pack>true</Pack>
<CopyToOutputDirectory Condition="'$(IsLinuxMuslX64)' == 'True'">PreserveNewest</CopyToOutputDirectory>
<Visible>false</Visible>
</Content>
<Content Include="$(MSBuildProjectDirectory)\..\..\build\linux\aarch64-musl\libpact_ffi.so">
<Link>libpact_ffi.so</Link>
<PackagePath>runtimes/linux-arm64-musl/native</PackagePath>
<Pack>true</Pack>
<CopyToOutputDirectory Condition="'$(IsLinuxMuslArm64)' == 'True'">PreserveNewest</CopyToOutputDirectory>
<Visible>false</Visible>
</Content>
<Content Include="$(MSBuildProjectDirectory)\..\..\build\macos\x86_64\libpact_ffi.dylib">
<Link>libpact_ffi.dylib</Link>
<PackagePath>runtimes/osx-x64/native</PackagePath>
<Pack>true</Pack>
<CopyToOutputDirectory Condition="'$(IsOSX)' == 'True' And '$(IsArm64)' == 'False'">PreserveNewest</CopyToOutputDirectory>
<Visible>false</Visible>
</Content>
<Content Include="$(MSBuildProjectDirectory)\..\..\build\macos\aarch64\libpact_ffi.dylib">
<Link>libpact_ffi.dylib</Link>
<PackagePath>runtimes/osx-arm64/native</PackagePath>
<Pack>true</Pack>
<CopyToOutputDirectory Condition="'$(IsOSX)' == 'True' And '$(IsArm64)' == 'True'">PreserveNewest</CopyToOutputDirectory>
<Visible>false</Visible>
</Content>
</ItemGroup>
</Target>
<ItemGroup>
<Content Include="$(MSBuildProjectDirectory)\..\..\build\PactNet.targets">
<PackagePath>build/net462/</PackagePath>
Expand Down

0 comments on commit 5a45405

Please sign in to comment.