From 450f1645fedc23476e8274b389b7c5e0da9d2568 Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Mon, 27 Apr 2026 03:58:51 +0900 Subject: [PATCH 001/101] Pivot to use vcpkg to build natives * put into nuget package --- .gitmodules | 3 + NetCord.Natives/.gitignore | 1 + NetCord.Natives/NetCord.Natives.csproj | 80 +++++++++++++++++++ NetCord.Natives/NetCord.Natives.props | 7 ++ NetCord.Natives/NetCord.Natives.targets | 42 ++++++++++ .../natives-ports/libdave/portfile.cmake | 29 +++++++ .../natives-ports/libdave/vcpkg.json | 18 +++++ .../natives-ports/mlspp/portfile.cmake | 29 +++++++ .../natives-ports/mlspp/vcpkg.json | 17 ++++ NetCord.Natives/vcpkg | 1 + NetCord.Natives/vcpkg.json | 12 +++ NetCord.slnx | 1 + 12 files changed, 240 insertions(+) create mode 100644 .gitmodules create mode 100644 NetCord.Natives/.gitignore create mode 100644 NetCord.Natives/NetCord.Natives.csproj create mode 100644 NetCord.Natives/NetCord.Natives.props create mode 100644 NetCord.Natives/NetCord.Natives.targets create mode 100644 NetCord.Natives/natives-ports/libdave/portfile.cmake create mode 100644 NetCord.Natives/natives-ports/libdave/vcpkg.json create mode 100644 NetCord.Natives/natives-ports/mlspp/portfile.cmake create mode 100644 NetCord.Natives/natives-ports/mlspp/vcpkg.json create mode 160000 NetCord.Natives/vcpkg create mode 100644 NetCord.Natives/vcpkg.json diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000..c33f058fc --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "NetCord.Natives/vcpkg"] + path = NetCord.Natives/vcpkg + url = https://github.com/microsoft/vcpkg.git diff --git a/NetCord.Natives/.gitignore b/NetCord.Natives/.gitignore new file mode 100644 index 000000000..07db887c6 --- /dev/null +++ b/NetCord.Natives/.gitignore @@ -0,0 +1 @@ +*.tlog diff --git a/NetCord.Natives/NetCord.Natives.csproj b/NetCord.Natives/NetCord.Natives.csproj new file mode 100644 index 000000000..37804cd0e --- /dev/null +++ b/NetCord.Natives/NetCord.Natives.csproj @@ -0,0 +1,80 @@ + + + + Pre-built binaries for NetCord, $(Description) + false + + bin\natives + vcpkg/scripts/buildsystems/msbuild/vcpkg + $([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)\..')) + + + + + + + vcpkg\%(Filename)%(Extension) + + + + + + + + true + + windows + x64 + $(Platform) + + debug + $(VcpkgInstalledDir)\$(VcpkgPlatformTarget)-$(VcpkgOSTarget)\$(DebugDefinedDir) + + + + + Built Natives $(DebugDefinedDir)\%(RecursiveDir)%(Filename)%(Extension) + + + + + + + + + + + + + + + + + + + + + + + + + + %(RecursiveDir)%(FileName)%(Extension) + true + runtimes\$(VcpkgOSTarget)-$(VcpkgPlatformTarget)\$(DebugDefinedDir)\ + + + + true + build\ + + + + + + + + + + diff --git a/NetCord.Natives/NetCord.Natives.props b/NetCord.Natives/NetCord.Natives.props new file mode 100644 index 000000000..ecee165d6 --- /dev/null +++ b/NetCord.Natives/NetCord.Natives.props @@ -0,0 +1,7 @@ + + + + $(MSBuildThisFileDirectory)..\runtimes\ + + + diff --git a/NetCord.Natives/NetCord.Natives.targets b/NetCord.Natives/NetCord.Natives.targets new file mode 100644 index 000000000..c65c04f8d --- /dev/null +++ b/NetCord.Natives/NetCord.Natives.targets @@ -0,0 +1,42 @@ + + + + + + true + true + true + + true + true + true + + true + + <_NetCordNativesPath>$(NetCordNativesPath)\$(RuntimeIdentifier) + + + + + + + + + + %(NativeFilter.Link) + %(Filename)%(Extension) + PreserveNewest + + + + + + + + + + + + diff --git a/NetCord.Natives/natives-ports/libdave/portfile.cmake b/NetCord.Natives/natives-ports/libdave/portfile.cmake new file mode 100644 index 000000000..8568d0223 --- /dev/null +++ b/NetCord.Natives/natives-ports/libdave/portfile.cmake @@ -0,0 +1,29 @@ +vcpkg_from_github( + OUT_SOURCE_PATH SOURCE_PATH + REPO discord/libdave + REF "${VERSION}" + SHA512 78b4e5b8ddc6397775d403465e0da770ec7905d7913546b3aec161baf4478443e554f0ae7bd012af8bfd308639be2601d46da22c02aff2b756ff91878f1fc843 + HEAD_REF main +) + +vcpkg_cmake_configure( + SOURCE_PATH "${SOURCE_PATH}/cpp" + OPTIONS + -DTESTING=OFF + -DBUILD_TESTING=OFF + MAYBE_UNUSED_VARIABLES + BUILD_TESTING +) + +vcpkg_cmake_build() + +vcpkg_cmake_install() +vcpkg_copy_pdbs() + +# file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include") + +# file(INSTALL +# "${SOURCE_PATH}/LICENSE" +# DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}" +# RENAME LICENSE.txt +# ) \ No newline at end of file diff --git a/NetCord.Natives/natives-ports/libdave/vcpkg.json b/NetCord.Natives/natives-ports/libdave/vcpkg.json new file mode 100644 index 000000000..9f74f4d3a --- /dev/null +++ b/NetCord.Natives/natives-ports/libdave/vcpkg.json @@ -0,0 +1,18 @@ +{ + "name": "libdave", + "version-string": "52cd56dc550f447fb354b3a06c9e2d2e2a4309c6", + "license": "MIT", + "dependencies": [ + "openssl", + "mlspp", + "nlohmann-json", + { + "name": "vcpkg-cmake", + "host": true + }, + { + "name": "vcpkg-cmake-config", + "host": true + } + ] +} \ No newline at end of file diff --git a/NetCord.Natives/natives-ports/mlspp/portfile.cmake b/NetCord.Natives/natives-ports/mlspp/portfile.cmake new file mode 100644 index 000000000..66dd943c4 --- /dev/null +++ b/NetCord.Natives/natives-ports/mlspp/portfile.cmake @@ -0,0 +1,29 @@ +vcpkg_from_github( + OUT_SOURCE_PATH SOURCE_PATH + REPO cisco/mlspp + REF "${VERSION}" + SHA512 5d37631e2c47daae1133ef074e60cc09ca2d395f9e11c416f829060e374051cf219d2d7fe98dae49d1d045292e07d6a09f4814a5f16e6cc05e67e7cd96f146c4 +) + +if(VCPKG_TARGET_IS_OSX AND EXISTS "/usr/local/include/openssl/") + set(VCPKG_INCLUDE_OVERRIDE "-DCMAKE_CXX_FLAGS=-I${CURRENT_INSTALLED_DIR}/include") +endif() + +set(VCPKG_LIBRARY_LINKAGE static) + +vcpkg_cmake_configure( + SOURCE_PATH "${SOURCE_PATH}" + OPTIONS + ${VCPKG_INCLUDE_OVERRIDE} + -DDISABLE_GREASE=ON + -DTESTING=OFF + -DBUILD_TESTING=OFF + -DMLS_CXX_NAMESPACE="mlspp" + MAYBE_UNUSED_VARIABLES + BUILD_TESTING +) + +vcpkg_cmake_install() +vcpkg_copy_pdbs() + +vcpkg_cmake_config_fixup(PACKAGE_NAME "MLSPP" CONFIG_PATH "share/MLSPP") diff --git a/NetCord.Natives/natives-ports/mlspp/vcpkg.json b/NetCord.Natives/natives-ports/mlspp/vcpkg.json new file mode 100644 index 000000000..fca869782 --- /dev/null +++ b/NetCord.Natives/natives-ports/mlspp/vcpkg.json @@ -0,0 +1,17 @@ +{ + "name": "mlspp", + "version-string": "1cc50a124a3bc4e143a787ec934280dc70c1034d", + "description": "Cisco MLS C++ library", + "dependencies": [ + "openssl", + "nlohmann-json", + { + "name": "vcpkg-cmake", + "host": true + }, + { + "name": "vcpkg-cmake-config", + "host": true + } + ] +} diff --git a/NetCord.Natives/vcpkg b/NetCord.Natives/vcpkg new file mode 160000 index 000000000..89dd0f4d2 --- /dev/null +++ b/NetCord.Natives/vcpkg @@ -0,0 +1 @@ +Subproject commit 89dd0f4d241136b843fb55813b2f0fa6448c204d diff --git a/NetCord.Natives/vcpkg.json b/NetCord.Natives/vcpkg.json new file mode 100644 index 000000000..426671ba9 --- /dev/null +++ b/NetCord.Natives/vcpkg.json @@ -0,0 +1,12 @@ +{ + "dependencies": [ + "libdave", + "opus", + "libsodium" + ], + "vcpkg-configuration": { + "overlay-ports": [ + "natives-ports" + ] + } +} diff --git a/NetCord.slnx b/NetCord.slnx index 23417afd4..fd20607e7 100644 --- a/NetCord.slnx +++ b/NetCord.slnx @@ -97,6 +97,7 @@ + From df31759176988977236369a99949fea9268cee24 Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Thu, 30 Apr 2026 00:38:00 +0900 Subject: [PATCH 002/101] * Add NetCord.Natives project and vcpkg support * Add native ports for libdave and mlspp * Update build workflows for native packaging * Add local targets and CI helpers for natives * Update README --- .github/workflows/build-and-publish.yml | 59 ++----- .github/workflows/build-natives.yml | 143 ++++++++++++++++ .github/workflows/build.yml | 1 + NetCord.Natives/NetCord.Natives.csproj | 159 ++++++++++++++---- NetCord.Natives/NetCord.Natives.local.targets | 17 ++ NetCord.Natives/NetCord.Natives.props | 10 +- NetCord.Natives/NetCord.Natives.targets | 44 ++--- .../natives-ports/libdave/portfile.cmake | 12 +- README.md | 3 + Resources/NuGet/README.md | 3 + 10 files changed, 328 insertions(+), 123 deletions(-) create mode 100644 .github/workflows/build-natives.yml create mode 100644 NetCord.Natives/NetCord.Natives.local.targets diff --git a/.github/workflows/build-and-publish.yml b/.github/workflows/build-and-publish.yml index e0e2b4c86..b404fa132 100644 --- a/.github/workflows/build-and-publish.yml +++ b/.github/workflows/build-and-publish.yml @@ -7,17 +7,18 @@ on: - "[0-9]+.[0-9]+.[0-9]+-*" jobs: - build-and-publish: + build: + uses: ./.github/workflows/build.yml + + publish: + needs: build runs-on: ubuntu-latest permissions: contents: write steps: - name: Checkout - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - with: - fetch-depth: 0 - filter: tree:0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Nix uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6 @@ -26,60 +27,26 @@ jobs: shell: &dev-shell 'nix develop -c bash -eo pipefail {0}' run: 'true' - - name: Restore dependencies - shell: *dev-shell - run: dotnet restore - - - name: Build - shell: *dev-shell - run: dotnet build -c Release --no-restore --warnaserror - - - name: Test - shell: *dev-shell - run: dotnet test -c Release --no-build --verbosity normal - - - name: Pack Packages - shell: *dev-shell - run: | - dotnet pack NetCord -c Release --no-build - dotnet pack NetCord.Services -c Release --no-build - dotnet pack Hosting/NetCord.Hosting -c Release --no-build - dotnet pack Hosting/NetCord.Hosting.Services -c Release --no-build - dotnet pack Hosting/NetCord.Hosting.AspNetCore -c Release --no-build - - - name: Setup docs environment - shell: &docs-shell 'nix develop .#docs -c bash -eo pipefail {0}' - run: 'true' - - - name: Build Documentation - shell: *docs-shell - working-directory: Documentation - run: | - npm install - npm run lint - npm run test - npm run build - - name: Publish Packages shell: *dev-shell env: KEY: ${{ secrets.NUGET_API_KEY }} run: | - dotnet nuget push NetCord/bin/Release/*.nupkg -k $KEY -s https://api.nuget.org/v3/index.json --skip-duplicate - dotnet nuget push NetCord.Services/bin/Release/*.nupkg -k $KEY -s https://api.nuget.org/v3/index.json --skip-duplicate - dotnet nuget push Hosting/NetCord.Hosting/bin/Release/*.nupkg -k $KEY -s https://api.nuget.org/v3/index.json --skip-duplicate - dotnet nuget push Hosting/NetCord.Hosting.Services/bin/Release/*.nupkg -k $KEY -s https://api.nuget.org/v3/index.json --skip-duplicate - dotnet nuget push Hosting/NetCord.Hosting.AspNetCore/bin/Release/*.nupkg -k $KEY -s https://api.nuget.org/v3/index.json --skip-duplicate + dotnet nuget push artifacts/build/NetCord/bin/Release/*.nupkg -k $KEY -s https://api.nuget.org/v3/index.json --skip-duplicate + dotnet nuget push artifacts/build/NetCord.Services/bin/Release/*.nupkg -k $KEY -s https://api.nuget.org/v3/index.json --skip-duplicate + dotnet nuget push artifacts/build/Hosting/NetCord.Hosting/bin/Release/*.nupkg -k $KEY -s https://api.nuget.org/v3/index.json --skip-duplicate + dotnet nuget push artifacts/build/Hosting/NetCord.Hosting.Services/bin/Release/*.nupkg -k $KEY -s https://api.nuget.org/v3/index.json --skip-duplicate + dotnet nuget push artifacts/build/Hosting/NetCord.Hosting.AspNetCore/bin/Release/*.nupkg -k $KEY -s https://api.nuget.org/v3/index.json --skip-duplicate - name: Deploy Documentation - uses: appleboy/scp-action@ff85246acaad7bdce478db94a363cd2bf7c90345 # v1.0.0 + uses: appleboy/scp-action@ff85246acaad7bdce478db94a363cd2bf7c90345 with: username: ${{ secrets.SSH_USERNAME }} host: ${{ secrets.SSH_HOST }} port: ${{ secrets.SSH_PORT }} key: ${{ secrets.SSH_KEY }} rm: true - source: Documentation/_site + source: artifacts/docs strip_components: 2 target: ~/NetCord/html diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml new file mode 100644 index 000000000..ed3496f24 --- /dev/null +++ b/.github/workflows/build-natives.yml @@ -0,0 +1,143 @@ +name: Build NetCord.Natives + +on: + workflow_dispatch: {} + push: + paths: + - 'NetCord.Natives/**' + +jobs: + build-natives: + runs-on: ${{ matrix.runs-on }} + env: + CI: true + VCPKG_BINARY_SOURCES: clear;files,${{ github.workspace }}/.vcpkg-cache,readwrite + VCPKG_DOWNLOADS: ${{ github.workspace }}/.vcpkg-downloads + strategy: + fail-fast: false + matrix: + include: + - rid: win-x64 + runs-on: windows-latest + vcpkg-os-target: windows + vcpkg-platform-target: x64 + - rid: win-arm64 + runs-on: windows-latest + vcpkg-os-target: windows + vcpkg-platform-target: arm64 + - rid: osx-x64 + runs-on: macos-latest + vcpkg-os-target: osx + vcpkg-platform-target: x64 + - rid: osx-arm64 + runs-on: macos-latest + vcpkg-os-target: osx + vcpkg-platform-target: arm64 + - rid: linux-x64 + runs-on: ubuntu-latest + vcpkg-os-target: linux + vcpkg-platform-target: x64 + - rid: linux-arm64 + runs-on: ubuntu-latest + vcpkg-os-target: linux + vcpkg-platform-target: arm64 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Cache vcpkg installs + uses: actions/cache@v4 + with: + path: | + .vcpkg-cache + .vcpkg-downloads + key: vcpkg-${{ runner.os }}-${{ matrix.rid }}-${{ hashFiles('NetCord.Natives/vcpkg.json') }} + restore-keys: | + vcpkg-${{ runner.os }}-${{ matrix.rid }}- + vcpkg-${{ runner.os }}- + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.0.x + + - name: Resolve vcpkg from runner image + shell: pwsh + run: | + $vcpkgRoot = $env:VCPKG_INSTALLATION_ROOT + if (-not $vcpkgRoot) { + $vcpkgCommand = Get-Command vcpkg -ErrorAction Stop + $vcpkgRoot = Split-Path -Parent $vcpkgCommand.Source + } + + if (-not (Test-Path $vcpkgRoot)) { + throw "vcpkg installation root not found." + } + + "VCPKG_ROOT=$vcpkgRoot" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 + "VcpkgMsbuildPath=$vcpkgRoot/scripts/buildsystems/msbuild/vcpkg" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 + + - name: Restore + shell: pwsh + run: | + dotnet restore NetCord.Natives/NetCord.Natives.csproj -p:VcpkgMsbuildPath=$env:VcpkgMsbuildPath -p:VcpkgOSTarget=${{ matrix.vcpkg-os-target }} -p:VcpkgPlatformTarget=${{ matrix.vcpkg-platform-target }} + + - name: Build native outputs for ${{ matrix.rid }} + shell: pwsh + run: | + dotnet build NetCord.Natives/NetCord.Natives.csproj -c Release --no-restore -p:GeneratePackageOnBuild=false -p:VcpkgMsbuildPath=$env:VcpkgMsbuildPath -p:VcpkgOSTarget=${{ matrix.vcpkg-os-target }} -p:VcpkgPlatformTarget=${{ matrix.vcpkg-platform-target }} + + - name: List artifacts + shell: pwsh + run: | + Get-ChildItem -Recurse NetCord.Natives/bin | Select-Object FullName + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.rid }} + path: NetCord.Natives/bin + + pack-natives: + needs: build-natives + runs-on: ubuntu-latest + env: + CI: true + NativeArtifactsRoot: ${{ github.workspace }}/artifacts + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Download native artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + merge-multiple: false + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.0.x + + - name: Resolve native license root + shell: pwsh + run: | + $licenseRoot = Get-ChildItem artifacts -Directory | Sort-Object Name | Select-Object -First 1 + if (-not $licenseRoot) { + throw "No native artifact directories were downloaded." + } + + "NativeLicenseRoot=$($licenseRoot.FullName)" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 + + - name: Pack combined nupkg + shell: pwsh + run: | + dotnet pack NetCord.Natives/NetCord.Natives.csproj -c Release --no-build --no-restore -p:VcpkgMsbuildPath=$env:VcpkgMsbuildPath -p:NativeArtifactsRoot=$env:NativeArtifactsRoot -p:NativeLicenseRoot=$env:NativeLicenseRoot -o artifacts/package + + - name: Upload nupkg + uses: actions/upload-artifact@v4 + with: + name: NetCord.Natives.Package + path: artifacts/package/*.nupkg diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 20ac2600e..47dbf5713 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,6 +1,7 @@ name: Build on: + workflow_call: pull_request: branches: - main diff --git a/NetCord.Natives/NetCord.Natives.csproj b/NetCord.Natives/NetCord.Natives.csproj index 37804cd0e..ef8e1acbc 100644 --- a/NetCord.Natives/NetCord.Natives.csproj +++ b/NetCord.Natives/NetCord.Natives.csproj @@ -1,45 +1,63 @@  - Pre-built binaries for NetCord, $(Description) + Pre-built native libraries for NetCord, $(Description) false - bin\natives - vcpkg/scripts/buildsystems/msbuild/vcpkg $([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)\..')) - - + + vcpkg\%(Filename)%(Extension) - - + debug + $(MSBuildProjectDirectory)\artifacts + + vcpkg/scripts/buildsystems/msbuild/vcpkg true - windows + windows + osx + linux + x64 $(Platform) - debug - $(VcpkgInstalledDir)\$(VcpkgPlatformTarget)-$(VcpkgOSTarget)\$(DebugDefinedDir) + bin\natives + $(VcpkgInstalledDir)-static + + $(VcpkgInstalledDir)\$(VcpkgPlatformTarget)-$(VcpkgOSTarget) + $(VcpkgInstalledDir)-static\$(VcpkgPlatformTarget)-$(VcpkgOSTarget)-static + $(BuildNativeOutputPath) + + ClCompile;_CopyNativeLicenses - - Built Natives $(DebugDefinedDir)\%(RecursiveDir)%(Filename)%(Extension) - + + + + + + + <_NetCordStaticFullPath Include="$([System.IO.Path]::GetFullPath('$(BuildNativeStaticOutputPath)'))" /> + + + + + - + @@ -47,34 +65,111 @@ - + + + + + + + + + + + + <_NativeLicenseSource Include="$(BuildNativeOutputPath)\share\%(AllowedNativesLicenses.Identity)\copyright" Condition="Exists('$(BuildNativeOutputPath)\share\%(AllowedNativesLicenses.Identity)\copyright')"> + $(BuildNativeOutputPath)\licenses\%(AllowedNativesLicenses.Identity)_LICENSE.txt + + + + - + + + + + + %(Filename)%(Extension) + PreserveNewest + + + + + + + $(PackageId).$(VcpkgOSTarget)-$(VcpkgPlatformTarget) + + + + runtimes\$(VcpkgOSTarget)-$(VcpkgPlatformTarget)\native\%(Filename)%(Extension) + + + runtimes-static\$(VcpkgOSTarget)-$(VcpkgPlatformTarget)\%(Filename)%(Extension) + + + + + <_NativeRuntime Include="win-x64"> + runtimes\win-x64\native\ + runtimes-static\win-x64\ + + <_NativeRuntime Include="win-arm64"> + runtimes\win-arm64\native\ + runtimes-static\win-arm64\ + + <_NativeRuntime Include="osx-x64"> + runtimes\osx-x64\native\ + runtimes-static\osx-x64\ + + <_NativeRuntime Include="osx-arm64"> + runtimes\osx-arm64\native\ + runtimes-static\osx-arm64\ + + <_NativeRuntime Include="linux-x64"> + runtimes\linux-x64\native\ + runtimes-static\linux-x64\ + + <_NativeRuntime Include="linux-arm64"> + runtimes\linux-arm64\native\ + runtimes-static\linux-arm64\ + + + + %(_NativeRuntime.PackageRuntimePath)%(Filename)%(Extension) + + + %(_NativeRuntime.PackageStaticPath)%(Filename)%(Extension) + + - - - - + + true + %(NativesBuilt.TargetPath) + - - %(RecursiveDir)%(FileName)%(Extension) + true - runtimes\$(VcpkgOSTarget)-$(VcpkgPlatformTarget)\$(DebugDefinedDir)\ + licenses\ - - + + <_BuildFiles Include="$(MSBuildProjectName).props;$(MSBuildProjectName).targets"> true - build\ + + + + build\$(PackageId)%(Extension) + + + buildTransitive\$(PackageId)%(Extension) - - - - - + + + + + diff --git a/NetCord.Natives/NetCord.Natives.local.targets b/NetCord.Natives/NetCord.Natives.local.targets new file mode 100644 index 000000000..1c79590df --- /dev/null +++ b/NetCord.Natives/NetCord.Natives.local.targets @@ -0,0 +1,17 @@ + + + + + + + + + + + + @(_NetCordStaticDir->'%(Identity)')\lib + + + + + diff --git a/NetCord.Natives/NetCord.Natives.props b/NetCord.Natives/NetCord.Natives.props index ecee165d6..021708eb4 100644 --- a/NetCord.Natives/NetCord.Natives.props +++ b/NetCord.Natives/NetCord.Natives.props @@ -1,7 +1,7 @@ - - - $(MSBuildThisFileDirectory)..\runtimes\ - - + + + $(MSBuildThisFileDirectory)..\runtimes-static\$(RuntimeIdentifier) + + diff --git a/NetCord.Natives/NetCord.Natives.targets b/NetCord.Natives/NetCord.Natives.targets index c65c04f8d..16d61ae6d 100644 --- a/NetCord.Natives/NetCord.Natives.targets +++ b/NetCord.Natives/NetCord.Natives.targets @@ -1,42 +1,20 @@ - + - - true - true - true + + <_NetCordStaticLink Include="libdave;mlspp;bytes;tls_syntax;hpke;libcrypto" + Condition="'%(DirectPInvoke.Identity)' == 'libdave'" /> + <_NetCordStaticLink Include="libsodium" + Condition="'%(DirectPInvoke.Identity)' == 'libsodium'" /> + <_NetCordStaticLink Include="opus" + Condition="'%(DirectPInvoke.Identity)' == 'opus'" /> - true - true - true + - true - - <_NetCordNativesPath>$(NetCordNativesPath)\$(RuntimeIdentifier) - - - - - - - - - - %(NativeFilter.Link) - %(Filename)%(Extension) - PreserveNewest - - - - - - - - + + diff --git a/NetCord.Natives/natives-ports/libdave/portfile.cmake b/NetCord.Natives/natives-ports/libdave/portfile.cmake index 8568d0223..a001f80e2 100644 --- a/NetCord.Natives/natives-ports/libdave/portfile.cmake +++ b/NetCord.Natives/natives-ports/libdave/portfile.cmake @@ -20,10 +20,8 @@ vcpkg_cmake_build() vcpkg_cmake_install() vcpkg_copy_pdbs() -# file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include") - -# file(INSTALL -# "${SOURCE_PATH}/LICENSE" -# DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}" -# RENAME LICENSE.txt -# ) \ No newline at end of file +file(INSTALL + "${SOURCE_PATH}/LICENSE" + DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}" + RENAME copyright +) diff --git a/README.md b/README.md index b3d29496c..cdbb638f1 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ You can install NetCord packages via NuGet package manager: | **[NetCord.Hosting](https://www.nuget.org/packages/NetCord.Hosting)** | Provides .NET Generic Host extensions for the NetCord package. | | **[NetCord.Hosting.Services](https://www.nuget.org/packages/NetCord.Hosting.Services)** | Provides .NET Generic Host extensions for the NetCord.Services package. | | **[NetCord.Hosting.AspNetCore](https://www.nuget.org/packages/NetCord.Hosting.AspNetCore)** | Provides ASP.NET Core extensions for seamless handling of HTTP events. | +| **[NetCord.Natives](https://www.nuget.org/packages/NetCord.Natives)** | Provides pre-built native binaries dependencies. | ## 2. 🚀 Showcase @@ -116,6 +117,8 @@ NetCord's goal is to allow .NET developers to create fully customizable Discord This repository is released under the [MIT License](LICENSE.md). +The use of NetCord.Natives may subject to each libraries licenses. + ## 9. 🛠️ Development ### Versioning diff --git a/Resources/NuGet/README.md b/Resources/NuGet/README.md index 89a1d4146..d7babe22d 100644 --- a/Resources/NuGet/README.md +++ b/Resources/NuGet/README.md @@ -25,6 +25,7 @@ You can install NetCord packages via NuGet package manager: | **[NetCord.Hosting](https://www.nuget.org/packages/NetCord.Hosting)** | Provides .NET Generic Host extensions for the NetCord package. | | **[NetCord.Hosting.Services](https://www.nuget.org/packages/NetCord.Hosting.Services)** | Provides .NET Generic Host extensions for the NetCord.Services package. | | **[NetCord.Hosting.AspNetCore](https://www.nuget.org/packages/NetCord.Hosting.AspNetCore)** | Provides ASP.NET Core extensions for seamless handling of HTTP events. | +| **[NetCord.Natives](https://www.nuget.org/packages/NetCord.Natives)** | Provides pre-built native binaries dependencies. | ## 2. 🚀 Showcase @@ -95,6 +96,8 @@ NetCord's goal is to allow .NET developers to create fully customizable Discord This repository is released under the [MIT License](https://github.com/NetCordDev/NetCord/blob/alpha/LICENSE.md). +The use of NetCord.Natives may subject to each libraries licenses. + ## 9. 🛠️ Development ### Versioning From 91178229dabe346b98cc4aed6a834116d1720059 Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Fri, 1 May 2026 05:56:49 +0900 Subject: [PATCH 003/101] feat: native library support and testing - GitHub Actions tag triggers, NuGet publish job - NativesHelper, NativeLibraryVersionAttribute - vcpkg integration, static linking - zstd support - native library tests, import checks - Native AOT test app - NetCordNativesDir assembly metadata --- .github/workflows/build-natives.yml | 41 +- NetCord.Natives/NativesHelper.cs | 20 + NetCord.Natives/NetCord.Natives.csproj | 389 ++++++++++-------- NetCord.Natives/NetCord.Natives.local.targets | 3 +- NetCord.Natives/NetCord.Natives.props | 2 +- NetCord.Natives/NetCord.Natives.targets | 2 + NetCord.Natives/vcpkg.json | 3 +- NetCord.slnx | 1 + Tests/NetCord.Natives.Tests/AssemblyInfo.cs | 3 + .../Assets/NativeAotApp/NativeAotApp.csproj | 24 ++ .../Assets/NativeAotApp/Program.cs | 90 ++++ .../NativesBuildTests.cs | 134 ++++++ .../NetCord.Natives.Tests.csproj | 44 ++ 13 files changed, 562 insertions(+), 194 deletions(-) create mode 100644 NetCord.Natives/NativesHelper.cs create mode 100644 Tests/NetCord.Natives.Tests/AssemblyInfo.cs create mode 100644 Tests/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj create mode 100644 Tests/NetCord.Natives.Tests/Assets/NativeAotApp/Program.cs create mode 100644 Tests/NetCord.Natives.Tests/NativesBuildTests.cs create mode 100644 Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index ed3496f24..91d27e9f0 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -5,6 +5,10 @@ on: push: paths: - 'NetCord.Natives/**' + - '.github/workflows/build-natives.yml' + tags: + - "[0-9]+.[0-9]+.[0-9]+" + - "[0-9]+.[0-9]+.[0-9]+-*" jobs: build-natives: @@ -57,11 +61,6 @@ jobs: vcpkg-${{ runner.os }}-${{ matrix.rid }}- vcpkg-${{ runner.os }}- - - name: Setup .NET - uses: actions/setup-dotnet@v4 - with: - dotnet-version: 8.0.x - - name: Resolve vcpkg from runner image shell: pwsh run: | @@ -116,21 +115,6 @@ jobs: path: artifacts merge-multiple: false - - name: Setup .NET - uses: actions/setup-dotnet@v4 - with: - dotnet-version: 8.0.x - - - name: Resolve native license root - shell: pwsh - run: | - $licenseRoot = Get-ChildItem artifacts -Directory | Sort-Object Name | Select-Object -First 1 - if (-not $licenseRoot) { - throw "No native artifact directories were downloaded." - } - - "NativeLicenseRoot=$($licenseRoot.FullName)" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 - - name: Pack combined nupkg shell: pwsh run: | @@ -141,3 +125,20 @@ jobs: with: name: NetCord.Natives.Package path: artifacts/package/*.nupkg + + publish: + needs: pack-natives + if: startsWith(github.ref, 'refs/tags/') + runs-on: ubuntu-latest + steps: + - name: Download nupkg + uses: actions/download-artifact@v4 + with: + name: NetCord.Natives.Package + path: artifacts/package + + - name: Publish Package + env: + KEY: ${{ secrets.NUGET_API_KEY }} + run: | + dotnet nuget push artifacts/package/*.nupkg -k $KEY -s https://api.nuget.org/v3/index.json --skip-duplicate diff --git a/NetCord.Natives/NativesHelper.cs b/NetCord.Natives/NativesHelper.cs new file mode 100644 index 000000000..866a421b6 --- /dev/null +++ b/NetCord.Natives/NativesHelper.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Reflection; + +namespace NetCord.Natives; + +[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] +public class NativeLibraryVersionAttribute(string name, string version) : Attribute +{ + public string Name { get; } = name; + public string Version { get; } = version; +} + +public static class NativesHelper +{ + public static IEnumerable GetNativeLibraryVersions() + { + return typeof(NativesHelper).Assembly.GetCustomAttributes(); + } +} diff --git a/NetCord.Natives/NetCord.Natives.csproj b/NetCord.Natives/NetCord.Natives.csproj index ef8e1acbc..0ea591d87 100644 --- a/NetCord.Natives/NetCord.Natives.csproj +++ b/NetCord.Natives/NetCord.Natives.csproj @@ -1,175 +1,222 @@  - - Pre-built native libraries for NetCord, $(Description) - false - - $([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)\..')) - - - - - - - vcpkg\%(Filename)%(Extension) - - - - - - debug - $(MSBuildProjectDirectory)\artifacts - - vcpkg/scripts/buildsystems/msbuild/vcpkg - true - - windows - osx - linux - - x64 - $(Platform) - - bin\natives - $(VcpkgInstalledDir)-static - - $(VcpkgInstalledDir)\$(VcpkgPlatformTarget)-$(VcpkgOSTarget) - $(VcpkgInstalledDir)-static\$(VcpkgPlatformTarget)-$(VcpkgOSTarget)-static - $(BuildNativeOutputPath) - - ClCompile;_CopyNativeLicenses - - - - - - - - - - - - <_NetCordStaticFullPath Include="$([System.IO.Path]::GetFullPath('$(BuildNativeStaticOutputPath)'))" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - <_NativeLicenseSource Include="$(BuildNativeOutputPath)\share\%(AllowedNativesLicenses.Identity)\copyright" Condition="Exists('$(BuildNativeOutputPath)\share\%(AllowedNativesLicenses.Identity)\copyright')"> - $(BuildNativeOutputPath)\licenses\%(AllowedNativesLicenses.Identity)_LICENSE.txt - - - - - - - - - - - - %(Filename)%(Extension) - PreserveNewest - - - - - - - $(PackageId).$(VcpkgOSTarget)-$(VcpkgPlatformTarget) - - - - runtimes\$(VcpkgOSTarget)-$(VcpkgPlatformTarget)\native\%(Filename)%(Extension) - - - runtimes-static\$(VcpkgOSTarget)-$(VcpkgPlatformTarget)\%(Filename)%(Extension) - - - - - <_NativeRuntime Include="win-x64"> - runtimes\win-x64\native\ - runtimes-static\win-x64\ - - <_NativeRuntime Include="win-arm64"> - runtimes\win-arm64\native\ - runtimes-static\win-arm64\ - - <_NativeRuntime Include="osx-x64"> - runtimes\osx-x64\native\ - runtimes-static\osx-x64\ - - <_NativeRuntime Include="osx-arm64"> - runtimes\osx-arm64\native\ - runtimes-static\osx-arm64\ - - <_NativeRuntime Include="linux-x64"> - runtimes\linux-x64\native\ - runtimes-static\linux-x64\ - - <_NativeRuntime Include="linux-arm64"> - runtimes\linux-arm64\native\ - runtimes-static\linux-arm64\ - - - - %(_NativeRuntime.PackageRuntimePath)%(Filename)%(Extension) - - - %(_NativeRuntime.PackageStaticPath)%(Filename)%(Extension) - - - - - - true - %(NativesBuilt.TargetPath) - - - - true - licenses\ - - - <_BuildFiles Include="$(MSBuildProjectName).props;$(MSBuildProjectName).targets"> - true - - - - build\$(PackageId)%(Extension) - - - buildTransitive\$(PackageId)%(Extension) - - - - - - - - + + Pre-built native libraries for NetCord, $(Description) + false + + $([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)\..')) + + + + + + + vcpkg\%(Filename)%(Extension) + + + + + + debug + + vcpkg/scripts/buildsystems/msbuild/vcpkg + true + + windows + osx + linux + + $(VcpkgOSTarget) + win + + x64 + $(Platform) + + bin + + $(NativeArtifactsRoot)\$(VcpkgBuildOS)-$(VcpkgPlatformTarget)\natives + $(VcpkgInstalledDir)-static + + $(VcpkgInstalledDir)\$(VcpkgPlatformTarget)-$(VcpkgOSTarget) + $(VcpkgInstalledDir)\$(VcpkgPlatformTarget)-$(VcpkgOSTarget)-static + + <_BuildNativeStaticOutputPath>$(VcpkgInstalledDir)\$(VcpkgPlatformTarget)-$(VcpkgOSTarget)-static + <_VcpkgStatusFile>$(VcpkgInstalledDir)\vcpkg\status + + + + + + + + + + + + + + <_NetCordStaticFullPath Include="$([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)\$(_BuildNativeStaticOutputPath)'))" /> + + + + + + + + + + + + + + + + + + + + + + + + <_NativeLicenseSource Include="$(BuildNativeOutputPath)\share\%(AllowedNativesLicenses.Identity)\copyright" + Condition="Exists('$(BuildNativeOutputPath)\share\%(AllowedNativesLicenses.Identity)\copyright')"> + $(BuildNativeOutputPath)\licenses\%(AllowedNativesLicenses.Identity)_LICENSE.txt + + + + + + + + + + + + + + + + @(StatusLines, ' ') + + + + + + + $([System.Text.RegularExpressions.Regex]::Match('$(StatusText)', 'Package: %(Identity)\n(?:.*\n)*?Version: (.*?)\n').Groups[1].Value) + + + + + + + <_Parameter1>%(PackageWithVersion.Identity) + <_Parameter2>%(PackageWithVersion.Version) + + + + + + + + + + + + + %(Filename)%(Extension) + PreserveNewest + false + + + + + + + + $(PackageId).$(VcpkgBuildOS)-$(VcpkgPlatformTarget) + + + + + runtimes\$(VcpkgBuildOS)-$(VcpkgPlatformTarget)\native\ + + + staticlibs\$(VcpkgBuildOS)-$(VcpkgPlatformTarget)\ + + + + + <_BuiltTriplets Include="x64-windows"> + win-x64 + x64-windows\bin\%(AllowedNativeLibrary.Identity) + x64-windows-static\lib\%(AllowedNativeLibrary.Identity) + + <_BuiltTriplets Include="arm64-windows"> + win-arm64 + arm64-windows\bin\%(AllowedNativeLibrary.Identity) + arm64-windows-static\lib\%(AllowedNativeLibrary.Identity) + + <_BuiltTriplets Include="x64-linux"> + linux-x64 + x64-linux\bin\%(AllowedNativeLibrary.Identity) + x64-linux-static\lib\%(AllowedNativeLibrary.Identity) + + <_BuiltTriplets Include="arm64-linux"> + linux-arm64 + arm64-linux\bin\%(AllowedNativeLibrary.Identity) + arm64-linux-static\lib\%(AllowedNativeLibrary.Identity) + + <_BuiltTriplets Include="x64-osx"> + osx-x64 + x64-osx\bin\%(AllowedNativeLibrary.Identity) + x64-osx-static\lib\%(AllowedNativeLibrary.Identity) + + <_BuiltTriplets Include="arm64-osx"> + osx-arm64 + arm64-osx\bin\%(AllowedNativeLibrary.Identity) + arm64-osx-static\lib\%(AllowedNativeLibrary.Identity) + + + + runtimes\%(_BuiltTriplets.RuntimeId)\native\ + + + staticlibs\%(_BuiltTriplets.RuntimeId)\ + + + + + + true + + + + true + licenses\ + + + <_BuildFiles Include="$(MSBuildProjectName).props;$(MSBuildProjectName).targets"> + true + + + + build\$(PackageId)%(Extension) + + + buildTransitive\$(PackageId)%(Extension) + + + + + + + + diff --git a/NetCord.Natives/NetCord.Natives.local.targets b/NetCord.Natives/NetCord.Natives.local.targets index 1c79590df..7a542e0e6 100644 --- a/NetCord.Natives/NetCord.Natives.local.targets +++ b/NetCord.Natives/NetCord.Natives.local.targets @@ -4,7 +4,8 @@ - + diff --git a/NetCord.Natives/NetCord.Natives.props b/NetCord.Natives/NetCord.Natives.props index 021708eb4..10bbd708b 100644 --- a/NetCord.Natives/NetCord.Natives.props +++ b/NetCord.Natives/NetCord.Natives.props @@ -1,7 +1,7 @@ - $(MSBuildThisFileDirectory)..\runtimes-static\$(RuntimeIdentifier) + $(MSBuildThisFileDirectory)..\staticlibs\$(RuntimeIdentifier) diff --git a/NetCord.Natives/NetCord.Natives.targets b/NetCord.Natives/NetCord.Natives.targets index 16d61ae6d..a9ab04c56 100644 --- a/NetCord.Natives/NetCord.Natives.targets +++ b/NetCord.Natives/NetCord.Natives.targets @@ -9,6 +9,8 @@ Condition="'%(DirectPInvoke.Identity)' == 'libsodium'" /> <_NetCordStaticLink Include="opus" Condition="'%(DirectPInvoke.Identity)' == 'opus'" /> + <_NetCordStaticLink Include="zstd" + Condition="'%(DirectPInvoke.Identity)' == 'zstd'" /> diff --git a/NetCord.Natives/vcpkg.json b/NetCord.Natives/vcpkg.json index 426671ba9..1712ed4f9 100644 --- a/NetCord.Natives/vcpkg.json +++ b/NetCord.Natives/vcpkg.json @@ -2,7 +2,8 @@ "dependencies": [ "libdave", "opus", - "libsodium" + "libsodium", + "zstd" ], "vcpkg-configuration": { "overlay-ports": [ diff --git a/NetCord.slnx b/NetCord.slnx index fd20607e7..08ac717dc 100644 --- a/NetCord.slnx +++ b/NetCord.slnx @@ -84,6 +84,7 @@ + diff --git a/Tests/NetCord.Natives.Tests/AssemblyInfo.cs b/Tests/NetCord.Natives.Tests/AssemblyInfo.cs new file mode 100644 index 000000000..ae411c7a1 --- /dev/null +++ b/Tests/NetCord.Natives.Tests/AssemblyInfo.cs @@ -0,0 +1,3 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; + +[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)] diff --git a/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj b/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj new file mode 100644 index 000000000..05c22e537 --- /dev/null +++ b/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj @@ -0,0 +1,24 @@ + + + + Exe + net10.0 + enable + enable + + true + true + + + + + + + + + + + + + + diff --git a/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/Program.cs b/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/Program.cs new file mode 100644 index 000000000..a64406852 --- /dev/null +++ b/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/Program.cs @@ -0,0 +1,90 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Runtime.InteropServices; + +internal static partial class NativeProbes +{ + [LibraryImport("libdave", EntryPoint = "daveMaxSupportedProtocolVersion")] + internal static partial uint DaveMaxSupportedProtocolVersion(); + + [LibraryImport("libsodium", EntryPoint = "sodium_init")] + internal static partial int SodiumInit(); + + [LibraryImport("opus", EntryPoint = "opus_get_version_string")] + internal static partial nint OpusGetVersionString(); + + [LibraryImport("libzstd", EntryPoint = "ZSTD_versionNumber")] + internal static partial uint ZstdVersionNumber(); +} + +internal static class Program +{ + private static void Main() + { + Console.WriteLine("NetCord native ahead of time publish app."); + + Console.WriteLine($"Dave Max Supported Protocol Version: {NativeProbes.DaveMaxSupportedProtocolVersion()}"); + Console.WriteLine($"Sodium Init: {NativeProbes.SodiumInit()}"); + Console.WriteLine($"Opus Version String: {Marshal.PtrToStringAnsi(NativeProbes.OpusGetVersionString())}"); + Console.WriteLine($"Zstd Version Number: {NativeProbes.ZstdVersionNumber()}"); + + var cwd = Path.GetFullPath(Directory.GetCurrentDirectory()); + Console.WriteLine($"Current working directory: {cwd}"); + + string[] libraries = new[] { "libdave", "libsodium", "opus", "libzstd" }; + var process = Process.GetCurrentProcess(); + var modules = process.Modules; + + bool allUnderCwd = true; + + foreach (var lib in libraries) + { + ProcessModule found = null; + foreach (ProcessModule m in modules) + { + if (!string.IsNullOrEmpty(m.FileName) && m.FileName.IndexOf(lib, StringComparison.OrdinalIgnoreCase) >= 0) + { + found = m; + break; + } + if (!string.IsNullOrEmpty(m.ModuleName) && m.ModuleName.IndexOf(lib, StringComparison.OrdinalIgnoreCase) >= 0) + { + found = m; + break; + } + } + + if (found == null) + { + Console.WriteLine($"Library '{lib}' not found among loaded modules."); + allUnderCwd = false; + continue; + } + + Console.WriteLine($"{lib} loaded from: {found.FileName}"); + if (!IsUnderDirectory(found.FileName, cwd)) + { + Console.WriteLine($"Library '{lib}' is not under current working directory."); + allUnderCwd = false; + } + } + + Environment.Exit(allUnderCwd ? 0 : 1); + } + + private static bool IsUnderDirectory(string path, string directory) + { + try + { + var fullPath = Path.GetFullPath(path); + var fullDir = Path.GetFullPath(directory).TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar) + Path.DirectorySeparatorChar; + var comparison = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal; + return fullPath.StartsWith(fullDir, comparison); + } + catch + { + return false; + } + } +} diff --git a/Tests/NetCord.Natives.Tests/NativesBuildTests.cs b/Tests/NetCord.Natives.Tests/NativesBuildTests.cs new file mode 100644 index 000000000..b47e24bb2 --- /dev/null +++ b/Tests/NetCord.Natives.Tests/NativesBuildTests.cs @@ -0,0 +1,134 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Reflection; +using System.Runtime.InteropServices; + +namespace NetCord.Natives.Tests; + +[TestClass] +public class NativesBuildTests +{ + // MSTest automatically injects this property + public TestContext TestContext { get; set; } + + [TestMethod] + [DataRow("libdave")] + [DataRow("libsodium")] + [DataRow("opus")] + [DataRow("zstd")] + public void NativesLoaded(string libName) + { + try + { + NativeLibrary.Load(libName); + } + catch (Exception ex) + { + Assert.Fail($"Failed to load library '{libName}': {ex}"); + } + } + + [TestMethod] + [DataRow("libdave", "NetCord.Gateway.Voice.Dave")] + [DataRow("libsodium", "NetCord.Gateway.Voice.Encryption.XChaCha20Poly1305")] + [DataRow("opus", "NetCord.Gateway.Voice.Opus")] + [DataRow("zstd", "NetCord.Gateway.Compression.Zstandard")] + public void AllLibraryImportsExistInBinary(string libName, string className) + { + IntPtr libHandle = IntPtr.Zero; + + try + { + var assembly = typeof(NetCord.Application).Assembly; + var typeWithImports = assembly.GetType(className, true); + + libHandle = NativeLibrary.Load(libName); + + var missingExports = new List(); + + // Reflect over methods with [LibraryImport] + var methods = typeWithImports!.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) + .Select(m => new { + MethodName = m.Name, + Attr = m.GetCustomAttribute() + }) + .Where(x => x.Attr != null); + Assert.IsNotEmpty(methods, $"No methods with [LibraryImport] found in '{className}'."); + + foreach (var item in methods) + { + // Use EntryPoint if defined, otherwise fallback to Method Name + string exportName = item.Attr!.EntryPoint ?? item.MethodName; + + if (!NativeLibrary.TryGetExport(libHandle, exportName, out _)) + { + missingExports.Add(exportName); + } + } + Assert.IsEmpty(missingExports, $"The following entry points were not found in '{libName}': {string.Join(", ", missingExports)}"); + } + catch (Exception ex) + { + Assert.Fail($"An error occurred while verifying imports for '{libName}': {ex}"); + } + finally + { + NativeLibrary.Free(libHandle); + } + } + + [TestMethod] + [DataRow("libdave;libsodium;opus;zstd")] + public void NativeAotStaticLinking(string libName) + { + try + { + // get NetCordNativesDir from AssemblyMetadata attribute + var assembly = typeof(NativesBuildTests).Assembly; + var nativesDir = assembly.GetCustomAttribute()?.Value; + Assert.IsNotNull(nativesDir, "NetCordNativesDir metadata attribute is not defined."); + + // build asset NativeAotApp with Native AoT enabled + var buildProcess = new System.Diagnostics.Process(); + buildProcess.StartInfo.FileName = "dotnet"; + buildProcess.StartInfo.ArgumentList.Add("publish"); + buildProcess.StartInfo.ArgumentList.Add("-p:Configuration=Release"); + buildProcess.StartInfo.ArgumentList.Add("-p:RuntimeIdentifier=" + RuntimeInformation.RuntimeIdentifier); + buildProcess.StartInfo.ArgumentList.Add($"-p:NetCordNativesDir={nativesDir}"); + buildProcess.StartInfo.ArgumentList.Add($"-p:NetCordDirectPInvoke=\"{libName}\""); + + TestContext.WriteLine($"Building Native AoT app: 'dotnet {buildProcess.StartInfo.ArgumentList.Aggregate((a, b) => $"{a} {b}")}'"); + + buildProcess.StartInfo.WorkingDirectory = Path.Combine(AppContext.BaseDirectory, "Assets", "NativeAotApp"); + buildProcess.StartInfo.RedirectStandardOutput = true; + buildProcess.StartInfo.RedirectStandardError = true; + buildProcess.Start(); + buildProcess.WaitForExit(); + + TestContext.WriteLine($"Build Output of AoT app for '{libName}': {buildProcess.StandardOutput.ReadToEnd()}"); + + Assert.AreEqual(0, buildProcess.ExitCode, + $"Native AoT build failed for '{libName}'. Output: {buildProcess.StandardError.ReadToEnd()}"); + + // check that the library is running without errors, which indicates that it was statically linked successfully + var aotProcess = new System.Diagnostics.Process(); + aotProcess.StartInfo.FileName = Path.Combine(AppContext.BaseDirectory, "Assets", "NativeAotApp", + "bin", "release", RuntimeInformation.RuntimeIdentifier, "publish", "NativeAotApp.exe"); + + TestContext.WriteLine($"Running Native AoT app: '{aotProcess.StartInfo.FileName}'"); + + aotProcess.StartInfo.RedirectStandardOutput = true; + aotProcess.StartInfo.RedirectStandardError = true; + aotProcess.Start(); + aotProcess.WaitForExit(); + + TestContext.WriteLine($"Output of AoT app for '{libName}': {aotProcess.StandardOutput.ReadToEnd()}"); + + Assert.AreEqual(0, aotProcess.ExitCode, + $"Native AoT app failed to run for '{libName}'. Output: {aotProcess.StandardError.ReadToEnd()}"); + } + catch (Exception ex) + { + Assert.Fail($"Failed to statically link '{libName}' for Native Ahead-of-Time (AoT) compilation: {ex}"); + } + } +} diff --git a/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj b/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj new file mode 100644 index 000000000..9ddd5a5b4 --- /dev/null +++ b/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj @@ -0,0 +1,44 @@ + + + + net10.0 + enable + enable + + false + true + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + ..\..\NetCord.Natives\ + + + + + + <_Parameter1>NetCordNativesDir + <_Parameter2>$([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)\$(NetCordNativesDir)')) + + + + + + + + From 88713281e1e94a266efbc11ba3d510fc347cce28 Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Tue, 5 May 2026 03:00:19 +0900 Subject: [PATCH 004/101] * Refactor NetCord.Natives.csproj for improved build configuration * Add MSVC builtin add overflow patch for libdave * Add vcpkg-non-windows.targets for cross-platform support * Update libdave and mlspp portfiles with build fixes * Update build-natives workflow and vcpkg.json versions * Fix vcpkg dependency resolution for multi-platform builds --- .github/workflows/build-natives.yml | 10 +- NetCord.Natives/NetCord.Natives.csproj | 186 +++++++++--------- .../fix-msvc-builtin-add-overflow.patch | 24 +++ .../natives-ports/libdave/portfile.cmake | 5 + .../natives-ports/mlspp/portfile.cmake | 4 + NetCord.Natives/vcpkg-non-windows.targets | 48 +++++ NetCord.Natives/vcpkg.json | 9 +- 7 files changed, 187 insertions(+), 99 deletions(-) create mode 100644 NetCord.Natives/natives-ports/libdave/fix-msvc-builtin-add-overflow.patch create mode 100644 NetCord.Natives/vcpkg-non-windows.targets diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index 91d27e9f0..26e8a3ba9 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -71,7 +71,11 @@ jobs: } if (-not (Test-Path $vcpkgRoot)) { - throw "vcpkg installation root not found." + # Bootstrap vcpkg + if ($IsWindows) { + & "$vcpkgRoot/bootstrap-vcpkg.bat" -disableMetrics + } else { + & "$vcpkgRoot/bootstrap-vcpkg.sh" -disableMetrics } "VCPKG_ROOT=$vcpkgRoot" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 @@ -85,7 +89,7 @@ jobs: - name: Build native outputs for ${{ matrix.rid }} shell: pwsh run: | - dotnet build NetCord.Natives/NetCord.Natives.csproj -c Release --no-restore -p:GeneratePackageOnBuild=false -p:VcpkgMsbuildPath=$env:VcpkgMsbuildPath -p:VcpkgOSTarget=${{ matrix.vcpkg-os-target }} -p:VcpkgPlatformTarget=${{ matrix.vcpkg-platform-target }} + dotnet build NetCord.Natives/NetCord.Natives.csproj -c Release --no-restore -p:GeneratePackageOnBuild=false -p:VcpkgRoot=$env:VCPKG_ROOT -p:VcpkgMsbuildPath=$env:VcpkgMsbuildPath -p:VcpkgOSTarget=${{ matrix.vcpkg-os-target }} -p:VcpkgPlatformTarget=${{ matrix.vcpkg-platform-target }} - name: List artifacts shell: pwsh @@ -118,7 +122,7 @@ jobs: - name: Pack combined nupkg shell: pwsh run: | - dotnet pack NetCord.Natives/NetCord.Natives.csproj -c Release --no-build --no-restore -p:VcpkgMsbuildPath=$env:VcpkgMsbuildPath -p:NativeArtifactsRoot=$env:NativeArtifactsRoot -p:NativeLicenseRoot=$env:NativeLicenseRoot -o artifacts/package + dotnet pack NetCord.Natives/NetCord.Natives.csproj -c Release --no-build --no-restore -p:VcpkgRoot=$env:VCPKG_ROOT -p:VcpkgMsbuildPath=$env:VcpkgMsbuildPath -p:NativeArtifactsRoot=$env:NativeArtifactsRoot -p:NativeLicenseRoot=$env:NativeLicenseRoot -o artifacts/package - name: Upload nupkg uses: actions/upload-artifact@v4 diff --git a/NetCord.Natives/NetCord.Natives.csproj b/NetCord.Natives/NetCord.Natives.csproj index 0ea591d87..67dbfe4fe 100644 --- a/NetCord.Natives/NetCord.Natives.csproj +++ b/NetCord.Natives/NetCord.Natives.csproj @@ -19,7 +19,12 @@ debug - vcpkg/scripts/buildsystems/msbuild/vcpkg + bin + + $(VCPKG_ROOT) + $(VcpkgRoot)\scripts\buildsystems\msbuild\vcpkg + + Release true windows @@ -28,71 +33,104 @@ $(VcpkgOSTarget) win - + + + false + x64 $(Platform) - bin - - $(NativeArtifactsRoot)\$(VcpkgBuildOS)-$(VcpkgPlatformTarget)\natives + $(VcpkgArtifactsRoot)\$(VcpkgBuildOS)-$(VcpkgPlatformTarget)\natives + $(VcpkgInstalledDirBase) $(VcpkgInstalledDir)-static - $(VcpkgInstalledDir)\$(VcpkgPlatformTarget)-$(VcpkgOSTarget) - $(VcpkgInstalledDir)\$(VcpkgPlatformTarget)-$(VcpkgOSTarget)-static - - <_BuildNativeStaticOutputPath>$(VcpkgInstalledDir)\$(VcpkgPlatformTarget)-$(VcpkgOSTarget)-static + $(VcpkgInstalledDirBase)-static\$(VcpkgPlatformTarget)-$(VcpkgOSTarget) + $(VcpkgOutputPath_Static)-static <_VcpkgStatusFile>$(VcpkgInstalledDir)\vcpkg\status - - - - + + + + + - + + + <_VcpkgRelatedFile Include="native-ports\**" /> - + - <_NetCordStaticFullPath Include="$([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)\$(_BuildNativeStaticOutputPath)'))" /> + <_StaticFullPath Include="$([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)\$(VcpkgOutputPath_Static)'))" /> - + + + + + + + $(VcpkgPlatformTarget)-$(VcpkgOSTarget) + $(VcpkgTriplet)-dynamic + + <_ZVcpkgMSBuildStampFile>$(_ZVcpkgInstalledDir).msbuildstamp-$(VcpkgTriplet).$(_ZVcpkgHostTripletSuffix)stamp + + + $(VcpkgInstalledDir)\$(VcpkgTriplet) + - - - - - - - - - + + <_LibArchs Include="x64;arm64"> + %(NativeLibSet.Identity) + + <_BuiltRid Include="win-%(_LibArchs.Identity)"> + %(_LibArchs.Identity)-windows\bin\%(_LibArchs.LibName) + %(_LibArchs.Identity)-windows-static\lib\%(_LibArchs.LibName) + dll + + <_BuiltRid Include="linux-%(_LibArchs.Identity)"> + %(_LibArchs.Identity)-linux-dynamic\lib\lib%(_LibArchs.LibName) + %(_LibArchs.Identity)-linux\lib\lib%(_LibArchs.LibName) + so + + <_BuiltRid Include="osx-%(_LibArchs.Identity)"> + %(_LibArchs.Identity)-osx-dynamic\lib\lib%(_LibArchs.LibName) + %(_LibArchs.Identity)-osx\lib\lib%(_LibArchs.LibName) + dylib + + <_BuiltRid Remove="%(Identity)" Condition="'$(CI)' != 'true' and '%(Identity)' != '$(VcpkgBuildOS)-$(VcpkgPlatformTarget)'" /> + - - + + + - - - <_NativeLicenseSource Include="$(BuildNativeOutputPath)\share\%(AllowedNativesLicenses.Identity)\copyright" - Condition="Exists('$(BuildNativeOutputPath)\share\%(AllowedNativesLicenses.Identity)\copyright')"> - $(BuildNativeOutputPath)\licenses\%(AllowedNativesLicenses.Identity)_LICENSE.txt + Properties="VcpkgUseStatic=true;GeneratePackageOnBuild=false" + Condition="'$(VcpkgUseStatic)' != 'true'" /> + + + <_NativeLicenseSource Include="$(VcpkgOutputPath)\share\%(NativeLibLic.Identity)\copyright" + Condition="Exists('$(VcpkgOutputPath)\share\%(NativeLibLic.Identity)\copyright')"> + $(VcpkgOutputPath)\licenses\%(NativeLibLic.Identity)_LICENSE.txt + SkipUnchangedFiles="true" Condition="'$(VcpkgUseStatic)' != 'true'" /> - + @@ -106,27 +144,27 @@ - + <_VcpkgPkg Include="@(NativeLibLic)"> $([System.Text.RegularExpressions.Regex]::Match('$(StatusText)', 'Package: %(Identity)\n(?:.*\n)*?Version: (.*?)\n').Groups[1].Value) - + - - <_Parameter1>%(PackageWithVersion.Identity) - <_Parameter2>%(PackageWithVersion.Version) + + <_Parameter1>%(_VcpkgPkg.Identity) + <_Parameter2>%(_VcpkgPkg.Version) - + - + - + %(Filename)%(Extension) @@ -136,67 +174,25 @@ - + $(PackageId).$(VcpkgBuildOS)-$(VcpkgPlatformTarget) - - - runtimes\$(VcpkgBuildOS)-$(VcpkgPlatformTarget)\native\ - - - staticlibs\$(VcpkgBuildOS)-$(VcpkgPlatformTarget)\ - - - - - <_BuiltTriplets Include="x64-windows"> - win-x64 - x64-windows\bin\%(AllowedNativeLibrary.Identity) - x64-windows-static\lib\%(AllowedNativeLibrary.Identity) - - <_BuiltTriplets Include="arm64-windows"> - win-arm64 - arm64-windows\bin\%(AllowedNativeLibrary.Identity) - arm64-windows-static\lib\%(AllowedNativeLibrary.Identity) - - <_BuiltTriplets Include="x64-linux"> - linux-x64 - x64-linux\bin\%(AllowedNativeLibrary.Identity) - x64-linux-static\lib\%(AllowedNativeLibrary.Identity) - - <_BuiltTriplets Include="arm64-linux"> - linux-arm64 - arm64-linux\bin\%(AllowedNativeLibrary.Identity) - arm64-linux-static\lib\%(AllowedNativeLibrary.Identity) - - <_BuiltTriplets Include="x64-osx"> - osx-x64 - x64-osx\bin\%(AllowedNativeLibrary.Identity) - x64-osx-static\lib\%(AllowedNativeLibrary.Identity) - - <_BuiltTriplets Include="arm64-osx"> - osx-arm64 - arm64-osx\bin\%(AllowedNativeLibrary.Identity) - arm64-osx-static\lib\%(AllowedNativeLibrary.Identity) - - - - runtimes\%(_BuiltTriplets.RuntimeId)\native\ + + + runtimes\%(_BuiltRid.Identity)\native\ - - staticlibs\%(_BuiltTriplets.RuntimeId)\ + + staticlibs\%(_BuiltRid.Identity)\ - - - + true - + true licenses\ diff --git a/NetCord.Natives/natives-ports/libdave/fix-msvc-builtin-add-overflow.patch b/NetCord.Natives/natives-ports/libdave/fix-msvc-builtin-add-overflow.patch new file mode 100644 index 000000000..f6d3360af --- /dev/null +++ b/NetCord.Natives/natives-ports/libdave/fix-msvc-builtin-add-overflow.patch @@ -0,0 +1,24 @@ +diff --git a/cpp/src/frame_processors.cpp b/cpp/src/frame_processors.cpp +index 37c8d70..5f0460c 100644 +--- a/cpp/src/frame_processors.cpp ++++ b/cpp/src/frame_processors.cpp +@@ -13,6 +13,9 @@ + + #if defined(_MSC_VER) + #include ++#if defined(_M_ARM64) ++#include ++#endif + #endif + + namespace discord { +@@ -25,6 +28,9 @@ std::pair OverflowAdd(size_t a, size_t b) + bool didOverflow = _addcarry_u64(0, a, b, &res); + #elif defined(_MSC_VER) && defined(_M_IX86) + bool didOverflow = _addcarry_u32(0, a, b, &res); ++#elif defined(_MSC_VER) && defined(_M_ARM64) ++ res = a + b; ++ bool didOverflow = res < a; + #else + bool didOverflow = __builtin_add_overflow(a, b, &res); + #endif diff --git a/NetCord.Natives/natives-ports/libdave/portfile.cmake b/NetCord.Natives/natives-ports/libdave/portfile.cmake index a001f80e2..4f7517e78 100644 --- a/NetCord.Natives/natives-ports/libdave/portfile.cmake +++ b/NetCord.Natives/natives-ports/libdave/portfile.cmake @@ -4,6 +4,7 @@ vcpkg_from_github( REF "${VERSION}" SHA512 78b4e5b8ddc6397775d403465e0da770ec7905d7913546b3aec161baf4478443e554f0ae7bd012af8bfd308639be2601d46da22c02aff2b756ff91878f1fc843 HEAD_REF main + PATCHES fix-msvc-builtin-add-overflow.patch ) vcpkg_cmake_configure( @@ -25,3 +26,7 @@ file(INSTALL DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}" RENAME copyright ) + +# Remove redundant debug directories to comply with vcpkg policy +file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include") +file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/share") diff --git a/NetCord.Natives/natives-ports/mlspp/portfile.cmake b/NetCord.Natives/natives-ports/mlspp/portfile.cmake index 66dd943c4..2ca219e33 100644 --- a/NetCord.Natives/natives-ports/mlspp/portfile.cmake +++ b/NetCord.Natives/natives-ports/mlspp/portfile.cmake @@ -27,3 +27,7 @@ vcpkg_cmake_install() vcpkg_copy_pdbs() vcpkg_cmake_config_fixup(PACKAGE_NAME "MLSPP" CONFIG_PATH "share/MLSPP") + +# Remove redundant debug directories to comply with vcpkg policy +file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include") +file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/share") diff --git a/NetCord.Natives/vcpkg-non-windows.targets b/NetCord.Natives/vcpkg-non-windows.targets new file mode 100644 index 000000000..134e697ad --- /dev/null +++ b/NetCord.Natives/vcpkg-non-windows.targets @@ -0,0 +1,48 @@ + + + + <_ZVcpkgInstallManifestDependenciesInputs Include="$(_ZVcpkgManifestFileLocation)"/> + <_ZVcpkgInstallManifestDependenciesInputs Include="$(_ZVcpkgConfigurationFileLocation)" + Condition="Exists('$(_ZVcpkgConfigurationFileLocation)')"/> + + + + + + + <_ZVcpkgTLogFileLocation>$(TLogLocation)VcpkgInstallManifest$(VcpkgTriplet).$(_ZVcpkgHostTripletSuffix)read.1u.tlog + + <_ZVcpkgExecutable>$(_ZVcpkgRoot)vcpkg + + + + + + + + + + + + + + + + + + + diff --git a/NetCord.Natives/vcpkg.json b/NetCord.Natives/vcpkg.json index 1712ed4f9..a3af5a404 100644 --- a/NetCord.Natives/vcpkg.json +++ b/NetCord.Natives/vcpkg.json @@ -9,5 +9,12 @@ "overlay-ports": [ "natives-ports" ] - } + }, + "builtin-baseline": "d07689ef165f033de5c0710e4f67c193a85373e1", + "overrides": [ + { + "name": "openssl", + "version": "3.0.7" + } + ] } From 48779598c690cc9eee908edb84558f188d9fa282 Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Tue, 5 May 2026 21:18:49 +0900 Subject: [PATCH 005/101] * Refactor native library handling and packaging * Add dynamic library exclusion for AOT builds * Add NativeAotApp test project --- NetCord.Natives/NetCord.Natives.csproj | 32 +++++++++---------- NetCord.Natives/NetCord.Natives.local.targets | 12 +++++-- NetCord.Natives/NetCord.Natives.props | 9 ++++++ NetCord.Natives/NetCord.Natives.targets | 28 ++++++++++++++-- NetCord.slnx | 1 + .../Assets/NativeAotApp/NativeAotApp.csproj | 20 ++++++------ .../Assets/NativeAotApp/Program.cs | 6 ++-- 7 files changed, 75 insertions(+), 33 deletions(-) diff --git a/NetCord.Natives/NetCord.Natives.csproj b/NetCord.Natives/NetCord.Natives.csproj index 67dbfe4fe..216d209f5 100644 --- a/NetCord.Natives/NetCord.Natives.csproj +++ b/NetCord.Natives/NetCord.Natives.csproj @@ -117,16 +117,6 @@ - - - <_NativeLicenseSource Include="$(VcpkgOutputPath)\share\%(NativeLibLic.Identity)\copyright" - Condition="Exists('$(VcpkgOutputPath)\share\%(NativeLibLic.Identity)\copyright')"> - $(VcpkgOutputPath)\licenses\%(NativeLibLic.Identity)_LICENSE.txt - - - - - + - - + <_CopyOutput Include="%(NativesRuntime.FullPath)" Condition="Exists('%(NativesRuntime.Identity)')"> %(Filename)%(Extension) PreserveNewest - false - + + + + <_NativeLicenseSource Include="$(VcpkgOutputPath_Static)\share\%(NativeLibLic.Identity)\copyright" + Condition="Exists('$(VcpkgOutputPath_Static)\share\%(NativeLibLic.Identity)\copyright')"> + $(VcpkgOutputPath_Static)\licenses\%(NativeLibLic.Identity)_LICENSE.txt + + + + + $(PackageId).$(VcpkgBuildOS)-$(VcpkgPlatformTarget) @@ -192,7 +192,7 @@ true - + true licenses\ diff --git a/NetCord.Natives/NetCord.Natives.local.targets b/NetCord.Natives/NetCord.Natives.local.targets index 7a542e0e6..3f730cc08 100644 --- a/NetCord.Natives/NetCord.Natives.local.targets +++ b/NetCord.Natives/NetCord.Natives.local.targets @@ -5,12 +5,20 @@ + Targets="GetStaticBuildDir" + Properties="CI=false"> + + + + - @(_NetCordStaticDir->'%(Identity)')\lib + %(_NetCordStaticDir.Identity)\lib + $([System.IO.Path]::GetDirectoryName('%(_NetCordRuntimesDir.FullPath)')) diff --git a/NetCord.Natives/NetCord.Natives.props b/NetCord.Natives/NetCord.Natives.props index 10bbd708b..c1b6ee94b 100644 --- a/NetCord.Natives/NetCord.Natives.props +++ b/NetCord.Natives/NetCord.Natives.props @@ -1,6 +1,15 @@ + + + + $(MSBuildThisFileDirectory)..\runtimes\$(RuntimeIdentifier) $(MSBuildThisFileDirectory)..\staticlibs\$(RuntimeIdentifier) diff --git a/NetCord.Natives/NetCord.Natives.targets b/NetCord.Natives/NetCord.Natives.targets index a9ab04c56..93d835ee1 100644 --- a/NetCord.Natives/NetCord.Natives.targets +++ b/NetCord.Natives/NetCord.Natives.targets @@ -12,11 +12,35 @@ <_NetCordStaticLink Include="zstd" Condition="'%(DirectPInvoke.Identity)' == 'zstd'" /> - + + - + + + + + <_NetCordExcluded Include="$(NetCordExcludeNatives)" + Condition="'$(NetCordExcludeNatives)' != ''" /> + <_NetCordExcluded Include="libcrypto" + Condition="$(NetCordExcludeNatives.Contains('libdave'))" /> + + <_NetCordExcluded Include="@(_NetCordStaticLink)" + Condition="'$(PublishAot)' == 'true' and '%(_NetCordStaticLink.Identity)' != ''"/> + + <_RunExclude Include="$(NetCordNativesRuntimesDir)\**\native\%(_NetCordExcluded.Identity)*.*" + Condition="'@(_NetCordExcluded.Identity)' != ''" /> + <_RunExclude Include="$(NetCordNativesRuntimesDir)\**\native\lib%(_NetCordExcluded.Identity)*.*" + Condition="'@(_NetCordExcluded.Identity)' != ''" /> + + + + + + diff --git a/NetCord.slnx b/NetCord.slnx index 08ac717dc..2338dbc5a 100644 --- a/NetCord.slnx +++ b/NetCord.slnx @@ -85,6 +85,7 @@ + diff --git a/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj b/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj index 05c22e537..8209957b8 100644 --- a/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj +++ b/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj @@ -1,4 +1,4 @@ - + Exe @@ -8,17 +8,17 @@ true true + true + false + + ..\..\..\..\NetCord.Natives - - - - - - + + + - - - + + diff --git a/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/Program.cs b/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/Program.cs index a64406852..111e3a690 100644 --- a/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/Program.cs +++ b/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/Program.cs @@ -14,7 +14,7 @@ internal static partial class NativeProbes [LibraryImport("opus", EntryPoint = "opus_get_version_string")] internal static partial nint OpusGetVersionString(); - [LibraryImport("libzstd", EntryPoint = "ZSTD_versionNumber")] + [LibraryImport("zstd", EntryPoint = "ZSTD_versionNumber")] internal static partial uint ZstdVersionNumber(); } @@ -32,7 +32,7 @@ private static void Main() var cwd = Path.GetFullPath(Directory.GetCurrentDirectory()); Console.WriteLine($"Current working directory: {cwd}"); - string[] libraries = new[] { "libdave", "libsodium", "opus", "libzstd" }; + string[] libraries = new[] { "libdave", "libsodium", "opus", "zstd" }; var process = Process.GetCurrentProcess(); var modules = process.Modules; @@ -40,7 +40,7 @@ private static void Main() foreach (var lib in libraries) { - ProcessModule found = null; + ProcessModule? found = null; foreach (ProcessModule m in modules) { if (!string.IsNullOrEmpty(m.FileName) && m.FileName.IndexOf(lib, StringComparison.OrdinalIgnoreCase) >= 0) From 925460c9a07761b50fcc40c70ad0c5938bfc7246 Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Wed, 6 May 2026 03:58:37 +0900 Subject: [PATCH 006/101] CI finished & fix typos & guarding --- .github/workflows/build-natives.yml | 119 ++++++++++++++++++++----- NetCord.Natives/NetCord.Natives.csproj | 4 +- 2 files changed, 99 insertions(+), 24 deletions(-) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index 26e8a3ba9..27e5fd3e5 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -48,15 +48,19 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6.0.2 - name: Cache vcpkg installs - uses: actions/cache@v4 + uses: actions/cache@v5.0.5 with: path: | .vcpkg-cache .vcpkg-downloads - key: vcpkg-${{ runner.os }}-${{ matrix.rid }}-${{ hashFiles('NetCord.Natives/vcpkg.json') }} + key: vcpkg-${{ runner.os }}-${{ matrix.rid }}- + ${{ hashFiles( + 'NetCord.Natives/vcpkg.json', + 'NetCord.Natives/natives-ports/**' + ) }} restore-keys: | vcpkg-${{ runner.os }}-${{ matrix.rid }}- vcpkg-${{ runner.os }}- @@ -64,68 +68,139 @@ jobs: - name: Resolve vcpkg from runner image shell: pwsh run: | + # Ensure vcpkg cache and downloads directories exist + New-Item -ItemType Directory -Path $env:VCPKG_BINARY_SOURCES.Split(',')[1] -Force | Out-Null + New-Item -ItemType Directory -Path $env:VCPKG_DOWNLOADS -Force | Out-Null + $vcpkgRoot = $env:VCPKG_INSTALLATION_ROOT if (-not $vcpkgRoot) { $vcpkgCommand = Get-Command vcpkg -ErrorAction Stop $vcpkgRoot = Split-Path -Parent $vcpkgCommand.Source } - if (-not (Test-Path $vcpkgRoot)) { - # Bootstrap vcpkg - if ($IsWindows) { - & "$vcpkgRoot/bootstrap-vcpkg.bat" -disableMetrics - } else { - & "$vcpkgRoot/bootstrap-vcpkg.sh" -disableMetrics + if (Test-Path $vcpkgRoot) { + # Bootstrap vcpkg + if ($IsWindows) { + & "$vcpkgRoot/bootstrap-vcpkg.bat" -disableMetrics + } else { + & "$vcpkgRoot/bootstrap-vcpkg.sh" -disableMetrics + } } "VCPKG_ROOT=$vcpkgRoot" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 - "VcpkgMsbuildPath=$vcpkgRoot/scripts/buildsystems/msbuild/vcpkg" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 + + - name: Install native build tools (macOS) + if: runner.os == 'macOS' + shell: bash + run: | + brew update + brew install autoconf automake libtool pkg-config + + - name: Install ARM64 cross-compiler (linux-arm64) + if: matrix.rid == 'linux-arm64' + shell: bash + run: | + sudo apt-get update + sudo apt-get install -yq gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc6-dev-arm64-cross - name: Restore shell: pwsh run: | - dotnet restore NetCord.Natives/NetCord.Natives.csproj -p:VcpkgMsbuildPath=$env:VcpkgMsbuildPath -p:VcpkgOSTarget=${{ matrix.vcpkg-os-target }} -p:VcpkgPlatformTarget=${{ matrix.vcpkg-platform-target }} + dotnet restore NetCord.Natives/NetCord.Natives.csproj -p:VcpkgRoot=$env:VCPKG_ROOT -p:VcpkgOSTarget=${{ matrix.vcpkg-os-target }} -p:VcpkgPlatformTarget=${{ matrix.vcpkg-platform-target }} - name: Build native outputs for ${{ matrix.rid }} shell: pwsh run: | - dotnet build NetCord.Natives/NetCord.Natives.csproj -c Release --no-restore -p:GeneratePackageOnBuild=false -p:VcpkgRoot=$env:VCPKG_ROOT -p:VcpkgMsbuildPath=$env:VcpkgMsbuildPath -p:VcpkgOSTarget=${{ matrix.vcpkg-os-target }} -p:VcpkgPlatformTarget=${{ matrix.vcpkg-platform-target }} + dotnet build NetCord.Natives/NetCord.Natives.csproj -c Release --no-restore -p:GeneratePackageOnBuild=false -p:VcpkgRoot=$env:VCPKG_ROOT -p:VcpkgOSTarget=${{ matrix.vcpkg-os-target }} -p:VcpkgPlatformTarget=${{ matrix.vcpkg-platform-target }} - - name: List artifacts + - name: List built for ${{ matrix.rid }} shell: pwsh run: | - Get-ChildItem -Recurse NetCord.Natives/bin | Select-Object FullName + $rid = '${{ matrix.rid }}' + $tripletBase = '${{ matrix.vcpkg-platform-target }}-${{ matrix.vcpkg-os-target }}' + $suffix = if ($IsWindows) { 'static' } else { 'dynamic' } + $triplets = @("$tripletBase", "$tripletBase-$suffix") + + foreach ($variant in @('natives','natives-static')) { + foreach ($triplet in @($triplets)) { + foreach ($folder in @('bin','lib')) { + $path = "NetCord.Natives/bin/$rid/$variant/$triplet/$folder" + if (Test-Path $path) { + Write-Host "Contents of: $path" + Get-ChildItem -Path $path -Recurse -Force | Select-Object FullName, Mode, Length, LastWriteTime + } else { + Write-Host "[Info]Not found: $path" + } + } + } + } - name: Upload artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7.0.1 with: name: ${{ matrix.rid }} - path: NetCord.Natives/bin + path: NetCord.Natives/bin/${{ matrix.rid }} pack-natives: needs: build-natives runs-on: ubuntu-latest env: CI: true - NativeArtifactsRoot: ${{ github.workspace }}/artifacts + VCPKG_BINARY_SOURCES: clear;files,${{ github.workspace }}/.vcpkg-cache,readwrite + VCPKG_DOWNLOADS: ${{ github.workspace }}/.vcpkg-downloads + VcpkgArtifactsRoot: ${{ github.workspace }}/artifacts steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6.0.2 - name: Download native artifacts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8.0.1 with: path: artifacts merge-multiple: false + - name: Resolve vcpkg from runner image + shell: pwsh + run: | + # Ensure vcpkg cache and downloads directories exist + New-Item -ItemType Directory -Path $env:VCPKG_BINARY_SOURCES.Split(',')[1] -Force | Out-Null + New-Item -ItemType Directory -Path $env:VCPKG_DOWNLOADS -Force | Out-Null + + $vcpkgRoot = $env:VCPKG_INSTALLATION_ROOT + if (-not $vcpkgRoot) { + $vcpkgCommand = Get-Command vcpkg -ErrorAction Stop + $vcpkgRoot = Split-Path -Parent $vcpkgCommand.Source + } + + if (Test-Path $vcpkgRoot) { + # Bootstrap vcpkg + if ($IsWindows) { + & "$vcpkgRoot/bootstrap-vcpkg.bat" -disableMetrics + } else { + & "$vcpkgRoot/bootstrap-vcpkg.sh" -disableMetrics + } + } + + "VCPKG_ROOT=$vcpkgRoot" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 + + - name: Restore (required for pack) + shell: pwsh + run: | + dotnet restore NetCord.Natives/NetCord.Natives.csproj -p:VcpkgRoot=$env:VCPKG_ROOT -p:VcpkgEnabled=false + + - name: Build cross-platform .NET (required for pack) + shell: pwsh + run: | + dotnet build NetCord.Natives/NetCord.Natives.csproj -c Release --no-restore -p:VcpkgRoot=$env:VCPKG_ROOT -p:VcpkgEnabled=false + - name: Pack combined nupkg shell: pwsh run: | - dotnet pack NetCord.Natives/NetCord.Natives.csproj -c Release --no-build --no-restore -p:VcpkgRoot=$env:VCPKG_ROOT -p:VcpkgMsbuildPath=$env:VcpkgMsbuildPath -p:NativeArtifactsRoot=$env:NativeArtifactsRoot -p:NativeLicenseRoot=$env:NativeLicenseRoot -o artifacts/package + dotnet pack NetCord.Natives/NetCord.Natives.csproj -c Release --no-build --no-restore -p:VcpkgRoot=$env:VCPKG_ROOT -p:VcpkgArtifactsRoot=$env:VcpkgArtifactsRoot -o $env:VcpkgArtifactsRoot/package - name: Upload nupkg - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7.0.1 with: name: NetCord.Natives.Package path: artifacts/package/*.nupkg @@ -136,7 +211,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Download nupkg - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8.0.1 with: name: NetCord.Natives.Package path: artifacts/package diff --git a/NetCord.Natives/NetCord.Natives.csproj b/NetCord.Natives/NetCord.Natives.csproj index 216d209f5..621f50651 100644 --- a/NetCord.Natives/NetCord.Natives.csproj +++ b/NetCord.Natives/NetCord.Natives.csproj @@ -55,7 +55,7 @@ - + @@ -174,7 +174,7 @@ + SkipUnchangedFiles="true" Condition="'@(_NativeLicenseSource)' != ''" /> $(PackageId).$(VcpkgBuildOS)-$(VcpkgPlatformTarget) From 57ac8b1cd8a6f4770cfa9c7c26941de39d2f44fc Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Wed, 6 May 2026 04:10:51 +0900 Subject: [PATCH 007/101] solution build fix --- .../Assets/NativeAotApp/NativeAotApp.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj b/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj index 8209957b8..2eade7215 100644 --- a/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj +++ b/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj @@ -11,7 +11,7 @@ true false - ..\..\..\..\NetCord.Natives + ..\..\..\..\NetCord.Natives From 2f1ab0b43c131721f408ea32646ccdc36f82d038 Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Wed, 6 May 2026 06:36:19 +0900 Subject: [PATCH 008/101] separate solution for natives * natives conditionals fix * fix nativeaot test structure * add natives tests to build workflow --- .github/workflows/build-natives.yml | 9 ++- .github/workflows/build.yml | 6 +- NetCord.Natives.slnx | 7 +++ NetCord.Natives/NetCord.Natives.csproj | 12 ++-- NetCord.Natives/NetCord.Natives.local.targets | 5 +- NetCord.Natives/NetCord.Natives.targets | 4 +- NetCord.slnx | 4 +- .../Assets/NativeAotApp/NativeAotApp.csproj | 1 + .../Assets/NativeAotApp/Program.cs | 60 +------------------ .../NativesBuildTests.cs | 31 ++++++++-- .../NetCord.Natives.Tests.csproj | 8 +++ 11 files changed, 67 insertions(+), 80 deletions(-) create mode 100644 NetCord.Natives.slnx diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index 27e5fd3e5..c56bd99c6 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -1,4 +1,4 @@ -name: Build NetCord.Natives +name: Build, Test, and Package NetCord.Natives on: workflow_dispatch: {} @@ -11,7 +11,7 @@ on: - "[0-9]+.[0-9]+.[0-9]+-*" jobs: - build-natives: + build-test-natives: runs-on: ${{ matrix.runs-on }} env: CI: true @@ -113,6 +113,11 @@ jobs: run: | dotnet build NetCord.Natives/NetCord.Natives.csproj -c Release --no-restore -p:GeneratePackageOnBuild=false -p:VcpkgRoot=$env:VCPKG_ROOT -p:VcpkgOSTarget=${{ matrix.vcpkg-os-target }} -p:VcpkgPlatformTarget=${{ matrix.vcpkg-platform-target }} + - name: Test native outputs for ${{ matrix.rid }} + shell: pwsh + run: | + dotnet test NetCord.Natives.Tests/NetCord.Natives.Tests.csproj -c Release -p:VcpkgRoot=$env:VCPKG_ROOT -p:VcpkgOSTarget=${{ matrix.vcpkg-os-target }} -p:VcpkgPlatformTarget=${{ matrix.vcpkg-platform-target }} --verbosity normal + - name: List built for ${{ matrix.rid }} shell: pwsh run: | diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 47dbf5713..bc3979d3c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -36,11 +36,13 @@ jobs: - name: Build shell: *dev-shell - run: dotnet build -c Release --no-restore --warnaserror + run: | + dotnet build NetCord.slnx -c Release --no-restore --warnaserror + dotnet build NetCord.Natives.slnx -c Release --no-restore --warnaserror -p:VcpkgRoot=$VCPKG_INSTALLATION_ROOT -p:VcpkgEnabled=false - name: Test shell: *dev-shell - run: dotnet test -c Release --no-build --verbosity normal + run: dotnet test NetCord.slnx -c Release --no-build --verbosity normal - name: Pack Packages shell: *dev-shell diff --git a/NetCord.Natives.slnx b/NetCord.Natives.slnx new file mode 100644 index 000000000..1f71c5697 --- /dev/null +++ b/NetCord.Natives.slnx @@ -0,0 +1,7 @@ + + + + + + + diff --git a/NetCord.Natives/NetCord.Natives.csproj b/NetCord.Natives/NetCord.Natives.csproj index 621f50651..735f1e982 100644 --- a/NetCord.Natives/NetCord.Natives.csproj +++ b/NetCord.Natives/NetCord.Natives.csproj @@ -76,6 +76,10 @@ Condition="'$(VcpkgBuildOS)' != 'win' and Exists('vcpkg-non-windows.targets')" /> + + + $(VcpkgPlatformTarget)-$(VcpkgOSTarget) $(VcpkgTriplet)-dynamic @@ -111,7 +115,7 @@ - + - <_CopyOutput Include="%(NativesRuntime.FullPath)" Condition="Exists('%(NativesRuntime.Identity)')"> - %(Filename)%(Extension) + <_CopyOutput Include="%(NativesRuntime.FullPath)"> + %(NativesRuntime.Filename)%(NativesRuntime.Extension) PreserveNewest - + diff --git a/NetCord.Natives/NetCord.Natives.local.targets b/NetCord.Natives/NetCord.Natives.local.targets index 3f730cc08..06e3c54de 100644 --- a/NetCord.Natives/NetCord.Natives.local.targets +++ b/NetCord.Natives/NetCord.Natives.local.targets @@ -1,6 +1,6 @@ - + @@ -18,7 +18,8 @@ %(_NetCordStaticDir.Identity)\lib - $([System.IO.Path]::GetDirectoryName('%(_NetCordRuntimesDir.FullPath)')) + $([System.IO.Path]::GetDirectoryName('%(_NetCordRuntimesDir.FullPath)')) diff --git a/NetCord.Natives/NetCord.Natives.targets b/NetCord.Natives/NetCord.Natives.targets index 93d835ee1..0e8c8d0fd 100644 --- a/NetCord.Natives/NetCord.Natives.targets +++ b/NetCord.Natives/NetCord.Natives.targets @@ -34,9 +34,9 @@ Condition="'$(PublishAot)' == 'true' and '%(_NetCordStaticLink.Identity)' != ''"/> <_RunExclude Include="$(NetCordNativesRuntimesDir)\**\native\%(_NetCordExcluded.Identity)*.*" - Condition="'@(_NetCordExcluded.Identity)' != ''" /> + Condition="'@(_NetCordExcluded.Identity)' != '' and '$(NetCordNativesRuntimesDir)' != ''" /> <_RunExclude Include="$(NetCordNativesRuntimesDir)\**\native\lib%(_NetCordExcluded.Identity)*.*" - Condition="'@(_NetCordExcluded.Identity)' != ''" /> + Condition="'@(_NetCordExcluded.Identity)' != '' and '$(NetCordNativesRuntimesDir)' != ''" /> diff --git a/NetCord.slnx b/NetCord.slnx index 2338dbc5a..30dd9affd 100644 --- a/NetCord.slnx +++ b/NetCord.slnx @@ -84,8 +84,7 @@ - - + @@ -99,7 +98,6 @@ - diff --git a/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj b/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj index 2eade7215..2fae99ab0 100644 --- a/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj +++ b/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj @@ -9,6 +9,7 @@ true true true + true false ..\..\..\..\NetCord.Natives diff --git a/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/Program.cs b/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/Program.cs index 111e3a690..bf91f09c8 100644 --- a/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/Program.cs +++ b/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/Program.cs @@ -25,66 +25,8 @@ private static void Main() Console.WriteLine("NetCord native ahead of time publish app."); Console.WriteLine($"Dave Max Supported Protocol Version: {NativeProbes.DaveMaxSupportedProtocolVersion()}"); - Console.WriteLine($"Sodium Init: {NativeProbes.SodiumInit()}"); + Console.WriteLine($"Sodium Init: {NativeProbes.SodiumInit()}. 0 = OK"); Console.WriteLine($"Opus Version String: {Marshal.PtrToStringAnsi(NativeProbes.OpusGetVersionString())}"); Console.WriteLine($"Zstd Version Number: {NativeProbes.ZstdVersionNumber()}"); - - var cwd = Path.GetFullPath(Directory.GetCurrentDirectory()); - Console.WriteLine($"Current working directory: {cwd}"); - - string[] libraries = new[] { "libdave", "libsodium", "opus", "zstd" }; - var process = Process.GetCurrentProcess(); - var modules = process.Modules; - - bool allUnderCwd = true; - - foreach (var lib in libraries) - { - ProcessModule? found = null; - foreach (ProcessModule m in modules) - { - if (!string.IsNullOrEmpty(m.FileName) && m.FileName.IndexOf(lib, StringComparison.OrdinalIgnoreCase) >= 0) - { - found = m; - break; - } - if (!string.IsNullOrEmpty(m.ModuleName) && m.ModuleName.IndexOf(lib, StringComparison.OrdinalIgnoreCase) >= 0) - { - found = m; - break; - } - } - - if (found == null) - { - Console.WriteLine($"Library '{lib}' not found among loaded modules."); - allUnderCwd = false; - continue; - } - - Console.WriteLine($"{lib} loaded from: {found.FileName}"); - if (!IsUnderDirectory(found.FileName, cwd)) - { - Console.WriteLine($"Library '{lib}' is not under current working directory."); - allUnderCwd = false; - } - } - - Environment.Exit(allUnderCwd ? 0 : 1); - } - - private static bool IsUnderDirectory(string path, string directory) - { - try - { - var fullPath = Path.GetFullPath(path); - var fullDir = Path.GetFullPath(directory).TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar) + Path.DirectorySeparatorChar; - var comparison = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal; - return fullPath.StartsWith(fullDir, comparison); - } - catch - { - return false; - } } } diff --git a/Tests/NetCord.Natives.Tests/NativesBuildTests.cs b/Tests/NetCord.Natives.Tests/NativesBuildTests.cs index b47e24bb2..f0bc87c62 100644 --- a/Tests/NetCord.Natives.Tests/NativesBuildTests.cs +++ b/Tests/NetCord.Natives.Tests/NativesBuildTests.cs @@ -80,25 +80,42 @@ public void AllLibraryImportsExistInBinary(string libName, string className) [DataRow("libdave;libsodium;opus;zstd")] public void NativeAotStaticLinking(string libName) { + var projectDirectory = Path.Combine(AppContext.BaseDirectory, "Assets", "NativeAotApp"); + var projectFile = Path.Combine(projectDirectory, "NativeAotApp.csproj"); + var generatedProjectFile = Path.Combine(projectDirectory, "NativeAotApp.g.csproj"); + try { + var originalProjectFileContents = File.ReadAllText(projectFile); + var generatedProjectFileContents = originalProjectFileContents.Replace("$(NetCordDirectPInvoke)", libName); + File.WriteAllText(generatedProjectFile, generatedProjectFileContents); + // get NetCordNativesDir from AssemblyMetadata attribute var assembly = typeof(NativesBuildTests).Assembly; - var nativesDir = assembly.GetCustomAttribute()?.Value; + var nativesDir = assembly.GetCustomAttributes()? + .FirstOrDefault(a => a.Key == "NetCordNativesDir")?.Value; Assert.IsNotNull(nativesDir, "NetCordNativesDir metadata attribute is not defined."); + var vcpkgRoot = assembly.GetCustomAttributes()? + .FirstOrDefault(a => a.Key == "VcpkgRoot")?.Value; + Assert.IsNotNull(vcpkgRoot, "VcpkgRoot metadata attribute is not defined."); + var targetFramework = assembly.GetCustomAttributes()? + .FirstOrDefault(a => a.Key == "TargetFramework")?.Value; + Assert.IsNotNull(targetFramework, "TargetFramework metadata attribute is not defined."); // build asset NativeAotApp with Native AoT enabled var buildProcess = new System.Diagnostics.Process(); buildProcess.StartInfo.FileName = "dotnet"; buildProcess.StartInfo.ArgumentList.Add("publish"); + buildProcess.StartInfo.ArgumentList.Add("NativeAotApp.g.csproj"); buildProcess.StartInfo.ArgumentList.Add("-p:Configuration=Release"); + buildProcess.StartInfo.ArgumentList.Add($"-p:TargetFramework={targetFramework}"); buildProcess.StartInfo.ArgumentList.Add("-p:RuntimeIdentifier=" + RuntimeInformation.RuntimeIdentifier); buildProcess.StartInfo.ArgumentList.Add($"-p:NetCordNativesDir={nativesDir}"); - buildProcess.StartInfo.ArgumentList.Add($"-p:NetCordDirectPInvoke=\"{libName}\""); + buildProcess.StartInfo.ArgumentList.Add($"-p:VcpkgRoot={vcpkgRoot}"); - TestContext.WriteLine($"Building Native AoT app: 'dotnet {buildProcess.StartInfo.ArgumentList.Aggregate((a, b) => $"{a} {b}")}'"); + TestContext.WriteLine($"Building Native AoT app in ({projectDirectory}): 'dotnet {buildProcess.StartInfo.ArgumentList.Aggregate((a, b) => $"{a} {b}")}'"); - buildProcess.StartInfo.WorkingDirectory = Path.Combine(AppContext.BaseDirectory, "Assets", "NativeAotApp"); + buildProcess.StartInfo.WorkingDirectory = projectDirectory; buildProcess.StartInfo.RedirectStandardOutput = true; buildProcess.StartInfo.RedirectStandardError = true; buildProcess.Start(); @@ -111,8 +128,10 @@ public void NativeAotStaticLinking(string libName) // check that the library is running without errors, which indicates that it was statically linked successfully var aotProcess = new System.Diagnostics.Process(); - aotProcess.StartInfo.FileName = Path.Combine(AppContext.BaseDirectory, "Assets", "NativeAotApp", - "bin", "release", RuntimeInformation.RuntimeIdentifier, "publish", "NativeAotApp.exe"); + aotProcess.StartInfo.FileName = Path.Combine(projectDirectory, "bin", "release", targetFramework, + RuntimeInformation.RuntimeIdentifier, "publish", + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? + "NativeAotApp.g.exe" : "NativeAotApp.g"); TestContext.WriteLine($"Running Native AoT app: '{aotProcess.StartInfo.FileName}'"); diff --git a/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj b/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj index 9ddd5a5b4..4eaa6e27b 100644 --- a/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj +++ b/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj @@ -35,6 +35,14 @@ <_Parameter1>NetCordNativesDir <_Parameter2>$([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)\$(NetCordNativesDir)')) + + <_Parameter1>VcpkgRoot + <_Parameter2>$(VcpkgRoot) + + + <_Parameter1>TargetFramework + <_Parameter2>$(TargetFramework) + From 9def22bbdbee125ea46ed98dda7c570764bf1784 Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Sat, 9 May 2026 01:30:34 +0900 Subject: [PATCH 009/101] refactor native build/test pipeline - add reusable vcpkg setup - pack per-RID native nupkgs - streamline NativeAOT test logging - tighten native linking targets --- .github/actions/setup-vcpkg/action.yml | 43 ++++ .github/workflows/build-and-publish.yml | 6 +- .github/workflows/build-natives.yml | 182 +++++--------- .github/workflows/build.yml | 18 +- NetCord.Natives.slnx | 20 ++ NetCord.Natives/NetCord.Natives.csproj | 3 +- NetCord.Natives/NetCord.Natives.targets | 35 ++- .../Assets/NativeAotApp/NativeAotApp.csproj | 6 + .../Assets/NativeAotApp/Program.cs | 35 +-- Tests/NetCord.Natives.Tests/NativeProbes.cs | 78 ++++++ .../NativesBuildTests.cs | 225 +++++++++--------- .../NetCord.Natives.Tests.csproj | 23 +- 12 files changed, 376 insertions(+), 298 deletions(-) create mode 100644 .github/actions/setup-vcpkg/action.yml create mode 100644 Tests/NetCord.Natives.Tests/NativeProbes.cs diff --git a/.github/actions/setup-vcpkg/action.yml b/.github/actions/setup-vcpkg/action.yml new file mode 100644 index 000000000..58416aea3 --- /dev/null +++ b/.github/actions/setup-vcpkg/action.yml @@ -0,0 +1,43 @@ +name: Setup vcpkg +description: Setup vcpkg with fallback to submodule checkout + +runs: + using: composite + steps: + - name: Resolve or checkout vcpkg + shell: pwsh + run: | + # Ensure vcpkg cache and downloads directories exist + New-Item -ItemType Directory -Path $env:VCPKG_BINARY_SOURCES.Split(',')[1] -Force | Out-Null + New-Item -ItemType Directory -Path $env:VCPKG_DOWNLOADS -Force | Out-Null + + $vcpkgRoot = $env:VCPKG_INSTALLATION_ROOT + if (-not $vcpkgRoot) { + $vcpkgCommand = Get-Command vcpkg -ErrorAction SilentlyContinue + if ($vcpkgCommand) { + $vcpkgRoot = Split-Path -Parent $vcpkgCommand.Source + } + } + + if (-not $vcpkgRoot -or -not (Test-Path $vcpkgRoot)) { + Write-Host "vcpkg not found in runner image, checking out from submodule..." + git config --file .gitmodules --get-regexp path | while-object { $_.Split()[-1] | where-object { $_ -match 'vcpkg' } } | ForEach-Object { + git submodule update --init --recursive $_ + } + $vcpkgRoot = Join-Path $env:GITHUB_WORKSPACE "vcpkg" + if (-not (Test-Path $vcpkgRoot)) { + Write-Error "vcpkg submodule not found and vcpkg executable not available" + exit 1 + } + } + + if (Test-Path $vcpkgRoot) { + Write-Host "Bootstrapping vcpkg from: $vcpkgRoot" + if ($IsWindows) { + & "$vcpkgRoot/bootstrap-vcpkg.bat" -disableMetrics + } else { + & "$vcpkgRoot/bootstrap-vcpkg.sh" -disableMetrics + } + } + + "VCPKG_ROOT=$vcpkgRoot" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 diff --git a/.github/workflows/build-and-publish.yml b/.github/workflows/build-and-publish.yml index b404fa132..306afe5f1 100644 --- a/.github/workflows/build-and-publish.yml +++ b/.github/workflows/build-and-publish.yml @@ -32,11 +32,7 @@ jobs: env: KEY: ${{ secrets.NUGET_API_KEY }} run: | - dotnet nuget push artifacts/build/NetCord/bin/Release/*.nupkg -k $KEY -s https://api.nuget.org/v3/index.json --skip-duplicate - dotnet nuget push artifacts/build/NetCord.Services/bin/Release/*.nupkg -k $KEY -s https://api.nuget.org/v3/index.json --skip-duplicate - dotnet nuget push artifacts/build/Hosting/NetCord.Hosting/bin/Release/*.nupkg -k $KEY -s https://api.nuget.org/v3/index.json --skip-duplicate - dotnet nuget push artifacts/build/Hosting/NetCord.Hosting.Services/bin/Release/*.nupkg -k $KEY -s https://api.nuget.org/v3/index.json --skip-duplicate - dotnet nuget push artifacts/build/Hosting/NetCord.Hosting.AspNetCore/bin/Release/*.nupkg -k $KEY -s https://api.nuget.org/v3/index.json --skip-duplicate + dotnet nuget push artifacts/pkgs/*.nupkg -k $KEY -s https://api.nuget.org/v3/index.json --skip-duplicate - name: Deploy Documentation uses: appleboy/scp-action@ff85246acaad7bdce478db94a363cd2bf7c90345 diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index c56bd99c6..a50799495 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -1,7 +1,7 @@ name: Build, Test, and Package NetCord.Natives on: - workflow_dispatch: {} + workflow_dispatch: push: paths: - 'NetCord.Natives/**' @@ -17,6 +17,12 @@ jobs: CI: true VCPKG_BINARY_SOURCES: clear;files,${{ github.workspace }}/.vcpkg-cache,readwrite VCPKG_DOWNLOADS: ${{ github.workspace }}/.vcpkg-downloads + VcpkgOSTarget: ${{ matrix.vcpkg-os-target }} + VcpkgPlatformTarget: ${{ matrix.vcpkg-platform-target }} + Configuration: Release + RuntimeIdentifier: ${{ matrix.rid }} + DotnetVerbose: minimal + strategy: fail-fast: false matrix: @@ -26,15 +32,15 @@ jobs: vcpkg-os-target: windows vcpkg-platform-target: x64 - rid: win-arm64 - runs-on: windows-latest + runs-on: windows-11-arm vcpkg-os-target: windows vcpkg-platform-target: arm64 - rid: osx-x64 - runs-on: macos-latest + runs-on: macos-15-intel vcpkg-os-target: osx vcpkg-platform-target: x64 - rid: osx-arm64 - runs-on: macos-latest + runs-on: macos-15 vcpkg-os-target: osx vcpkg-platform-target: arm64 - rid: linux-x64 @@ -42,83 +48,62 @@ jobs: vcpkg-os-target: linux vcpkg-platform-target: x64 - rid: linux-arm64 - runs-on: ubuntu-latest + runs-on: ubuntu-24.04-arm vcpkg-os-target: linux vcpkg-platform-target: arm64 steps: - name: Checkout uses: actions/checkout@v6.0.2 + with: + fetch-depth: 0 - - name: Cache vcpkg installs - uses: actions/cache@v5.0.5 + - name: Restore vcpkg cache + uses: actions/cache/restore@v5.0.5 with: path: | .vcpkg-cache .vcpkg-downloads - key: vcpkg-${{ runner.os }}-${{ matrix.rid }}- - ${{ hashFiles( - 'NetCord.Natives/vcpkg.json', - 'NetCord.Natives/natives-ports/**' - ) }} + key: vcpkg-${{ runner.os }}-${{ matrix.rid }}-${{ hashFiles('NetCord.Natives/vcpkg.json', 'NetCord.Natives/natives-ports/**') }} restore-keys: | vcpkg-${{ runner.os }}-${{ matrix.rid }}- vcpkg-${{ runner.os }}- - - name: Resolve vcpkg from runner image - shell: pwsh - run: | - # Ensure vcpkg cache and downloads directories exist - New-Item -ItemType Directory -Path $env:VCPKG_BINARY_SOURCES.Split(',')[1] -Force | Out-Null - New-Item -ItemType Directory -Path $env:VCPKG_DOWNLOADS -Force | Out-Null - - $vcpkgRoot = $env:VCPKG_INSTALLATION_ROOT - if (-not $vcpkgRoot) { - $vcpkgCommand = Get-Command vcpkg -ErrorAction Stop - $vcpkgRoot = Split-Path -Parent $vcpkgCommand.Source - } + - name: Setup vcpkg + uses: ./.github/actions/setup-vcpkg - if (Test-Path $vcpkgRoot) { - # Bootstrap vcpkg - if ($IsWindows) { - & "$vcpkgRoot/bootstrap-vcpkg.bat" -disableMetrics - } else { - & "$vcpkgRoot/bootstrap-vcpkg.sh" -disableMetrics - } - } - - "VCPKG_ROOT=$vcpkgRoot" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 + - name: Setup .NET Core SDK + uses: actions/setup-dotnet@v5.2.0 + with: + global-json-file: global.json - name: Install native build tools (macOS) if: runner.os == 'macOS' shell: bash run: | brew update - brew install autoconf automake libtool pkg-config - - - name: Install ARM64 cross-compiler (linux-arm64) - if: matrix.rid == 'linux-arm64' - shell: bash - run: | - sudo apt-get update - sudo apt-get install -yq gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc6-dev-arm64-cross + brew install autoconf automake libtool - name: Restore shell: pwsh run: | - dotnet restore NetCord.Natives/NetCord.Natives.csproj -p:VcpkgRoot=$env:VCPKG_ROOT -p:VcpkgOSTarget=${{ matrix.vcpkg-os-target }} -p:VcpkgPlatformTarget=${{ matrix.vcpkg-platform-target }} + dotnet restore Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj -v normal - - name: Build native outputs for ${{ matrix.rid }} + - name: Build natives projects for ${{ matrix.rid }} shell: pwsh - run: | - dotnet build NetCord.Natives/NetCord.Natives.csproj -c Release --no-restore -p:GeneratePackageOnBuild=false -p:VcpkgRoot=$env:VCPKG_ROOT -p:VcpkgOSTarget=${{ matrix.vcpkg-os-target }} -p:VcpkgPlatformTarget=${{ matrix.vcpkg-platform-target }} + run: > # Building tests will build dependencies including the native libraries + dotnet build Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj --no-restore -v ${{ env.DotnetVerbose }} + -p:AppendNativeAotAppProps="RuntimeIdentifier=${{ env.RuntimeIdentifier }}" + -p:GeneratePackageOnBuild=false - - name: Test native outputs for ${{ matrix.rid }} + - name: Test natives outputs for ${{ matrix.rid }} shell: pwsh - run: | - dotnet test NetCord.Natives.Tests/NetCord.Natives.Tests.csproj -c Release -p:VcpkgRoot=$env:VCPKG_ROOT -p:VcpkgOSTarget=${{ matrix.vcpkg-os-target }} -p:VcpkgPlatformTarget=${{ matrix.vcpkg-platform-target }} --verbosity normal + run: > + dotnet test Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj --no-restore --no-build -v ${{ env.DotnetVerbose }} + --logger GitHubActions - name: List built for ${{ matrix.rid }} + if: ${{ always() }} shell: pwsh run: | $rid = '${{ matrix.rid }}' @@ -131,98 +116,49 @@ jobs: foreach ($folder in @('bin','lib')) { $path = "NetCord.Natives/bin/$rid/$variant/$triplet/$folder" if (Test-Path $path) { - Write-Host "Contents of: $path" - Get-ChildItem -Path $path -Recurse -Force | Select-Object FullName, Mode, Length, LastWriteTime + Get-ChildItem -Path $path -Recurse } else { - Write-Host "[Info]Not found: $path" + Write-Host "[Info] Not found: $path" } } } } - - name: Upload artifact - uses: actions/upload-artifact@v7.0.1 - with: - name: ${{ matrix.rid }} - path: NetCord.Natives/bin/${{ matrix.rid }} - - pack-natives: - needs: build-natives - runs-on: ubuntu-latest - env: - CI: true - VCPKG_BINARY_SOURCES: clear;files,${{ github.workspace }}/.vcpkg-cache,readwrite - VCPKG_DOWNLOADS: ${{ github.workspace }}/.vcpkg-downloads - VcpkgArtifactsRoot: ${{ github.workspace }}/artifacts - - steps: - - name: Checkout - uses: actions/checkout@v6.0.2 - - - name: Download native artifacts - uses: actions/download-artifact@v8.0.1 - with: - path: artifacts - merge-multiple: false - - - name: Resolve vcpkg from runner image - shell: pwsh - run: | - # Ensure vcpkg cache and downloads directories exist - New-Item -ItemType Directory -Path $env:VCPKG_BINARY_SOURCES.Split(',')[1] -Force | Out-Null - New-Item -ItemType Directory -Path $env:VCPKG_DOWNLOADS -Force | Out-Null - - $vcpkgRoot = $env:VCPKG_INSTALLATION_ROOT - if (-not $vcpkgRoot) { - $vcpkgCommand = Get-Command vcpkg -ErrorAction Stop - $vcpkgRoot = Split-Path -Parent $vcpkgCommand.Source - } - - if (Test-Path $vcpkgRoot) { - # Bootstrap vcpkg - if ($IsWindows) { - & "$vcpkgRoot/bootstrap-vcpkg.bat" -disableMetrics - } else { - & "$vcpkgRoot/bootstrap-vcpkg.sh" -disableMetrics - } - } - - "VCPKG_ROOT=$vcpkgRoot" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 - - - name: Restore (required for pack) + - name: Pack NuGet Package for ${{ matrix.rid }} shell: pwsh - run: | - dotnet restore NetCord.Natives/NetCord.Natives.csproj -p:VcpkgRoot=$env:VCPKG_ROOT -p:VcpkgEnabled=false + run: > + dotnet pack NetCord.Natives/NetCord.Natives.csproj --no-restore --no-build -v ${{ env.DotnetVerbose }} + -o NetCord.Natives/bin/${{ matrix.rid }} + -p:CI=false - - name: Build cross-platform .NET (required for pack) - shell: pwsh - run: | - dotnet build NetCord.Natives/NetCord.Natives.csproj -c Release --no-restore -p:VcpkgRoot=$env:VCPKG_ROOT -p:VcpkgEnabled=false - - - name: Pack combined nupkg - shell: pwsh - run: | - dotnet pack NetCord.Natives/NetCord.Natives.csproj -c Release --no-build --no-restore -p:VcpkgRoot=$env:VCPKG_ROOT -p:VcpkgArtifactsRoot=$env:VcpkgArtifactsRoot -o $env:VcpkgArtifactsRoot/package - - - name: Upload nupkg + - name: Upload NuGet Package Artifact uses: actions/upload-artifact@v7.0.1 with: - name: NetCord.Natives.Package - path: artifacts/package/*.nupkg + name: NetCord.Natives.${{ matrix.rid }}.nupkg + path: NetCord.Natives/bin/${{ matrix.rid }}/*.nupkg + + - name: Save vcpkg cache + if: ${{ always() }} + uses: actions/cache/save@v5.0.5 + with: + path: | + .vcpkg-cache + .vcpkg-downloads + key: vcpkg-${{ runner.os }}-${{ matrix.rid }}-${{ hashFiles('NetCord.Natives/vcpkg.json', 'NetCord.Natives/natives-ports/**') }} publish: - needs: pack-natives + needs: [build-test-natives] if: startsWith(github.ref, 'refs/tags/') runs-on: ubuntu-latest steps: - - name: Download nupkg + - name: Download All NuGet Package Artifacts uses: actions/download-artifact@v8.0.1 with: - name: NetCord.Natives.Package - path: artifacts/package + path: artifacts/pkgs + pattern: NetCord.Natives*.nupkg - - name: Publish Package + - name: Publish packages env: KEY: ${{ secrets.NUGET_API_KEY }} run: | - dotnet nuget push artifacts/package/*.nupkg -k $KEY -s https://api.nuget.org/v3/index.json --skip-duplicate + dotnet nuget push artifacts/pkgs/*.nupkg -k $KEY -s https://api.nuget.org/v3/index.json --skip-duplicate diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bc3979d3c..94e633544 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -32,7 +32,9 @@ jobs: - name: Restore dependencies shell: *dev-shell - run: dotnet restore + run: | + dotnet restore NetCord.slnx + dotnet restore NetCord.Natives.slnx -p:VcpkgRoot=$VCPKG_INSTALLATION_ROOT -p:VcpkgEnabled=false - name: Build shell: *dev-shell @@ -66,16 +68,16 @@ jobs: npm run test npm run build - - name: Upload Build Artifacts + - name: Upload NuGet Package Artifacts uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: - name: Build Artifacts + name: NuGet Packages path: | - NetCord/bin/Release - NetCord.Services/bin/Release - Hosting/NetCord.Hosting/bin/Release - Hosting/NetCord.Hosting.Services/bin/Release - Hosting/NetCord.Hosting.AspNetCore/bin/Release + NetCord/bin/Release/*.nupkg + NetCord.Services/bin/Release/*.nupkg + Hosting/NetCord.Hosting/bin/Release/*.nupkg + Hosting/NetCord.Hosting.Services/bin/Release/*.nupkg + Hosting/NetCord.Hosting.AspNetCore/bin/Release/*.nupkg - name: Upload Documentation Artifacts uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 diff --git a/NetCord.Natives.slnx b/NetCord.Natives.slnx index 1f71c5697..8e3060606 100644 --- a/NetCord.Natives.slnx +++ b/NetCord.Natives.slnx @@ -1,7 +1,27 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/NetCord.Natives/NetCord.Natives.csproj b/NetCord.Natives/NetCord.Natives.csproj index 735f1e982..3d38cf8c4 100644 --- a/NetCord.Natives/NetCord.Natives.csproj +++ b/NetCord.Natives/NetCord.Natives.csproj @@ -157,7 +157,7 @@ + Returns="@(_CopyOutput)"> <_CopyOutput Include="%(NativesRuntime.FullPath)"> @@ -166,6 +166,7 @@ + diff --git a/NetCord.Natives/NetCord.Natives.targets b/NetCord.Natives/NetCord.Natives.targets index 0e8c8d0fd..bdb1a6f63 100644 --- a/NetCord.Natives/NetCord.Natives.targets +++ b/NetCord.Natives/NetCord.Natives.targets @@ -1,23 +1,40 @@ - + - <_NetCordStaticLink Include="libdave;mlspp;bytes;tls_syntax;hpke;libcrypto" - Condition="'%(DirectPInvoke.Identity)' == 'libdave'" /> - <_NetCordStaticLink Include="libsodium" + + + <_NetCordStaticLink Include="libsodium;sodium" Condition="'%(DirectPInvoke.Identity)' == 'libsodium'" /> - <_NetCordStaticLink Include="opus" - Condition="'%(DirectPInvoke.Identity)' == 'opus'" /> - <_NetCordStaticLink Include="zstd" - Condition="'%(DirectPInvoke.Identity)' == 'zstd'" /> + <_NetCordStaticLink Include="libdave;dave" + Condition="'%(DirectPInvoke.Identity)' == 'libdave'" /> + + + <_NetCordStaticLink Include="mlspp;hpke;bytes;tls_syntax" + Condition="'%(DirectPInvoke.Identity)' == 'libdave'" /> + + + <_NetCordStaticLink Include="opus;zstd" + Condition="'%(DirectPInvoke.Identity)' == 'opus' or '%(DirectPInvoke.Identity)' == 'zstd'" /> + + + <_NetCordStaticLink Include="libcrypto;crypto" + Condition="'%(DirectPInvoke.Identity)' == 'libdave'" /> - + + + + true + true true false + $(NoWarn);IL2075;IL2026 ..\..\..\..\NetCord.Natives + + + + + diff --git a/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/Program.cs b/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/Program.cs index bf91f09c8..6581e6975 100644 --- a/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/Program.cs +++ b/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/Program.cs @@ -1,32 +1,9 @@ -using System; -using System.Diagnostics; -using System.IO; using System.Runtime.InteropServices; +using NetCord.Natives.Tests; -internal static partial class NativeProbes -{ - [LibraryImport("libdave", EntryPoint = "daveMaxSupportedProtocolVersion")] - internal static partial uint DaveMaxSupportedProtocolVersion(); +Console.WriteLine("NetCord native ahead of time publish app."); - [LibraryImport("libsodium", EntryPoint = "sodium_init")] - internal static partial int SodiumInit(); - - [LibraryImport("opus", EntryPoint = "opus_get_version_string")] - internal static partial nint OpusGetVersionString(); - - [LibraryImport("zstd", EntryPoint = "ZSTD_versionNumber")] - internal static partial uint ZstdVersionNumber(); -} - -internal static class Program -{ - private static void Main() - { - Console.WriteLine("NetCord native ahead of time publish app."); - - Console.WriteLine($"Dave Max Supported Protocol Version: {NativeProbes.DaveMaxSupportedProtocolVersion()}"); - Console.WriteLine($"Sodium Init: {NativeProbes.SodiumInit()}. 0 = OK"); - Console.WriteLine($"Opus Version String: {Marshal.PtrToStringAnsi(NativeProbes.OpusGetVersionString())}"); - Console.WriteLine($"Zstd Version Number: {NativeProbes.ZstdVersionNumber()}"); - } -} +Console.WriteLine($"Dave Max Supported Protocol Version: {NativeProbes.DaveMaxSupportedProtocolVersion()}"); +Console.WriteLine($"Sodium Init: {NativeProbes.SodiumInit()}. 0 = OK"); +Console.WriteLine($"Opus Version String: {Marshal.PtrToStringAnsi(NativeProbes.OpusGetVersionString())}"); +Console.WriteLine($"Zstd Version Number: {NativeProbes.ZstdVersionNumber()}"); diff --git a/Tests/NetCord.Natives.Tests/NativeProbes.cs b/Tests/NetCord.Natives.Tests/NativeProbes.cs new file mode 100644 index 000000000..c8e95ef79 --- /dev/null +++ b/Tests/NetCord.Natives.Tests/NativeProbes.cs @@ -0,0 +1,78 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +namespace NetCord.Natives.Tests; + +public static partial class NativeProbes +{ + [LibraryImport("libdave", EntryPoint = "daveMaxSupportedProtocolVersion")] + internal static partial uint DaveMaxSupportedProtocolVersion(); + + [LibraryImport("libsodium", EntryPoint = "sodium_init")] + internal static partial int SodiumInit(); + + [LibraryImport("opus", EntryPoint = "opus_get_version_string")] + internal static partial IntPtr OpusGetVersionString(); + + [LibraryImport("zstd", EntryPoint = "ZSTD_versionNumber")] + internal static partial uint ZstdVersionNumber(); + + internal static IReadOnlyList GetMissingLibraryImports(string libName, string className, Assembly assemblyWithImports) + { + var typeWithImports = assemblyWithImports.GetType(className, true); + var libHandle = GetLoadedNativeModuleHandle(libName); + var missingExports = new List(); + + var methods = typeWithImports!.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) + .Select(m => new + { + MethodName = m.Name, + Attr = m.GetCustomAttribute(), + }) + .Where(x => x.Attr != null) + .ToArray(); + + if (methods.Length == 0) + throw new InvalidOperationException($"No methods with [LibraryImport] found in '{className}'."); + + foreach (var item in methods) + { + // Use EntryPoint if defined, otherwise fallback to method name. + string exportName = item.Attr!.EntryPoint ?? item.MethodName; + + if (!NativeLibrary.TryGetExport(libHandle, exportName, out _)) + { + missingExports.Add(exportName); + } + } + + return missingExports; + } + + internal static IntPtr GetLoadedNativeModuleHandle(string libName) + { + _ = libName switch + { + "libdave" => (object)DaveMaxSupportedProtocolVersion(), + "libsodium" => (object)SodiumInit(), + "opus" => (object)OpusGetVersionString(), + "zstd" => (object)ZstdVersionNumber(), + _ => throw new InvalidOperationException($"Unknown library name '{libName}' provided to test."), + }; + + var module = System.Diagnostics.Process.GetCurrentProcess().Modules + .Cast() + .FirstOrDefault(m => + { + var moduleName = Path.GetFileName(m.ModuleName); + return moduleName.StartsWith(libName, StringComparison.OrdinalIgnoreCase) + || moduleName.StartsWith($"lib{libName}", StringComparison.OrdinalIgnoreCase); + }) + ?? throw new InvalidOperationException($"Native module '{libName}' was not found in the current process."); + + if (NativeLibrary.TryLoad(module.FileName, out var libHandleByPath)) + return libHandleByPath; + + throw new InvalidOperationException($"Failed to obtain a handle for native module '{libName}'."); + } +} diff --git a/Tests/NetCord.Natives.Tests/NativesBuildTests.cs b/Tests/NetCord.Natives.Tests/NativesBuildTests.cs index f0bc87c62..f24625859 100644 --- a/Tests/NetCord.Natives.Tests/NativesBuildTests.cs +++ b/Tests/NetCord.Natives.Tests/NativesBuildTests.cs @@ -1,4 +1,4 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Diagnostics; using System.Reflection; using System.Runtime.InteropServices; @@ -7,9 +7,6 @@ namespace NetCord.Natives.Tests; [TestClass] public class NativesBuildTests { - // MSTest automatically injects this property - public TestContext TestContext { get; set; } - [TestMethod] [DataRow("libdave")] [DataRow("libsodium")] @@ -17,14 +14,14 @@ public class NativesBuildTests [DataRow("zstd")] public void NativesLoaded(string libName) { - try + _ = libName switch { - NativeLibrary.Load(libName); - } - catch (Exception ex) - { - Assert.Fail($"Failed to load library '{libName}': {ex}"); - } + "libdave" => (object)NativeProbes.DaveMaxSupportedProtocolVersion(), + "libsodium" => (object)NativeProbes.SodiumInit(), + "opus" => (object)NativeProbes.OpusGetVersionString(), + "zstd" => (object)NativeProbes.ZstdVersionNumber(), + _ => throw new InvalidOperationException($"Unknown library name '{libName}' provided to test."), + }; } [TestMethod] @@ -34,48 +31,13 @@ public void NativesLoaded(string libName) [DataRow("zstd", "NetCord.Gateway.Compression.Zstandard")] public void AllLibraryImportsExistInBinary(string libName, string className) { - IntPtr libHandle = IntPtr.Zero; - - try - { - var assembly = typeof(NetCord.Application).Assembly; - var typeWithImports = assembly.GetType(className, true); - - libHandle = NativeLibrary.Load(libName); - - var missingExports = new List(); - - // Reflect over methods with [LibraryImport] - var methods = typeWithImports!.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) - .Select(m => new { - MethodName = m.Name, - Attr = m.GetCustomAttribute() - }) - .Where(x => x.Attr != null); - Assert.IsNotEmpty(methods, $"No methods with [LibraryImport] found in '{className}'."); + var missingExports = NativeProbes.GetMissingLibraryImports(libName, className, typeof(NetCord.Application).Assembly); - foreach (var item in methods) - { - // Use EntryPoint if defined, otherwise fallback to Method Name - string exportName = item.Attr!.EntryPoint ?? item.MethodName; - - if (!NativeLibrary.TryGetExport(libHandle, exportName, out _)) - { - missingExports.Add(exportName); - } - } - Assert.IsEmpty(missingExports, $"The following entry points were not found in '{libName}': {string.Join(", ", missingExports)}"); - } - catch (Exception ex) - { - Assert.Fail($"An error occurred while verifying imports for '{libName}': {ex}"); - } - finally - { - NativeLibrary.Free(libHandle); - } + Assert.IsEmpty(missingExports, $"The following entry points were not found in '{libName}': {string.Join(", ", missingExports)}"); } + const string NativeAotAppLogTag = $"[{nameof(NativeAotStaticLinking)}]"; + [DoNotParallelize] [TestMethod] [DataRow("libdave;libsodium;opus;zstd")] public void NativeAotStaticLinking(string libName) @@ -84,70 +46,107 @@ public void NativeAotStaticLinking(string libName) var projectFile = Path.Combine(projectDirectory, "NativeAotApp.csproj"); var generatedProjectFile = Path.Combine(projectDirectory, "NativeAotApp.g.csproj"); - try + // get properties to be passed to the NativeAotApp build from AssemblyMetadata attribute + var assembly = typeof(NativesBuildTests).Assembly; + + var properties = assembly.GetCustomAttributes()? + .FirstOrDefault(a => a.Key == "NativeAotAppProps")?.Value; + Assert.IsNotNull(properties, "NativeAotAppProps metadata attribute is not defined."); + + // build asset NativeAotApp with Native AoT enabled + var buildProcess = new System.Diagnostics.Process(); + buildProcess.StartInfo.FileName = "dotnet"; + buildProcess.StartInfo.ArgumentList.Add("publish"); + buildProcess.StartInfo.ArgumentList.Add("NativeAotApp.csproj"); + buildProcess.StartInfo.ArgumentList.Add("-tl:off"); + buildProcess.StartInfo.ArgumentList.Add("-v:n"); + buildProcess.StartInfo.ArgumentList.Add($"-p:{properties}"); + + Console.WriteLine($"{NativeAotAppLogTag} Building Native AoT app in ({projectDirectory}): 'dotnet {buildProcess.StartInfo.ArgumentList.Aggregate((a, b) => $"{a} {b}")}'"); + + buildProcess.StartInfo.WorkingDirectory = projectDirectory; + buildProcess.StartInfo.RedirectStandardOutput = true; + buildProcess.OutputDataReceived += (sender, e) => + { + if (!string.IsNullOrEmpty(e.Data)) + Console.WriteLine($"{NativeAotAppLogTag} {e.Data}"); + }; + buildProcess.StartInfo.RedirectStandardError = true; + buildProcess.ErrorDataReceived += (sender, e) => + { + if (!string.IsNullOrEmpty(e.Data)) + Console.WriteLine($"{NativeAotAppLogTag} {e.Data}"); + }; + var ok = buildProcess.Start(); + buildProcess.BeginOutputReadLine(); + buildProcess.BeginErrorReadLine(); + buildProcess.WaitForExit(); + + Assert.AreEqual(0, buildProcess.ExitCode, $"Native AoT build failed for '{libName}'."); + + // Obtain the generated RunCommand from a build so we launch the same command the SDK would. + var getRunCmd = new System.Diagnostics.Process(); + getRunCmd.StartInfo.FileName = "dotnet"; + getRunCmd.StartInfo.ArgumentList.Add("build"); + getRunCmd.StartInfo.ArgumentList.Add("NativeAotApp.csproj"); + getRunCmd.StartInfo.ArgumentList.Add($"-p:{properties}"); + getRunCmd.StartInfo.ArgumentList.Add("-t:GetTargetPath"); + getRunCmd.StartInfo.ArgumentList.Add("-getProperty:PublishDir"); + getRunCmd.StartInfo.ArgumentList.Add("--no-restore"); + + string? runCmdOutput = null; + + getRunCmd.StartInfo.WorkingDirectory = projectDirectory; + getRunCmd.StartInfo.RedirectStandardOutput = true; + getRunCmd.OutputDataReceived += (sender, e) => + { + if (!string.IsNullOrEmpty(e.Data)) + { + Console.WriteLine($"{NativeAotAppLogTag} {e.Data}"); + runCmdOutput = e.Data.Trim('\r', '\n', '"'); + } + }; + getRunCmd.StartInfo.RedirectStandardError = true; + getRunCmd.ErrorDataReceived += (sender, e) => + { + if (!string.IsNullOrEmpty(e.Data)) + Console.WriteLine($"{NativeAotAppLogTag} {e.Data}"); + }; + getRunCmd.Start(); + getRunCmd.BeginErrorReadLine(); + getRunCmd.BeginOutputReadLine(); + getRunCmd.WaitForExit(); + + Assert.AreEqual(0, getRunCmd.ExitCode, $"Failed to obtain PublishDir for '{libName}'."); + Assert.IsFalse(string.IsNullOrEmpty(runCmdOutput), $"PublishDir is empty for '{libName}'."); + + runCmdOutput = Path.Combine(projectDirectory, runCmdOutput, + "NativeAotApp" + (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : "")); + + // check that the library is running without errors, which indicates that it was statically linked successfully + var aotProcess = new System.Diagnostics.Process(); + aotProcess.StartInfo.FileName = runCmdOutput; + aotProcess.StartInfo.WorkingDirectory = Path.GetDirectoryName(runCmdOutput); + + Console.WriteLine($"{NativeAotAppLogTag} Running Native AoT app: '{runCmdOutput}'"); + + aotProcess.StartInfo.RedirectStandardOutput = true; + aotProcess.OutputDataReceived += (sender, e) => { - var originalProjectFileContents = File.ReadAllText(projectFile); - var generatedProjectFileContents = originalProjectFileContents.Replace("$(NetCordDirectPInvoke)", libName); - File.WriteAllText(generatedProjectFile, generatedProjectFileContents); - - // get NetCordNativesDir from AssemblyMetadata attribute - var assembly = typeof(NativesBuildTests).Assembly; - var nativesDir = assembly.GetCustomAttributes()? - .FirstOrDefault(a => a.Key == "NetCordNativesDir")?.Value; - Assert.IsNotNull(nativesDir, "NetCordNativesDir metadata attribute is not defined."); - var vcpkgRoot = assembly.GetCustomAttributes()? - .FirstOrDefault(a => a.Key == "VcpkgRoot")?.Value; - Assert.IsNotNull(vcpkgRoot, "VcpkgRoot metadata attribute is not defined."); - var targetFramework = assembly.GetCustomAttributes()? - .FirstOrDefault(a => a.Key == "TargetFramework")?.Value; - Assert.IsNotNull(targetFramework, "TargetFramework metadata attribute is not defined."); - - // build asset NativeAotApp with Native AoT enabled - var buildProcess = new System.Diagnostics.Process(); - buildProcess.StartInfo.FileName = "dotnet"; - buildProcess.StartInfo.ArgumentList.Add("publish"); - buildProcess.StartInfo.ArgumentList.Add("NativeAotApp.g.csproj"); - buildProcess.StartInfo.ArgumentList.Add("-p:Configuration=Release"); - buildProcess.StartInfo.ArgumentList.Add($"-p:TargetFramework={targetFramework}"); - buildProcess.StartInfo.ArgumentList.Add("-p:RuntimeIdentifier=" + RuntimeInformation.RuntimeIdentifier); - buildProcess.StartInfo.ArgumentList.Add($"-p:NetCordNativesDir={nativesDir}"); - buildProcess.StartInfo.ArgumentList.Add($"-p:VcpkgRoot={vcpkgRoot}"); - - TestContext.WriteLine($"Building Native AoT app in ({projectDirectory}): 'dotnet {buildProcess.StartInfo.ArgumentList.Aggregate((a, b) => $"{a} {b}")}'"); - - buildProcess.StartInfo.WorkingDirectory = projectDirectory; - buildProcess.StartInfo.RedirectStandardOutput = true; - buildProcess.StartInfo.RedirectStandardError = true; - buildProcess.Start(); - buildProcess.WaitForExit(); - - TestContext.WriteLine($"Build Output of AoT app for '{libName}': {buildProcess.StandardOutput.ReadToEnd()}"); - - Assert.AreEqual(0, buildProcess.ExitCode, - $"Native AoT build failed for '{libName}'. Output: {buildProcess.StandardError.ReadToEnd()}"); - - // check that the library is running without errors, which indicates that it was statically linked successfully - var aotProcess = new System.Diagnostics.Process(); - aotProcess.StartInfo.FileName = Path.Combine(projectDirectory, "bin", "release", targetFramework, - RuntimeInformation.RuntimeIdentifier, "publish", - RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? - "NativeAotApp.g.exe" : "NativeAotApp.g"); - - TestContext.WriteLine($"Running Native AoT app: '{aotProcess.StartInfo.FileName}'"); - - aotProcess.StartInfo.RedirectStandardOutput = true; - aotProcess.StartInfo.RedirectStandardError = true; - aotProcess.Start(); - aotProcess.WaitForExit(); - - TestContext.WriteLine($"Output of AoT app for '{libName}': {aotProcess.StandardOutput.ReadToEnd()}"); - - Assert.AreEqual(0, aotProcess.ExitCode, - $"Native AoT app failed to run for '{libName}'. Output: {aotProcess.StandardError.ReadToEnd()}"); - } - catch (Exception ex) + if (!string.IsNullOrEmpty(e.Data)) + Console.WriteLine($"{NativeAotAppLogTag} {e.Data}"); + }; + aotProcess.StartInfo.RedirectStandardError = true; + aotProcess.ErrorDataReceived += (sender, e) => { - Assert.Fail($"Failed to statically link '{libName}' for Native Ahead-of-Time (AoT) compilation: {ex}"); - } + if (!string.IsNullOrEmpty(e.Data)) + Console.WriteLine($"{NativeAotAppLogTag} {e.Data}"); + }; + aotProcess.Start(); + aotProcess.BeginOutputReadLine(); + aotProcess.BeginErrorReadLine(); + aotProcess.WaitForExit(); + + Assert.AreEqual(0, aotProcess.ExitCode, $"Native AoT app failed to run for '{libName}'."); } } diff --git a/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj b/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj index 4eaa6e27b..6dd95eedf 100644 --- a/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj +++ b/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj @@ -4,6 +4,7 @@ net10.0 enable enable + true false true @@ -13,6 +14,8 @@ + @@ -23,25 +26,25 @@ + + ..\..\NetCord.Natives\ + NetCordNativesDir=$([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)\$(NetCordNativesDir)')) + + $(VCPKG_ROOT) + $(NativeAotAppProps),VcpkgRoot=$(VcpkgRoot) + + $(NativeAotAppProps),$(AppendNativeAotAppProps) - <_Parameter1>NetCordNativesDir - <_Parameter2>$([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)\$(NetCordNativesDir)')) - - - <_Parameter1>VcpkgRoot - <_Parameter2>$(VcpkgRoot) - - - <_Parameter1>TargetFramework - <_Parameter2>$(TargetFramework) + <_Parameter1>NativeAotAppProps + <_Parameter2>$(NativeAotAppProps) From 4a9dc0dee56164e1a42badc78297b0b8158e1224 Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Mon, 11 May 2026 05:49:25 +0900 Subject: [PATCH 010/101] Clean up & atomize CI workflows * Skip testing for OSX due to dyld limitation * Clean up natives packaging * Docs updates for prebuilt natives --- .github/workflows/build-and-publish.yml | 1 + .github/workflows/build-natives.yml | 82 +++++------ .github/workflows/build-publish-natives.yml | 35 +++++ .github/workflows/build.yml | 17 +-- Directory.Packages.props | 1 + .../installing-native-dependencies.md | 138 ++++++++++-------- NetCord.Natives/NativesHelper.cs | 20 --- NetCord.Natives/NetCord.Natives.csproj | 29 ++-- Tests/NetCord.Natives.Tests/NativeProbes.cs | 20 ++- .../NativesBuildTests.cs | 3 + .../NetCord.Natives.Tests.csproj | 1 - 11 files changed, 191 insertions(+), 156 deletions(-) create mode 100644 .github/workflows/build-publish-natives.yml delete mode 100644 NetCord.Natives/NativesHelper.cs diff --git a/.github/workflows/build-and-publish.yml b/.github/workflows/build-and-publish.yml index 306afe5f1..4f15b8808 100644 --- a/.github/workflows/build-and-publish.yml +++ b/.github/workflows/build-and-publish.yml @@ -33,6 +33,7 @@ jobs: KEY: ${{ secrets.NUGET_API_KEY }} run: | dotnet nuget push artifacts/pkgs/*.nupkg -k $KEY -s https://api.nuget.org/v3/index.json --skip-duplicate + dotnet nuget push artifacts/pkgs/*.snupkg -k $KEY -s https://api.nuget.org/v3/index.json --skip-duplicate - name: Deploy Documentation uses: appleboy/scp-action@ff85246acaad7bdce478db94a363cd2bf7c90345 diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index a50799495..6cada1d31 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -1,17 +1,20 @@ -name: Build, Test, and Package NetCord.Natives +name: Build NetCord.Natives on: + workflow_call: workflow_dispatch: + inputs: + GenerateBinLog: + type: boolean + default: false push: paths: - 'NetCord.Natives/**' + - 'Tests/NetCord.Natives.Tests/**' - '.github/workflows/build-natives.yml' - tags: - - "[0-9]+.[0-9]+.[0-9]+" - - "[0-9]+.[0-9]+.[0-9]+-*" jobs: - build-test-natives: + build-natives: runs-on: ${{ matrix.runs-on }} env: CI: true @@ -22,6 +25,7 @@ jobs: Configuration: Release RuntimeIdentifier: ${{ matrix.rid }} DotnetVerbose: minimal + GenerateBinLog: ${{ github.event.inputs.GenerateBinLog || inputs.GenerateBinLog || false }} strategy: fail-fast: false @@ -57,6 +61,7 @@ jobs: uses: actions/checkout@v6.0.2 with: fetch-depth: 0 + filter: tree:0 - name: Restore vcpkg cache uses: actions/cache/restore@v5.0.5 @@ -82,60 +87,56 @@ jobs: shell: bash run: | brew update - brew install autoconf automake libtool + for pkg in autoconf automake libtool; do + brew list $pkg &>/dev/null || brew install $pkg + done - name: Restore shell: pwsh run: | - dotnet restore Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj -v normal + dotnet restore Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:restore.binlog' || '' }} - name: Build natives projects for ${{ matrix.rid }} shell: pwsh run: > # Building tests will build dependencies including the native libraries dotnet build Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj --no-restore -v ${{ env.DotnetVerbose }} + ${{ env.GenerateBinLog == 'true' && '-bl:build.binlog' || '' }} -p:AppendNativeAotAppProps="RuntimeIdentifier=${{ env.RuntimeIdentifier }}" - -p:GeneratePackageOnBuild=false + -p:GeneratePackageOnBuild=false -p:CI=false - name: Test natives outputs for ${{ matrix.rid }} shell: pwsh run: > dotnet test Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj --no-restore --no-build -v ${{ env.DotnetVerbose }} + ${{ env.GenerateBinLog == 'true' && '-bl:test.binlog' || '' }} + --logger "console;verbosity=detailed" --logger GitHubActions - - name: List built for ${{ matrix.rid }} - if: ${{ always() }} - shell: pwsh - run: | - $rid = '${{ matrix.rid }}' - $tripletBase = '${{ matrix.vcpkg-platform-target }}-${{ matrix.vcpkg-os-target }}' - $suffix = if ($IsWindows) { 'static' } else { 'dynamic' } - $triplets = @("$tripletBase", "$tripletBase-$suffix") - - foreach ($variant in @('natives','natives-static')) { - foreach ($triplet in @($triplets)) { - foreach ($folder in @('bin','lib')) { - $path = "NetCord.Natives/bin/$rid/$variant/$triplet/$folder" - if (Test-Path $path) { - Get-ChildItem -Path $path -Recurse - } else { - Write-Host "[Info] Not found: $path" - } - } - } - } - - name: Pack NuGet Package for ${{ matrix.rid }} + if: ${{ always() }} shell: pwsh run: > dotnet pack NetCord.Natives/NetCord.Natives.csproj --no-restore --no-build -v ${{ env.DotnetVerbose }} + ${{ env.GenerateBinLog == 'true' && '-bl:pack.binlog' || '' }} -o NetCord.Natives/bin/${{ matrix.rid }} -p:CI=false + - name: Upload Binary Logs + if: ${{ env.GenerateBinLog == 'true' && always() }} + uses: actions/upload-artifact@v4.6.0 + with: + name: ${{ matrix.rid }}-binlogs + path: | + *.binlog + - name: Upload NuGet Package Artifact + if: ${{ always() }} uses: actions/upload-artifact@v7.0.1 with: - name: NetCord.Natives.${{ matrix.rid }}.nupkg - path: NetCord.Natives/bin/${{ matrix.rid }}/*.nupkg + name: NetCord.Natives.${{ matrix.rid }}.packages + path: | + NetCord.Natives/bin/${{ matrix.rid }}/*.nupkg + NetCord.Natives/bin/${{ matrix.rid }}/*.snupkg - name: Save vcpkg cache if: ${{ always() }} @@ -145,20 +146,3 @@ jobs: .vcpkg-cache .vcpkg-downloads key: vcpkg-${{ runner.os }}-${{ matrix.rid }}-${{ hashFiles('NetCord.Natives/vcpkg.json', 'NetCord.Natives/natives-ports/**') }} - - publish: - needs: [build-test-natives] - if: startsWith(github.ref, 'refs/tags/') - runs-on: ubuntu-latest - steps: - - name: Download All NuGet Package Artifacts - uses: actions/download-artifact@v8.0.1 - with: - path: artifacts/pkgs - pattern: NetCord.Natives*.nupkg - - - name: Publish packages - env: - KEY: ${{ secrets.NUGET_API_KEY }} - run: | - dotnet nuget push artifacts/pkgs/*.nupkg -k $KEY -s https://api.nuget.org/v3/index.json --skip-duplicate diff --git a/.github/workflows/build-publish-natives.yml b/.github/workflows/build-publish-natives.yml new file mode 100644 index 000000000..8850fb498 --- /dev/null +++ b/.github/workflows/build-publish-natives.yml @@ -0,0 +1,35 @@ +name: Build & Publish NetCord.Natives + +on: + workflow_dispatch: + push: + paths: + - 'NetCord.Natives/**' + - '.github/workflows/build-natives.yml' + - '.github/workflows/publish-natives.yml' + tags: + - "[0-9]+.[0-9]+.[0-9]+" + - "[0-9]+.[0-9]+.[0-9]+-*" + +jobs: + build-natives: + uses: ./.github/workflows/build-natives.yml + + publish: + needs: [build-natives] + runs-on: ubuntu-latest + + steps: + - name: Download All NuGet Package Artifacts + uses: actions/download-artifact@v8.0.1 + with: + path: artifacts/pkgs + pattern: NetCord.Natives.*.packages + merge-multiple: true + + - name: Publish packages + env: + KEY: ${{ secrets.NUGET_API_KEY }} + run: | + dotnet nuget push artifacts/pkgs/*.nupkg -k $KEY -s https://api.nuget.org/v3/index.json --skip-duplicate + dotnet nuget push artifacts/pkgs/*.snupkg -k $KEY -s https://api.nuget.org/v3/index.json --skip-duplicate diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 94e633544..9894ac481 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -49,11 +49,11 @@ jobs: - name: Pack Packages shell: *dev-shell run: | - dotnet pack NetCord -c Release --no-build - dotnet pack NetCord.Services -c Release --no-build - dotnet pack Hosting/NetCord.Hosting -c Release --no-build - dotnet pack Hosting/NetCord.Hosting.Services -c Release --no-build - dotnet pack Hosting/NetCord.Hosting.AspNetCore -c Release --no-build + dotnet pack NetCord -c Release --no-build -o pkgs/ + dotnet pack NetCord.Services -c Release --no-build -o pkgs/ + dotnet pack Hosting/NetCord.Hosting -c Release --no-build -o pkgs/ + dotnet pack Hosting/NetCord.Hosting.Services -c Release --no-build -o pkgs/ + dotnet pack Hosting/NetCord.Hosting.AspNetCore -c Release --no-build -o pkgs/ - name: Setup docs environment shell: &docs-shell 'nix develop .#docs -c bash -eo pipefail {0}' @@ -73,11 +73,8 @@ jobs: with: name: NuGet Packages path: | - NetCord/bin/Release/*.nupkg - NetCord.Services/bin/Release/*.nupkg - Hosting/NetCord.Hosting/bin/Release/*.nupkg - Hosting/NetCord.Hosting.Services/bin/Release/*.nupkg - Hosting/NetCord.Hosting.AspNetCore/bin/Release/*.nupkg + pkgs/*.nupkg + pkgs/*.snupkg - name: Upload Documentation Artifacts uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 diff --git a/Directory.Packages.props b/Directory.Packages.props index f8c63b7c0..286810234 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -23,6 +23,7 @@ + diff --git a/Documentation/guides/basic-concepts/installing-native-dependencies.md b/Documentation/guides/basic-concepts/installing-native-dependencies.md index 9c9fe2d4d..061d36f03 100644 --- a/Documentation/guides/basic-concepts/installing-native-dependencies.md +++ b/Documentation/guides/basic-concepts/installing-native-dependencies.md @@ -1,91 +1,109 @@ # Installing Native Dependencies -This is a hidden guide that is not visible in the guides index! If you are reading this, you are probably looking for information on how to install native dependencies for HTTP interactions or voice. +NetCord relies on several native libraries for high-performance audio processing and encryption. NetCord provides prebuilt native binaries via NuGet packages, which is the recommended way to manage these dependencies. -## HTTP Interactions +## Native Dependencies Context -For HTTP interactions, [Libsodium](https://doc.libsodium.org/installation) is required. +- **Libdave**: Essential for voice connection interactions. +- **Libsodium**: Used for encryption. While NetCord defaults to native AES-GCM (which does not require Libsodium), Libsodium is a highly recommended production dependency. It acts as a fallback for the XChaCha20-Poly1305 encryption mode, ensuring your bot remains compatible if Discord switches to this mode for your connection. +- **Opus**: A versatile audio codec required for any classes in NetCord prefixed with `Opus` (e.g., audio encoding/decoding). +- **Zstd**: Used for efficient payload compression. -## Voice +## NuGet Packages (Recommended) -For voice: -- [Libdave](https://github.com/discord/libdave) is required. -- [Libsodium](https://doc.libsodium.org/installation) **is not generally** required, but it **is highly recommended for production bots**. It is caused by the fact that generally @NetCord.Gateway.Voice.Encryption.Aes256GcmRtpSizeEncryption, which does not require Libsodium, is supported by Discord and is used by default. However, there is a small chance that Discord will not support this encryption mode for your connection. In this case, @NetCord.Gateway.Voice.Encryption.XChaCha20Poly1305RtpSizeEncryption, which does require Libsodium, is used by default. -- [Opus](https://opus-codec.org/downloads) is only required when you are using `Opus` prefixed classes. +NetCord distributes these dependencies as per-RID (Runtime Identifier) packages. This model automates binary resolution, ensuring the correct libraries are provided for your target platform. -## Installation +### Supported Platforms +Packages are available for: -### [Dynamic Linking](#tab/dynamic) +| Platform | RID | NativeAOT Support |
Size
![Storage Requirement](https://img.shields.io/badge/Runtime-Package-blue)
| +|----------|-----|-------------------------|-----------| +| Windows x64 | `win-x64` | ✓ (Static CRT /MT) | ![Windows x64](https://img.shields.io/badge/6_MB-42_MB_(176_MB)-blue) | +| Windows ARM64 | `win-arm64` | ✓ (Static CRT /MT) | ![Windows ARM64](https://img.shields.io/badge/6_MB-41_MB_(183_MB)-blue) | +| Linux x64 | `linux-x64` | ✓ (Dynamic CRT) | ![Linux x64](https://img.shields.io/badge/10_MB-9_MB_(28_MB)-blue) | +| Linux ARM64 | `linux-arm64` | ✓ (Dynamic CRT) | ![Linux ARM64](https://img.shields.io/badge/10_MB-8_MB_(26_MB)-blue) | +| ⓘ macOS x64 | `osx-x64` | ✓ (Dynamic CRT) | ![macOS x64](https://img.shields.io/badge/15_MB-11_MB_(28_MB)-blue) | +| ⓘ macOS ARM64 | `osx-arm64` | ✓ (Dynamic CRT) | ![macOS ARM64](https://img.shields.io/badge/13_MB-10_MB_(25_MB)-blue) | -For dynamic linking, you can install Libsodium for the most popular platforms by referencing the [official Libsodium NuGet package](https://www.nuget.org/packages/libsodium). +ⓘ Currently, the macOS packages are built and published, but functions verification tests are skipped due to limitations with `dyld`. +They are still expected to work correctly, but we recommend testing on macOS before production use. -### Manual or System-wide Installation +## Dynamic Linking +For standard .NET applications, you can simply reference the relevant packages for your target platforms. The runtimes will be correctly copied and loaded across platforms. -#### Windows - -For dynamic linking on Windows, you need to use the dynamic link libraries (`libdave`, `libsodium`, and/or `opus`). Here's how to set it up: -- Download or build the dynamic link libraries (`libdave`, `libsodium`, and/or `opus`) compatible with your development environment. - -- Place these files in the runtime directory of your application. This is the folder where your application's executable is located. - -#### Linux and MacOS - -Dynamic linking on Linux and MacOS involves using shared libraries (`libdave`, `libsodium`, and/or `opus`). You can install them using your system's package manager if available or follow these steps to install them manually: -- Download or build the shared libraries (`libdave`, `libsodium`, and/or `opus`) that are compatible with your development environment. - -- Place these files in the runtime directory of your application, which is the folder where your application's executable is located. - -### [Static Linking](#tab/static) - -> [!NOTE] -> Static linking requires [Native AOT](https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot) compilation. - -#### Windows - -When using static linking on Windows, you need to link to the static libraries (`libdave`, `libsodium`, and/or `opus`). Here are the steps to set up static linking in your application: -- Download or build the static libraries (`libdave`, `libsodium`, and/or `opus`) compatible with your development environment. -- Link these libraries in your project settings. Ensure that you specify the correct paths to these libraries: - ```xml - - - - - - - - - - - ``` +```xml + + + + + +``` -You don't need to place any of these files in the runtime directory, as static linking embeds the library code directly into your application, eliminating the need for separate files. +## Usage with NativeAOT (Static Linking) -#### Linux and MacOS +When using [NativeAOT](https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot), static libraries are automatically linked from the NuGet package, embedding the necessary native code directly into your executable. -Static linking on Linux and MacOS involves linking your application with the static libraries (`libdave`, `libsodium`, and/or `opus`). You can install them using your system's package manager if available or download or build the static libraries (`libdave`, `libsodium`, and/or `opus`) compatible with your development environment manually. +### Requirement for DirectPInvoke +When targeting NativeAOT, you must ensure that all used native libraries are explicitly registered using `` in your project file to ensure they are properly included during the AOT compilation process: -Link these libraries in your project settings. Make sure you specify the correct paths to these libraries: ```xml - - - - - + ``` -Since you're statically linking, you won't need to place any of these files in the runtime directory. The necessary code from the libraries will be included directly in your application. +### Excluding Bundled Dependencies +If you have provided your own native binaries and need to exclude the ones bundled in the NetCord NuGet package to avoid conflicts, use the `NetCordExcludeNatives` property. + +```xml + + opus + +``` -*** +## Custom Manual/System-wide Installation -#### Installation External Links +If you are developing for an unsupported platform or require a custom-built native binary, you may choose to handle native dependencies manually. + +1. **Obtain Binaries**: Use your system's package manager (e.g., `apt`, `brew`, `dnf`) if available, or download the binaries from the official sources listed below. +2. **Placement**: Ensure the native libraries are available to your application at runtime. On Windows, place `.dll` files in your application's output directory. On Unix-like systems, ensure shared libraries are in your `LD_LIBRARY_PATH` or system standard paths. + +### Installation External Links | Library | Installation Link | |-----------|---------------------------------------------| | Libdave | https://github.com/discord/libdave/releases | | Libsodium | https://doc.libsodium.org/installation | | Opus | https://opus-codec.org/downloads | +| Zstd | https://github.com/facebook/zstd/releases | + +## Troubleshooting +- If you encounter issues with native dependencies, ensure that the correct versions are installed and that they are accessible to your application. +- Use tools like `ldd` (Linux) or `Dependency Walker` (Windows) to verify that your application is correctly linking against the native libraries. + +--- + +## Extra Notes on Native Dependencies + +The native packaging model is designed to make managing dependencies as transparent and reliable as possible. + +### What You Get +* **Ready-to-use binaries**: We provide prebuilt runtime binaries for standard .NET and static libraries for NativeAOT. +* **Automatic Configuration**: MSBuild files are included in the packages to automatically handle paths and linking requirements, so you don't have to manually configure build settings. + +### Built-in Compliance +All necessary licenses and copyright notices from the original native project sources are bundled automatically within each package under the `licenses/` directory. + +| Library | License | Remarks | +| :--- | :--- | :--- | +| **Libdave** | MIT | Discord voice communication | +| **Libsodium** | ISC | Used for encryption | +| **OpenSSL** | Apache 2.0 | Cryptographic operations | +| **Opus** | BSD-3-Clause | Audio codec | +| **Zstd** | BSD-3-Clause | Compression | + +### How It’s Built +* **Reproducible builds**: Dependencies are strictly pinned using [vcpkg](https://github.com/microsoft/vcpkg) baselines. This means every build result should be identical, regardless of who or what runs the build. diff --git a/NetCord.Natives/NativesHelper.cs b/NetCord.Natives/NativesHelper.cs deleted file mode 100644 index 866a421b6..000000000 --- a/NetCord.Natives/NativesHelper.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection; - -namespace NetCord.Natives; - -[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] -public class NativeLibraryVersionAttribute(string name, string version) : Attribute -{ - public string Name { get; } = name; - public string Version { get; } = version; -} - -public static class NativesHelper -{ - public static IEnumerable GetNativeLibraryVersions() - { - return typeof(NativesHelper).Assembly.GetCustomAttributes(); - } -} diff --git a/NetCord.Natives/NetCord.Natives.csproj b/NetCord.Natives/NetCord.Natives.csproj index 3d38cf8c4..a13b761d4 100644 --- a/NetCord.Natives/NetCord.Natives.csproj +++ b/NetCord.Natives/NetCord.Natives.csproj @@ -3,6 +3,9 @@ Pre-built native libraries for NetCord, $(Description) false + false + false + true $([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)\..')) @@ -123,7 +126,7 @@ Condition="'$(VcpkgUseStatic)' != 'true'" />
- @@ -131,29 +134,27 @@ - + @(StatusLines, ' ') - + <_VcpkgPkg Include="@(NativeLibLic)"> - - $([System.Text.RegularExpressions.Regex]::Match('$(StatusText)', 'Package: %(Identity)\n(?:.*\n)*?Version: (.*?)\n').Groups[1].Value) + + $([System.Text.RegularExpressions.Regex]::Match('$(StatusText)', 'Package: %(Identity)\n(?:.*\n)*?Version: (.*?)\n').Groups[1].Value) - - - - <_Parameter1>%(_VcpkgPkg.Identity) - <_Parameter2>%(_VcpkgPkg.Version) - - - + + + $(PackageDescription) (Includes: @(_VcpkgPkg->'%(Identity) v%(Version)', ', ')) + + - + GetMissingLibraryImports(string libName, s return missingExports; } + /* + * This method is not working on macOS due to System.Diagnostics.ProcessModule + * not listing native libraries loaded by the runtime's dynamic library loader (dyld). + * This is likely because dyld does not expose these libraries to the process in the + * same way that LoadLibrary on Windows or dlopen on Linux does, and as a result they + * do not appear in the list of modules for the process. This is a known limitation + * when trying to inspect loaded native libraries on macOS using .NET, and may require + * platform-specific workarounds or tools to verify the presence of native libraries + * on that platform. + */ internal static IntPtr GetLoadedNativeModuleHandle(string libName) { _ = libName switch @@ -60,19 +70,25 @@ internal static IntPtr GetLoadedNativeModuleHandle(string libName) _ => throw new InvalidOperationException($"Unknown library name '{libName}' provided to test."), }; + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + throw new PlatformNotSupportedException("Retrieving loaded native module handles is not supported on macOS due to platform limitations."); + var module = System.Diagnostics.Process.GetCurrentProcess().Modules .Cast() .FirstOrDefault(m => { - var moduleName = Path.GetFileName(m.ModuleName); + var moduleName = Path.GetFileName(m.FileName); return moduleName.StartsWith(libName, StringComparison.OrdinalIgnoreCase) || moduleName.StartsWith($"lib{libName}", StringComparison.OrdinalIgnoreCase); }) ?? throw new InvalidOperationException($"Native module '{libName}' was not found in the current process."); if (NativeLibrary.TryLoad(module.FileName, out var libHandleByPath)) + { + Console.WriteLine($"Successfully obtained a handle for native module '{module.ModuleName}' using path '{module.FileName}'."); return libHandleByPath; + } - throw new InvalidOperationException($"Failed to obtain a handle for native module '{libName}'."); + throw new InvalidOperationException($"Failed to obtain a handle for native module '{module.ModuleName}'."); } } diff --git a/Tests/NetCord.Natives.Tests/NativesBuildTests.cs b/Tests/NetCord.Natives.Tests/NativesBuildTests.cs index f24625859..8de10c24b 100644 --- a/Tests/NetCord.Natives.Tests/NativesBuildTests.cs +++ b/Tests/NetCord.Natives.Tests/NativesBuildTests.cs @@ -25,6 +25,7 @@ public void NativesLoaded(string libName) } [TestMethod] + [OSCondition(ConditionMode.Exclude, OperatingSystems.OSX)] [DataRow("libdave", "NetCord.Gateway.Voice.Dave")] [DataRow("libsodium", "NetCord.Gateway.Voice.Encryption.XChaCha20Poly1305")] [DataRow("opus", "NetCord.Gateway.Voice.Opus")] @@ -93,6 +94,8 @@ public void NativeAotStaticLinking(string libName) getRunCmd.StartInfo.ArgumentList.Add("-t:GetTargetPath"); getRunCmd.StartInfo.ArgumentList.Add("-getProperty:PublishDir"); getRunCmd.StartInfo.ArgumentList.Add("--no-restore"); + + getRunCmd.StartInfo.ArgumentList.Add("--bl"); string? runCmdOutput = null; diff --git a/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj b/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj index 6dd95eedf..636b6f9ae 100644 --- a/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj +++ b/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj @@ -27,7 +27,6 @@ - From 29e03effdea0e18034004b52f0a1e5bc96224109 Mon Sep 17 00:00:00 2001 From: Haves Irfan Date: Fri, 22 May 2026 03:29:03 +0900 Subject: [PATCH 011/101] Apply typos and internals fixes Co-authored-by: Kuba_Z2 <77853483+KubaZ2@users.noreply.github.com> --- .../installing-native-dependencies.md | 14 +++++++------- NetCord.Natives/natives-ports/libdave/vcpkg.json | 2 +- NetCord.slnx | 1 - Tests/NetCord.Natives.Tests/NativeProbes.cs | 2 +- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/Documentation/guides/basic-concepts/installing-native-dependencies.md b/Documentation/guides/basic-concepts/installing-native-dependencies.md index 061d36f03..c67919069 100644 --- a/Documentation/guides/basic-concepts/installing-native-dependencies.md +++ b/Documentation/guides/basic-concepts/installing-native-dependencies.md @@ -97,13 +97,13 @@ The native packaging model is designed to make managing dependencies as transpar ### Built-in Compliance All necessary licenses and copyright notices from the original native project sources are bundled automatically within each package under the `licenses/` directory. -| Library | License | Remarks | -| :--- | :--- | :--- | -| **Libdave** | MIT | Discord voice communication | -| **Libsodium** | ISC | Used for encryption | -| **OpenSSL** | Apache 2.0 | Cryptographic operations | -| **Opus** | BSD-3-Clause | Audio codec | -| **Zstd** | BSD-3-Clause | Compression | +| Library | License | Remarks | +|---------------|--------------|-----------------------------| +| **Libdave** | MIT | Discord voice communication | +| **Libsodium** | ISC | Used for encryption | +| **OpenSSL** | Apache 2.0 | Cryptographic operations | +| **Opus** | BSD-3-Clause | Audio codec | +| **Zstd** | BSD-3-Clause | Compression | ### How It’s Built * **Reproducible builds**: Dependencies are strictly pinned using [vcpkg](https://github.com/microsoft/vcpkg) baselines. This means every build result should be identical, regardless of who or what runs the build. diff --git a/NetCord.Natives/natives-ports/libdave/vcpkg.json b/NetCord.Natives/natives-ports/libdave/vcpkg.json index 9f74f4d3a..9a95c5338 100644 --- a/NetCord.Natives/natives-ports/libdave/vcpkg.json +++ b/NetCord.Natives/natives-ports/libdave/vcpkg.json @@ -15,4 +15,4 @@ "host": true } ] -} \ No newline at end of file +} diff --git a/NetCord.slnx b/NetCord.slnx index 30dd9affd..23417afd4 100644 --- a/NetCord.slnx +++ b/NetCord.slnx @@ -84,7 +84,6 @@ - diff --git a/Tests/NetCord.Natives.Tests/NativeProbes.cs b/Tests/NetCord.Natives.Tests/NativeProbes.cs index 4a03b6d2a..14338f938 100644 --- a/Tests/NetCord.Natives.Tests/NativeProbes.cs +++ b/Tests/NetCord.Natives.Tests/NativeProbes.cs @@ -23,7 +23,7 @@ internal static IReadOnlyList GetMissingLibraryImports(string libName, s var libHandle = GetLoadedNativeModuleHandle(libName); var missingExports = new List(); - var methods = typeWithImports!.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) + var methods = typeWithImports!.GetMethods(BindingFlags.Static | BindingFlags.NonPublic) .Select(m => new { MethodName = m.Name, From 4ac12da16f556736424cf2fdcd036ca526bfb708 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Tue, 26 May 2026 23:44:57 +0900 Subject: [PATCH 012/101] Resolve PR comments * Implement resolved PR #257 review comments - Fix NetCord.Natives.targets comment typo: 'comes' -> 'come' - Normalize Importance='High' to 'high' in NetCord.Natives.csproj - Remove stale commented-out PackageReference in NativeAotApp.csproj - Update Resources/NuGet/README.md to link to docs for full package list - Add 'natives' devShell to flake.nix with autoconf/automake/libtool - Replace macOS brew step with Nix in build-natives.yml; split Build step for Windows/non-Windows - Pin all GitHub Actions by commit hash in build-natives.yml - Rename build-publish-natives.yml -> build-and-publish-natives.yml; pin download-artifact hash; fix self-reference in paths trigger Agent-Logs-Url: https://github.com/ha-ves/NetCord/sessions/f6e9307c-fd0a-40c8-b3a8-e0484782c21e Co-authored-by: ha-ves <20160532+ha-ves@users.noreply.github.com> * fix: address natives README link and reflection method visibility Agent-Logs-Url: https://github.com/ha-ves/NetCord/sessions/e686bf59-4e1e-4ec5-82f8-cc6b3ef93656 Co-authored-by: ha-ves <20160532+ha-ves@users.noreply.github.com> * README: add period to NetCord.Natives table description Agent-Logs-Url: https://github.com/ha-ves/NetCord/sessions/0553c8bd-a710-4a4d-a8a8-deb3dc917faa Co-authored-by: ha-ves <20160532+ha-ves@users.noreply.github.com> * Deduplicate native build workflow step and remove MSBuild XML schema namespaces Agent-Logs-Url: https://github.com/ha-ves/NetCord/sessions/a0011395-8ab0-458e-a04e-8152069b7880 Co-authored-by: ha-ves <20160532+ha-ves@users.noreply.github.com> * Fix README NetCord.Natives description punctuation Agent-Logs-Url: https://github.com/ha-ves/NetCord/sessions/a0011395-8ab0-458e-a04e-8152069b7880 Co-authored-by: ha-ves <20160532+ha-ves@users.noreply.github.com> * Revert prior README tweak and set NetCord.Natives row text as requested Agent-Logs-Url: https://github.com/ha-ves/NetCord/sessions/52fb7ee0-c97d-452c-9d94-1eec13cd17ee Co-authored-by: ha-ves <20160532+ha-ves@users.noreply.github.com> * Set README NetCord.Natives row to exact requested text Agent-Logs-Url: https://github.com/ha-ves/NetCord/sessions/5f1c09c3-27c2-48af-872c-0ae465ec420b Co-authored-by: ha-ves <20160532+ha-ves@users.noreply.github.com> * Update README natives row, native dependencies docs, and test configs - Update all README.md files with new NetCord.Natives. row format - Replace size column with NuGet package badges in native dependencies table - Clarify libsodium description regarding voice server encryption requirements - Update NativeAotApp.csproj: change DirectPInvoke to directly include libraries - Remove CentrallyManagedPackage false and NoWarn settings from NativeAotApp.csproj - Remove stray -bl argument from NativesBuildTests.cs GetRunCmd Agent-Logs-Url: https://github.com/ha-ves/NetCord/sessions/e244793a-3f65-4653-8019-ee2d5151b0c1 Co-authored-by: ha-ves <20160532+ha-ves@users.noreply.github.com> * Improve libsodium documentation with clearer explanation of encryption fallback scenarios Agent-Logs-Url: https://github.com/ha-ves/NetCord/sessions/2a7fe8b8-026b-4918-8d18-9356084ad340 Co-authored-by: ha-ves <20160532+ha-ves@users.noreply.github.com> * Fix README for NetCord.Natives * fix readme in nuget --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: ha-ves <20160532+ha-ves@users.noreply.github.com> Co-authored-by: Haves Irfan fix CI shell error --- ...ives.yml => build-and-publish-natives.yml} | 4 +- .github/workflows/build-natives.yml | 116 +++++++++++------- .../installing-native-dependencies.md | 20 +-- NetCord.Natives/NetCord.Natives.csproj | 2 +- NetCord.Natives/NetCord.Natives.local.targets | 2 +- NetCord.Natives/NetCord.Natives.props | 2 +- NetCord.Natives/NetCord.Natives.targets | 4 +- NetCord.Natives/vcpkg-non-windows.targets | 2 +- README.md | 2 +- Resources/NuGet/README.md | 2 +- .../Assets/NativeAotApp/NativeAotApp.csproj | 8 +- Tests/NetCord.Natives.Tests/NativeProbes.cs | 2 +- .../NativesBuildTests.cs | 2 - flake.nix | 8 ++ 14 files changed, 110 insertions(+), 66 deletions(-) rename .github/workflows/{build-publish-natives.yml => build-and-publish-natives.yml} (85%) diff --git a/.github/workflows/build-publish-natives.yml b/.github/workflows/build-and-publish-natives.yml similarity index 85% rename from .github/workflows/build-publish-natives.yml rename to .github/workflows/build-and-publish-natives.yml index 8850fb498..12e98107d 100644 --- a/.github/workflows/build-publish-natives.yml +++ b/.github/workflows/build-and-publish-natives.yml @@ -6,7 +6,7 @@ on: paths: - 'NetCord.Natives/**' - '.github/workflows/build-natives.yml' - - '.github/workflows/publish-natives.yml' + - '.github/workflows/build-and-publish-natives.yml' tags: - "[0-9]+.[0-9]+.[0-9]+" - "[0-9]+.[0-9]+.[0-9]+-*" @@ -21,7 +21,7 @@ jobs: steps: - name: Download All NuGet Package Artifacts - uses: actions/download-artifact@v8.0.1 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: path: artifacts/pkgs pattern: NetCord.Natives.*.packages diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index 6cada1d31..c169b1be7 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -15,18 +15,6 @@ on: jobs: build-natives: - runs-on: ${{ matrix.runs-on }} - env: - CI: true - VCPKG_BINARY_SOURCES: clear;files,${{ github.workspace }}/.vcpkg-cache,readwrite - VCPKG_DOWNLOADS: ${{ github.workspace }}/.vcpkg-downloads - VcpkgOSTarget: ${{ matrix.vcpkg-os-target }} - VcpkgPlatformTarget: ${{ matrix.vcpkg-platform-target }} - Configuration: Release - RuntimeIdentifier: ${{ matrix.rid }} - DotnetVerbose: minimal - GenerateBinLog: ${{ github.event.inputs.GenerateBinLog || inputs.GenerateBinLog || false }} - strategy: fail-fast: false matrix: @@ -35,36 +23,55 @@ jobs: runs-on: windows-latest vcpkg-os-target: windows vcpkg-platform-target: x64 + run-prefix: '' - rid: win-arm64 runs-on: windows-11-arm vcpkg-os-target: windows vcpkg-platform-target: arm64 + run-prefix: '' - rid: osx-x64 runs-on: macos-15-intel vcpkg-os-target: osx vcpkg-platform-target: x64 + run-prefix: nix develop .#natives -c bash -eo pipefail -c - rid: osx-arm64 runs-on: macos-15 vcpkg-os-target: osx vcpkg-platform-target: arm64 + run-prefix: nix develop .#natives -c bash -eo pipefail -c - rid: linux-x64 runs-on: ubuntu-latest vcpkg-os-target: linux vcpkg-platform-target: x64 + run-prefix: nix develop .#natives -c bash -eo pipefail -c - rid: linux-arm64 runs-on: ubuntu-24.04-arm vcpkg-os-target: linux vcpkg-platform-target: arm64 + run-prefix: nix develop .#natives -c bash -eo pipefail -c + + runs-on: ${{ matrix.runs-on }} + env: + CI: true + VCPKG_BINARY_SOURCES: clear;files,${{ github.workspace }}/.vcpkg-cache,readwrite + VCPKG_DOWNLOADS: ${{ github.workspace }}/.vcpkg-downloads + VcpkgOSTarget: ${{ matrix.vcpkg-os-target }} + VcpkgPlatformTarget: ${{ matrix.vcpkg-platform-target }} + RUN_PREFIX: ${{ matrix.run-prefix }} + Configuration: Release + RuntimeIdentifier: ${{ matrix.rid }} + DotnetVerbose: minimal + GenerateBinLog: ${{ github.event.inputs.GenerateBinLog || inputs.GenerateBinLog || false }} steps: - name: Checkout - uses: actions/checkout@v6.0.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 filter: tree:0 - name: Restore vcpkg cache - uses: actions/cache/restore@v5.0.5 + uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: path: | .vcpkg-cache @@ -78,52 +85,79 @@ jobs: uses: ./.github/actions/setup-vcpkg - name: Setup .NET Core SDK - uses: actions/setup-dotnet@v5.2.0 + uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5.2.0 with: global-json-file: global.json - - name: Install native build tools (macOS) - if: runner.os == 'macOS' - shell: bash - run: | - brew update - for pkg in autoconf automake libtool; do - brew list $pkg &>/dev/null || brew install $pkg - done + - name: Install Nix + if: runner.os != 'Windows' + uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6 + + - name: Setup dev environment + if: runner.os != 'Windows' + shell: pwsh + run: 'true' - name: Restore shell: pwsh run: | + $command = @' dotnet restore Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:restore.binlog' || '' }} + '@ + + if ($env:RUN_PREFIX) { + Invoke-Expression "$env:RUN_PREFIX `"$command`"" + } + else { + Invoke-Expression $command + } - name: Build natives projects for ${{ matrix.rid }} shell: pwsh - run: > # Building tests will build dependencies including the native libraries - dotnet build Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj --no-restore -v ${{ env.DotnetVerbose }} - ${{ env.GenerateBinLog == 'true' && '-bl:build.binlog' || '' }} - -p:AppendNativeAotAppProps="RuntimeIdentifier=${{ env.RuntimeIdentifier }}" - -p:GeneratePackageOnBuild=false -p:CI=false + run: | # Building tests will build dependencies including the native libraries + $command = @' + dotnet build Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj --no-restore -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:build.binlog' || '' }} -p:AppendNativeAotAppProps="RuntimeIdentifier=${{ env.RuntimeIdentifier }}" -p:GeneratePackageOnBuild=false -p:CI=false + '@ + + if ($env:RUN_PREFIX) { + Invoke-Expression "$env:RUN_PREFIX `"$command`"" + } + else { + Invoke-Expression $command + } - name: Test natives outputs for ${{ matrix.rid }} shell: pwsh - run: > - dotnet test Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj --no-restore --no-build -v ${{ env.DotnetVerbose }} - ${{ env.GenerateBinLog == 'true' && '-bl:test.binlog' || '' }} - --logger "console;verbosity=detailed" - --logger GitHubActions + run: | + $command = @' + dotnet test Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj --no-restore --no-build -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:test.binlog' || '' }} --logger "console;verbosity=detailed" --logger GitHubActions + '@ + + if ($env:RUN_PREFIX) { + Invoke-Expression "$env:RUN_PREFIX `"$command`"" + } + else { + Invoke-Expression $command + } - name: Pack NuGet Package for ${{ matrix.rid }} if: ${{ always() }} shell: pwsh - run: > - dotnet pack NetCord.Natives/NetCord.Natives.csproj --no-restore --no-build -v ${{ env.DotnetVerbose }} - ${{ env.GenerateBinLog == 'true' && '-bl:pack.binlog' || '' }} - -o NetCord.Natives/bin/${{ matrix.rid }} - -p:CI=false + run: | + $command = @' + dotnet pack NetCord.Natives/NetCord.Natives.csproj --no-restore --no-build -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:pack.binlog' || '' }} -o NetCord.Natives/bin/${{ matrix.rid }} -p:CI=false + '@ + + if ($env:RUN_PREFIX) { + Invoke-Expression "$env:RUN_PREFIX `"$command`"" + } + else { + Invoke-Expression $command + } - name: Upload Binary Logs if: ${{ env.GenerateBinLog == 'true' && always() }} - uses: actions/upload-artifact@v4.6.0 + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: name: ${{ matrix.rid }}-binlogs path: | @@ -131,7 +165,7 @@ jobs: - name: Upload NuGet Package Artifact if: ${{ always() }} - uses: actions/upload-artifact@v7.0.1 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: NetCord.Natives.${{ matrix.rid }}.packages path: | @@ -140,7 +174,7 @@ jobs: - name: Save vcpkg cache if: ${{ always() }} - uses: actions/cache/save@v5.0.5 + uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: path: | .vcpkg-cache diff --git a/Documentation/guides/basic-concepts/installing-native-dependencies.md b/Documentation/guides/basic-concepts/installing-native-dependencies.md index c67919069..beaa94161 100644 --- a/Documentation/guides/basic-concepts/installing-native-dependencies.md +++ b/Documentation/guides/basic-concepts/installing-native-dependencies.md @@ -5,7 +5,11 @@ NetCord relies on several native libraries for high-performance audio processing ## Native Dependencies Context - **Libdave**: Essential for voice connection interactions. -- **Libsodium**: Used for encryption. While NetCord defaults to native AES-GCM (which does not require Libsodium), Libsodium is a highly recommended production dependency. It acts as a fallback for the XChaCha20-Poly1305 encryption mode, ensuring your bot remains compatible if Discord switches to this mode for your connection. +- **Libsodium**: Used for encryption and provides fallback encryption modes. NetCord attempts to use the platform's native AES-GCM encryption for voice connections. However, Libsodium becomes essential in two scenarios: + - **Server-side limitation**: When connecting to a voice channel, Discord assigns you to a voice server. Depending on the server and region, it may or may not support AES-GCM. All voice servers support XChaCha20-Poly1305, so if AES-GCM is unavailable on the server you're assigned to, Libsodium is required to use XChaCha20-Poly1305 as a fallback. + - **Hardware limitation**: If your hardware doesn't support AES-GCM (rare but possible on older CPUs), Libsodium is required to provide the XChaCha20-Poly1305 fallback encryption. + + Without Libsodium, your bot will fail to connect to voice channels if either of these conditions occur. - **Opus**: A versatile audio codec required for any classes in NetCord prefixed with `Opus` (e.g., audio encoding/decoding). - **Zstd**: Used for efficient payload compression. @@ -16,14 +20,14 @@ NetCord distributes these dependencies as per-RID (Runtime Identifier) packages. ### Supported Platforms Packages are available for: -| Platform | RID | NativeAOT Support |
Size
![Storage Requirement](https://img.shields.io/badge/Runtime-Package-blue)
| +| Platform | RID | NativeAOT Support | NuGet Package | |----------|-----|-------------------------|-----------| -| Windows x64 | `win-x64` | ✓ (Static CRT /MT) | ![Windows x64](https://img.shields.io/badge/6_MB-42_MB_(176_MB)-blue) | -| Windows ARM64 | `win-arm64` | ✓ (Static CRT /MT) | ![Windows ARM64](https://img.shields.io/badge/6_MB-41_MB_(183_MB)-blue) | -| Linux x64 | `linux-x64` | ✓ (Dynamic CRT) | ![Linux x64](https://img.shields.io/badge/10_MB-9_MB_(28_MB)-blue) | -| Linux ARM64 | `linux-arm64` | ✓ (Dynamic CRT) | ![Linux ARM64](https://img.shields.io/badge/10_MB-8_MB_(26_MB)-blue) | -| ⓘ macOS x64 | `osx-x64` | ✓ (Dynamic CRT) | ![macOS x64](https://img.shields.io/badge/15_MB-11_MB_(28_MB)-blue) | -| ⓘ macOS ARM64 | `osx-arm64` | ✓ (Dynamic CRT) | ![macOS ARM64](https://img.shields.io/badge/13_MB-10_MB_(25_MB)-blue) | +| Windows x64 | `win-x64` | ✓ (Static CRT /MT) | [![NetCord.Natives.win-x64](https://img.shields.io/nuget/v/NetCord.Natives.win-x64?label=NetCord.Natives.win-x64)](https://www.nuget.org/packages/NetCord.Natives.win-x64) | +| Windows ARM64 | `win-arm64` | ✓ (Static CRT /MT) | [![NetCord.Natives.win-arm64](https://img.shields.io/nuget/v/NetCord.Natives.win-arm64?label=NetCord.Natives.win-arm64)](https://www.nuget.org/packages/NetCord.Natives.win-arm64) | +| Linux x64 | `linux-x64` | ✓ (Dynamic CRT) | [![NetCord.Natives.linux-x64](https://img.shields.io/nuget/v/NetCord.Natives.linux-x64?label=NetCord.Natives.linux-x64)](https://www.nuget.org/packages/NetCord.Natives.linux-x64) | +| Linux ARM64 | `linux-arm64` | ✓ (Dynamic CRT) | [![NetCord.Natives.linux-arm64](https://img.shields.io/nuget/v/NetCord.Natives.linux-arm64?label=NetCord.Natives.linux-arm64)](https://www.nuget.org/packages/NetCord.Natives.linux-arm64) | +| ⓘ macOS x64 | `osx-x64` | ✓ (Dynamic CRT) | [![NetCord.Natives.osx-x64](https://img.shields.io/nuget/v/NetCord.Natives.osx-x64?label=NetCord.Natives.osx-x64)](https://www.nuget.org/packages/NetCord.Natives.osx-x64) | +| ⓘ macOS ARM64 | `osx-arm64` | ✓ (Dynamic CRT) | [![NetCord.Natives.osx-arm64](https://img.shields.io/nuget/v/NetCord.Natives.osx-arm64?label=NetCord.Natives.osx-arm64)](https://www.nuget.org/packages/NetCord.Natives.osx-arm64) | ⓘ Currently, the macOS packages are built and published, but functions verification tests are skipped due to limitations with `dyld`. They are still expected to work correctly, but we recommend testing on macOS before production use. diff --git a/NetCord.Natives/NetCord.Natives.csproj b/NetCord.Natives/NetCord.Natives.csproj index a13b761d4..cf6e4f236 100644 --- a/NetCord.Natives/NetCord.Natives.csproj +++ b/NetCord.Natives/NetCord.Natives.csproj @@ -119,7 +119,7 @@ - + diff --git a/NetCord.Natives/NetCord.Natives.props b/NetCord.Natives/NetCord.Natives.props index c1b6ee94b..7060b8ea2 100644 --- a/NetCord.Natives/NetCord.Natives.props +++ b/NetCord.Natives/NetCord.Natives.props @@ -1,4 +1,4 @@ - + + <_NetCordStaticLink Include="libsodium;sodium" Condition="'%(DirectPInvoke.Identity)' == 'libsodium'" /> diff --git a/NetCord.Natives/vcpkg-non-windows.targets b/NetCord.Natives/vcpkg-non-windows.targets index 134e697ad..66778834c 100644 --- a/NetCord.Natives/vcpkg-non-windows.targets +++ b/NetCord.Natives/vcpkg-non-windows.targets @@ -1,4 +1,4 @@ - + <_ZVcpkgInstallManifestDependenciesInputs Include="$(_ZVcpkgManifestFileLocation)"/> diff --git a/README.md b/README.md index cdbb638f1..efd74ac6c 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ You can install NetCord packages via NuGet package manager: | **[NetCord.Hosting](https://www.nuget.org/packages/NetCord.Hosting)** | Provides .NET Generic Host extensions for the NetCord package. | | **[NetCord.Hosting.Services](https://www.nuget.org/packages/NetCord.Hosting.Services)** | Provides .NET Generic Host extensions for the NetCord.Services package. | | **[NetCord.Hosting.AspNetCore](https://www.nuget.org/packages/NetCord.Hosting.AspNetCore)** | Provides ASP.NET Core extensions for seamless handling of HTTP events. | -| **[NetCord.Natives](https://www.nuget.org/packages/NetCord.Natives)** | Provides pre-built native binaries dependencies. | +| NetCord.Natives.<RuntimeId> | Provides pre-built native runtime dependencies binary.
[See Native Dependencies Installation Guide.](https://netcord.dev/guides/basic-concepts/installing-native-dependencies.html) | ## 2. 🚀 Showcase diff --git a/Resources/NuGet/README.md b/Resources/NuGet/README.md index d7babe22d..617844cf9 100644 --- a/Resources/NuGet/README.md +++ b/Resources/NuGet/README.md @@ -25,7 +25,7 @@ You can install NetCord packages via NuGet package manager: | **[NetCord.Hosting](https://www.nuget.org/packages/NetCord.Hosting)** | Provides .NET Generic Host extensions for the NetCord package. | | **[NetCord.Hosting.Services](https://www.nuget.org/packages/NetCord.Hosting.Services)** | Provides .NET Generic Host extensions for the NetCord.Services package. | | **[NetCord.Hosting.AspNetCore](https://www.nuget.org/packages/NetCord.Hosting.AspNetCore)** | Provides ASP.NET Core extensions for seamless handling of HTTP events. | -| **[NetCord.Natives](https://www.nuget.org/packages/NetCord.Natives)** | Provides pre-built native binaries dependencies. | +| NetCord.Natives.<RuntimeId> | Provides pre-built native runtime dependencies binary.
[See Native Dependencies Installation Guide.](https://netcord.dev/guides/basic-concepts/installing-native-dependencies.html) | ## 2. 🚀 Showcase diff --git a/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj b/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj index d06d6424d..11eff813a 100644 --- a/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj +++ b/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj @@ -10,8 +10,6 @@ true true true - false - $(NoWarn);IL2075;IL2026 ..\..\..\..\NetCord.Natives
@@ -21,8 +19,10 @@ - - + + + + diff --git a/Tests/NetCord.Natives.Tests/NativeProbes.cs b/Tests/NetCord.Natives.Tests/NativeProbes.cs index 14338f938..4a03b6d2a 100644 --- a/Tests/NetCord.Natives.Tests/NativeProbes.cs +++ b/Tests/NetCord.Natives.Tests/NativeProbes.cs @@ -23,7 +23,7 @@ internal static IReadOnlyList GetMissingLibraryImports(string libName, s var libHandle = GetLoadedNativeModuleHandle(libName); var missingExports = new List(); - var methods = typeWithImports!.GetMethods(BindingFlags.Static | BindingFlags.NonPublic) + var methods = typeWithImports!.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) .Select(m => new { MethodName = m.Name, diff --git a/Tests/NetCord.Natives.Tests/NativesBuildTests.cs b/Tests/NetCord.Natives.Tests/NativesBuildTests.cs index 8de10c24b..ec112fbca 100644 --- a/Tests/NetCord.Natives.Tests/NativesBuildTests.cs +++ b/Tests/NetCord.Natives.Tests/NativesBuildTests.cs @@ -95,8 +95,6 @@ public void NativeAotStaticLinking(string libName) getRunCmd.StartInfo.ArgumentList.Add("-getProperty:PublishDir"); getRunCmd.StartInfo.ArgumentList.Add("--no-restore"); - getRunCmd.StartInfo.ArgumentList.Add("--bl"); - string? runCmdOutput = null; getRunCmd.StartInfo.WorkingDirectory = projectDirectory; diff --git a/flake.nix b/flake.nix index f9954b91e..7a6c133ec 100644 --- a/flake.nix +++ b/flake.nix @@ -47,6 +47,14 @@ DOTNET_ROOT = dotnetRoot; }; + natives = pkgs.mkShell { + packages = [ + pkgs.autoconf + pkgs.automake + pkgs.libtool + ]; + }; + docs = pkgs.mkShell { packages = [ docfx From 243c384178c2e53ce3c2cb3034a9cf08ee0c5a1b Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Wed, 27 May 2026 02:02:36 +0900 Subject: [PATCH 013/101] Revert to not using nix for building the natives, as it causes more issues than it solves (build tools & dependency pinning, which should already be handled by vcpkg). We can revisit this in the future if we find a better way to use nix for this purpose. * re-order workflow properties to be more logical and easier to read. This reverts commit e62276d6b10693fd3da6be1ad1bb094206181ef3. --- .github/workflows/build-natives.yml | 75 +++++++---------------------- 1 file changed, 18 insertions(+), 57 deletions(-) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index c169b1be7..83942d72c 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -23,32 +23,26 @@ jobs: runs-on: windows-latest vcpkg-os-target: windows vcpkg-platform-target: x64 - run-prefix: '' - rid: win-arm64 runs-on: windows-11-arm vcpkg-os-target: windows vcpkg-platform-target: arm64 - run-prefix: '' - rid: osx-x64 runs-on: macos-15-intel vcpkg-os-target: osx vcpkg-platform-target: x64 - run-prefix: nix develop .#natives -c bash -eo pipefail -c - rid: osx-arm64 runs-on: macos-15 vcpkg-os-target: osx vcpkg-platform-target: arm64 - run-prefix: nix develop .#natives -c bash -eo pipefail -c - rid: linux-x64 runs-on: ubuntu-latest vcpkg-os-target: linux vcpkg-platform-target: x64 - run-prefix: nix develop .#natives -c bash -eo pipefail -c - rid: linux-arm64 runs-on: ubuntu-24.04-arm vcpkg-os-target: linux vcpkg-platform-target: arm64 - run-prefix: nix develop .#natives -c bash -eo pipefail -c runs-on: ${{ matrix.runs-on }} env: @@ -57,7 +51,6 @@ jobs: VCPKG_DOWNLOADS: ${{ github.workspace }}/.vcpkg-downloads VcpkgOSTarget: ${{ matrix.vcpkg-os-target }} VcpkgPlatformTarget: ${{ matrix.vcpkg-platform-target }} - RUN_PREFIX: ${{ matrix.run-prefix }} Configuration: Release RuntimeIdentifier: ${{ matrix.rid }} DotnetVerbose: minimal @@ -89,71 +82,39 @@ jobs: with: global-json-file: global.json - - name: Install Nix - if: runner.os != 'Windows' - uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6 - - - name: Setup dev environment - if: runner.os != 'Windows' - shell: pwsh - run: 'true' + # - name: Install Nix + # if: runner.os != 'Windows' + # uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6 - name: Restore shell: pwsh run: | - $command = @' dotnet restore Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:restore.binlog' || '' }} - '@ - - if ($env:RUN_PREFIX) { - Invoke-Expression "$env:RUN_PREFIX `"$command`"" - } - else { - Invoke-Expression $command - } - name: Build natives projects for ${{ matrix.rid }} shell: pwsh - run: | # Building tests will build dependencies including the native libraries - $command = @' - dotnet build Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj --no-restore -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:build.binlog' || '' }} -p:AppendNativeAotAppProps="RuntimeIdentifier=${{ env.RuntimeIdentifier }}" -p:GeneratePackageOnBuild=false -p:CI=false - '@ - - if ($env:RUN_PREFIX) { - Invoke-Expression "$env:RUN_PREFIX `"$command`"" - } - else { - Invoke-Expression $command - } + run: > # Building tests will build dependencies including the native libraries + dotnet build Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj --no-restore -v ${{ env.DotnetVerbose }} + ${{ env.GenerateBinLog == 'true' && '-bl:build.binlog' || '' }} + -p:AppendNativeAotAppProps="RuntimeIdentifier=${{ env.RuntimeIdentifier }}" + -p:GeneratePackageOnBuild=false -p:CI=false - name: Test natives outputs for ${{ matrix.rid }} shell: pwsh - run: | - $command = @' - dotnet test Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj --no-restore --no-build -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:test.binlog' || '' }} --logger "console;verbosity=detailed" --logger GitHubActions - '@ - - if ($env:RUN_PREFIX) { - Invoke-Expression "$env:RUN_PREFIX `"$command`"" - } - else { - Invoke-Expression $command - } + run: > + dotnet test Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj --no-restore --no-build -v ${{ env.DotnetVerbose }} + ${{ env.GenerateBinLog == 'true' && '-bl:test.binlog' || '' }} + --logger "console;verbosity=detailed" + --logger GitHubActions - name: Pack NuGet Package for ${{ matrix.rid }} if: ${{ always() }} shell: pwsh - run: | - $command = @' - dotnet pack NetCord.Natives/NetCord.Natives.csproj --no-restore --no-build -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:pack.binlog' || '' }} -o NetCord.Natives/bin/${{ matrix.rid }} -p:CI=false - '@ - - if ($env:RUN_PREFIX) { - Invoke-Expression "$env:RUN_PREFIX `"$command`"" - } - else { - Invoke-Expression $command - } + run: > + dotnet pack NetCord.Natives/NetCord.Natives.csproj --no-restore --no-build -v ${{ env.DotnetVerbose }} + ${{ env.GenerateBinLog == 'true' && '-bl:pack.binlog' || '' }} + -o NetCord.Natives/bin/${{ matrix.rid }} + -p:CI=false - name: Upload Binary Logs if: ${{ env.GenerateBinLog == 'true' && always() }} From 9a796fdf69606c0e756eaf8377cc8fa92276cadf Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Sun, 31 May 2026 00:21:43 +0900 Subject: [PATCH 014/101] separate nix workflow & fix warn-no-error --- .github/actions/setup-vcpkg/action.yml | 43 ----- .../workflows/build-and-publish-natives.yml | 12 +- .github/workflows/build-and-publish.yml | 2 +- .github/workflows/build-natives-nix.yml | 148 ++++++++++++++++++ ...-natives.yml => build-natives-windows.yml} | 41 ++--- .../natives-ports/mlspp/portfile.cmake | 1 + 6 files changed, 172 insertions(+), 75 deletions(-) delete mode 100644 .github/actions/setup-vcpkg/action.yml create mode 100644 .github/workflows/build-natives-nix.yml rename .github/workflows/{build-natives.yml => build-natives-windows.yml} (80%) diff --git a/.github/actions/setup-vcpkg/action.yml b/.github/actions/setup-vcpkg/action.yml deleted file mode 100644 index 58416aea3..000000000 --- a/.github/actions/setup-vcpkg/action.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: Setup vcpkg -description: Setup vcpkg with fallback to submodule checkout - -runs: - using: composite - steps: - - name: Resolve or checkout vcpkg - shell: pwsh - run: | - # Ensure vcpkg cache and downloads directories exist - New-Item -ItemType Directory -Path $env:VCPKG_BINARY_SOURCES.Split(',')[1] -Force | Out-Null - New-Item -ItemType Directory -Path $env:VCPKG_DOWNLOADS -Force | Out-Null - - $vcpkgRoot = $env:VCPKG_INSTALLATION_ROOT - if (-not $vcpkgRoot) { - $vcpkgCommand = Get-Command vcpkg -ErrorAction SilentlyContinue - if ($vcpkgCommand) { - $vcpkgRoot = Split-Path -Parent $vcpkgCommand.Source - } - } - - if (-not $vcpkgRoot -or -not (Test-Path $vcpkgRoot)) { - Write-Host "vcpkg not found in runner image, checking out from submodule..." - git config --file .gitmodules --get-regexp path | while-object { $_.Split()[-1] | where-object { $_ -match 'vcpkg' } } | ForEach-Object { - git submodule update --init --recursive $_ - } - $vcpkgRoot = Join-Path $env:GITHUB_WORKSPACE "vcpkg" - if (-not (Test-Path $vcpkgRoot)) { - Write-Error "vcpkg submodule not found and vcpkg executable not available" - exit 1 - } - } - - if (Test-Path $vcpkgRoot) { - Write-Host "Bootstrapping vcpkg from: $vcpkgRoot" - if ($IsWindows) { - & "$vcpkgRoot/bootstrap-vcpkg.bat" -disableMetrics - } else { - & "$vcpkgRoot/bootstrap-vcpkg.sh" -disableMetrics - } - } - - "VCPKG_ROOT=$vcpkgRoot" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 diff --git a/.github/workflows/build-and-publish-natives.yml b/.github/workflows/build-and-publish-natives.yml index 12e98107d..a47964a57 100644 --- a/.github/workflows/build-and-publish-natives.yml +++ b/.github/workflows/build-and-publish-natives.yml @@ -5,18 +5,22 @@ on: push: paths: - 'NetCord.Natives/**' - - '.github/workflows/build-natives.yml' + - '.github/workflows/build-natives-nix.yml' + - '.github/workflows/build-natives-windows.yml' - '.github/workflows/build-and-publish-natives.yml' tags: - "[0-9]+.[0-9]+.[0-9]+" - "[0-9]+.[0-9]+.[0-9]+-*" jobs: - build-natives: - uses: ./.github/workflows/build-natives.yml + build-natives-nix: + uses: ./.github/workflows/build-natives-nix.yml + + build-natives-windows: + uses: ./.github/workflows/build-natives-windows.yml publish: - needs: [build-natives] + needs: [build-natives-nix, build-natives-windows] runs-on: ubuntu-latest steps: diff --git a/.github/workflows/build-and-publish.yml b/.github/workflows/build-and-publish.yml index 4f15b8808..d7176ef8e 100644 --- a/.github/workflows/build-and-publish.yml +++ b/.github/workflows/build-and-publish.yml @@ -36,7 +36,7 @@ jobs: dotnet nuget push artifacts/pkgs/*.snupkg -k $KEY -s https://api.nuget.org/v3/index.json --skip-duplicate - name: Deploy Documentation - uses: appleboy/scp-action@ff85246acaad7bdce478db94a363cd2bf7c90345 + uses: appleboy/scp-action@ff85246acaad7bdce478db94a363cd2bf7c90345 # v1.0.0 with: username: ${{ secrets.SSH_USERNAME }} host: ${{ secrets.SSH_HOST }} diff --git a/.github/workflows/build-natives-nix.yml b/.github/workflows/build-natives-nix.yml new file mode 100644 index 000000000..4dcfd87fe --- /dev/null +++ b/.github/workflows/build-natives-nix.yml @@ -0,0 +1,148 @@ +name: Build NetCord.Natives (Linux/MacOS, Nix) + +on: + workflow_call: + workflow_dispatch: + inputs: + GenerateBinLog: + type: boolean + default: false + push: + paths: + - 'NetCord.Natives/**' + - 'Tests/NetCord.Natives.Tests/**' + - '.github/workflows/build-natives-nix.yml' + +jobs: + build-natives-nix: + strategy: + fail-fast: false + matrix: + include: + - rid: osx-x64 + runs-on: macos-15-intel + vcpkg-os-target: osx + vcpkg-platform-target: x64 + - rid: osx-arm64 + runs-on: macos-15 + vcpkg-os-target: osx + vcpkg-platform-target: arm64 + - rid: linux-x64 + runs-on: ubuntu-latest + vcpkg-os-target: linux + vcpkg-platform-target: x64 + - rid: linux-arm64 + runs-on: ubuntu-24.04-arm + vcpkg-os-target: linux + vcpkg-platform-target: arm64 + + runs-on: ${{ matrix.runs-on }} + env: + CI: true + VCPKG_BINARY_SOURCES: clear;files,${{ github.workspace }}/.vcpkg-cache,readwrite + VCPKG_DOWNLOADS: ${{ github.workspace }}/.vcpkg-downloads + VcpkgOSTarget: ${{ matrix.vcpkg-os-target }} + VcpkgPlatformTarget: ${{ matrix.vcpkg-platform-target }} + Configuration: Release + RuntimeIdentifier: ${{ matrix.rid }} + DotnetVerbose: minimal + GenerateBinLog: ${{ github.event.inputs.GenerateBinLog || inputs.GenerateBinLog || false }} + + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + filter: tree:0 + + - name: Restore vcpkg cache + uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 + with: + path: | + .vcpkg-cache + .vcpkg-downloads + key: vcpkg-${{ runner.os }}-${{ matrix.rid }}-${{ hashFiles('NetCord.Natives/vcpkg.json', 'NetCord.Natives/natives-ports/**') }} + restore-keys: | + vcpkg-${{ runner.os }}-${{ matrix.rid }}- + vcpkg-${{ runner.os }}- + + - name: Install Nix + uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6 + + - name: Setup vcpkg (non-Windows, Nix) + shell: bash + run: | + cat > bootstrap-vcpkg.sh <<'EOF' + #!/usr/bin/env bash + set -euo pipefail + mkdir -p "${VCPKG_BINARY_SOURCES#*,}" + mkdir -p "${VCPKG_DOWNLOADS}" + vcpkgRoot="${GITHUB_WORKSPACE}/NetCord.Natives/vcpkg" + echo "Bootstrapping vcpkg from: $vcpkgRoot" + "$vcpkgRoot/bootstrap-vcpkg.sh" -disableMetrics + echo "VCPKG_ROOT=$vcpkgRoot" >> "$GITHUB_ENV" + EOF + + chmod +x bootstrap-vcpkg.sh + nix-shell --run ./bootstrap-vcpkg.sh + rm -f bootstrap-vcpkg.sh + + - name: Setup dev shell + shell: &dev-shell 'nix develop -c bash -eo pipefail {0}' + run: 'true' + + - name: Restore + shell: *dev-shell + run: | + dotnet restore Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:restore.binlog' || '' }} + + - name: Build natives projects for ${{ matrix.rid }} + shell: *dev-shell + run: > + dotnet build Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj --no-restore -v ${{ env.DotnetVerbose }} + ${{ env.GenerateBinLog == 'true' && '-bl:build.binlog' || '' }} + -p:AppendNativeAotAppProps="RuntimeIdentifier=${{ env.RuntimeIdentifier }}" + -p:GeneratePackageOnBuild=false -p:CI=false + + - name: Test natives outputs for ${{ matrix.rid }} + shell: *dev-shell + run: > + dotnet test Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj --no-restore --no-build -v ${{ env.DotnetVerbose }} + ${{ env.GenerateBinLog == 'true' && '-bl:test.binlog' || '' }} + --logger "console;verbosity=detailed" + --logger GitHubActions + + - name: Pack NuGet Package for ${{ matrix.rid }} + if: ${{ always() }} + shell: *dev-shell + run: > + dotnet pack NetCord.Natives/NetCord.Natives.csproj --no-restore --no-build -v ${{ env.DotnetVerbose }} + ${{ env.GenerateBinLog == 'true' && '-bl:pack.binlog' || '' }} + -o NetCord.Natives/bin/${{ matrix.rid }} + -p:CI=false + + - name: Upload Binary Logs + if: ${{ env.GenerateBinLog == 'true' && always() }} + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: ${{ matrix.rid }}-binlogs + path: | + *.binlog + + - name: Upload NuGet Package Artifact + if: ${{ always() }} + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: NetCord.Natives.${{ matrix.rid }}.packages + path: | + NetCord.Natives/bin/${{ matrix.rid }}/*.nupkg + NetCord.Natives/bin/${{ matrix.rid }}/*.snupkg + + - name: Save vcpkg cache + if: ${{ always() }} + uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 + with: + path: | + .vcpkg-cache + .vcpkg-downloads + key: vcpkg-${{ runner.os }}-${{ matrix.rid }}-${{ hashFiles('NetCord.Natives/vcpkg.json', 'NetCord.Natives/natives-ports/**') }} diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives-windows.yml similarity index 80% rename from .github/workflows/build-natives.yml rename to .github/workflows/build-natives-windows.yml index 83942d72c..a7c8fd299 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives-windows.yml @@ -1,4 +1,4 @@ -name: Build NetCord.Natives +name: Build NetCord.Natives (Windows) on: workflow_call: @@ -11,10 +11,10 @@ on: paths: - 'NetCord.Natives/**' - 'Tests/NetCord.Natives.Tests/**' - - '.github/workflows/build-natives.yml' + - '.github/workflows/build-natives-windows.yml' jobs: - build-natives: + build-natives-windows: strategy: fail-fast: false matrix: @@ -27,22 +27,6 @@ jobs: runs-on: windows-11-arm vcpkg-os-target: windows vcpkg-platform-target: arm64 - - rid: osx-x64 - runs-on: macos-15-intel - vcpkg-os-target: osx - vcpkg-platform-target: x64 - - rid: osx-arm64 - runs-on: macos-15 - vcpkg-os-target: osx - vcpkg-platform-target: arm64 - - rid: linux-x64 - runs-on: ubuntu-latest - vcpkg-os-target: linux - vcpkg-platform-target: x64 - - rid: linux-arm64 - runs-on: ubuntu-24.04-arm - vcpkg-os-target: linux - vcpkg-platform-target: arm64 runs-on: ${{ matrix.runs-on }} env: @@ -74,18 +58,21 @@ jobs: vcpkg-${{ runner.os }}-${{ matrix.rid }}- vcpkg-${{ runner.os }}- - - name: Setup vcpkg - uses: ./.github/actions/setup-vcpkg + - name: Setup vcpkg (Windows) + shell: pwsh + run: | + New-Item -ItemType Directory -Path $env:VCPKG_BINARY_SOURCES.Split(',')[1] -Force | Out-Null + New-Item -ItemType Directory -Path $env:VCPKG_DOWNLOADS -Force | Out-Null + $vcpkgRoot = Join-Path $env:GITHUB_WORKSPACE "NetCord.Natives/vcpkg" + Write-Host "Bootstrapping vcpkg from: $vcpkgRoot" + & "$vcpkgRoot/bootstrap-vcpkg.bat" -disableMetrics + "VCPKG_ROOT=$vcpkgRoot" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 - name: Setup .NET Core SDK uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5.2.0 with: global-json-file: global.json - # - name: Install Nix - # if: runner.os != 'Windows' - # uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6 - - name: Restore shell: pwsh run: | @@ -93,7 +80,7 @@ jobs: - name: Build natives projects for ${{ matrix.rid }} shell: pwsh - run: > # Building tests will build dependencies including the native libraries + run: > dotnet build Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj --no-restore -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:build.binlog' || '' }} -p:AppendNativeAotAppProps="RuntimeIdentifier=${{ env.RuntimeIdentifier }}" @@ -118,7 +105,7 @@ jobs: - name: Upload Binary Logs if: ${{ env.GenerateBinLog == 'true' && always() }} - uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: ${{ matrix.rid }}-binlogs path: | diff --git a/NetCord.Natives/natives-ports/mlspp/portfile.cmake b/NetCord.Natives/natives-ports/mlspp/portfile.cmake index 2ca219e33..4e863f9f6 100644 --- a/NetCord.Natives/natives-ports/mlspp/portfile.cmake +++ b/NetCord.Natives/natives-ports/mlspp/portfile.cmake @@ -19,6 +19,7 @@ vcpkg_cmake_configure( -DTESTING=OFF -DBUILD_TESTING=OFF -DMLS_CXX_NAMESPACE="mlspp" + -DCMAKE_CXX_FLAGS="-Wno-error" MAYBE_UNUSED_VARIABLES BUILD_TESTING ) From 9a2f59d79363e33f31e9b24a35522e2c71c3d77d Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Sun, 31 May 2026 00:44:12 +0900 Subject: [PATCH 015/101] fix checkout submodules --- .github/workflows/build-natives-nix.yml | 1 + .github/workflows/build-natives-windows.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/build-natives-nix.yml b/.github/workflows/build-natives-nix.yml index 4dcfd87fe..0647f3d7c 100644 --- a/.github/workflows/build-natives-nix.yml +++ b/.github/workflows/build-natives-nix.yml @@ -54,6 +54,7 @@ jobs: with: fetch-depth: 0 filter: tree:0 + submodules: true - name: Restore vcpkg cache uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 diff --git a/.github/workflows/build-natives-windows.yml b/.github/workflows/build-natives-windows.yml index a7c8fd299..df5847fa8 100644 --- a/.github/workflows/build-natives-windows.yml +++ b/.github/workflows/build-natives-windows.yml @@ -46,6 +46,7 @@ jobs: with: fetch-depth: 0 filter: tree:0 + submodules: true - name: Restore vcpkg cache uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 From f6c6a4388d215477ce4424e62669407610453d11 Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Sun, 31 May 2026 00:50:29 +0900 Subject: [PATCH 016/101] [skip ci] rearrange nix & fix vcpkg --- .github/workflows/build-natives-nix.yml | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/.github/workflows/build-natives-nix.yml b/.github/workflows/build-natives-nix.yml index 0647f3d7c..1e5a0bda8 100644 --- a/.github/workflows/build-natives-nix.yml +++ b/.github/workflows/build-natives-nix.yml @@ -70,27 +70,19 @@ jobs: - name: Install Nix uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6 + - name: Setup dev shell + shell: &dev-shell 'nix develop -c bash -eo pipefail {0}' + run: 'true' + - name: Setup vcpkg (non-Windows, Nix) - shell: bash + shell: *dev-shell run: | - cat > bootstrap-vcpkg.sh <<'EOF' - #!/usr/bin/env bash - set -euo pipefail mkdir -p "${VCPKG_BINARY_SOURCES#*,}" mkdir -p "${VCPKG_DOWNLOADS}" vcpkgRoot="${GITHUB_WORKSPACE}/NetCord.Natives/vcpkg" echo "Bootstrapping vcpkg from: $vcpkgRoot" "$vcpkgRoot/bootstrap-vcpkg.sh" -disableMetrics echo "VCPKG_ROOT=$vcpkgRoot" >> "$GITHUB_ENV" - EOF - - chmod +x bootstrap-vcpkg.sh - nix-shell --run ./bootstrap-vcpkg.sh - rm -f bootstrap-vcpkg.sh - - - name: Setup dev shell - shell: &dev-shell 'nix develop -c bash -eo pipefail {0}' - run: 'true' - name: Restore shell: *dev-shell From 3bd4cffcf6c9e5dd563417919aa39d56aa73647d Mon Sep 17 00:00:00 2001 From: Haves Irfan Date: Sun, 14 Jun 2026 11:33:05 +0000 Subject: [PATCH 017/101] restructure netcord.natives * add bootstrap vcpkg * update nix --- .../workflows/build-and-publish-natives.yml | 14 +- .github/workflows/build-natives-nix.yml | 141 ------------------ ...-natives-windows.yml => build-natives.yml} | 80 +++++++--- .gitmodules | 4 +- .../NetCord.Natives.Tests/AssemblyInfo.cs | 0 .../Assets/NativeAotApp/NativeAotApp.csproj | 4 +- .../Assets/NativeAotApp/Program.cs | 0 .../NetCord.Natives.Tests/NativeProbes.cs | 0 .../NativesBuildTests.cs | 0 .../NetCord.Natives.Tests.csproj | 2 +- Natives/NetCord.Natives.slnx | 27 ++++ .../NetCord.Natives}/.gitignore | 0 .../NetCord.Natives}/NetCord.Natives.csproj | 10 +- .../NetCord.Natives.local.targets | 0 .../NetCord.Natives}/NetCord.Natives.props | 0 .../NetCord.Natives}/NetCord.Natives.targets | 0 .../fix-msvc-builtin-add-overflow.patch | 0 .../natives-ports/libdave/portfile.cmake | 0 .../natives-ports/libdave/vcpkg.json | 0 .../natives-ports/mlspp/portfile.cmake | 0 .../natives-ports/mlspp/vcpkg.json | 0 .../NetCord.Natives}/vcpkg | 0 .../vcpkg-non-windows.targets | 3 +- .../NetCord.Natives}/vcpkg.json | 0 NetCord.Natives.slnx | 27 ---- flake.nix | 6 + 26 files changed, 110 insertions(+), 208 deletions(-) delete mode 100644 .github/workflows/build-natives-nix.yml rename .github/workflows/{build-natives-windows.yml => build-natives.yml} (60%) rename {Tests => Natives}/NetCord.Natives.Tests/AssemblyInfo.cs (100%) rename {Tests => Natives}/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj (87%) rename {Tests => Natives}/NetCord.Natives.Tests/Assets/NativeAotApp/Program.cs (100%) rename {Tests => Natives}/NetCord.Natives.Tests/NativeProbes.cs (100%) rename {Tests => Natives}/NetCord.Natives.Tests/NativesBuildTests.cs (100%) rename {Tests => Natives}/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj (96%) create mode 100644 Natives/NetCord.Natives.slnx rename {NetCord.Natives => Natives/NetCord.Natives}/.gitignore (100%) rename {NetCord.Natives => Natives/NetCord.Natives}/NetCord.Natives.csproj (95%) rename {NetCord.Natives => Natives/NetCord.Natives}/NetCord.Natives.local.targets (100%) rename {NetCord.Natives => Natives/NetCord.Natives}/NetCord.Natives.props (100%) rename {NetCord.Natives => Natives/NetCord.Natives}/NetCord.Natives.targets (100%) rename {NetCord.Natives => Natives/NetCord.Natives}/natives-ports/libdave/fix-msvc-builtin-add-overflow.patch (100%) rename {NetCord.Natives => Natives/NetCord.Natives}/natives-ports/libdave/portfile.cmake (100%) rename {NetCord.Natives => Natives/NetCord.Natives}/natives-ports/libdave/vcpkg.json (100%) rename {NetCord.Natives => Natives/NetCord.Natives}/natives-ports/mlspp/portfile.cmake (100%) rename {NetCord.Natives => Natives/NetCord.Natives}/natives-ports/mlspp/vcpkg.json (100%) rename {NetCord.Natives => Natives/NetCord.Natives}/vcpkg (100%) rename {NetCord.Natives => Natives/NetCord.Natives}/vcpkg-non-windows.targets (92%) rename {NetCord.Natives => Natives/NetCord.Natives}/vcpkg.json (100%) delete mode 100644 NetCord.Natives.slnx diff --git a/.github/workflows/build-and-publish-natives.yml b/.github/workflows/build-and-publish-natives.yml index a47964a57..794860713 100644 --- a/.github/workflows/build-and-publish-natives.yml +++ b/.github/workflows/build-and-publish-natives.yml @@ -4,23 +4,19 @@ on: workflow_dispatch: push: paths: - - 'NetCord.Natives/**' - - '.github/workflows/build-natives-nix.yml' - - '.github/workflows/build-natives-windows.yml' + - 'Natives/**' + - '.github/workflows/build-natives.yml' - '.github/workflows/build-and-publish-natives.yml' tags: - "[0-9]+.[0-9]+.[0-9]+" - "[0-9]+.[0-9]+.[0-9]+-*" jobs: - build-natives-nix: - uses: ./.github/workflows/build-natives-nix.yml - - build-natives-windows: - uses: ./.github/workflows/build-natives-windows.yml + build-natives: + uses: ./.github/workflows/build-natives.yml publish: - needs: [build-natives-nix, build-natives-windows] + needs: [build-natives] runs-on: ubuntu-latest steps: diff --git a/.github/workflows/build-natives-nix.yml b/.github/workflows/build-natives-nix.yml deleted file mode 100644 index 1e5a0bda8..000000000 --- a/.github/workflows/build-natives-nix.yml +++ /dev/null @@ -1,141 +0,0 @@ -name: Build NetCord.Natives (Linux/MacOS, Nix) - -on: - workflow_call: - workflow_dispatch: - inputs: - GenerateBinLog: - type: boolean - default: false - push: - paths: - - 'NetCord.Natives/**' - - 'Tests/NetCord.Natives.Tests/**' - - '.github/workflows/build-natives-nix.yml' - -jobs: - build-natives-nix: - strategy: - fail-fast: false - matrix: - include: - - rid: osx-x64 - runs-on: macos-15-intel - vcpkg-os-target: osx - vcpkg-platform-target: x64 - - rid: osx-arm64 - runs-on: macos-15 - vcpkg-os-target: osx - vcpkg-platform-target: arm64 - - rid: linux-x64 - runs-on: ubuntu-latest - vcpkg-os-target: linux - vcpkg-platform-target: x64 - - rid: linux-arm64 - runs-on: ubuntu-24.04-arm - vcpkg-os-target: linux - vcpkg-platform-target: arm64 - - runs-on: ${{ matrix.runs-on }} - env: - CI: true - VCPKG_BINARY_SOURCES: clear;files,${{ github.workspace }}/.vcpkg-cache,readwrite - VCPKG_DOWNLOADS: ${{ github.workspace }}/.vcpkg-downloads - VcpkgOSTarget: ${{ matrix.vcpkg-os-target }} - VcpkgPlatformTarget: ${{ matrix.vcpkg-platform-target }} - Configuration: Release - RuntimeIdentifier: ${{ matrix.rid }} - DotnetVerbose: minimal - GenerateBinLog: ${{ github.event.inputs.GenerateBinLog || inputs.GenerateBinLog || false }} - - steps: - - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - fetch-depth: 0 - filter: tree:0 - submodules: true - - - name: Restore vcpkg cache - uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 - with: - path: | - .vcpkg-cache - .vcpkg-downloads - key: vcpkg-${{ runner.os }}-${{ matrix.rid }}-${{ hashFiles('NetCord.Natives/vcpkg.json', 'NetCord.Natives/natives-ports/**') }} - restore-keys: | - vcpkg-${{ runner.os }}-${{ matrix.rid }}- - vcpkg-${{ runner.os }}- - - - name: Install Nix - uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6 - - - name: Setup dev shell - shell: &dev-shell 'nix develop -c bash -eo pipefail {0}' - run: 'true' - - - name: Setup vcpkg (non-Windows, Nix) - shell: *dev-shell - run: | - mkdir -p "${VCPKG_BINARY_SOURCES#*,}" - mkdir -p "${VCPKG_DOWNLOADS}" - vcpkgRoot="${GITHUB_WORKSPACE}/NetCord.Natives/vcpkg" - echo "Bootstrapping vcpkg from: $vcpkgRoot" - "$vcpkgRoot/bootstrap-vcpkg.sh" -disableMetrics - echo "VCPKG_ROOT=$vcpkgRoot" >> "$GITHUB_ENV" - - - name: Restore - shell: *dev-shell - run: | - dotnet restore Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:restore.binlog' || '' }} - - - name: Build natives projects for ${{ matrix.rid }} - shell: *dev-shell - run: > - dotnet build Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj --no-restore -v ${{ env.DotnetVerbose }} - ${{ env.GenerateBinLog == 'true' && '-bl:build.binlog' || '' }} - -p:AppendNativeAotAppProps="RuntimeIdentifier=${{ env.RuntimeIdentifier }}" - -p:GeneratePackageOnBuild=false -p:CI=false - - - name: Test natives outputs for ${{ matrix.rid }} - shell: *dev-shell - run: > - dotnet test Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj --no-restore --no-build -v ${{ env.DotnetVerbose }} - ${{ env.GenerateBinLog == 'true' && '-bl:test.binlog' || '' }} - --logger "console;verbosity=detailed" - --logger GitHubActions - - - name: Pack NuGet Package for ${{ matrix.rid }} - if: ${{ always() }} - shell: *dev-shell - run: > - dotnet pack NetCord.Natives/NetCord.Natives.csproj --no-restore --no-build -v ${{ env.DotnetVerbose }} - ${{ env.GenerateBinLog == 'true' && '-bl:pack.binlog' || '' }} - -o NetCord.Natives/bin/${{ matrix.rid }} - -p:CI=false - - - name: Upload Binary Logs - if: ${{ env.GenerateBinLog == 'true' && always() }} - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: ${{ matrix.rid }}-binlogs - path: | - *.binlog - - - name: Upload NuGet Package Artifact - if: ${{ always() }} - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: NetCord.Natives.${{ matrix.rid }}.packages - path: | - NetCord.Natives/bin/${{ matrix.rid }}/*.nupkg - NetCord.Natives/bin/${{ matrix.rid }}/*.snupkg - - - name: Save vcpkg cache - if: ${{ always() }} - uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 - with: - path: | - .vcpkg-cache - .vcpkg-downloads - key: vcpkg-${{ runner.os }}-${{ matrix.rid }}-${{ hashFiles('NetCord.Natives/vcpkg.json', 'NetCord.Natives/natives-ports/**') }} diff --git a/.github/workflows/build-natives-windows.yml b/.github/workflows/build-natives.yml similarity index 60% rename from .github/workflows/build-natives-windows.yml rename to .github/workflows/build-natives.yml index df5847fa8..1d08ac96b 100644 --- a/.github/workflows/build-natives-windows.yml +++ b/.github/workflows/build-natives.yml @@ -1,4 +1,4 @@ -name: Build NetCord.Natives (Windows) +name: Build NetCord.Natives on: workflow_call: @@ -9,12 +9,11 @@ on: default: false push: paths: - - 'NetCord.Natives/**' - - 'Tests/NetCord.Natives.Tests/**' - - '.github/workflows/build-natives-windows.yml' + - 'Natives/**' + - '.github/workflows/build-natives.yml' jobs: - build-natives-windows: + build-natives: strategy: fail-fast: false matrix: @@ -23,10 +22,32 @@ jobs: runs-on: windows-latest vcpkg-os-target: windows vcpkg-platform-target: x64 + use-nix: false - rid: win-arm64 runs-on: windows-11-arm vcpkg-os-target: windows vcpkg-platform-target: arm64 + use-nix: false + - rid: osx-x64 + runs-on: macos-15-intel + vcpkg-os-target: osx + vcpkg-platform-target: x64 + use-nix: true + - rid: osx-arm64 + runs-on: macos-15 + vcpkg-os-target: osx + vcpkg-platform-target: arm64 + use-nix: true + - rid: linux-x64 + runs-on: ubuntu-latest + vcpkg-os-target: linux + vcpkg-platform-target: x64 + use-nix: true + - rid: linux-arm64 + runs-on: ubuntu-24.04-arm + vcpkg-os-target: linux + vcpkg-platform-target: arm64 + use-nix: true runs-on: ${{ matrix.runs-on }} env: @@ -54,54 +75,67 @@ jobs: path: | .vcpkg-cache .vcpkg-downloads - key: vcpkg-${{ runner.os }}-${{ matrix.rid }}-${{ hashFiles('NetCord.Natives/vcpkg.json', 'NetCord.Natives/natives-ports/**') }} + key: vcpkg-${{ runner.os }}-${{ matrix.rid }}-${{ hashFiles('Natives/Natives/vcpkg.json', 'Natives/Natives/natives-ports/**') }} restore-keys: | vcpkg-${{ runner.os }}-${{ matrix.rid }}- vcpkg-${{ runner.os }}- + - name: Install Nix + if: ${{ matrix.use-nix }} + uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6 + + - name: Setup .NET Core SDK (Windows) + if: ${{ !matrix.use-nix }} + uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5.2.0 + with: + global-json-file: global.json + - name: Setup vcpkg (Windows) + if: ${{ !matrix.use-nix }} shell: pwsh run: | New-Item -ItemType Directory -Path $env:VCPKG_BINARY_SOURCES.Split(',')[1] -Force | Out-Null New-Item -ItemType Directory -Path $env:VCPKG_DOWNLOADS -Force | Out-Null - $vcpkgRoot = Join-Path $env:GITHUB_WORKSPACE "NetCord.Natives/vcpkg" + $vcpkgRoot = Join-Path $env:GITHUB_WORKSPACE "Natives/Natives/vcpkg" Write-Host "Bootstrapping vcpkg from: $vcpkgRoot" & "$vcpkgRoot/bootstrap-vcpkg.bat" -disableMetrics "VCPKG_ROOT=$vcpkgRoot" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 - - name: Setup .NET Core SDK - uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5.2.0 - with: - global-json-file: global.json + - name: Setup vcpkg (Nix) + if: ${{ matrix.use-nix }} + shell: nix develop .#natives -c bash -eo pipefail {0} + run: | + mkdir -p "${VCPKG_BINARY_SOURCES#*,}" + mkdir -p "${VCPKG_DOWNLOADS}" - name: Restore - shell: pwsh + shell: ${{ matrix.use-nix && 'nix develop .#natives -c bash -eo pipefail {0}' || 'pwsh' }} run: | - dotnet restore Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:restore.binlog' || '' }} + dotnet restore Natives/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:restore.binlog' || '' }} - name: Build natives projects for ${{ matrix.rid }} - shell: pwsh + shell: ${{ matrix.use-nix && 'nix develop .#natives -c bash -eo pipefail {0}' || 'pwsh' }} run: > - dotnet build Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj --no-restore -v ${{ env.DotnetVerbose }} + dotnet build Natives/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj --no-restore -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:build.binlog' || '' }} -p:AppendNativeAotAppProps="RuntimeIdentifier=${{ env.RuntimeIdentifier }}" -p:GeneratePackageOnBuild=false -p:CI=false - name: Test natives outputs for ${{ matrix.rid }} - shell: pwsh + shell: ${{ matrix.use-nix && 'nix develop .#natives -c bash -eo pipefail {0}' || 'pwsh' }} run: > - dotnet test Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj --no-restore --no-build -v ${{ env.DotnetVerbose }} + dotnet test Natives/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj --no-restore --no-build -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:test.binlog' || '' }} --logger "console;verbosity=detailed" --logger GitHubActions - name: Pack NuGet Package for ${{ matrix.rid }} if: ${{ always() }} - shell: pwsh + shell: ${{ matrix.use-nix && 'nix develop .#natives -c bash -eo pipefail {0}' || 'pwsh' }} run: > - dotnet pack NetCord.Natives/NetCord.Natives.csproj --no-restore --no-build -v ${{ env.DotnetVerbose }} + dotnet pack Natives/Natives/NetCord.Natives.csproj --no-restore --no-build -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:pack.binlog' || '' }} - -o NetCord.Natives/bin/${{ matrix.rid }} + -o Natives/Natives/bin/${{ matrix.rid }} -p:CI=false - name: Upload Binary Logs @@ -118,8 +152,8 @@ jobs: with: name: NetCord.Natives.${{ matrix.rid }}.packages path: | - NetCord.Natives/bin/${{ matrix.rid }}/*.nupkg - NetCord.Natives/bin/${{ matrix.rid }}/*.snupkg + Natives/Natives/bin/${{ matrix.rid }}/*.nupkg + Natives/Natives/bin/${{ matrix.rid }}/*.snupkg - name: Save vcpkg cache if: ${{ always() }} @@ -128,4 +162,4 @@ jobs: path: | .vcpkg-cache .vcpkg-downloads - key: vcpkg-${{ runner.os }}-${{ matrix.rid }}-${{ hashFiles('NetCord.Natives/vcpkg.json', 'NetCord.Natives/natives-ports/**') }} + key: vcpkg-${{ runner.os }}-${{ matrix.rid }}-${{ hashFiles('Natives/Natives/vcpkg.json', 'Natives/Natives/natives-ports/**') }} diff --git a/.gitmodules b/.gitmodules index c33f058fc..4f87b73d4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "NetCord.Natives/vcpkg"] - path = NetCord.Natives/vcpkg +[submodule "Natives/NetCord.Natives/vcpkg"] + path = Natives/NetCord.Natives/vcpkg url = https://github.com/microsoft/vcpkg.git diff --git a/Tests/NetCord.Natives.Tests/AssemblyInfo.cs b/Natives/NetCord.Natives.Tests/AssemblyInfo.cs similarity index 100% rename from Tests/NetCord.Natives.Tests/AssemblyInfo.cs rename to Natives/NetCord.Natives.Tests/AssemblyInfo.cs diff --git a/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj b/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj similarity index 87% rename from Tests/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj rename to Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj index 11eff813a..952c0ba16 100644 --- a/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj +++ b/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj @@ -11,7 +11,7 @@ true true - ..\..\..\..\NetCord.Natives + ..\..\..\NetCord.Natives
@@ -24,7 +24,7 @@ - + diff --git a/Tests/NetCord.Natives.Tests/Assets/NativeAotApp/Program.cs b/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/Program.cs similarity index 100% rename from Tests/NetCord.Natives.Tests/Assets/NativeAotApp/Program.cs rename to Natives/NetCord.Natives.Tests/Assets/NativeAotApp/Program.cs diff --git a/Tests/NetCord.Natives.Tests/NativeProbes.cs b/Natives/NetCord.Natives.Tests/NativeProbes.cs similarity index 100% rename from Tests/NetCord.Natives.Tests/NativeProbes.cs rename to Natives/NetCord.Natives.Tests/NativeProbes.cs diff --git a/Tests/NetCord.Natives.Tests/NativesBuildTests.cs b/Natives/NetCord.Natives.Tests/NativesBuildTests.cs similarity index 100% rename from Tests/NetCord.Natives.Tests/NativesBuildTests.cs rename to Natives/NetCord.Natives.Tests/NativesBuildTests.cs diff --git a/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj b/Natives/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj similarity index 96% rename from Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj rename to Natives/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj index 636b6f9ae..5653a4b14 100644 --- a/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj +++ b/Natives/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj @@ -30,7 +30,7 @@ - ..\..\NetCord.Natives\ + ..\NetCord.Natives\ NetCordNativesDir=$([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)\$(NetCordNativesDir)')) $(VCPKG_ROOT) diff --git a/Natives/NetCord.Natives.slnx b/Natives/NetCord.Natives.slnx new file mode 100644 index 000000000..48c64d326 --- /dev/null +++ b/Natives/NetCord.Natives.slnx @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/NetCord.Natives/.gitignore b/Natives/NetCord.Natives/.gitignore similarity index 100% rename from NetCord.Natives/.gitignore rename to Natives/NetCord.Natives/.gitignore diff --git a/NetCord.Natives/NetCord.Natives.csproj b/Natives/NetCord.Natives/NetCord.Natives.csproj similarity index 95% rename from NetCord.Natives/NetCord.Natives.csproj rename to Natives/NetCord.Natives/NetCord.Natives.csproj index cf6e4f236..f510da258 100644 --- a/NetCord.Natives/NetCord.Natives.csproj +++ b/Natives/NetCord.Natives/NetCord.Natives.csproj @@ -7,7 +7,7 @@ false true - $([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)\..')) + $([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)\..\..\..')) @@ -78,7 +78,13 @@ - + + + + + + + diff --git a/NetCord.Natives/NetCord.Natives.local.targets b/Natives/NetCord.Natives/NetCord.Natives.local.targets similarity index 100% rename from NetCord.Natives/NetCord.Natives.local.targets rename to Natives/NetCord.Natives/NetCord.Natives.local.targets diff --git a/NetCord.Natives/NetCord.Natives.props b/Natives/NetCord.Natives/NetCord.Natives.props similarity index 100% rename from NetCord.Natives/NetCord.Natives.props rename to Natives/NetCord.Natives/NetCord.Natives.props diff --git a/NetCord.Natives/NetCord.Natives.targets b/Natives/NetCord.Natives/NetCord.Natives.targets similarity index 100% rename from NetCord.Natives/NetCord.Natives.targets rename to Natives/NetCord.Natives/NetCord.Natives.targets diff --git a/NetCord.Natives/natives-ports/libdave/fix-msvc-builtin-add-overflow.patch b/Natives/NetCord.Natives/natives-ports/libdave/fix-msvc-builtin-add-overflow.patch similarity index 100% rename from NetCord.Natives/natives-ports/libdave/fix-msvc-builtin-add-overflow.patch rename to Natives/NetCord.Natives/natives-ports/libdave/fix-msvc-builtin-add-overflow.patch diff --git a/NetCord.Natives/natives-ports/libdave/portfile.cmake b/Natives/NetCord.Natives/natives-ports/libdave/portfile.cmake similarity index 100% rename from NetCord.Natives/natives-ports/libdave/portfile.cmake rename to Natives/NetCord.Natives/natives-ports/libdave/portfile.cmake diff --git a/NetCord.Natives/natives-ports/libdave/vcpkg.json b/Natives/NetCord.Natives/natives-ports/libdave/vcpkg.json similarity index 100% rename from NetCord.Natives/natives-ports/libdave/vcpkg.json rename to Natives/NetCord.Natives/natives-ports/libdave/vcpkg.json diff --git a/NetCord.Natives/natives-ports/mlspp/portfile.cmake b/Natives/NetCord.Natives/natives-ports/mlspp/portfile.cmake similarity index 100% rename from NetCord.Natives/natives-ports/mlspp/portfile.cmake rename to Natives/NetCord.Natives/natives-ports/mlspp/portfile.cmake diff --git a/NetCord.Natives/natives-ports/mlspp/vcpkg.json b/Natives/NetCord.Natives/natives-ports/mlspp/vcpkg.json similarity index 100% rename from NetCord.Natives/natives-ports/mlspp/vcpkg.json rename to Natives/NetCord.Natives/natives-ports/mlspp/vcpkg.json diff --git a/NetCord.Natives/vcpkg b/Natives/NetCord.Natives/vcpkg similarity index 100% rename from NetCord.Natives/vcpkg rename to Natives/NetCord.Natives/vcpkg diff --git a/NetCord.Natives/vcpkg-non-windows.targets b/Natives/NetCord.Natives/vcpkg-non-windows.targets similarity index 92% rename from NetCord.Natives/vcpkg-non-windows.targets rename to Natives/NetCord.Natives/vcpkg-non-windows.targets index 66778834c..a32fae993 100644 --- a/NetCord.Natives/vcpkg-non-windows.targets +++ b/Natives/NetCord.Natives/vcpkg-non-windows.targets @@ -15,7 +15,8 @@ <_ZVcpkgTLogFileLocation>$(TLogLocation)VcpkgInstallManifest$(VcpkgTriplet).$(_ZVcpkgHostTripletSuffix)read.1u.tlog - <_ZVcpkgExecutable>$(_ZVcpkgRoot)vcpkg + <_ZVcpkgExecutable Condition="Exists('$(_ZVcpkgRoot)vcpkg')">$(_ZVcpkgRoot)vcpkg + <_ZVcpkgExecutable Condition="'$(_ZVcpkgExecutable)' == ''">vcpkg diff --git a/NetCord.Natives/vcpkg.json b/Natives/NetCord.Natives/vcpkg.json similarity index 100% rename from NetCord.Natives/vcpkg.json rename to Natives/NetCord.Natives/vcpkg.json diff --git a/NetCord.Natives.slnx b/NetCord.Natives.slnx deleted file mode 100644 index 8e3060606..000000000 --- a/NetCord.Natives.slnx +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/flake.nix b/flake.nix index 7a6c133ec..67ffe8eeb 100644 --- a/flake.nix +++ b/flake.nix @@ -49,10 +49,16 @@ natives = pkgs.mkShell { packages = [ + dotnet + pkgs.cmake + pkgs.ninja + pkgs.pkg-config pkgs.autoconf pkgs.automake pkgs.libtool ]; + + DOTNET_ROOT = dotnetRoot; }; docs = pkgs.mkShell { From d688e22da39c5813c419e266efb68a5b43fdfd87 Mon Sep 17 00:00:00 2001 From: Haves Irfan Date: Sun, 14 Jun 2026 16:08:16 +0000 Subject: [PATCH 018/101] Use symlink to versioned shared libs * fix build * rearrange workflows * fix syntaxes --- .github/workflows/build-and-publish.yml | 25 +------ .github/workflows/build-natives.yml | 75 ++++++++++--------- .github/workflows/build.yml | 11 +++ .../NetCord.Natives/NetCord.Natives.csproj | 36 ++++++++- .../NetCord.Natives/NetCord.Natives.targets | 12 +++ .../natives-ports/mlspp/portfile.cmake | 11 +-- README.md | 2 +- 7 files changed, 106 insertions(+), 66 deletions(-) diff --git a/.github/workflows/build-and-publish.yml b/.github/workflows/build-and-publish.yml index d7176ef8e..ed762e41d 100644 --- a/.github/workflows/build-and-publish.yml +++ b/.github/workflows/build-and-publish.yml @@ -53,7 +53,7 @@ jobs: TAG: ${{ github.ref_name }} IS_PRERELEASE: ${{ contains(github.ref_name, '-') }} run: | - cp -r Documentation/_site "Documentation-$TAG" + cp -r artifacts/docs "Documentation-$TAG" zip -r "Documentation-$TAG.zip" "Documentation-$TAG" tar -czvf "Documentation-$TAG.tar.gz" "Documentation-$TAG" @@ -61,11 +61,7 @@ jobs: rm -r "Documentation-$TAG" FILES=( - NetCord/bin/Release/*.*nupkg - NetCord.Services/bin/Release/*.*nupkg - Hosting/NetCord.Hosting/bin/Release/*.*nupkg - Hosting/NetCord.Hosting.Services/bin/Release/*.*nupkg - Hosting/NetCord.Hosting.AspNetCore/bin/Release/*.*nupkg + artifacts/pkgs/*.nupkg "Documentation-$TAG.zip" "Documentation-$TAG.tar.gz" ) @@ -80,20 +76,3 @@ jobs: --prerelease="$IS_PRERELEASE" \ "${FILES[@]}" fi - - - name: Upload Build Artifacts - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: Build Artifacts - path: | - NetCord/bin/Release - NetCord.Services/bin/Release - Hosting/NetCord.Hosting/bin/Release - Hosting/NetCord.Hosting.Services/bin/Release - Hosting/NetCord.Hosting.AspNetCore/bin/Release - - - name: Upload Documentation Artifacts - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: Documentation Artifacts - path: Documentation/_site diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index 1d08ac96b..34b57353b 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -23,33 +23,42 @@ jobs: vcpkg-os-target: windows vcpkg-platform-target: x64 use-nix: false + shell_command: pwsh - rid: win-arm64 runs-on: windows-11-arm vcpkg-os-target: windows vcpkg-platform-target: arm64 use-nix: false + shell_command: pwsh - rid: osx-x64 runs-on: macos-15-intel vcpkg-os-target: osx vcpkg-platform-target: x64 use-nix: true + shell_command: nix develop .#natives -c bash -eo pipefail {0} - rid: osx-arm64 runs-on: macos-15 vcpkg-os-target: osx vcpkg-platform-target: arm64 use-nix: true + shell_command: nix develop .#natives -c bash -eo pipefail {0} - rid: linux-x64 runs-on: ubuntu-latest vcpkg-os-target: linux vcpkg-platform-target: x64 use-nix: true + shell_command: nix develop .#natives -c bash -eo pipefail {0} - rid: linux-arm64 runs-on: ubuntu-24.04-arm vcpkg-os-target: linux vcpkg-platform-target: arm64 use-nix: true + shell_command: nix develop .#natives -c bash -eo pipefail {0} runs-on: ${{ matrix.runs-on }} + defaults: + run: + shell: ${{ matrix.shell_command }} env: CI: true VCPKG_BINARY_SOURCES: clear;files,${{ github.workspace }}/.vcpkg-cache,readwrite @@ -60,6 +69,7 @@ jobs: RuntimeIdentifier: ${{ matrix.rid }} DotnetVerbose: minimal GenerateBinLog: ${{ github.event.inputs.GenerateBinLog || inputs.GenerateBinLog || false }} + VCPKG_ROOT: ${{ github.workspace }}/Natives/NetCord.Natives/vcpkg steps: - name: Checkout @@ -69,73 +79,69 @@ jobs: filter: tree:0 submodules: true + - name: Install Nix + if: ${{ matrix.use-nix }} + uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6 + + - name: Setup vcpkg cache directories (Windows) + if: ${{ !matrix.use-nix }} + run: | + New-Item -ItemType Directory -Path $env:VCPKG_BINARY_SOURCES.Split(',')[1] -Force | Out-Null + New-Item -ItemType Directory -Path $env:VCPKG_DOWNLOADS -Force | Out-Null + + - name: Setup vcpkg cache directories (Nix) + if: ${{ matrix.use-nix }} + run: | + mkdir -p "${VCPKG_BINARY_SOURCES#*,}" + mkdir -p "${VCPKG_DOWNLOADS}" + - name: Restore vcpkg cache uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: path: | .vcpkg-cache .vcpkg-downloads - key: vcpkg-${{ runner.os }}-${{ matrix.rid }}-${{ hashFiles('Natives/Natives/vcpkg.json', 'Natives/Natives/natives-ports/**') }} + key: vcpkg-${{ runner.os }}-${{ matrix.rid }}-${{ hashFiles('Natives/NetCord.Natives/vcpkg.json', 'Natives/NetCord.Natives/natives-ports/**') }} restore-keys: | vcpkg-${{ runner.os }}-${{ matrix.rid }}- vcpkg-${{ runner.os }}- - - name: Install Nix - if: ${{ matrix.use-nix }} - uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6 - - name: Setup .NET Core SDK (Windows) if: ${{ !matrix.use-nix }} uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5.2.0 with: global-json-file: global.json - - name: Setup vcpkg (Windows) - if: ${{ !matrix.use-nix }} - shell: pwsh - run: | - New-Item -ItemType Directory -Path $env:VCPKG_BINARY_SOURCES.Split(',')[1] -Force | Out-Null - New-Item -ItemType Directory -Path $env:VCPKG_DOWNLOADS -Force | Out-Null - $vcpkgRoot = Join-Path $env:GITHUB_WORKSPACE "Natives/Natives/vcpkg" - Write-Host "Bootstrapping vcpkg from: $vcpkgRoot" - & "$vcpkgRoot/bootstrap-vcpkg.bat" -disableMetrics - "VCPKG_ROOT=$vcpkgRoot" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 - - - name: Setup vcpkg (Nix) - if: ${{ matrix.use-nix }} - shell: nix develop .#natives -c bash -eo pipefail {0} - run: | - mkdir -p "${VCPKG_BINARY_SOURCES#*,}" - mkdir -p "${VCPKG_DOWNLOADS}" - - name: Restore - shell: ${{ matrix.use-nix && 'nix develop .#natives -c bash -eo pipefail {0}' || 'pwsh' }} run: | dotnet restore Natives/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:restore.binlog' || '' }} - name: Build natives projects for ${{ matrix.rid }} - shell: ${{ matrix.use-nix && 'nix develop .#natives -c bash -eo pipefail {0}' || 'pwsh' }} + id: build_step # Added an ID here to track this step's status run: > dotnet build Natives/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj --no-restore -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:build.binlog' || '' }} -p:AppendNativeAotAppProps="RuntimeIdentifier=${{ env.RuntimeIdentifier }}" -p:GeneratePackageOnBuild=false -p:CI=false + ${{ matrix.vcpkg-os-target == 'osx' && '-p:UseAppHostGlobalization=false -p:InvariantGlobalization=false' || '' }} - name: Test natives outputs for ${{ matrix.rid }} - shell: ${{ matrix.use-nix && 'nix develop .#natives -c bash -eo pipefail {0}' || 'pwsh' }} + # This will still run if Build succeeds. If Build fails, this is skipped automatically. run: > dotnet test Natives/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj --no-restore --no-build -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:test.binlog' || '' }} --logger "console;verbosity=detailed" --logger GitHubActions + ${{ matrix.vcpkg-os-target == 'osx' && '-p:UseAppHostGlobalization=false -p:InvariantGlobalization=false' || '' }} - name: Pack NuGet Package for ${{ matrix.rid }} - if: ${{ always() }} - shell: ${{ matrix.use-nix && 'nix develop .#natives -c bash -eo pipefail {0}' || 'pwsh' }} + # This forces the step to run even if 'Test' failed, as long as 'Build' succeeded. + if: ${{ always() && steps.build_step.outcome == 'success' }} + id: pack_step # Added an ID here to track the pack status for the upload step run: > - dotnet pack Natives/Natives/NetCord.Natives.csproj --no-restore --no-build -v ${{ env.DotnetVerbose }} + dotnet pack Natives/NetCord.Natives/NetCord.Natives.csproj --no-restore --no-build -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:pack.binlog' || '' }} - -o Natives/Natives/bin/${{ matrix.rid }} + -o Natives/NetCord.Natives/bin/${{ matrix.rid }} -p:CI=false - name: Upload Binary Logs @@ -147,13 +153,14 @@ jobs: *.binlog - name: Upload NuGet Package Artifact - if: ${{ always() }} + # This ensures we only upload if the Pack step actually finished successfully. + if: ${{ always() && steps.pack_step.outcome == 'success' }} uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: NetCord.Natives.${{ matrix.rid }}.packages path: | - Natives/Natives/bin/${{ matrix.rid }}/*.nupkg - Natives/Natives/bin/${{ matrix.rid }}/*.snupkg + Natives/NetCord.Natives/bin/${{ matrix.rid }}/*.nupkg + Natives/NetCord.Natives/bin/${{ matrix.rid }}/*.snupkg - name: Save vcpkg cache if: ${{ always() }} @@ -162,4 +169,4 @@ jobs: path: | .vcpkg-cache .vcpkg-downloads - key: vcpkg-${{ runner.os }}-${{ matrix.rid }}-${{ hashFiles('Natives/Natives/vcpkg.json', 'Natives/Natives/natives-ports/**') }} + key: vcpkg-${{ runner.os }}-${{ matrix.rid }}-${{ hashFiles('Natives/NetCord.Natives/vcpkg.json', 'Natives/NetCord.Natives/natives-ports/**') }} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9894ac481..60cdcaaa1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -81,3 +81,14 @@ jobs: with: name: Documentation Artifacts path: Documentation/_site + + - name: Upload Build Artifacts + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: Build Artifacts + path: | + NetCord/bin/Release + NetCord.Services/bin/Release + Hosting/NetCord.Hosting/bin/Release + Hosting/NetCord.Hosting.Services/bin/Release + Hosting/NetCord.Hosting.AspNetCore/bin/Release diff --git a/Natives/NetCord.Natives/NetCord.Natives.csproj b/Natives/NetCord.Natives/NetCord.Natives.csproj index f510da258..6d154b483 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.csproj +++ b/Natives/NetCord.Natives/NetCord.Natives.csproj @@ -80,7 +80,7 @@ - + @@ -166,7 +166,15 @@ - + + + + <_SymlinksToRemoveRuntime Include="@(NativesRuntime)" + Condition="Exists('%(FullPath)') and ($([MSBuild]::BitwiseAnd($([System.IO.File]::GetAttributes('%(FullPath)')), 1024)) == 1024)" /> + + <_CopyOutput Include="%(NativesRuntime.FullPath)"> %(NativesRuntime.Filename)%(NativesRuntime.Extension) PreserveNewest @@ -176,6 +184,15 @@ + + + <_SymlinksToCreate Include="@(NativesRuntime)" + Condition="$([System.String]::new('%(Filename)').Contains('%(NativeLibSet.Identity)'))" /> + + + + + @@ -193,13 +210,26 @@ - + + + runtimes\%(_BuiltRid.Identity)\native\ + + + runtimes\%(_BuiltRid.Identity)\native\ + + staticlibs\%(_BuiltRid.Identity)\ + <_SymlinksToRemoveBuilt Include="@(NativesBuilt)" + Condition="Exists('%(FullPath)') and ($([MSBuild]::BitwiseAnd($([System.IO.File]::GetAttributes('%(FullPath)')), 1024)) == 1024)" /> + + true diff --git a/Natives/NetCord.Natives/NetCord.Natives.targets b/Natives/NetCord.Natives/NetCord.Natives.targets index aa140dec8..cea684f43 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.targets +++ b/Natives/NetCord.Natives/NetCord.Natives.targets @@ -60,4 +60,16 @@ + + + <_NativeLibNames Include="dave;mlspp;bytes;tls_syntax;hpke;crypto;sodium;opus;zstd" /> + + + <_NativeFiles Include="$(OutDir)**\lib%(_NativeLibNames.Identity)*.so.*" /> + <_NativeFiles Include="$(OutDir)**\lib%(_NativeLibNames.Identity)*.dylib" /> + + + + +
diff --git a/Natives/NetCord.Natives/natives-ports/mlspp/portfile.cmake b/Natives/NetCord.Natives/natives-ports/mlspp/portfile.cmake index 4e863f9f6..9a7df81b8 100644 --- a/Natives/NetCord.Natives/natives-ports/mlspp/portfile.cmake +++ b/Natives/NetCord.Natives/natives-ports/mlspp/portfile.cmake @@ -11,15 +11,16 @@ endif() set(VCPKG_LIBRARY_LINKAGE static) +set(EXTRA_OPTIONS -DDISABLE_GREASE=ON -DTESTING=OFF -DBUILD_TESTING=OFF -DMLS_CXX_NAMESPACE="mlspp") +if(VCPKG_HOST_IS_LINUX) + list(APPEND EXTRA_OPTIONS -DCMAKE_CXX_FLAGS="-Wno-error=maybe-uninitialized") +endif() + vcpkg_cmake_configure( SOURCE_PATH "${SOURCE_PATH}" OPTIONS ${VCPKG_INCLUDE_OVERRIDE} - -DDISABLE_GREASE=ON - -DTESTING=OFF - -DBUILD_TESTING=OFF - -DMLS_CXX_NAMESPACE="mlspp" - -DCMAKE_CXX_FLAGS="-Wno-error" + ${EXTRA_OPTIONS} MAYBE_UNUSED_VARIABLES BUILD_TESTING ) diff --git a/README.md b/README.md index efd74ac6c..275ac7d16 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ You can install NetCord packages via NuGet package manager: | **[NetCord.Hosting](https://www.nuget.org/packages/NetCord.Hosting)** | Provides .NET Generic Host extensions for the NetCord package. | | **[NetCord.Hosting.Services](https://www.nuget.org/packages/NetCord.Hosting.Services)** | Provides .NET Generic Host extensions for the NetCord.Services package. | | **[NetCord.Hosting.AspNetCore](https://www.nuget.org/packages/NetCord.Hosting.AspNetCore)** | Provides ASP.NET Core extensions for seamless handling of HTTP events. | -| NetCord.Natives.<RuntimeId> | Provides pre-built native runtime dependencies binary.
[See Native Dependencies Installation Guide.](https://netcord.dev/guides/basic-concepts/installing-native-dependencies.html) | +| NetCord.Natives.<RuntimeId> | Provides pre-built native runtime dependencies binary.
[See Native Dependencies Installation Guide.](https://netcord.dev/guides/basic-concepts/installing-native-dependencies.html) | ## 2. 🚀 Showcase From 13605f1236e5db468e3a8b1f891bfaf27d0c0318 Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Thu, 18 Jun 2026 23:15:18 +0900 Subject: [PATCH 019/101] fix bootstrapping & update vcpkg baseline --- Natives/NetCord.Natives/NetCord.Natives.csproj | 14 +++++++------- Natives/NetCord.Natives/vcpkg-non-windows.targets | 5 +++++ Natives/NetCord.Natives/vcpkg.json | 2 +- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/Natives/NetCord.Natives/NetCord.Natives.csproj b/Natives/NetCord.Natives/NetCord.Natives.csproj index 6d154b483..21449da8f 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.csproj +++ b/Natives/NetCord.Natives/NetCord.Natives.csproj @@ -1,4 +1,4 @@ - + Pre-built native libraries for NetCord, $(Description) @@ -74,16 +74,16 @@ + + + + + + - - - - - - + + + + + diff --git a/Natives/NetCord.Natives/vcpkg.json b/Natives/NetCord.Natives/vcpkg.json index a3af5a404..b00133eb1 100644 --- a/Natives/NetCord.Natives/vcpkg.json +++ b/Natives/NetCord.Natives/vcpkg.json @@ -10,7 +10,7 @@ "natives-ports" ] }, - "builtin-baseline": "d07689ef165f033de5c0710e4f67c193a85373e1", + "builtin-baseline": "89dd0f4d241136b843fb55813b2f0fa6448c204d", "overrides": [ { "name": "openssl", From d31bd948388aa66e9ae45436bb64383f28316822 Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Sat, 20 Jun 2026 14:16:11 +0900 Subject: [PATCH 020/101] Fix use namespace reflection for libimports * fix unix build for fPIC & macos nix * fix symlink copy of native libraries to output directory * fix msbuild props & proper naming * fix workflows --- .github/workflows/build-and-publish.yml | 14 ++- .github/workflows/build-natives.yml | 49 +++++++--- .../installing-native-dependencies.md | 4 +- .../Assets/NativeAotApp/NativeAotApp.csproj | 3 + Natives/NetCord.Natives.Tests/NativeProbes.cs | 93 +++++++++++++++---- .../NativesBuildTests.cs | 52 ++++++----- .../NetCord.Natives.Tests.csproj | 6 +- .../NetCord.Natives/NetCord.Natives.csproj | 32 ++++++- Natives/NetCord.Natives/NetCord.Natives.props | 4 +- .../NetCord.Natives/NetCord.Natives.targets | 30 +++++- .../natives-ports/mlspp/portfile.cmake | 1 + flake.nix | 4 +- 12 files changed, 223 insertions(+), 69 deletions(-) diff --git a/.github/workflows/build-and-publish.yml b/.github/workflows/build-and-publish.yml index ed762e41d..2cc2198ff 100644 --- a/.github/workflows/build-and-publish.yml +++ b/.github/workflows/build-and-publish.yml @@ -18,7 +18,19 @@ jobs: steps: - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + + - name: Download NuGet Package Artifacts + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: NuGet Packages + path: artifacts/pkgs + + - name: Download Documentation Artifacts + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: Documentation Artifacts + path: artifacts/docs - name: Install Nix uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6 diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index 34b57353b..a11719fde 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -7,6 +7,17 @@ on: GenerateBinLog: type: boolean default: false + MSBuildVerbosity: + type: choice + description: 'MSBuild Verbosity Level' + required: true + default: 'Minimal' + options: + - Quiet + - Minimal + - Normal + - Detailed + - Diagnostic push: paths: - 'Natives/**' @@ -66,14 +77,14 @@ jobs: VcpkgOSTarget: ${{ matrix.vcpkg-os-target }} VcpkgPlatformTarget: ${{ matrix.vcpkg-platform-target }} Configuration: Release - RuntimeIdentifier: ${{ matrix.rid }} - DotnetVerbose: minimal + TargetRID: ${{ matrix.rid }} + DotnetVerbose: ${{ github.event.inputs.MSBuildVerbosity || inputs.MSBuildVerbosity || 'Minimal' }} GenerateBinLog: ${{ github.event.inputs.GenerateBinLog || inputs.GenerateBinLog || false }} VCPKG_ROOT: ${{ github.workspace }}/Natives/NetCord.Natives/vcpkg steps: - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 0 filter: tree:0 @@ -101,7 +112,9 @@ jobs: path: | .vcpkg-cache .vcpkg-downloads + # Unique key per run key: vcpkg-${{ runner.os }}-${{ matrix.rid }}-${{ hashFiles('Natives/NetCord.Natives/vcpkg.json', 'Natives/NetCord.Natives/natives-ports/**') }} + # Fallback keys to grab the latest previous cache restore-keys: | vcpkg-${{ runner.os }}-${{ matrix.rid }}- vcpkg-${{ runner.os }}- @@ -113,26 +126,35 @@ jobs: global-json-file: global.json - name: Restore - run: | - dotnet restore Natives/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:restore.binlog' || '' }} + run: > + dotnet restore Natives/NetCord.Natives.slnx + -v ${{ env.DotnetVerbose }} + ${{ env.GenerateBinLog == 'true' && '-bl:restore.binlog' || '' }} - name: Build natives projects for ${{ matrix.rid }} id: build_step # Added an ID here to track this step's status run: > - dotnet build Natives/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj --no-restore -v ${{ env.DotnetVerbose }} + dotnet build Natives/NetCord.Natives.slnx --no-restore + -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:build.binlog' || '' }} - -p:AppendNativeAotAppProps="RuntimeIdentifier=${{ env.RuntimeIdentifier }}" + -p:AppendNativeAotAppProps="RuntimeIdentifier=${{ env.TargetRID }}" -p:GeneratePackageOnBuild=false -p:CI=false - ${{ matrix.vcpkg-os-target == 'osx' && '-p:UseAppHostGlobalization=false -p:InvariantGlobalization=false' || '' }} + ${{ matrix.vcpkg-os-target == 'osx' && '-p:InvariantGlobalization=true' || '' }} + + - name: List output directory for ${{ matrix.rid }} + if: ${{ matrix.use-nix }} + run: | + ls -Rlsha Natives/NetCord.Natives.Tests/bin/ - name: Test natives outputs for ${{ matrix.rid }} # This will still run if Build succeeds. If Build fails, this is skipped automatically. run: > - dotnet test Natives/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj --no-restore --no-build -v ${{ env.DotnetVerbose }} + dotnet test Natives/NetCord.Natives.slnx --no-restore --no-build + -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:test.binlog' || '' }} - --logger "console;verbosity=detailed" - --logger GitHubActions - ${{ matrix.vcpkg-os-target == 'osx' && '-p:UseAppHostGlobalization=false -p:InvariantGlobalization=false' || '' }} + --logger "console;verbosity=detailed" + --logger GitHubActions + ${{ matrix.vcpkg-os-target == 'osx' && '-p:InvariantGlobalization=true' || '' }} - name: Pack NuGet Package for ${{ matrix.rid }} # This forces the step to run even if 'Test' failed, as long as 'Build' succeeded. @@ -163,10 +185,11 @@ jobs: Natives/NetCord.Natives/bin/${{ matrix.rid }}/*.snupkg - name: Save vcpkg cache - if: ${{ always() }} + if: ${{ always() && steps.build_step.outcome == 'success' }} uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: path: | .vcpkg-cache .vcpkg-downloads + # Must match the unique key from the restore step key: vcpkg-${{ runner.os }}-${{ matrix.rid }}-${{ hashFiles('Natives/NetCord.Natives/vcpkg.json', 'Natives/NetCord.Natives/natives-ports/**') }} diff --git a/Documentation/guides/basic-concepts/installing-native-dependencies.md b/Documentation/guides/basic-concepts/installing-native-dependencies.md index beaa94161..617f76c28 100644 --- a/Documentation/guides/basic-concepts/installing-native-dependencies.md +++ b/Documentation/guides/basic-concepts/installing-native-dependencies.md @@ -60,11 +60,11 @@ When targeting NativeAOT, you must ensure that all used native libraries are exp ``` ### Excluding Bundled Dependencies -If you have provided your own native binaries and need to exclude the ones bundled in the NetCord NuGet package to avoid conflicts, use the `NetCordExcludeNatives` property. +If you have provided your own native binaries and need to exclude the ones bundled in the NetCord NuGet package to avoid conflicts, use the `NetCordExcludeNativesDynamic` property. ```xml - opus + opus;libsodium ``` diff --git a/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj b/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj index 952c0ba16..8d92bddef 100644 --- a/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj +++ b/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj @@ -26,6 +26,9 @@ + + libdave;libsodium;opus;zstd + diff --git a/Natives/NetCord.Natives.Tests/NativeProbes.cs b/Natives/NetCord.Natives.Tests/NativeProbes.cs index 4a03b6d2a..704f68cc6 100644 --- a/Natives/NetCord.Natives.Tests/NativeProbes.cs +++ b/Natives/NetCord.Natives.Tests/NativeProbes.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Runtime.InteropServices; @@ -17,38 +18,96 @@ public static partial class NativeProbes [LibraryImport("zstd", EntryPoint = "ZSTD_versionNumber")] internal static partial uint ZstdVersionNumber(); - internal static IReadOnlyList GetMissingLibraryImports(string libName, string className, Assembly assemblyWithImports) + [UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", Justification = "This method is only used in tests to verify native library exports and is not called in the runtime path of trimmed/AOT applications.")] + [UnconditionalSuppressMessage("Trimming", "IL2075:DynamicallyAccessedMembers", Justification = "This method is only used in tests to verify native library exports and is not called in the runtime path of trimmed/AOT applications.")] + internal static IReadOnlyList GetMissingLibraryImports(IntPtr libHandle, string libName) { - var typeWithImports = assemblyWithImports.GetType(className, true); - var libHandle = GetLoadedNativeModuleHandle(libName); var missingExports = new List(); + var methods = new List<(MethodInfo Method, string? EntryPoint)>(); - var methods = typeWithImports!.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) - .Select(m => new + // typeof(NetCord.Application).Assembly ensures the NetCord assembly is loaded before scanning. + // Exclude the test assembly itself — its probe stubs are not real library consumers. + var testAssembly = Assembly.GetExecutingAssembly(); + var netcordAssemblies = new[] { typeof(NetCord.Application).Assembly } + .Concat(AppDomain.CurrentDomain.GetAssemblies() + .Where(a => a != testAssembly && a.GetName().Name?.StartsWith("NetCord", StringComparison.OrdinalIgnoreCase) == true)) + .DistinctBy(a => a.FullName) + .ToList(); + + Console.WriteLine($"[{libName}] Scanning {netcordAssemblies.Count} NetCord assemblies: {string.Join(", ", netcordAssemblies.Select(a => a.GetName().Name))}"); + + foreach (var type in netcordAssemblies.SelectMany(a => a.GetTypes())) + { + foreach (var method in type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)) { - MethodName = m.Name, - Attr = m.GetCustomAttribute(), - }) - .Where(x => x.Attr != null) - .ToArray(); + var libraryImport = method.GetCustomAttribute(); + if (libraryImport != null) + { + if (IsMatchingLibrary(libraryImport.LibraryName, libName)) + { + methods.Add((method, libraryImport.EntryPoint)); + } + continue; + } + + var dllImport = method.GetCustomAttribute(); + if (dllImport != null) + { + if (IsMatchingLibrary(dllImport.Value, libName)) + { + methods.Add((method, dllImport.EntryPoint)); + } + } + } + } - if (methods.Length == 0) - throw new InvalidOperationException($"No methods with [LibraryImport] found in '{className}'."); + if (methods.Count == 0) + throw new InvalidOperationException($"No methods with [LibraryImport] or [DllImport] found for library '{libName}'."); - foreach (var item in methods) + foreach (var item in methods.DistinctBy(m => m.EntryPoint ?? m.Method.Name)) { // Use EntryPoint if defined, otherwise fallback to method name. - string exportName = item.Attr!.EntryPoint ?? item.MethodName; + string exportName = item.EntryPoint ?? item.Method.Name; + string importSig = $"{item.Method.ReturnType.Name} {item.Method.DeclaringType!.FullName}.{item.Method.Name}({string.Join(", ", item.Method.GetParameters().Select(p => $"{p.ParameterType.Name} {p.Name}"))})"; if (!NativeLibrary.TryGetExport(libHandle, exportName, out _)) { + Console.WriteLine($"[{libName}] MISSING: {exportName}"); + Console.WriteLine($" Import: {importSig}"); missingExports.Add(exportName); } + else + { + Console.WriteLine($"[{libName}] Found: {exportName}"); + Console.WriteLine($" Import: {importSig}"); + } } return missingExports; } + private static bool IsMatchingLibrary(string? attributeLibName, string searchLibName) + { + if (attributeLibName == null) + return false; + + if (string.Equals(attributeLibName, searchLibName, StringComparison.OrdinalIgnoreCase)) + return true; + + if (attributeLibName.StartsWith("lib", StringComparison.OrdinalIgnoreCase)) + { + if (string.Equals(attributeLibName.Substring(3), searchLibName, StringComparison.OrdinalIgnoreCase)) + return true; + } + else + { + if (string.Equals("lib" + attributeLibName, searchLibName, StringComparison.OrdinalIgnoreCase)) + return true; + } + + return false; + } + /* * This method is not working on macOS due to System.Diagnostics.ProcessModule * not listing native libraries loaded by the runtime's dynamic library loader (dyld). @@ -63,9 +122,9 @@ internal static IntPtr GetLoadedNativeModuleHandle(string libName) { _ = libName switch { - "libdave" => (object)DaveMaxSupportedProtocolVersion(), - "libsodium" => (object)SodiumInit(), - "opus" => (object)OpusGetVersionString(), + "libdave" => DaveMaxSupportedProtocolVersion(), + "libsodium" => SodiumInit(), + "opus" => OpusGetVersionString(), "zstd" => (object)ZstdVersionNumber(), _ => throw new InvalidOperationException($"Unknown library name '{libName}' provided to test."), }; diff --git a/Natives/NetCord.Natives.Tests/NativesBuildTests.cs b/Natives/NetCord.Natives.Tests/NativesBuildTests.cs index ec112fbca..3e8cbc275 100644 --- a/Natives/NetCord.Natives.Tests/NativesBuildTests.cs +++ b/Natives/NetCord.Natives.Tests/NativesBuildTests.cs @@ -16,9 +16,9 @@ public void NativesLoaded(string libName) { _ = libName switch { - "libdave" => (object)NativeProbes.DaveMaxSupportedProtocolVersion(), - "libsodium" => (object)NativeProbes.SodiumInit(), - "opus" => (object)NativeProbes.OpusGetVersionString(), + "libdave" => NativeProbes.DaveMaxSupportedProtocolVersion(), + "libsodium" => NativeProbes.SodiumInit(), + "opus" => NativeProbes.OpusGetVersionString(), "zstd" => (object)NativeProbes.ZstdVersionNumber(), _ => throw new InvalidOperationException($"Unknown library name '{libName}' provided to test."), }; @@ -26,18 +26,19 @@ public void NativesLoaded(string libName) [TestMethod] [OSCondition(ConditionMode.Exclude, OperatingSystems.OSX)] - [DataRow("libdave", "NetCord.Gateway.Voice.Dave")] - [DataRow("libsodium", "NetCord.Gateway.Voice.Encryption.XChaCha20Poly1305")] - [DataRow("opus", "NetCord.Gateway.Voice.Opus")] - [DataRow("zstd", "NetCord.Gateway.Compression.Zstandard")] - public void AllLibraryImportsExistInBinary(string libName, string className) + [DataRow("libdave")] + [DataRow("libsodium")] + [DataRow("opus")] + [DataRow("zstd")] + public void AllLibraryImportsExistInBinary(string libName) { - var missingExports = NativeProbes.GetMissingLibraryImports(libName, className, typeof(NetCord.Application).Assembly); + var libHandle = NativeProbes.GetLoadedNativeModuleHandle(libName); + var missingExports = NativeProbes.GetMissingLibraryImports(libHandle, libName); Assert.IsEmpty(missingExports, $"The following entry points were not found in '{libName}': {string.Join(", ", missingExports)}"); } - const string NativeAotAppLogTag = $"[{nameof(NativeAotStaticLinking)}]"; + const string NativeAotAppLogTag = nameof(NativeAotStaticLinking); [DoNotParallelize] [TestMethod] [DataRow("libdave;libsodium;opus;zstd")] @@ -51,32 +52,38 @@ public void NativeAotStaticLinking(string libName) var assembly = typeof(NativesBuildTests).Assembly; var properties = assembly.GetCustomAttributes()? - .FirstOrDefault(a => a.Key == "NativeAotAppProps")?.Value; + .FirstOrDefault(a => a.Key == "NativeAotAppProps")? + .Value?.Split(";").Select(p => $"-p:{p.Trim()}"); Assert.IsNotNull(properties, "NativeAotAppProps metadata attribute is not defined."); + var configuration = assembly.GetCustomAttribute()?.Configuration ?? "Debug"; + // build asset NativeAotApp with Native AoT enabled var buildProcess = new System.Diagnostics.Process(); buildProcess.StartInfo.FileName = "dotnet"; buildProcess.StartInfo.ArgumentList.Add("publish"); buildProcess.StartInfo.ArgumentList.Add("NativeAotApp.csproj"); + buildProcess.StartInfo.ArgumentList.Add("-c"); + buildProcess.StartInfo.ArgumentList.Add(configuration); buildProcess.StartInfo.ArgumentList.Add("-tl:off"); buildProcess.StartInfo.ArgumentList.Add("-v:n"); - buildProcess.StartInfo.ArgumentList.Add($"-p:{properties}"); + foreach (var property in properties) + buildProcess.StartInfo.ArgumentList.Add(property); - Console.WriteLine($"{NativeAotAppLogTag} Building Native AoT app in ({projectDirectory}): 'dotnet {buildProcess.StartInfo.ArgumentList.Aggregate((a, b) => $"{a} {b}")}'"); + Console.WriteLine($"[{NativeAotAppLogTag}/Publish] Building Native AoT app in ({projectDirectory}): 'dotnet {buildProcess.StartInfo.ArgumentList.Aggregate((a, b) => $"{a} {b}")}'"); buildProcess.StartInfo.WorkingDirectory = projectDirectory; buildProcess.StartInfo.RedirectStandardOutput = true; buildProcess.OutputDataReceived += (sender, e) => { if (!string.IsNullOrEmpty(e.Data)) - Console.WriteLine($"{NativeAotAppLogTag} {e.Data}"); + Console.WriteLine($"[{NativeAotAppLogTag}/Publish] {e.Data}"); }; buildProcess.StartInfo.RedirectStandardError = true; buildProcess.ErrorDataReceived += (sender, e) => { if (!string.IsNullOrEmpty(e.Data)) - Console.WriteLine($"{NativeAotAppLogTag} {e.Data}"); + Console.Error.WriteLine($"[{NativeAotAppLogTag}/Publish] {e.Data}"); }; var ok = buildProcess.Start(); buildProcess.BeginOutputReadLine(); @@ -90,10 +97,13 @@ public void NativeAotStaticLinking(string libName) getRunCmd.StartInfo.FileName = "dotnet"; getRunCmd.StartInfo.ArgumentList.Add("build"); getRunCmd.StartInfo.ArgumentList.Add("NativeAotApp.csproj"); - getRunCmd.StartInfo.ArgumentList.Add($"-p:{properties}"); + getRunCmd.StartInfo.ArgumentList.Add("-c"); + getRunCmd.StartInfo.ArgumentList.Add(configuration); getRunCmd.StartInfo.ArgumentList.Add("-t:GetTargetPath"); getRunCmd.StartInfo.ArgumentList.Add("-getProperty:PublishDir"); getRunCmd.StartInfo.ArgumentList.Add("--no-restore"); + foreach (var property in properties) + getRunCmd.StartInfo.ArgumentList.Add(property); string? runCmdOutput = null; @@ -103,7 +113,7 @@ public void NativeAotStaticLinking(string libName) { if (!string.IsNullOrEmpty(e.Data)) { - Console.WriteLine($"{NativeAotAppLogTag} {e.Data}"); + Console.WriteLine($"[{NativeAotAppLogTag}/GetRunCmd] {e.Data}"); runCmdOutput = e.Data.Trim('\r', '\n', '"'); } }; @@ -111,7 +121,7 @@ public void NativeAotStaticLinking(string libName) getRunCmd.ErrorDataReceived += (sender, e) => { if (!string.IsNullOrEmpty(e.Data)) - Console.WriteLine($"{NativeAotAppLogTag} {e.Data}"); + Console.Error.WriteLine($"[{NativeAotAppLogTag}/GetRunCmd] {e.Data}"); }; getRunCmd.Start(); getRunCmd.BeginErrorReadLine(); @@ -129,19 +139,19 @@ public void NativeAotStaticLinking(string libName) aotProcess.StartInfo.FileName = runCmdOutput; aotProcess.StartInfo.WorkingDirectory = Path.GetDirectoryName(runCmdOutput); - Console.WriteLine($"{NativeAotAppLogTag} Running Native AoT app: '{runCmdOutput}'"); + Console.WriteLine($"[{NativeAotAppLogTag}/Run] Running Native AoT app: '{runCmdOutput}'"); aotProcess.StartInfo.RedirectStandardOutput = true; aotProcess.OutputDataReceived += (sender, e) => { if (!string.IsNullOrEmpty(e.Data)) - Console.WriteLine($"{NativeAotAppLogTag} {e.Data}"); + Console.WriteLine($"[{NativeAotAppLogTag}/Run] {e.Data}"); }; aotProcess.StartInfo.RedirectStandardError = true; aotProcess.ErrorDataReceived += (sender, e) => { if (!string.IsNullOrEmpty(e.Data)) - Console.WriteLine($"{NativeAotAppLogTag} {e.Data}"); + Console.Error.WriteLine($"[{NativeAotAppLogTag}/Run] {e.Data}"); }; aotProcess.Start(); aotProcess.BeginOutputReadLine(); diff --git a/Natives/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj b/Natives/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj index 5653a4b14..55ed5ebda 100644 --- a/Natives/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj +++ b/Natives/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj @@ -34,9 +34,9 @@ NetCordNativesDir=$([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)\$(NetCordNativesDir)')) $(VCPKG_ROOT) - $(NativeAotAppProps),VcpkgRoot=$(VcpkgRoot) + $(NativeAotAppProps);VcpkgRoot=$(VcpkgRoot) - $(NativeAotAppProps),$(AppendNativeAotAppProps) + $(NativeAotAppProps);$(AppendNativeAotAppProps) @@ -51,4 +51,6 @@ + +
diff --git a/Natives/NetCord.Natives/NetCord.Natives.csproj b/Natives/NetCord.Natives/NetCord.Natives.csproj index 21449da8f..debad306c 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.csproj +++ b/Natives/NetCord.Natives/NetCord.Natives.csproj @@ -184,13 +184,35 @@ - + - <_SymlinksToCreate Include="@(NativesRuntime)" - Condition="$([System.String]::new('%(Filename)').Contains('%(NativeLibSet.Identity)'))" /> + <_NativeFiles Include="$(OutDir)**\lib%(NativeLibSet.Identity)*.so.*" /> + <_NativeFiles Include="$(OutDir)**\lib%(NativeLibSet.Identity)*.dylib" /> + + + $([System.Text.RegularExpressions.Regex]::IsMatch('%(Filename)%(Extension)', '\.dylib')) + + + + %(Filename)%(Extension) + $([System.Text.RegularExpressions.Regex]::Match('%(Filename)%(Extension)', '.*\.so\.\d+')) + $([System.Text.RegularExpressions.Regex]::Replace('%(Filename)%(Extension)', '^([a-zA-Z0-9_-]+\.\d+)\..*', '$1%(Extension)')) + + $([System.Text.RegularExpressions.Regex]::Match('%(Filename)%(Extension)', '.*\.so\.\d+')) + $([System.Text.RegularExpressions.Regex]::Replace('%(Filename)%(Extension)', '^([a-zA-Z0-9_-]+\.\d+)\..*', '$1%(Extension)')) + $([System.Text.RegularExpressions.Regex]::Replace('%(Filename)%(Extension)', '\.so\..*', '.so')) + $([System.Text.RegularExpressions.Regex]::Replace('%(Filename)%(Extension)', '\.\d+.*\.dylib', '.dylib')) + - - + + + + diff --git a/Natives/NetCord.Natives/NetCord.Natives.props b/Natives/NetCord.Natives/NetCord.Natives.props index 7060b8ea2..ec6964832 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.props +++ b/Natives/NetCord.Natives/NetCord.Natives.props @@ -2,12 +2,12 @@ - + $(MSBuildThisFileDirectory)..\runtimes\$(RuntimeIdentifier) $(MSBuildThisFileDirectory)..\staticlibs\$(RuntimeIdentifier) diff --git a/Natives/NetCord.Natives/NetCord.Natives.targets b/Natives/NetCord.Natives/NetCord.Natives.targets index cea684f43..dd36c7326 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.targets +++ b/Natives/NetCord.Natives/NetCord.Natives.targets @@ -60,16 +60,36 @@ - + <_NativeLibNames Include="dave;mlspp;bytes;tls_syntax;hpke;crypto;sodium;opus;zstd" /> - - <_NativeFiles Include="$(OutDir)**\lib%(_NativeLibNames.Identity)*.so.*" /> <_NativeFiles Include="$(OutDir)**\lib%(_NativeLibNames.Identity)*.dylib" /> + + + $([System.Text.RegularExpressions.Regex]::IsMatch('%(Filename)%(Extension)', '\.dylib')) + + + + %(Filename)%(Extension) + $([System.Text.RegularExpressions.Regex]::Match('%(Filename)%(Extension)', '.*\.so\.\d+')) + $([System.Text.RegularExpressions.Regex]::Replace('%(Filename)%(Extension)', '^([a-zA-Z0-9_-]+\.\d+)\..*', '$1%(Extension)')) + + $([System.Text.RegularExpressions.Regex]::Match('%(Filename)%(Extension)', '.*\.so\.\d+')) + $([System.Text.RegularExpressions.Regex]::Replace('%(Filename)%(Extension)', '^([a-zA-Z0-9_-]+\.\d+)\..*', '$1%(Extension)')) + $([System.Text.RegularExpressions.Regex]::Replace('%(Filename)%(Extension)', '\.so\..*', '.so')) + $([System.Text.RegularExpressions.Regex]::Replace('%(Filename)%(Extension)', '\.\d+.*\.dylib', '.dylib')) + - - + + + +
diff --git a/Natives/NetCord.Natives/natives-ports/mlspp/portfile.cmake b/Natives/NetCord.Natives/natives-ports/mlspp/portfile.cmake index 9a7df81b8..812385cad 100644 --- a/Natives/NetCord.Natives/natives-ports/mlspp/portfile.cmake +++ b/Natives/NetCord.Natives/natives-ports/mlspp/portfile.cmake @@ -19,6 +19,7 @@ endif() vcpkg_cmake_configure( SOURCE_PATH "${SOURCE_PATH}" OPTIONS + -DCMAKE_POSITION_INDEPENDENT_CODE=ON ${VCPKG_INCLUDE_OVERRIDE} ${EXTRA_OPTIONS} MAYBE_UNUSED_VARIABLES diff --git a/flake.nix b/flake.nix index 67ffe8eeb..6b620898f 100644 --- a/flake.nix +++ b/flake.nix @@ -37,6 +37,7 @@ }; dotnetRoot = "${dotnet.unwrapped}/share/dotnet"; + in { default = pkgs.mkShell { @@ -54,10 +55,11 @@ pkgs.ninja pkgs.pkg-config pkgs.autoconf + pkgs.autoconf-archive pkgs.automake pkgs.libtool ]; - + DOTNET_ROOT = dotnetRoot; }; From 4f5e55301f58886cf78cdb3c6f4505cd94fe0191 Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Sun, 21 Jun 2026 08:24:52 +0900 Subject: [PATCH 021/101] fix osx nativeaot test build fix flake.nix OSX try fix CI try fix nix osx fix flake osx fix flake.nix modern osx --- .github/workflows/build-natives.yml | 4 ++-- flake.nix | 27 +++++++++++++++++++++++++-- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index a11719fde..b888aa795 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -140,8 +140,8 @@ jobs: -p:AppendNativeAotAppProps="RuntimeIdentifier=${{ env.TargetRID }}" -p:GeneratePackageOnBuild=false -p:CI=false ${{ matrix.vcpkg-os-target == 'osx' && '-p:InvariantGlobalization=true' || '' }} - - - name: List output directory for ${{ matrix.rid }} + + - name: List output directory (Nix) if: ${{ matrix.use-nix }} run: | ls -Rlsha Natives/NetCord.Natives.Tests/bin/ diff --git a/flake.nix b/flake.nix index 6b620898f..330b89c7f 100644 --- a/flake.nix +++ b/flake.nix @@ -38,6 +38,16 @@ dotnetRoot = "${dotnet.unwrapped}/share/dotnet"; + # Use the modern top-level apple-sdk_14 + darwinPackages = pkgs.lib.optionals pkgs.stdenv.hostPlatform.isDarwin (with pkgs; [ + libiconv + apple-sdk_14 + ]); + + # The internal directory structure has changed in recent nixpkgs. + # It is now located directly in /SDKs/MacOSX.sdk + sdkRoot = pkgs.lib.optionalString pkgs.stdenv.hostPlatform.isDarwin + "${pkgs.apple-sdk_14}/SDKs/MacOSX.sdk"; in { default = pkgs.mkShell { @@ -58,9 +68,22 @@ pkgs.autoconf-archive pkgs.automake pkgs.libtool - ]; - + ] ++ darwinPackages; + DOTNET_ROOT = dotnetRoot; + + SDKROOT = sdkRoot; + + NIX_CFLAGS_COMPILE = pkgs.lib.optionalString pkgs.stdenv.hostPlatform.isDarwin + "-isysroot ${sdkRoot}"; + + shellHook = pkgs.lib.optionalString pkgs.stdenv.hostPlatform.isDarwin '' + export SDKROOT="${sdkRoot}" + export LDFLAGS="-F$SDKROOT/System/Library/Frameworks -L$SDKROOT/usr/lib" + export NIX_LDFLAGS="-F$SDKROOT/System/Library/Frameworks -L$SDKROOT/usr/lib" + export NIX_CFLAGS_COMPILE="-isysroot $SDKROOT" + export NIX_CPPFLAGS="-isysroot $SDKROOT" + ''; }; docs = pkgs.mkShell { From 689a8b4233d780cb86d1cb3ee80d867efe2215ba Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Sun, 21 Jun 2026 21:13:47 +0900 Subject: [PATCH 022/101] fix flake.nix for osx compiler --- flake.nix | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/flake.nix b/flake.nix index 330b89c7f..84ca8cada 100644 --- a/flake.nix +++ b/flake.nix @@ -38,14 +38,11 @@ dotnetRoot = "${dotnet.unwrapped}/share/dotnet"; - # Use the modern top-level apple-sdk_14 darwinPackages = pkgs.lib.optionals pkgs.stdenv.hostPlatform.isDarwin (with pkgs; [ libiconv apple-sdk_14 ]); - # The internal directory structure has changed in recent nixpkgs. - # It is now located directly in /SDKs/MacOSX.sdk sdkRoot = pkgs.lib.optionalString pkgs.stdenv.hostPlatform.isDarwin "${pkgs.apple-sdk_14}/SDKs/MacOSX.sdk"; in @@ -72,17 +69,17 @@ DOTNET_ROOT = dotnetRoot; - SDKROOT = sdkRoot; + # 1. Force vcpkg to use Nix's CMake and Ninja instead of Homebrew/System tools + VCPKG_FORCE_SYSTEM_BINARIES = "1"; - NIX_CFLAGS_COMPILE = pkgs.lib.optionalString pkgs.stdenv.hostPlatform.isDarwin - "-isysroot ${sdkRoot}"; + # 2. Explicitly point to the Nix Clang wrapper + CC = "clang"; + CXX = "clang++"; shellHook = pkgs.lib.optionalString pkgs.stdenv.hostPlatform.isDarwin '' + # Provide SDKROOT for MSBuild and Apple tools that expect it. + # We omit manual LDFLAGS/CFLAGS because Nix's Clang wrapper handles them automatically. export SDKROOT="${sdkRoot}" - export LDFLAGS="-F$SDKROOT/System/Library/Frameworks -L$SDKROOT/usr/lib" - export NIX_LDFLAGS="-F$SDKROOT/System/Library/Frameworks -L$SDKROOT/usr/lib" - export NIX_CFLAGS_COMPILE="-isysroot $SDKROOT" - export NIX_CPPFLAGS="-isysroot $SDKROOT" ''; }; From 6e9ef6c15716681ee72d8510afd349519d626c12 Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Sun, 21 Jun 2026 21:26:51 +0200 Subject: [PATCH 023/101] Enable InvariantGlobalization and remove icu --- .../Assets/NativeAotApp/NativeAotApp.csproj | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj b/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj index 8d92bddef..fed542f3f 100644 --- a/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj +++ b/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj @@ -1,10 +1,11 @@ - + Exe net10.0 enable enable + true true true @@ -14,6 +15,12 @@ ..\..\..\NetCord.Natives + + + + + + From fac0d1a746ddace21ddf1773523a310edf04dd9e Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Sun, 21 Jun 2026 21:36:23 +0200 Subject: [PATCH 024/101] Remove default macos12 target --- .../Assets/NativeAotApp/NativeAotApp.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj b/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj index fed542f3f..1862507b1 100644 --- a/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj +++ b/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj @@ -18,6 +18,7 @@ + From 2d71f37ac3742ee691b2f82e2fde2f4c2f96d33e Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Sun, 21 Jun 2026 21:47:52 +0200 Subject: [PATCH 025/101] Add arm64-apple-darwin target --- .../Assets/NativeAotApp/NativeAotApp.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj b/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj index 1862507b1..18bce3c46 100644 --- a/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj +++ b/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj @@ -19,6 +19,7 @@ + From df0fe6d97818818845812a49002681a443f5718d Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Sun, 21 Jun 2026 21:54:47 +0200 Subject: [PATCH 026/101] Disable symbol stripping --- .../Assets/NativeAotApp/NativeAotApp.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj b/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj index 18bce3c46..9d38ede2c 100644 --- a/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj +++ b/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj @@ -6,6 +6,7 @@ enable enable true + false true true From e2f42d8b404f99f38b42dd51a4466c75c6ee0e3f Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Sun, 21 Jun 2026 22:04:21 +0200 Subject: [PATCH 027/101] Remove custom linker args --- .../Assets/NativeAotApp/NativeAotApp.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj b/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj index 9d38ede2c..f0c5220ab 100644 --- a/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj +++ b/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj @@ -19,8 +19,8 @@ - - + + From 0977ec2af8cd09c82954149d1b7cba2de248c53d Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Sun, 21 Jun 2026 22:12:42 +0200 Subject: [PATCH 028/101] Remove invalid comments --- .../Assets/NativeAotApp/NativeAotApp.csproj | 2 -- 1 file changed, 2 deletions(-) diff --git a/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj b/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj index f0c5220ab..361d2d21f 100644 --- a/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj +++ b/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj @@ -19,8 +19,6 @@ - - From c8bc2b5356c95ed62bc6c03273d50316d606c912 Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Sun, 21 Jun 2026 22:26:47 +0200 Subject: [PATCH 029/101] # This is a combination of 2 commits. # This is the 1st commit message: Use apple sdk 12 instead of 14 # This is the commit message #2: Run CI --- flake.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flake.nix b/flake.nix index 84ca8cada..c125933b7 100644 --- a/flake.nix +++ b/flake.nix @@ -40,11 +40,11 @@ darwinPackages = pkgs.lib.optionals pkgs.stdenv.hostPlatform.isDarwin (with pkgs; [ libiconv - apple-sdk_14 + apple-sdk_12 ]); sdkRoot = pkgs.lib.optionalString pkgs.stdenv.hostPlatform.isDarwin - "${pkgs.apple-sdk_14}/SDKs/MacOSX.sdk"; + "${pkgs.apple-sdk_12}/SDKs/MacOSX.sdk"; in { default = pkgs.mkShell { From 31e4d2ceeee449635203e769fdc5987f1359d8f9 Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Mon, 22 Jun 2026 13:12:06 +0200 Subject: [PATCH 030/101] Attempt to fix flake.nix and make it use apple sdk 12 target --- flake.nix | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/flake.nix b/flake.nix index c125933b7..089e8ce3e 100644 --- a/flake.nix +++ b/flake.nix @@ -40,11 +40,11 @@ darwinPackages = pkgs.lib.optionals pkgs.stdenv.hostPlatform.isDarwin (with pkgs; [ libiconv - apple-sdk_12 + apple-sdk ]); sdkRoot = pkgs.lib.optionalString pkgs.stdenv.hostPlatform.isDarwin - "${pkgs.apple-sdk_12}/SDKs/MacOSX.sdk"; + "${pkgs.apple-sdk}/SDKs/MacOSX.sdk"; in { default = pkgs.mkShell { @@ -69,6 +69,8 @@ DOTNET_ROOT = dotnetRoot; + MACOSX_DEPLOYMENT_TARGET = "12.0"; + # 1. Force vcpkg to use Nix's CMake and Ninja instead of Homebrew/System tools VCPKG_FORCE_SYSTEM_BINARIES = "1"; From c3a52037579a6b7bd2b698c64294074b0fa2f777 Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Mon, 22 Jun 2026 13:28:29 +0200 Subject: [PATCH 031/101] Override stdenv to target macOS 12 --- flake.nix | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/flake.nix b/flake.nix index 089e8ce3e..fa55c71d4 100644 --- a/flake.nix +++ b/flake.nix @@ -55,7 +55,12 @@ DOTNET_ROOT = dotnetRoot; }; - natives = pkgs.mkShell { + natives = pkgs.mkShell.override { + stdenv = pkgs.stdenv.override (old: { + hostPlatform = old.hostPlatform // { darwinMinVersion = "12.0"; }; + targetPlatform = old.targetPlatform // { darwinMinVersion = "12.0"; }; + }); + } { packages = [ dotnet pkgs.cmake @@ -69,8 +74,6 @@ DOTNET_ROOT = dotnetRoot; - MACOSX_DEPLOYMENT_TARGET = "12.0"; - # 1. Force vcpkg to use Nix's CMake and Ninja instead of Homebrew/System tools VCPKG_FORCE_SYSTEM_BINARIES = "1"; From 0d33f7036fa77e0010847e1961a901b20567c435 Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Mon, 22 Jun 2026 13:41:25 +0200 Subject: [PATCH 032/101] Add MACOSX_DEPLOYMENT_TARGET env variable set to 12.0 --- flake.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/flake.nix b/flake.nix index fa55c71d4..b06145c5e 100644 --- a/flake.nix +++ b/flake.nix @@ -74,6 +74,8 @@ DOTNET_ROOT = dotnetRoot; + MACOSX_DEPLOYMENT_TARGET = "12.0"; + # 1. Force vcpkg to use Nix's CMake and Ninja instead of Homebrew/System tools VCPKG_FORCE_SYSTEM_BINARIES = "1"; From 0111ef663ed1b3aeaa725e5370169d35d419f3ef Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Mon, 22 Jun 2026 13:58:38 +0200 Subject: [PATCH 033/101] Add VCPKG_ENV_PASSTHROUGH --- flake.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/flake.nix b/flake.nix index b06145c5e..5b9396d37 100644 --- a/flake.nix +++ b/flake.nix @@ -76,6 +76,8 @@ MACOSX_DEPLOYMENT_TARGET = "12.0"; + VCPKG_ENV_PASSTHROUGH = "MACOSX_DEPLOYMENT_TARGET,SDKROOT"; + # 1. Force vcpkg to use Nix's CMake and Ninja instead of Homebrew/System tools VCPKG_FORCE_SYSTEM_BINARIES = "1"; From c18d2a589a8f292e7d3b92e9373188e26a0c94b3 Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Mon, 22 Jun 2026 14:53:35 +0200 Subject: [PATCH 034/101] Cleanup macOS stuff in flake.nix --- flake.nix | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/flake.nix b/flake.nix index 5b9396d37..cbf767467 100644 --- a/flake.nix +++ b/flake.nix @@ -42,9 +42,6 @@ libiconv apple-sdk ]); - - sdkRoot = pkgs.lib.optionalString pkgs.stdenv.hostPlatform.isDarwin - "${pkgs.apple-sdk}/SDKs/MacOSX.sdk"; in { default = pkgs.mkShell { @@ -60,7 +57,7 @@ hostPlatform = old.hostPlatform // { darwinMinVersion = "12.0"; }; targetPlatform = old.targetPlatform // { darwinMinVersion = "12.0"; }; }); - } { + } ({ packages = [ dotnet pkgs.cmake @@ -74,23 +71,14 @@ DOTNET_ROOT = dotnetRoot; - MACOSX_DEPLOYMENT_TARGET = "12.0"; - - VCPKG_ENV_PASSTHROUGH = "MACOSX_DEPLOYMENT_TARGET,SDKROOT"; - - # 1. Force vcpkg to use Nix's CMake and Ninja instead of Homebrew/System tools VCPKG_FORCE_SYSTEM_BINARIES = "1"; - - # 2. Explicitly point to the Nix Clang wrapper CC = "clang"; CXX = "clang++"; - - shellHook = pkgs.lib.optionalString pkgs.stdenv.hostPlatform.isDarwin '' - # Provide SDKROOT for MSBuild and Apple tools that expect it. - # We omit manual LDFLAGS/CFLAGS because Nix's Clang wrapper handles them automatically. - export SDKROOT="${sdkRoot}" - ''; - }; + } // pkgs.lib.optionalAttrs pkgs.stdenv.hostPlatform.isDarwin { + SDKROOT = "${pkgs.apple-sdk}/SDKs/MacOSX.sdk"; + MACOSX_DEPLOYMENT_TARGET = "12.0"; + VCPKG_ENV_PASSTHROUGH = "MACOSX_DEPLOYMENT_TARGET,SDKROOT"; + }); docs = pkgs.mkShell { packages = [ From 2138e519f2aab432319f1af187cb54eaefe97fb0 Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Mon, 22 Jun 2026 15:47:00 +0200 Subject: [PATCH 035/101] Cleanup NetCord.Natives.csproj --- .../Assets/NativeAotApp/NativeAotApp.csproj | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj b/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj index 361d2d21f..6c141f197 100644 --- a/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj +++ b/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj @@ -12,7 +12,7 @@ true true true - + ..\..\..\NetCord.Natives @@ -26,17 +26,19 @@ - - - - - - - - + + + + + + + + + libdave;libsodium;opus;zstd - + + From f508fa125bdf795cba08d3ef17524e0d880117c9 Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Mon, 22 Jun 2026 22:59:27 +0900 Subject: [PATCH 036/101] add binlogpath to nativeaotapp test * fix main build.yml * confine nativeaot linkerargs removal target --- .github/workflows/build-natives.yml | 2 +- .github/workflows/build.yml | 2 -- .../Assets/NativeAotApp/NativeAotApp.csproj | 23 +++++++++++-------- .../NativesBuildTests.cs | 7 +++++- .../NetCord.Natives.Tests.csproj | 4 ++++ 5 files changed, 24 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index b888aa795..8c96365bf 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -136,7 +136,7 @@ jobs: run: > dotnet build Natives/NetCord.Natives.slnx --no-restore -v ${{ env.DotnetVerbose }} - ${{ env.GenerateBinLog == 'true' && '-bl:build.binlog' || '' }} + ${{ env.GenerateBinLog == 'true' && format('-bl:build.binlog -p:NativeAotBinLogPath={0}/nativeaotapptest.binlog', github.workspace) || '' }} -p:AppendNativeAotAppProps="RuntimeIdentifier=${{ env.TargetRID }}" -p:GeneratePackageOnBuild=false -p:CI=false ${{ matrix.vcpkg-os-target == 'osx' && '-p:InvariantGlobalization=true' || '' }} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 60cdcaaa1..85845fa45 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -34,13 +34,11 @@ jobs: shell: *dev-shell run: | dotnet restore NetCord.slnx - dotnet restore NetCord.Natives.slnx -p:VcpkgRoot=$VCPKG_INSTALLATION_ROOT -p:VcpkgEnabled=false - name: Build shell: *dev-shell run: | dotnet build NetCord.slnx -c Release --no-restore --warnaserror - dotnet build NetCord.Natives.slnx -c Release --no-restore --warnaserror -p:VcpkgRoot=$VCPKG_INSTALLATION_ROOT -p:VcpkgEnabled=false - name: Test shell: *dev-shell diff --git a/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj b/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj index 6c141f197..373216258 100644 --- a/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj +++ b/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj @@ -5,7 +5,6 @@ net10.0 enable enable - true false true @@ -16,7 +15,11 @@ ..\..\..\NetCord.Natives - + + + true + + @@ -26,14 +29,14 @@ - - - - - - - - + + + + + + + + libdave;libsodium;opus;zstd diff --git a/Natives/NetCord.Natives.Tests/NativesBuildTests.cs b/Natives/NetCord.Natives.Tests/NativesBuildTests.cs index 3e8cbc275..6e295f2da 100644 --- a/Natives/NetCord.Natives.Tests/NativesBuildTests.cs +++ b/Natives/NetCord.Natives.Tests/NativesBuildTests.cs @@ -53,9 +53,12 @@ public void NativeAotStaticLinking(string libName) var properties = assembly.GetCustomAttributes()? .FirstOrDefault(a => a.Key == "NativeAotAppProps")? - .Value?.Split(";").Select(p => $"-p:{p.Trim()}"); + .Value?.Split([';',','], StringSplitOptions.RemoveEmptyEntries).Select(p => $"-p:{p.Trim()}"); Assert.IsNotNull(properties, "NativeAotAppProps metadata attribute is not defined."); + var binlogpath = assembly.GetCustomAttributes()? + .FirstOrDefault(a => a.Key == "NativeAotBinLogPath")?.Value; + var configuration = assembly.GetCustomAttribute()?.Configuration ?? "Debug"; // build asset NativeAotApp with Native AoT enabled @@ -67,6 +70,8 @@ public void NativeAotStaticLinking(string libName) buildProcess.StartInfo.ArgumentList.Add(configuration); buildProcess.StartInfo.ArgumentList.Add("-tl:off"); buildProcess.StartInfo.ArgumentList.Add("-v:n"); + if (!string.IsNullOrEmpty(binlogpath)) + buildProcess.StartInfo.ArgumentList.Add($"-bl:{binlogpath}"); foreach (var property in properties) buildProcess.StartInfo.ArgumentList.Add(property); diff --git a/Natives/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj b/Natives/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj index 55ed5ebda..7f4e4ac74 100644 --- a/Natives/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj +++ b/Natives/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj @@ -45,6 +45,10 @@ <_Parameter1>NativeAotAppProps <_Parameter2>$(NativeAotAppProps) + + <_Parameter1>NativeAotBinLogPath + <_Parameter2>$(NativeAotBinLogPath) + From 618e497159ad78f1d336b17d94819ef95b7e06b0 Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Mon, 22 Jun 2026 20:42:23 +0200 Subject: [PATCH 037/101] Add musl builds --- .../NetCord.Natives/NetCord.Natives.csproj | 12 ++++++++ .../natives-ports/mlspp/portfile.cmake | 2 +- .../triplets/x64-linux-musl-dynamic.cmake | 4 +++ .../triplets/x64-linux-musl.cmake | 4 +++ flake.nix | 28 +++++++++++++++++-- 5 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 Natives/NetCord.Natives/triplets/x64-linux-musl-dynamic.cmake create mode 100644 Natives/NetCord.Natives/triplets/x64-linux-musl.cmake diff --git a/Natives/NetCord.Natives/NetCord.Natives.csproj b/Natives/NetCord.Natives/NetCord.Natives.csproj index debad306c..282020e19 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.csproj +++ b/Natives/NetCord.Natives/NetCord.Natives.csproj @@ -32,6 +32,8 @@ windows osx + + linux-musl linux $(VcpkgOSTarget) @@ -103,21 +105,31 @@ <_LibArchs Include="x64;arm64"> %(NativeLibSet.Identity) + <_BuiltRid Include="win-%(_LibArchs.Identity)"> %(_LibArchs.Identity)-windows\bin\%(_LibArchs.LibName) %(_LibArchs.Identity)-windows-static\lib\%(_LibArchs.LibName) dll + <_BuiltRid Include="linux-%(_LibArchs.Identity)"> %(_LibArchs.Identity)-linux-dynamic\lib\lib%(_LibArchs.LibName) %(_LibArchs.Identity)-linux\lib\lib%(_LibArchs.LibName) so + + <_BuiltRid Include="linux-musl-%(_LibArchs.Identity)"> + %(_LibArchs.Identity)-linux-musl-dynamic\lib\lib%(_LibArchs.LibName) + %(_LibArchs.Identity)-linux-musl\lib\lib%(_LibArchs.LibName) + so + + <_BuiltRid Include="osx-%(_LibArchs.Identity)"> %(_LibArchs.Identity)-osx-dynamic\lib\lib%(_LibArchs.LibName) %(_LibArchs.Identity)-osx\lib\lib%(_LibArchs.LibName) dylib + <_BuiltRid Remove="%(Identity)" Condition="'$(CI)' != 'true' and '%(Identity)' != '$(VcpkgBuildOS)-$(VcpkgPlatformTarget)'" /> diff --git a/Natives/NetCord.Natives/natives-ports/mlspp/portfile.cmake b/Natives/NetCord.Natives/natives-ports/mlspp/portfile.cmake index 812385cad..c24466d30 100644 --- a/Natives/NetCord.Natives/natives-ports/mlspp/portfile.cmake +++ b/Natives/NetCord.Natives/natives-ports/mlspp/portfile.cmake @@ -13,7 +13,7 @@ set(VCPKG_LIBRARY_LINKAGE static) set(EXTRA_OPTIONS -DDISABLE_GREASE=ON -DTESTING=OFF -DBUILD_TESTING=OFF -DMLS_CXX_NAMESPACE="mlspp") if(VCPKG_HOST_IS_LINUX) - list(APPEND EXTRA_OPTIONS -DCMAKE_CXX_FLAGS="-Wno-error=maybe-uninitialized") + list(APPEND EXTRA_OPTIONS -DCMAKE_CXX_FLAGS="-Wno-error=uninitialized") endif() vcpkg_cmake_configure( diff --git a/Natives/NetCord.Natives/triplets/x64-linux-musl-dynamic.cmake b/Natives/NetCord.Natives/triplets/x64-linux-musl-dynamic.cmake new file mode 100644 index 000000000..b6f5fc5fc --- /dev/null +++ b/Natives/NetCord.Natives/triplets/x64-linux-musl-dynamic.cmake @@ -0,0 +1,4 @@ +set(VCPKG_TARGET_ARCHITECTURE x64) +set(VCPKG_CRT_LINKAGE dynamic) +set(VCPKG_LIBRARY_LINKAGE dynamic) +set(VCPKG_CMAKE_SYSTEM_NAME Linux) diff --git a/Natives/NetCord.Natives/triplets/x64-linux-musl.cmake b/Natives/NetCord.Natives/triplets/x64-linux-musl.cmake new file mode 100644 index 000000000..8361f30d4 --- /dev/null +++ b/Natives/NetCord.Natives/triplets/x64-linux-musl.cmake @@ -0,0 +1,4 @@ +set(VCPKG_TARGET_ARCHITECTURE x64) +set(VCPKG_CRT_LINKAGE static) +set(VCPKG_LIBRARY_LINKAGE static) +set(VCPKG_CMAKE_SYSTEM_NAME Linux) diff --git a/flake.nix b/flake.nix index cbf767467..3264cda8b 100644 --- a/flake.nix +++ b/flake.nix @@ -53,7 +53,9 @@ }; natives = pkgs.mkShell.override { - stdenv = pkgs.stdenv.override (old: { + stdenv = if pkgs.clangStdenv.isLinux then + pkgs.clangStdenv + else pkgs.clangStdenv.override (old: { hostPlatform = old.hostPlatform // { darwinMinVersion = "12.0"; }; targetPlatform = old.targetPlatform // { darwinMinVersion = "12.0"; }; }); @@ -72,14 +74,34 @@ DOTNET_ROOT = dotnetRoot; VCPKG_FORCE_SYSTEM_BINARIES = "1"; - CC = "clang"; - CXX = "clang++"; } // pkgs.lib.optionalAttrs pkgs.stdenv.hostPlatform.isDarwin { SDKROOT = "${pkgs.apple-sdk}/SDKs/MacOSX.sdk"; MACOSX_DEPLOYMENT_TARGET = "12.0"; VCPKG_ENV_PASSTHROUGH = "MACOSX_DEPLOYMENT_TARGET,SDKROOT"; }); + natives-musl = pkgs.mkShell.override { + stdenv = pkgs.pkgsMusl.clangStdenv; + } ({ + packages = [ + dotnet + pkgs.cmake + pkgs.ninja + pkgs.pkg-config + pkgs.autoconf + pkgs.autoconf-archive + pkgs.automake + pkgs.libtool + ] ++ darwinPackages; + + DOTNET_ROOT = dotnetRoot; + + VCPKG_FORCE_SYSTEM_BINARIES = "1"; + } // pkgs.lib.optionalAttrs pkgs.stdenv.hostPlatform.isDarwin { + SDKROOT = "${pkgs.apple-sdk}/SDKs/MacOSX.sdk"; + MACOSX_DEPLOYMENT_TARGET = "12.0"; + VCPKG_ENV_PASSTHROUGH = "MACOSX_DEPLOYMENT_TARGET,SDKROOT"; + }); docs = pkgs.mkShell { packages = [ docfx From b10e143b4ff706af98da2281cd16f3e181fd2ac9 Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Mon, 22 Jun 2026 23:29:01 +0200 Subject: [PATCH 038/101] Improve musl options and automatically set default VCPKG_ROOT in flake.nix --- Natives/NetCord.Natives.Tests/NativesBuildTests.cs | 12 ++++++++---- Natives/NetCord.Natives/NetCord.Natives.csproj | 6 +++++- flake.nix | 13 +++++++++++++ 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/Natives/NetCord.Natives.Tests/NativesBuildTests.cs b/Natives/NetCord.Natives.Tests/NativesBuildTests.cs index 6e295f2da..791f988ca 100644 --- a/Natives/NetCord.Natives.Tests/NativesBuildTests.cs +++ b/Natives/NetCord.Natives.Tests/NativesBuildTests.cs @@ -53,7 +53,7 @@ public void NativeAotStaticLinking(string libName) var properties = assembly.GetCustomAttributes()? .FirstOrDefault(a => a.Key == "NativeAotAppProps")? - .Value?.Split([';',','], StringSplitOptions.RemoveEmptyEntries).Select(p => $"-p:{p.Trim()}"); + .Value?.Split([';', ','], StringSplitOptions.RemoveEmptyEntries).Select(p => $"-p:{p.Trim()}"); Assert.IsNotNull(properties, "NativeAotAppProps metadata attribute is not defined."); var binlogpath = assembly.GetCustomAttributes()? @@ -70,11 +70,13 @@ public void NativeAotStaticLinking(string libName) buildProcess.StartInfo.ArgumentList.Add(configuration); buildProcess.StartInfo.ArgumentList.Add("-tl:off"); buildProcess.StartInfo.ArgumentList.Add("-v:n"); + buildProcess.StartInfo.ArgumentList.Add("-nodeReuse:false"); + if (!string.IsNullOrEmpty(binlogpath)) buildProcess.StartInfo.ArgumentList.Add($"-bl:{binlogpath}"); foreach (var property in properties) buildProcess.StartInfo.ArgumentList.Add(property); - + Console.WriteLine($"[{NativeAotAppLogTag}/Publish] Building Native AoT app in ({projectDirectory}): 'dotnet {buildProcess.StartInfo.ArgumentList.Aggregate((a, b) => $"{a} {b}")}'"); buildProcess.StartInfo.WorkingDirectory = projectDirectory; @@ -107,9 +109,11 @@ public void NativeAotStaticLinking(string libName) getRunCmd.StartInfo.ArgumentList.Add("-t:GetTargetPath"); getRunCmd.StartInfo.ArgumentList.Add("-getProperty:PublishDir"); getRunCmd.StartInfo.ArgumentList.Add("--no-restore"); + getRunCmd.StartInfo.ArgumentList.Add("-nodeReuse:false"); + foreach (var property in properties) getRunCmd.StartInfo.ArgumentList.Add(property); - + string? runCmdOutput = null; getRunCmd.StartInfo.WorkingDirectory = projectDirectory; @@ -136,7 +140,7 @@ public void NativeAotStaticLinking(string libName) Assert.AreEqual(0, getRunCmd.ExitCode, $"Failed to obtain PublishDir for '{libName}'."); Assert.IsFalse(string.IsNullOrEmpty(runCmdOutput), $"PublishDir is empty for '{libName}'."); - runCmdOutput = Path.Combine(projectDirectory, runCmdOutput, + runCmdOutput = Path.Combine(projectDirectory, runCmdOutput, "NativeAotApp" + (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : "")); // check that the library is running without errors, which indicates that it was statically linked successfully diff --git a/Natives/NetCord.Natives/NetCord.Natives.csproj b/Natives/NetCord.Natives/NetCord.Natives.csproj index 282020e19..6e564e9ac 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.csproj +++ b/Natives/NetCord.Natives/NetCord.Natives.csproj @@ -30,10 +30,14 @@ Release true + false + + true + windows osx - linux-musl + linux-musl linux $(VcpkgOSTarget) diff --git a/flake.nix b/flake.nix index 3264cda8b..b32f4aae2 100644 --- a/flake.nix +++ b/flake.nix @@ -74,6 +74,10 @@ DOTNET_ROOT = dotnetRoot; VCPKG_FORCE_SYSTEM_BINARIES = "1"; + + shellHook = '' + export VCPKG_ROOT="$PWD/Natives/NetCord.Natives/vcpkg" + ''; } // pkgs.lib.optionalAttrs pkgs.stdenv.hostPlatform.isDarwin { SDKROOT = "${pkgs.apple-sdk}/SDKs/MacOSX.sdk"; MACOSX_DEPLOYMENT_TARGET = "12.0"; @@ -96,12 +100,21 @@ DOTNET_ROOT = dotnetRoot; + TARGET_MUSL = "true"; + + VCPKG_OVERLAY_TRIPLETS="${toString ./.}/Natives/NetCord.Natives/triplets"; + VCPKG_FORCE_SYSTEM_BINARIES = "1"; + + shellHook = '' + export VCPKG_ROOT="$PWD/Natives/NetCord.Natives/vcpkg" + ''; } // pkgs.lib.optionalAttrs pkgs.stdenv.hostPlatform.isDarwin { SDKROOT = "${pkgs.apple-sdk}/SDKs/MacOSX.sdk"; MACOSX_DEPLOYMENT_TARGET = "12.0"; VCPKG_ENV_PASSTHROUGH = "MACOSX_DEPLOYMENT_TARGET,SDKROOT"; }); + docs = pkgs.mkShell { packages = [ docfx From 8754966e6b3f6b7ce70ca9b18b5aad3f004895da Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Tue, 23 Jun 2026 00:16:26 +0200 Subject: [PATCH 039/101] Add CI builds and tests for musl --- .github/workflows/build-natives.yml | 52 +++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index 8c96365bf..2b8abc811 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -35,36 +35,56 @@ jobs: vcpkg-platform-target: x64 use-nix: false shell_command: pwsh + musl: false - rid: win-arm64 runs-on: windows-11-arm vcpkg-os-target: windows vcpkg-platform-target: arm64 use-nix: false shell_command: pwsh + musl: false - rid: osx-x64 runs-on: macos-15-intel vcpkg-os-target: osx vcpkg-platform-target: x64 use-nix: true shell_command: nix develop .#natives -c bash -eo pipefail {0} + musl: false - rid: osx-arm64 runs-on: macos-15 vcpkg-os-target: osx vcpkg-platform-target: arm64 use-nix: true shell_command: nix develop .#natives -c bash -eo pipefail {0} + musl: false - rid: linux-x64 runs-on: ubuntu-latest vcpkg-os-target: linux vcpkg-platform-target: x64 use-nix: true shell_command: nix develop .#natives -c bash -eo pipefail {0} + musl: false - rid: linux-arm64 runs-on: ubuntu-24.04-arm vcpkg-os-target: linux vcpkg-platform-target: arm64 use-nix: true shell_command: nix develop .#natives -c bash -eo pipefail {0} + musl: false + - rid: linux-musl-x64 + runs-on: ubuntu-latest + vcpkg-os-target: linux + vcpkg-platform-target: x64 + use-nix: true + shell_command: nix develop .#natives-musl -c bash -eo pipefail {0} + musl: true + - rid: linux-musl-arm64 + runs-on: ubuntu-24.04-arm + vcpkg-os-target: linux + vcpkg-platform-target: arm64 + use-nix: true + shell_command: nix develop .#natives-musl -c bash -eo pipefail {0} + musl: true runs-on: ${{ matrix.runs-on }} defaults: @@ -91,17 +111,17 @@ jobs: submodules: true - name: Install Nix - if: ${{ matrix.use-nix }} + if: matrix.use-nix uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6 - name: Setup vcpkg cache directories (Windows) - if: ${{ !matrix.use-nix }} + if: !matrix.use-nix run: | New-Item -ItemType Directory -Path $env:VCPKG_BINARY_SOURCES.Split(',')[1] -Force | Out-Null New-Item -ItemType Directory -Path $env:VCPKG_DOWNLOADS -Force | Out-Null - name: Setup vcpkg cache directories (Nix) - if: ${{ matrix.use-nix }} + if: matrix.use-nix run: | mkdir -p "${VCPKG_BINARY_SOURCES#*,}" mkdir -p "${VCPKG_DOWNLOADS}" @@ -120,7 +140,7 @@ jobs: vcpkg-${{ runner.os }}- - name: Setup .NET Core SDK (Windows) - if: ${{ !matrix.use-nix }} + if: !matrix.use-nix uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5.2.0 with: global-json-file: global.json @@ -142,12 +162,12 @@ jobs: ${{ matrix.vcpkg-os-target == 'osx' && '-p:InvariantGlobalization=true' || '' }} - name: List output directory (Nix) - if: ${{ matrix.use-nix }} + if: matrix.use-nix run: | ls -Rlsha Natives/NetCord.Natives.Tests/bin/ - - name: Test natives outputs for ${{ matrix.rid }} - # This will still run if Build succeeds. If Build fails, this is skipped automatically. + - name: Test natives outputs for ${{ matrix.rid }} (non musl) + if: !matrix.musl run: > dotnet test Natives/NetCord.Natives.slnx --no-restore --no-build -v ${{ env.DotnetVerbose }} @@ -156,9 +176,19 @@ jobs: --logger GitHubActions ${{ matrix.vcpkg-os-target == 'osx' && '-p:InvariantGlobalization=true' || '' }} + - name: Test natives outputs for ${{ matrix.rid }} (musl) + if: matrix.musl + run: > + docker run --rm -v $(pwd):$(pwd) -w $(pwd) -e VCPKG_ROOT -e TARGET_MUSL -e MINVERVERSIONOVERRIDE=1.0.0 mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot dotnet test --no-restore --no-build + -v ${{ env.DotnetVerbose }} + ${{ env.GenerateBinLog == 'true' && '-bl:test.binlog' || '' }} + --logger "console;verbosity=detailed" + --logger GitHubActions + ${{ matrix.vcpkg-os-target == 'osx' && '-p:InvariantGlobalization=true' || '' }} + - name: Pack NuGet Package for ${{ matrix.rid }} # This forces the step to run even if 'Test' failed, as long as 'Build' succeeded. - if: ${{ always() && steps.build_step.outcome == 'success' }} + if: always() && steps.build_step.outcome == 'success' id: pack_step # Added an ID here to track the pack status for the upload step run: > dotnet pack Natives/NetCord.Natives/NetCord.Natives.csproj --no-restore --no-build -v ${{ env.DotnetVerbose }} @@ -167,7 +197,7 @@ jobs: -p:CI=false - name: Upload Binary Logs - if: ${{ env.GenerateBinLog == 'true' && always() }} + if: env.GenerateBinLog == 'true' && always() uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: ${{ matrix.rid }}-binlogs @@ -176,7 +206,7 @@ jobs: - name: Upload NuGet Package Artifact # This ensures we only upload if the Pack step actually finished successfully. - if: ${{ always() && steps.pack_step.outcome == 'success' }} + if: always() && steps.pack_step.outcome == 'success' uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: NetCord.Natives.${{ matrix.rid }}.packages @@ -185,7 +215,7 @@ jobs: Natives/NetCord.Natives/bin/${{ matrix.rid }}/*.snupkg - name: Save vcpkg cache - if: ${{ always() && steps.build_step.outcome == 'success' }} + if: always() && steps.build_step.outcome == 'success' uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: path: | From 1c842af0ac34ffa05ed7772be4ba7b203cf20115 Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Tue, 23 Jun 2026 00:20:27 +0200 Subject: [PATCH 040/101] Fix ifs in workflows --- .github/workflows/build-natives.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index 2b8abc811..6ccb7d7ee 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -111,17 +111,17 @@ jobs: submodules: true - name: Install Nix - if: matrix.use-nix + if: ${{ matrix.use-nix }} uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6 - name: Setup vcpkg cache directories (Windows) - if: !matrix.use-nix + if: ${{ !matrix.use-nix }} run: | New-Item -ItemType Directory -Path $env:VCPKG_BINARY_SOURCES.Split(',')[1] -Force | Out-Null New-Item -ItemType Directory -Path $env:VCPKG_DOWNLOADS -Force | Out-Null - name: Setup vcpkg cache directories (Nix) - if: matrix.use-nix + if: ${{ matrix.use-nix }} run: | mkdir -p "${VCPKG_BINARY_SOURCES#*,}" mkdir -p "${VCPKG_DOWNLOADS}" @@ -140,7 +140,7 @@ jobs: vcpkg-${{ runner.os }}- - name: Setup .NET Core SDK (Windows) - if: !matrix.use-nix + if: ${{ !matrix.use-nix }} uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5.2.0 with: global-json-file: global.json @@ -162,12 +162,12 @@ jobs: ${{ matrix.vcpkg-os-target == 'osx' && '-p:InvariantGlobalization=true' || '' }} - name: List output directory (Nix) - if: matrix.use-nix + if: ${{ matrix.use-nix }} run: | ls -Rlsha Natives/NetCord.Natives.Tests/bin/ - name: Test natives outputs for ${{ matrix.rid }} (non musl) - if: !matrix.musl + if: ${{ !matrix.musl }} run: > dotnet test Natives/NetCord.Natives.slnx --no-restore --no-build -v ${{ env.DotnetVerbose }} @@ -177,7 +177,7 @@ jobs: ${{ matrix.vcpkg-os-target == 'osx' && '-p:InvariantGlobalization=true' || '' }} - name: Test natives outputs for ${{ matrix.rid }} (musl) - if: matrix.musl + if: ${{ matrix.musl }} run: > docker run --rm -v $(pwd):$(pwd) -w $(pwd) -e VCPKG_ROOT -e TARGET_MUSL -e MINVERVERSIONOVERRIDE=1.0.0 mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot dotnet test --no-restore --no-build -v ${{ env.DotnetVerbose }} @@ -188,7 +188,7 @@ jobs: - name: Pack NuGet Package for ${{ matrix.rid }} # This forces the step to run even if 'Test' failed, as long as 'Build' succeeded. - if: always() && steps.build_step.outcome == 'success' + if: ${{ always() && steps.build_step.outcome == 'success' }} id: pack_step # Added an ID here to track the pack status for the upload step run: > dotnet pack Natives/NetCord.Natives/NetCord.Natives.csproj --no-restore --no-build -v ${{ env.DotnetVerbose }} @@ -197,7 +197,7 @@ jobs: -p:CI=false - name: Upload Binary Logs - if: env.GenerateBinLog == 'true' && always() + if: ${{ env.GenerateBinLog == 'true' && always()}} uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: ${{ matrix.rid }}-binlogs @@ -206,7 +206,7 @@ jobs: - name: Upload NuGet Package Artifact # This ensures we only upload if the Pack step actually finished successfully. - if: always() && steps.pack_step.outcome == 'success' + if: ${{ always() && steps.pack_step.outcome == 'success' }} uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: NetCord.Natives.${{ matrix.rid }}.packages @@ -215,7 +215,7 @@ jobs: Natives/NetCord.Natives/bin/${{ matrix.rid }}/*.snupkg - name: Save vcpkg cache - if: always() && steps.build_step.outcome == 'success' + if: ${{ always() && steps.build_step.outcome == 'success' }} uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: path: | From b879bdbfb26473b397ad2742013fab8860eda4de Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Tue, 23 Jun 2026 10:38:55 +0200 Subject: [PATCH 041/101] Fix musl tests and merge musl and non-musl tests into a single step --- .github/workflows/build-natives.yml | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index 6ccb7d7ee..f08f0c5ac 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -166,20 +166,12 @@ jobs: run: | ls -Rlsha Natives/NetCord.Natives.Tests/bin/ - - name: Test natives outputs for ${{ matrix.rid }} (non musl) - if: ${{ !matrix.musl }} + - name: Test natives outputs for ${{ matrix.rid }} run: > - dotnet test Natives/NetCord.Natives.slnx --no-restore --no-build - -v ${{ env.DotnetVerbose }} - ${{ env.GenerateBinLog == 'true' && '-bl:test.binlog' || '' }} - --logger "console;verbosity=detailed" - --logger GitHubActions - ${{ matrix.vcpkg-os-target == 'osx' && '-p:InvariantGlobalization=true' || '' }} - - - name: Test natives outputs for ${{ matrix.rid }} (musl) - if: ${{ matrix.musl }} - run: > - docker run --rm -v $(pwd):$(pwd) -w $(pwd) -e VCPKG_ROOT -e TARGET_MUSL -e MINVERVERSIONOVERRIDE=1.0.0 mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot dotnet test --no-restore --no-build + ${{ matrix.musl && 'docker run --rm -v $PWD:$PWD -w $PWD -e VCPKG_ROOT -e TARGET_MUSL -e MINVERVERSIONOVERRIDE=1.0.0 mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot' || '' }} + dotnet test Natives/NetCord.Natives.slnx + --no-restore + --no-build -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:test.binlog' || '' }} --logger "console;verbosity=detailed" From 14e5b38be225074a394d10a265e616f8ced06a94 Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Tue, 23 Jun 2026 10:39:47 +0200 Subject: [PATCH 042/101] Fix daveMaxSupportedProtocolVersion pinvoke in a test --- Natives/NetCord.Natives.Tests/NativeProbes.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Natives/NetCord.Natives.Tests/NativeProbes.cs b/Natives/NetCord.Natives.Tests/NativeProbes.cs index 704f68cc6..0f92c002a 100644 --- a/Natives/NetCord.Natives.Tests/NativeProbes.cs +++ b/Natives/NetCord.Natives.Tests/NativeProbes.cs @@ -7,7 +7,7 @@ namespace NetCord.Natives.Tests; public static partial class NativeProbes { [LibraryImport("libdave", EntryPoint = "daveMaxSupportedProtocolVersion")] - internal static partial uint DaveMaxSupportedProtocolVersion(); + internal static partial ushort DaveMaxSupportedProtocolVersion(); [LibraryImport("libsodium", EntryPoint = "sodium_init")] internal static partial int SodiumInit(); @@ -68,7 +68,7 @@ internal static IReadOnlyList GetMissingLibraryImports(IntPtr libHandle, { // Use EntryPoint if defined, otherwise fallback to method name. string exportName = item.EntryPoint ?? item.Method.Name; - string importSig = $"{item.Method.ReturnType.Name} {item.Method.DeclaringType!.FullName}.{item.Method.Name}({string.Join(", ", item.Method.GetParameters().Select(p => $"{p.ParameterType.Name} {p.Name}"))})"; + string importSig = $"{item.Method.ReturnType.Name} {item.Method.DeclaringType!.FullName}.{item.Method.Name}({string.Join(", ", item.Method.GetParameters().Select(p => $"{p.ParameterType.Name} {p.Name}"))})"; if (!NativeLibrary.TryGetExport(libHandle, exportName, out _)) { From db8af6562c14f2642d69e579ffcf9abf45048a5f Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Tue, 23 Jun 2026 11:28:51 +0200 Subject: [PATCH 043/101] Add Nix cache to CI --- .github/workflows/build-natives.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index f08f0c5ac..4be0ec8fd 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -114,6 +114,10 @@ jobs: if: ${{ matrix.use-nix }} uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6 + - name: Magic Nix Cache + if: ${{ matrix.use-nix && matrix.musl }} + uses: DeterminateSystems/magic-nix-cache-action@908b263ff629f4cc17666315b7fd3ec127c6244d # v14 + - name: Setup vcpkg cache directories (Windows) if: ${{ !matrix.use-nix }} run: | From bcc951906bad082fb847a8a066c60fb9bfca403d Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Tue, 23 Jun 2026 20:32:54 +0900 Subject: [PATCH 044/101] Rearrange targets * fix publish natives dll from being copied when nativeaot * update the test accordingly --- .../Assets/NativeAotApp/NativeAotApp.csproj | 6 +-- .../NativesBuildTests.cs | 52 ++++++++++++++++--- .../NetCord.Natives.local.targets | 12 ++++- Natives/NetCord.Natives/NetCord.Natives.props | 2 +- .../NetCord.Natives/NetCord.Natives.targets | 46 ++++++++-------- 5 files changed, 81 insertions(+), 37 deletions(-) diff --git a/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj b/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj index 373216258..af12d4605 100644 --- a/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj +++ b/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj @@ -19,7 +19,7 @@ true - + @@ -38,10 +38,6 @@ - - libdave;libsodium;opus;zstd - - diff --git a/Natives/NetCord.Natives.Tests/NativesBuildTests.cs b/Natives/NetCord.Natives.Tests/NativesBuildTests.cs index 791f988ca..030279b20 100644 --- a/Natives/NetCord.Natives.Tests/NativesBuildTests.cs +++ b/Natives/NetCord.Natives.Tests/NativesBuildTests.cs @@ -42,7 +42,7 @@ public void AllLibraryImportsExistInBinary(string libName) [DoNotParallelize] [TestMethod] [DataRow("libdave;libsodium;opus;zstd")] - public void NativeAotStaticLinking(string libName) + public void NativeAotStaticLinking(string libNames) { var projectDirectory = Path.Combine(AppContext.BaseDirectory, "Assets", "NativeAotApp"); var projectFile = Path.Combine(projectDirectory, "NativeAotApp.csproj"); @@ -95,9 +95,10 @@ public void NativeAotStaticLinking(string libName) var ok = buildProcess.Start(); buildProcess.BeginOutputReadLine(); buildProcess.BeginErrorReadLine(); - buildProcess.WaitForExit(); + if (!buildProcess.HasExited) + buildProcess.WaitForExit(); - Assert.AreEqual(0, buildProcess.ExitCode, $"Native AoT build failed for '{libName}'."); + Assert.AreEqual(0, buildProcess.ExitCode, $"Native AoT build failed for '{libNames}'."); // Obtain the generated RunCommand from a build so we launch the same command the SDK would. var getRunCmd = new System.Diagnostics.Process(); @@ -135,14 +136,48 @@ public void NativeAotStaticLinking(string libName) getRunCmd.Start(); getRunCmd.BeginErrorReadLine(); getRunCmd.BeginOutputReadLine(); - getRunCmd.WaitForExit(); + if (!getRunCmd.HasExited) + getRunCmd.WaitForExit(); - Assert.AreEqual(0, getRunCmd.ExitCode, $"Failed to obtain PublishDir for '{libName}'."); - Assert.IsFalse(string.IsNullOrEmpty(runCmdOutput), $"PublishDir is empty for '{libName}'."); + Assert.AreEqual(0, getRunCmd.ExitCode, $"Failed to obtain PublishDir for '{libNames}'."); + Assert.IsFalse(string.IsNullOrEmpty(runCmdOutput), $"PublishDir is empty for '{libNames}'."); runCmdOutput = Path.Combine(projectDirectory, runCmdOutput, "NativeAotApp" + (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : "")); + var libs = libNames.Split([';',','], StringSplitOptions.RemoveEmptyEntries).Select(l => l.Trim()); + List deps = []; + + foreach (var lib in libs) + { + switch (lib) + { + case "libdave": + deps.AddRange([lib, "crypto"]); + break; + case "libsodium": + case "opus": + case "zstd": + deps.Add(lib); + break; + default: + throw new InvalidOperationException($"Unknown library name '{lib}' provided to test."); + } + } + + var copiedDlls = Directory.GetFiles(Path.GetDirectoryName(runCmdOutput) ?? string.Empty, + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "*.dll" : + RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? "lib*.so" : "lib*.dylib", + SearchOption.TopDirectoryOnly) + .Select(f => Path.GetFileName(f)); + + var matchCopied = copiedDlls.Where(dll => deps.Any(lib => + dll.StartsWith(lib, StringComparison.OrdinalIgnoreCase) || + dll.StartsWith($"lib{lib}", StringComparison.OrdinalIgnoreCase) + )); + + Assert.IsEmpty(matchCopied, $"These should've not been copied to the publish output directory: {string.Join(", ", matchCopied)}"); + // check that the library is running without errors, which indicates that it was statically linked successfully var aotProcess = new System.Diagnostics.Process(); aotProcess.StartInfo.FileName = runCmdOutput; @@ -165,8 +200,9 @@ public void NativeAotStaticLinking(string libName) aotProcess.Start(); aotProcess.BeginOutputReadLine(); aotProcess.BeginErrorReadLine(); - aotProcess.WaitForExit(); + if (!aotProcess.HasExited) + aotProcess.WaitForExit(); - Assert.AreEqual(0, aotProcess.ExitCode, $"Native AoT app failed to run for '{libName}'."); + Assert.AreEqual(0, aotProcess.ExitCode, $"Native AoT app failed to run for '{libNames}'."); } } diff --git a/Natives/NetCord.Natives/NetCord.Natives.local.targets b/Natives/NetCord.Natives/NetCord.Natives.local.targets index ab66f1de6..3fab9fbb6 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.local.targets +++ b/Natives/NetCord.Natives/NetCord.Natives.local.targets @@ -2,7 +2,7 @@ - + + + + + + + +
diff --git a/Natives/NetCord.Natives/NetCord.Natives.props b/Natives/NetCord.Natives/NetCord.Natives.props index ec6964832..fcfe954c0 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.props +++ b/Natives/NetCord.Natives/NetCord.Natives.props @@ -9,7 +9,7 @@ --> - $(MSBuildThisFileDirectory)..\runtimes\$(RuntimeIdentifier) + $(MSBuildThisFileDirectory)..\runtimes\$(RuntimeIdentifier)\native $(MSBuildThisFileDirectory)..\staticlibs\$(RuntimeIdentifier) diff --git a/Natives/NetCord.Natives/NetCord.Natives.targets b/Natives/NetCord.Natives/NetCord.Natives.targets index dd36c7326..2f8f19934 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.targets +++ b/Natives/NetCord.Natives/NetCord.Natives.targets @@ -1,8 +1,6 @@ - - + @@ -26,9 +24,30 @@ - + <_NetCordExcluded Include="$(NetCordExcludeNatives)" + Condition="'$(NetCordExcludeNatives)' != ''" /> + <_NetCordExcluded Include="libcrypto" + Condition="$(NetCordExcludeNatives.Contains('libdave'))" /> + + <_NetCordExcluded Include="@(_NetCordStaticLink)" + Condition="'$(PublishAot)' == 'true' and '%(_NetCordStaticLink.Identity)' != ''"/> + + <_RunExclude Include="$(NetCordNativesRuntimesDir)\%(_NetCordExcluded.Identity)*.*" + Condition="'%(_NetCordExcluded.Identity)' != '' and '$(NetCordNativesRuntimesDir)' != ''" /> + <_RunExclude Include="$(NetCordNativesRuntimesDir)\lib%(_NetCordExcluded.Identity)*.*" + Condition="'%(_NetCordExcluded.Identity)' != '' and '$(NetCordNativesRuntimesDir)' != ''" /> + + + + + + + + - - <_NetCordExcluded Include="$(NetCordExcludeNatives)" - Condition="'$(NetCordExcludeNatives)' != ''" /> - <_NetCordExcluded Include="libcrypto" - Condition="$(NetCordExcludeNatives.Contains('libdave'))" /> - - <_NetCordExcluded Include="@(_NetCordStaticLink)" - Condition="'$(PublishAot)' == 'true' and '%(_NetCordStaticLink.Identity)' != ''"/> - - <_RunExclude Include="$(NetCordNativesRuntimesDir)\**\native\%(_NetCordExcluded.Identity)*.*" - Condition="'@(_NetCordExcluded.Identity)' != '' and '$(NetCordNativesRuntimesDir)' != ''" /> - <_RunExclude Include="$(NetCordNativesRuntimesDir)\**\native\lib%(_NetCordExcluded.Identity)*.*" - Condition="'@(_NetCordExcluded.Identity)' != '' and '$(NetCordNativesRuntimesDir)' != ''" /> - @@ -83,10 +89,6 @@ - - From 56e5860fee63e7d7880bc3e088c777a598c32443 Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Tue, 23 Jun 2026 22:25:23 +0900 Subject: [PATCH 045/101] [skip ci] Test NativeAOT publish using MSBuild API --- Directory.Packages.props | 2 + Natives/NetCord.Natives.Tests/AssemblyInfo.cs | 1 - .../NativesBuildTests.cs | 160 ++++++++---------- .../NetCord.Natives.Tests.csproj | 2 + 4 files changed, 75 insertions(+), 90 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 286810234..4fd34170a 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -24,6 +24,8 @@ + + diff --git a/Natives/NetCord.Natives.Tests/AssemblyInfo.cs b/Natives/NetCord.Natives.Tests/AssemblyInfo.cs index ae411c7a1..ab8dcc1e1 100644 --- a/Natives/NetCord.Natives.Tests/AssemblyInfo.cs +++ b/Natives/NetCord.Natives.Tests/AssemblyInfo.cs @@ -1,3 +1,2 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; [assembly: Parallelize(Scope = ExecutionScope.MethodLevel)] diff --git a/Natives/NetCord.Natives.Tests/NativesBuildTests.cs b/Natives/NetCord.Natives.Tests/NativesBuildTests.cs index 030279b20..3508b9da4 100644 --- a/Natives/NetCord.Natives.Tests/NativesBuildTests.cs +++ b/Natives/NetCord.Natives.Tests/NativesBuildTests.cs @@ -1,6 +1,12 @@ using System.Diagnostics; using System.Reflection; using System.Runtime.InteropServices; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Microsoft.Build.Evaluation; +using Microsoft.Build.Execution; +using Microsoft.Build.Framework; +using Microsoft.Build.Locator; +using Microsoft.Build.Logging; namespace NetCord.Natives.Tests; @@ -39,114 +45,87 @@ public void AllLibraryImportsExistInBinary(string libName) } const string NativeAotAppLogTag = nameof(NativeAotStaticLinking); - [DoNotParallelize] [TestMethod] [DataRow("libdave;libsodium;opus;zstd")] public void NativeAotStaticLinking(string libNames) + { + MSBuildLocator.RegisterDefaults(); + MSBuildNativeAotPublish(libNames); + } + + private static void MSBuildNativeAotPublish(string libNames) { var projectDirectory = Path.Combine(AppContext.BaseDirectory, "Assets", "NativeAotApp"); var projectFile = Path.Combine(projectDirectory, "NativeAotApp.csproj"); - var generatedProjectFile = Path.Combine(projectDirectory, "NativeAotApp.g.csproj"); - // get properties to be passed to the NativeAotApp build from AssemblyMetadata attribute + // 1. Get properties from AssemblyMetadata attributes var assembly = typeof(NativesBuildTests).Assembly; - var properties = assembly.GetCustomAttributes()? - .FirstOrDefault(a => a.Key == "NativeAotAppProps")? - .Value?.Split([';', ','], StringSplitOptions.RemoveEmptyEntries).Select(p => $"-p:{p.Trim()}"); - Assert.IsNotNull(properties, "NativeAotAppProps metadata attribute is not defined."); + var propsAttr = assembly.GetCustomAttributes() + .FirstOrDefault(a => a.Key == "NativeAotAppProps")?.Value; + Assert.IsNotNull(propsAttr, "NativeAotAppProps metadata attribute is not defined."); - var binlogpath = assembly.GetCustomAttributes()? - .FirstOrDefault(a => a.Key == "NativeAotBinLogPath")?.Value; + var binlogpath = assembly.GetCustomAttributes() + .FirstOrDefault(a => a.Key == "NativeAotBinLogPath")?.Value; var configuration = assembly.GetCustomAttribute()?.Configuration ?? "Debug"; - // build asset NativeAotApp with Native AoT enabled - var buildProcess = new System.Diagnostics.Process(); - buildProcess.StartInfo.FileName = "dotnet"; - buildProcess.StartInfo.ArgumentList.Add("publish"); - buildProcess.StartInfo.ArgumentList.Add("NativeAotApp.csproj"); - buildProcess.StartInfo.ArgumentList.Add("-c"); - buildProcess.StartInfo.ArgumentList.Add(configuration); - buildProcess.StartInfo.ArgumentList.Add("-tl:off"); - buildProcess.StartInfo.ArgumentList.Add("-v:n"); - buildProcess.StartInfo.ArgumentList.Add("-nodeReuse:false"); - - if (!string.IsNullOrEmpty(binlogpath)) - buildProcess.StartInfo.ArgumentList.Add($"-bl:{binlogpath}"); - foreach (var property in properties) - buildProcess.StartInfo.ArgumentList.Add(property); - - Console.WriteLine($"[{NativeAotAppLogTag}/Publish] Building Native AoT app in ({projectDirectory}): 'dotnet {buildProcess.StartInfo.ArgumentList.Aggregate((a, b) => $"{a} {b}")}'"); - - buildProcess.StartInfo.WorkingDirectory = projectDirectory; - buildProcess.StartInfo.RedirectStandardOutput = true; - buildProcess.OutputDataReceived += (sender, e) => + // 2. Parse MSBuild Global Properties into a Dictionary + var globalProperties = new Dictionary { - if (!string.IsNullOrEmpty(e.Data)) - Console.WriteLine($"[{NativeAotAppLogTag}/Publish] {e.Data}"); - }; - buildProcess.StartInfo.RedirectStandardError = true; - buildProcess.ErrorDataReceived += (sender, e) => - { - if (!string.IsNullOrEmpty(e.Data)) - Console.Error.WriteLine($"[{NativeAotAppLogTag}/Publish] {e.Data}"); + { "Configuration", configuration } }; - var ok = buildProcess.Start(); - buildProcess.BeginOutputReadLine(); - buildProcess.BeginErrorReadLine(); - if (!buildProcess.HasExited) - buildProcess.WaitForExit(); - - Assert.AreEqual(0, buildProcess.ExitCode, $"Native AoT build failed for '{libNames}'."); - - // Obtain the generated RunCommand from a build so we launch the same command the SDK would. - var getRunCmd = new System.Diagnostics.Process(); - getRunCmd.StartInfo.FileName = "dotnet"; - getRunCmd.StartInfo.ArgumentList.Add("build"); - getRunCmd.StartInfo.ArgumentList.Add("NativeAotApp.csproj"); - getRunCmd.StartInfo.ArgumentList.Add("-c"); - getRunCmd.StartInfo.ArgumentList.Add(configuration); - getRunCmd.StartInfo.ArgumentList.Add("-t:GetTargetPath"); - getRunCmd.StartInfo.ArgumentList.Add("-getProperty:PublishDir"); - getRunCmd.StartInfo.ArgumentList.Add("--no-restore"); - getRunCmd.StartInfo.ArgumentList.Add("-nodeReuse:false"); - - foreach (var property in properties) - getRunCmd.StartInfo.ArgumentList.Add(property); - - string? runCmdOutput = null; - - getRunCmd.StartInfo.WorkingDirectory = projectDirectory; - getRunCmd.StartInfo.RedirectStandardOutput = true; - getRunCmd.OutputDataReceived += (sender, e) => + + var pairs = propsAttr.Split([';', ','], StringSplitOptions.RemoveEmptyEntries); + foreach (var pair in pairs) { - if (!string.IsNullOrEmpty(e.Data)) + var kvp = pair.Split('='); + if (kvp.Length == 2) { - Console.WriteLine($"[{NativeAotAppLogTag}/GetRunCmd] {e.Data}"); - runCmdOutput = e.Data.Trim('\r', '\n', '"'); + globalProperties[kvp[0].Trim()] = kvp[1].Trim(); } + } + + // 3. Set up Loggers (Console + optional Binary Logger) + var loggers = new List + { + new ConsoleLogger(LoggerVerbosity.Normal, msg => Console.WriteLine($"[{NativeAotAppLogTag}/Publish] {msg.Trim()}"), null, null) }; - getRunCmd.StartInfo.RedirectStandardError = true; - getRunCmd.ErrorDataReceived += (sender, e) => + + if (!string.IsNullOrEmpty(binlogpath)) { - if (!string.IsNullOrEmpty(e.Data)) - Console.Error.WriteLine($"[{NativeAotAppLogTag}/GetRunCmd] {e.Data}"); + loggers.Add(new BinaryLogger { Parameters = binlogpath }); + } + + // 4. Evaluate and Execute the "Publish" target programmatically + Console.WriteLine($"[{NativeAotAppLogTag}/Publish] Building Native AoT app in ({projectDirectory}) via MSBuild API..."); + + using var projectCollection = new ProjectCollection(); + var projectInstance = new ProjectInstance(projectFile, globalProperties, null, projectCollection); + + var buildParameters = new BuildParameters + { + Loggers = loggers, + EnableNodeReuse = false, }; - getRunCmd.Start(); - getRunCmd.BeginErrorReadLine(); - getRunCmd.BeginOutputReadLine(); - if (!getRunCmd.HasExited) - getRunCmd.WaitForExit(); + var buildRequest = new BuildRequestData(projectInstance, ["Publish"]); + + var buildResult = BuildManager.DefaultBuildManager.Build(buildParameters, buildRequest); - Assert.AreEqual(0, getRunCmd.ExitCode, $"Failed to obtain PublishDir for '{libNames}'."); - Assert.IsFalse(string.IsNullOrEmpty(runCmdOutput), $"PublishDir is empty for '{libNames}'."); + // Assert build success + Assert.AreEqual(BuildResultCode.Success, buildResult.OverallResult, $"Native AoT build failed for '{libNames}'."); - runCmdOutput = Path.Combine(projectDirectory, runCmdOutput, - "NativeAotApp" + (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : "")); + // 5. Instantly extract the 'PublishDir' property from the evaluated project state + // (This replaces the entire second "dotnet build -getProperty" process call!) + var publishDirProperty = projectInstance.GetPropertyValue("PublishDir"); + Assert.IsFalse(string.IsNullOrEmpty(publishDirProperty), $"PublishDir is empty for '{libNames}'."); - var libs = libNames.Split([';',','], StringSplitOptions.RemoveEmptyEntries).Select(l => l.Trim()); - List deps = []; + var runCmdOutput = Path.GetFullPath(Path.Combine(projectDirectory, publishDirProperty, + "NativeAotApp" + (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : ""))); + + // 6. Assertions on copied native binaries + var libs = libNames.Split([';', ','], StringSplitOptions.RemoveEmptyEntries).Select(l => l.Trim()); + var deps = new List(); foreach (var lib in libs) { @@ -169,16 +148,17 @@ public void NativeAotStaticLinking(string libNames) RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "*.dll" : RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? "lib*.so" : "lib*.dylib", SearchOption.TopDirectoryOnly) - .Select(f => Path.GetFileName(f)); + .Select(Path.GetFileName); - var matchCopied = copiedDlls.Where(dll => deps.Any(lib => + var matchCopied = copiedDlls.Where(dll => dll != null && deps.Any(lib => dll.StartsWith(lib, StringComparison.OrdinalIgnoreCase) || - dll.StartsWith($"lib{lib}", StringComparison.OrdinalIgnoreCase) - )); + dll.StartsWith($"lib{lib}", StringComparison.OrdinalIgnoreCase))) + .ToList(); Assert.IsEmpty(matchCopied, $"These should've not been copied to the publish output directory: {string.Join(", ", matchCopied)}"); - // check that the library is running without errors, which indicates that it was statically linked successfully + // 7. Execute the generated Native AOT Binary + // NOTE: Running the compiled native application still requires System.Diagnostics.Process var aotProcess = new System.Diagnostics.Process(); aotProcess.StartInfo.FileName = runCmdOutput; aotProcess.StartInfo.WorkingDirectory = Path.GetDirectoryName(runCmdOutput); @@ -197,9 +177,11 @@ public void NativeAotStaticLinking(string libNames) if (!string.IsNullOrEmpty(e.Data)) Console.Error.WriteLine($"[{NativeAotAppLogTag}/Run] {e.Data}"); }; + aotProcess.Start(); aotProcess.BeginOutputReadLine(); aotProcess.BeginErrorReadLine(); + if (!aotProcess.HasExited) aotProcess.WaitForExit(); diff --git a/Natives/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj b/Natives/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj index 7f4e4ac74..130de3339 100644 --- a/Natives/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj +++ b/Natives/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj @@ -27,6 +27,8 @@ + + From ab030df8394048c085d30921e319423592321951 Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Thu, 25 Jun 2026 10:57:52 +0900 Subject: [PATCH 046/101] Rearrange natives test s --- .../Assets => Tests}/NativeAotApp/NativeAotApp.csproj | 0 .../Assets => Tests}/NativeAotApp/Program.cs | 0 Natives/{NetCord.Natives.Tests => Tests}/NativeProbes.cs | 0 Natives/{ => Tests}/NetCord.Natives.Tests/AssemblyInfo.cs | 0 Natives/{ => Tests}/NetCord.Natives.Tests/NativesBuildTests.cs | 0 .../NetCord.Natives.Tests/NetCord.Natives.Tests.csproj | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename Natives/{NetCord.Natives.Tests/Assets => Tests}/NativeAotApp/NativeAotApp.csproj (100%) rename Natives/{NetCord.Natives.Tests/Assets => Tests}/NativeAotApp/Program.cs (100%) rename Natives/{NetCord.Natives.Tests => Tests}/NativeProbes.cs (100%) rename Natives/{ => Tests}/NetCord.Natives.Tests/AssemblyInfo.cs (100%) rename Natives/{ => Tests}/NetCord.Natives.Tests/NativesBuildTests.cs (100%) rename Natives/{ => Tests}/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj (100%) diff --git a/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj b/Natives/Tests/NativeAotApp/NativeAotApp.csproj similarity index 100% rename from Natives/NetCord.Natives.Tests/Assets/NativeAotApp/NativeAotApp.csproj rename to Natives/Tests/NativeAotApp/NativeAotApp.csproj diff --git a/Natives/NetCord.Natives.Tests/Assets/NativeAotApp/Program.cs b/Natives/Tests/NativeAotApp/Program.cs similarity index 100% rename from Natives/NetCord.Natives.Tests/Assets/NativeAotApp/Program.cs rename to Natives/Tests/NativeAotApp/Program.cs diff --git a/Natives/NetCord.Natives.Tests/NativeProbes.cs b/Natives/Tests/NativeProbes.cs similarity index 100% rename from Natives/NetCord.Natives.Tests/NativeProbes.cs rename to Natives/Tests/NativeProbes.cs diff --git a/Natives/NetCord.Natives.Tests/AssemblyInfo.cs b/Natives/Tests/NetCord.Natives.Tests/AssemblyInfo.cs similarity index 100% rename from Natives/NetCord.Natives.Tests/AssemblyInfo.cs rename to Natives/Tests/NetCord.Natives.Tests/AssemblyInfo.cs diff --git a/Natives/NetCord.Natives.Tests/NativesBuildTests.cs b/Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs similarity index 100% rename from Natives/NetCord.Natives.Tests/NativesBuildTests.cs rename to Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs diff --git a/Natives/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj b/Natives/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj similarity index 100% rename from Natives/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj rename to Natives/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj From eec7ae3e35d081945998ede815485df8ae9fc49c Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Thu, 25 Jun 2026 11:23:20 +0900 Subject: [PATCH 047/101] Remove musl triplets since already overriden via cross compiler & nix * fix natives test paths * pull bootstrap vcpkg out of msbuild * remove vcpkg download, workflow caches binary sources only * pack libssl --- .github/workflows/build-natives.yml | 10 ++-- Natives/NetCord.Natives.slnx | 4 +- .../NetCord.Natives/NetCord.Natives.csproj | 52 +++++++++---------- .../NetCord.Natives/NetCord.Natives.targets | 2 +- .../triplets/x64-linux-musl-dynamic.cmake | 4 -- .../triplets/x64-linux-musl.cmake | 4 -- .../Tests/NativeAotApp/NativeAotApp.csproj | 4 +- .../NativesBuildTests.cs | 17 ++++-- .../NetCord.Natives.Tests.csproj | 18 ++++--- flake.nix | 2 - 10 files changed, 58 insertions(+), 59 deletions(-) delete mode 100644 Natives/NetCord.Natives/triplets/x64-linux-musl-dynamic.cmake delete mode 100644 Natives/NetCord.Natives/triplets/x64-linux-musl.cmake diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index 4be0ec8fd..cb4f84de6 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -118,24 +118,25 @@ jobs: if: ${{ matrix.use-nix && matrix.musl }} uses: DeterminateSystems/magic-nix-cache-action@908b263ff629f4cc17666315b7fd3ec127c6244d # v14 - - name: Setup vcpkg cache directories (Windows) + - name: Setup vcpkg (Windows) if: ${{ !matrix.use-nix }} run: | New-Item -ItemType Directory -Path $env:VCPKG_BINARY_SOURCES.Split(',')[1] -Force | Out-Null New-Item -ItemType Directory -Path $env:VCPKG_DOWNLOADS -Force | Out-Null + $VCPKG_ROOT/vcpkg/bootstrap-vcpkg.bat - - name: Setup vcpkg cache directories (Nix) + - name: Setup vcpkg (Nix) if: ${{ matrix.use-nix }} run: | mkdir -p "${VCPKG_BINARY_SOURCES#*,}" mkdir -p "${VCPKG_DOWNLOADS}" + $VCPKG_ROOT/vcpkg/bootstrap-vcpkg.sh - name: Restore vcpkg cache uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: path: | .vcpkg-cache - .vcpkg-downloads # Unique key per run key: vcpkg-${{ runner.os }}-${{ matrix.rid }}-${{ hashFiles('Natives/NetCord.Natives/vcpkg.json', 'Natives/NetCord.Natives/natives-ports/**') }} # Fallback keys to grab the latest previous cache @@ -177,7 +178,7 @@ jobs: --no-restore --no-build -v ${{ env.DotnetVerbose }} - ${{ env.GenerateBinLog == 'true' && '-bl:test.binlog' || '' }} + ${{ env.GenerateBinLog == 'true' && '-bl:test.binlog -p:NativeAotBinLogPath="$PWD/nativeaotapptest.binlog"' || '' }} --logger "console;verbosity=detailed" --logger GitHubActions ${{ matrix.vcpkg-os-target == 'osx' && '-p:InvariantGlobalization=true' || '' }} @@ -216,6 +217,5 @@ jobs: with: path: | .vcpkg-cache - .vcpkg-downloads # Must match the unique key from the restore step key: vcpkg-${{ runner.os }}-${{ matrix.rid }}-${{ hashFiles('Natives/NetCord.Natives/vcpkg.json', 'Natives/NetCord.Natives/natives-ports/**') }} diff --git a/Natives/NetCord.Natives.slnx b/Natives/NetCord.Natives.slnx index 48c64d326..1c7166ef8 100644 --- a/Natives/NetCord.Natives.slnx +++ b/Natives/NetCord.Natives.slnx @@ -19,8 +19,8 @@ - - + + diff --git a/Natives/NetCord.Natives/NetCord.Natives.csproj b/Natives/NetCord.Natives/NetCord.Natives.csproj index 6e564e9ac..bcdaabdfa 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.csproj +++ b/Natives/NetCord.Natives/NetCord.Natives.csproj @@ -23,26 +23,23 @@ debug bin - + $(VCPKG_ROOT) $(VcpkgRoot)\scripts\buildsystems\msbuild\vcpkg Release true - false - - true - windows osx - linux-musl linux $(VcpkgOSTarget) win + $(VcpkgBuildOS)-musl + false @@ -62,15 +59,15 @@ - + - + <_VcpkgRelatedFile Include="native-ports\**" /> - + <_StaticFullPath Include="$([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)\$(VcpkgOutputPath_Static)'))" /> @@ -80,25 +77,17 @@ - - - - - - - - - + + $(VcpkgPlatformTarget)-$(VcpkgOSTarget) $(VcpkgTriplet)-dynamic - + <_ZVcpkgMSBuildStampFile>$(_ZVcpkgInstalledDir).msbuildstamp-$(VcpkgTriplet).$(_ZVcpkgHostTripletSuffix)stamp @@ -122,9 +111,10 @@ so - <_BuiltRid Include="linux-musl-%(_LibArchs.Identity)"> - %(_LibArchs.Identity)-linux-musl-dynamic\lib\lib%(_LibArchs.LibName) - %(_LibArchs.Identity)-linux-musl\lib\lib%(_LibArchs.LibName) + <_BuiltRid Include="linux-musl-%(_LibArchs.Identity)" + Condition="'$(VcpkgBuildOS)' == 'linux-musl'"> + %(_LibArchs.Identity)-linux-dynamic\lib\lib%(_LibArchs.LibName) + %(_LibArchs.Identity)-linux\lib\lib%(_LibArchs.LibName) so @@ -138,6 +128,14 @@ + + + + + + @@ -173,7 +171,7 @@ $(PackageDescription) (Includes: @(_VcpkgPkg->'%(Identity) v%(Version)', ', ')) - + @@ -263,11 +261,11 @@ staticlibs\%(_BuiltRid.Identity)\ - + <_SymlinksToRemoveBuilt Include="@(NativesBuilt)" Condition="Exists('%(FullPath)') and ($([MSBuild]::BitwiseAnd($([System.IO.File]::GetAttributes('%(FullPath)')), 1024)) == 1024)" /> - + true @@ -289,7 +287,7 @@ - + diff --git a/Natives/NetCord.Natives/NetCord.Natives.targets b/Natives/NetCord.Natives/NetCord.Natives.targets index 2f8f19934..d4a1a1faa 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.targets +++ b/Natives/NetCord.Natives/NetCord.Natives.targets @@ -18,7 +18,7 @@ Condition="'%(DirectPInvoke.Identity)' == 'opus' or '%(DirectPInvoke.Identity)' == 'zstd'" /> - <_NetCordStaticLink Include="libcrypto;crypto" + <_NetCordStaticLink Include="libcrypto;crypto;libssl;ssl" Condition="'%(DirectPInvoke.Identity)' == 'libdave'" /> diff --git a/Natives/NetCord.Natives/triplets/x64-linux-musl-dynamic.cmake b/Natives/NetCord.Natives/triplets/x64-linux-musl-dynamic.cmake deleted file mode 100644 index b6f5fc5fc..000000000 --- a/Natives/NetCord.Natives/triplets/x64-linux-musl-dynamic.cmake +++ /dev/null @@ -1,4 +0,0 @@ -set(VCPKG_TARGET_ARCHITECTURE x64) -set(VCPKG_CRT_LINKAGE dynamic) -set(VCPKG_LIBRARY_LINKAGE dynamic) -set(VCPKG_CMAKE_SYSTEM_NAME Linux) diff --git a/Natives/NetCord.Natives/triplets/x64-linux-musl.cmake b/Natives/NetCord.Natives/triplets/x64-linux-musl.cmake deleted file mode 100644 index 8361f30d4..000000000 --- a/Natives/NetCord.Natives/triplets/x64-linux-musl.cmake +++ /dev/null @@ -1,4 +0,0 @@ -set(VCPKG_TARGET_ARCHITECTURE x64) -set(VCPKG_CRT_LINKAGE static) -set(VCPKG_LIBRARY_LINKAGE static) -set(VCPKG_CMAKE_SYSTEM_NAME Linux) diff --git a/Natives/Tests/NativeAotApp/NativeAotApp.csproj b/Natives/Tests/NativeAotApp/NativeAotApp.csproj index af12d4605..7f73b4cb6 100644 --- a/Natives/Tests/NativeAotApp/NativeAotApp.csproj +++ b/Natives/Tests/NativeAotApp/NativeAotApp.csproj @@ -12,7 +12,7 @@ true true - ..\..\..\NetCord.Natives + ..\..\NetCord.Natives @@ -26,7 +26,7 @@ - + diff --git a/Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs b/Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs index 3508b9da4..01e04d377 100644 --- a/Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs +++ b/Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs @@ -55,15 +55,17 @@ public void NativeAotStaticLinking(string libNames) private static void MSBuildNativeAotPublish(string libNames) { - var projectDirectory = Path.Combine(AppContext.BaseDirectory, "Assets", "NativeAotApp"); - var projectFile = Path.Combine(projectDirectory, "NativeAotApp.csproj"); - // 1. Get properties from AssemblyMetadata attributes var assembly = typeof(NativesBuildTests).Assembly; + var projectDirectory = assembly.GetCustomAttributes() + .FirstOrDefault(a => a.Key == "NativeAotAppDir")?.Value; + Assert.IsNotNull(projectDirectory, "NativeAotAppDir metadata attribute is not defined."); + + var projectFile = Path.Combine(projectDirectory, "NativeAotApp.csproj"); + var propsAttr = assembly.GetCustomAttributes() .FirstOrDefault(a => a.Key == "NativeAotAppProps")?.Value; - Assert.IsNotNull(propsAttr, "NativeAotAppProps metadata attribute is not defined."); var binlogpath = assembly.GetCustomAttributes() .FirstOrDefault(a => a.Key == "NativeAotBinLogPath")?.Value; @@ -76,7 +78,7 @@ private static void MSBuildNativeAotPublish(string libNames) { "Configuration", configuration } }; - var pairs = propsAttr.Split([';', ','], StringSplitOptions.RemoveEmptyEntries); + var pairs = propsAttr?.Split([';', ','], StringSplitOptions.RemoveEmptyEntries) ?? []; foreach (var pair in pairs) { var kvp = pair.Split('='); @@ -120,9 +122,14 @@ private static void MSBuildNativeAotPublish(string libNames) var publishDirProperty = projectInstance.GetPropertyValue("PublishDir"); Assert.IsFalse(string.IsNullOrEmpty(publishDirProperty), $"PublishDir is empty for '{libNames}'."); + // sanitize back-slash + publishDirProperty = publishDirProperty.Replace('\\', Path.DirectorySeparatorChar); + var runCmdOutput = Path.GetFullPath(Path.Combine(projectDirectory, publishDirProperty, "NativeAotApp" + (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : ""))); + Console.WriteLine($"[{NativeAotAppLogTag}/Publish] Native AoT app published to: '{runCmdOutput}'"); + // 6. Assertions on copied native binaries var libs = libNames.Split([';', ','], StringSplitOptions.RemoveEmptyEntries).Select(l => l.Trim()); var deps = new List(); diff --git a/Natives/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj b/Natives/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj index 130de3339..32d744637 100644 --- a/Natives/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj +++ b/Natives/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj @@ -11,11 +11,7 @@ - - - - + @@ -32,7 +28,7 @@ - ..\NetCord.Natives\ + ..\..\NetCord.Natives\ NetCordNativesDir=$([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)\$(NetCordNativesDir)')) $(VCPKG_ROOT) @@ -40,9 +36,17 @@ $(NativeAotAppProps);$(AppendNativeAotAppProps) + - + + + + + + <_Parameter1>NativeAotAppDir + <_Parameter2>$([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)/../NativeAotApp')) + <_Parameter1>NativeAotAppProps <_Parameter2>$(NativeAotAppProps) diff --git a/flake.nix b/flake.nix index b32f4aae2..67083f5e9 100644 --- a/flake.nix +++ b/flake.nix @@ -102,8 +102,6 @@ TARGET_MUSL = "true"; - VCPKG_OVERLAY_TRIPLETS="${toString ./.}/Natives/NetCord.Natives/triplets"; - VCPKG_FORCE_SYSTEM_BINARIES = "1"; shellHook = '' From af15eee8eadd3b14cb15e84d242289777e11856c Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Tue, 23 Jun 2026 22:45:02 +0200 Subject: [PATCH 048/101] Pass Configuration env variable to musl tests --- .github/workflows/build-natives.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index cb4f84de6..9e6248a28 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -173,7 +173,7 @@ jobs: - name: Test natives outputs for ${{ matrix.rid }} run: > - ${{ matrix.musl && 'docker run --rm -v $PWD:$PWD -w $PWD -e VCPKG_ROOT -e TARGET_MUSL -e MINVERVERSIONOVERRIDE=1.0.0 mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot' || '' }} + ${{ matrix.musl && 'docker run --rm -v $PWD:$PWD -w $PWD -e Configuration -e VCPKG_ROOT -e TARGET_MUSL -e MINVERVERSIONOVERRIDE=1.0.0 mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot' || '' }} dotnet test Natives/NetCord.Natives.slnx --no-restore --no-build From 762d6625911f55ef8de6dc4c1996b231a586f3b1 Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Wed, 24 Jun 2026 02:06:19 +0200 Subject: [PATCH 049/101] Set max-jobs and cores to 2 for linux arm64 runner building for musl --- .github/workflows/build-natives.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index 9e6248a28..d6b97035f 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -83,7 +83,7 @@ jobs: vcpkg-os-target: linux vcpkg-platform-target: arm64 use-nix: true - shell_command: nix develop .#natives-musl -c bash -eo pipefail {0} + shell_command: nix develop .#natives-musl --option max-jobs 2 --option cores 2 -c bash -eo pipefail {0} musl: true runs-on: ${{ matrix.runs-on }} From e40f8bde943dae5c288086aadc036b2f037b12dc Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Wed, 24 Jun 2026 13:22:46 +0200 Subject: [PATCH 050/101] Add missing packages to flake.nix --- flake.nix | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/flake.nix b/flake.nix index 67083f5e9..bae7ddba4 100644 --- a/flake.nix +++ b/flake.nix @@ -69,6 +69,11 @@ pkgs.autoconf-archive pkgs.automake pkgs.libtool + pkgs.git + pkgs.zip + pkgs.unzip + pkgs.perl + pkgs.curl ] ++ darwinPackages; DOTNET_ROOT = dotnetRoot; @@ -96,6 +101,11 @@ pkgs.autoconf-archive pkgs.automake pkgs.libtool + pkgs.git + pkgs.zip + pkgs.unzip + pkgs.perl + pkgs.curl ] ++ darwinPackages; DOTNET_ROOT = dotnetRoot; From 29457ecf8393f8075e2fc467009a2e1cddd853b3 Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Mon, 22 Jun 2026 20:42:23 +0200 Subject: [PATCH 051/101] Add x64 musl build --- Natives/NetCord.Natives/NetCord.Natives.csproj | 5 ++--- .../NetCord.Natives/triplets/x64-linux-musl-dynamic.cmake | 4 ++++ Natives/NetCord.Natives/triplets/x64-linux-musl.cmake | 4 ++++ 3 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 Natives/NetCord.Natives/triplets/x64-linux-musl-dynamic.cmake create mode 100644 Natives/NetCord.Natives/triplets/x64-linux-musl.cmake diff --git a/Natives/NetCord.Natives/NetCord.Natives.csproj b/Natives/NetCord.Natives/NetCord.Natives.csproj index bcdaabdfa..b43ca3938 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.csproj +++ b/Natives/NetCord.Natives/NetCord.Natives.csproj @@ -32,14 +32,13 @@ windows osx - linux + $(VcpkgOSTarget)-musl + $(VcpkgOSTarget) win - $(VcpkgBuildOS)-musl - false diff --git a/Natives/NetCord.Natives/triplets/x64-linux-musl-dynamic.cmake b/Natives/NetCord.Natives/triplets/x64-linux-musl-dynamic.cmake new file mode 100644 index 000000000..b6f5fc5fc --- /dev/null +++ b/Natives/NetCord.Natives/triplets/x64-linux-musl-dynamic.cmake @@ -0,0 +1,4 @@ +set(VCPKG_TARGET_ARCHITECTURE x64) +set(VCPKG_CRT_LINKAGE dynamic) +set(VCPKG_LIBRARY_LINKAGE dynamic) +set(VCPKG_CMAKE_SYSTEM_NAME Linux) diff --git a/Natives/NetCord.Natives/triplets/x64-linux-musl.cmake b/Natives/NetCord.Natives/triplets/x64-linux-musl.cmake new file mode 100644 index 000000000..8361f30d4 --- /dev/null +++ b/Natives/NetCord.Natives/triplets/x64-linux-musl.cmake @@ -0,0 +1,4 @@ +set(VCPKG_TARGET_ARCHITECTURE x64) +set(VCPKG_CRT_LINKAGE static) +set(VCPKG_LIBRARY_LINKAGE static) +set(VCPKG_CMAKE_SYSTEM_NAME Linux) From 46b15e73649a318c69df9422cc54d221098eded3 Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Wed, 24 Jun 2026 22:24:49 +0200 Subject: [PATCH 052/101] Add arm64-linux-musl triplets --- .../NetCord.Natives/triplets/arm64-linux-musl-dynamic.cmake | 4 ++++ Natives/NetCord.Natives/triplets/arm64-linux-musl.cmake | 4 ++++ 2 files changed, 8 insertions(+) create mode 100644 Natives/NetCord.Natives/triplets/arm64-linux-musl-dynamic.cmake create mode 100644 Natives/NetCord.Natives/triplets/arm64-linux-musl.cmake diff --git a/Natives/NetCord.Natives/triplets/arm64-linux-musl-dynamic.cmake b/Natives/NetCord.Natives/triplets/arm64-linux-musl-dynamic.cmake new file mode 100644 index 000000000..2e76fb3af --- /dev/null +++ b/Natives/NetCord.Natives/triplets/arm64-linux-musl-dynamic.cmake @@ -0,0 +1,4 @@ +set(VCPKG_TARGET_ARCHITECTURE arm64) +set(VCPKG_CRT_LINKAGE dynamic) +set(VCPKG_LIBRARY_LINKAGE dynamic) +set(VCPKG_CMAKE_SYSTEM_NAME Linux) diff --git a/Natives/NetCord.Natives/triplets/arm64-linux-musl.cmake b/Natives/NetCord.Natives/triplets/arm64-linux-musl.cmake new file mode 100644 index 000000000..a402a1fa4 --- /dev/null +++ b/Natives/NetCord.Natives/triplets/arm64-linux-musl.cmake @@ -0,0 +1,4 @@ +set(VCPKG_TARGET_ARCHITECTURE arm64) +set(VCPKG_CRT_LINKAGE static) +set(VCPKG_LIBRARY_LINKAGE static) +set(VCPKG_CMAKE_SYSTEM_NAME Linux) From b118af30fe51b15a450af5a65a8ef8fd589d3e35 Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Fri, 26 Jun 2026 01:47:38 +0900 Subject: [PATCH 053/101] Packge per native deps for all runtimeid * add overlay-triplets --- .../NetCord.Natives/NetCord.Natives.csproj | 103 ++++++++++++------ Natives/NetCord.Natives/vcpkg.json | 3 + .../NativesBuildTests.cs | 27 ++--- 3 files changed, 85 insertions(+), 48 deletions(-) diff --git a/Natives/NetCord.Natives/NetCord.Natives.csproj b/Natives/NetCord.Natives/NetCord.Natives.csproj index b43ca3938..fafc28127 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.csproj +++ b/Natives/NetCord.Natives/NetCord.Natives.csproj @@ -20,6 +20,8 @@ + <_IsPackingNative Condition="'$(_IsPackingNative)' == ''">false + debug bin @@ -42,7 +44,7 @@ false - x64 $(Platform) @@ -55,17 +57,31 @@ <_VcpkgStatusFile>$(VcpkgInstalledDir)\vcpkg\status - + + + + - + + + + + + + + + + - + + - <_VcpkgRelatedFile Include="native-ports\**" /> - + + @@ -74,13 +90,6 @@ - - - - - - @@ -110,8 +119,7 @@ so - <_BuiltRid Include="linux-musl-%(_LibArchs.Identity)" - Condition="'$(VcpkgBuildOS)' == 'linux-musl'"> + <_BuiltRid Include="linux-musl-%(_LibArchs.Identity)"> %(_LibArchs.Identity)-linux-dynamic\lib\lib%(_LibArchs.LibName) %(_LibArchs.Identity)-linux\lib\lib%(_LibArchs.LibName) so @@ -123,12 +131,12 @@ dylib - <_BuiltRid Remove="%(Identity)" Condition="'$(CI)' != 'true' and '%(Identity)' != '$(VcpkgBuildOS)-$(VcpkgPlatformTarget)'" /> + <_BuiltRid Remove="%(Identity)" Condition="'$(PackageNativeDep)' == '' and '%(Identity)' != '$(VcpkgBuildOS)-$(VcpkgPlatformTarget)'" /> - - @@ -172,7 +178,7 @@ - @@ -219,46 +225,69 @@ - - - + + + + + + + + + + + SkipBasePackage + + + + + + false + + + + - <_NativeLicenseSource Include="$(VcpkgOutputPath_Static)\share\%(NativeLibLic.Identity)\copyright" + <_NativeLicenseSource Include="$(VcpkgOutputPath_Static)\share\%(NativeLibLic.Identity)\copyright" Condition="Exists('$(VcpkgOutputPath_Static)\share\%(NativeLibLic.Identity)\copyright')"> $(VcpkgOutputPath_Static)\licenses\%(NativeLibLic.Identity)_LICENSE.txt - - - $(PackageId).$(VcpkgBuildOS)-$(VcpkgPlatformTarget) + + $(PackageId).$(PackageNativeDep) - runtimes\%(_BuiltRid.Identity)\native\ + runtimes\%(_BuiltRid.Identity)\native\ - runtimes\%(_BuiltRid.Identity)\native\ + runtimes\%(_BuiltRid.Identity)\native\ - staticlibs\%(_BuiltRid.Identity)\ + staticlibs\%(_BuiltRid.Identity)\ <_SymlinksToRemoveBuilt Include="@(NativesBuilt)" @@ -267,11 +296,13 @@ true + %(NativesBuilt.PackPath)%(NativesBuilt.Filename)%(NativesBuilt.Extension) - + true - licenses\ + licenses\%(NativeLibLic.Identity)_LICENSE.txt <_BuildFiles Include="$(MSBuildProjectName).props;$(MSBuildProjectName).targets"> @@ -287,7 +318,9 @@ - + + diff --git a/Natives/NetCord.Natives/vcpkg.json b/Natives/NetCord.Natives/vcpkg.json index b00133eb1..bff7c3a3e 100644 --- a/Natives/NetCord.Natives/vcpkg.json +++ b/Natives/NetCord.Natives/vcpkg.json @@ -8,6 +8,9 @@ "vcpkg-configuration": { "overlay-ports": [ "natives-ports" + ], + "overlay-triplets": [ + "natives-triplets" ] }, "builtin-baseline": "89dd0f4d241136b843fb55813b2f0fa6448c204d", diff --git a/Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs b/Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs index 01e04d377..a399f485a 100644 --- a/Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs +++ b/Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs @@ -91,7 +91,8 @@ private static void MSBuildNativeAotPublish(string libNames) // 3. Set up Loggers (Console + optional Binary Logger) var loggers = new List { - new ConsoleLogger(LoggerVerbosity.Normal, msg => Console.WriteLine($"[{NativeAotAppLogTag}/Publish] {msg.Trim()}"), null, null) + new ConsoleLogger(Enum.Parse(Environment.GetEnvironmentVariable("DotnetVerbose") ?? "Minimal", true), + msg => Console.WriteLine($"[{NativeAotAppLogTag}/Publish] {msg.Trim()}"), null, null) }; if (!string.IsNullOrEmpty(binlogpath)) @@ -101,12 +102,12 @@ private static void MSBuildNativeAotPublish(string libNames) // 4. Evaluate and Execute the "Publish" target programmatically Console.WriteLine($"[{NativeAotAppLogTag}/Publish] Building Native AoT app in ({projectDirectory}) via MSBuild API..."); - + using var projectCollection = new ProjectCollection(); var projectInstance = new ProjectInstance(projectFile, globalProperties, null, projectCollection); - - var buildParameters = new BuildParameters - { + + var buildParameters = new BuildParameters + { Loggers = loggers, EnableNodeReuse = false, }; @@ -125,7 +126,7 @@ private static void MSBuildNativeAotPublish(string libNames) // sanitize back-slash publishDirProperty = publishDirProperty.Replace('\\', Path.DirectorySeparatorChar); - var runCmdOutput = Path.GetFullPath(Path.Combine(projectDirectory, publishDirProperty, + var runCmdOutput = Path.GetFullPath(Path.Combine(projectDirectory, publishDirProperty, "NativeAotApp" + (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : ""))); Console.WriteLine($"[{NativeAotAppLogTag}/Publish] Native AoT app published to: '{runCmdOutput}'"); @@ -151,14 +152,14 @@ private static void MSBuildNativeAotPublish(string libNames) } } - var copiedDlls = Directory.GetFiles(Path.GetDirectoryName(runCmdOutput) ?? string.Empty, - RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "*.dll" : + var copiedDlls = Directory.GetFiles(Path.GetDirectoryName(runCmdOutput) ?? string.Empty, + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "*.dll" : RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? "lib*.so" : "lib*.dylib", SearchOption.TopDirectoryOnly) .Select(Path.GetFileName); - - var matchCopied = copiedDlls.Where(dll => dll != null && deps.Any(lib => - dll.StartsWith(lib, StringComparison.OrdinalIgnoreCase) || + + var matchCopied = copiedDlls.Where(dll => dll != null && deps.Any(lib => + dll.StartsWith(lib, StringComparison.OrdinalIgnoreCase) || dll.StartsWith($"lib{lib}", StringComparison.OrdinalIgnoreCase))) .ToList(); @@ -184,11 +185,11 @@ private static void MSBuildNativeAotPublish(string libNames) if (!string.IsNullOrEmpty(e.Data)) Console.Error.WriteLine($"[{NativeAotAppLogTag}/Run] {e.Data}"); }; - + aotProcess.Start(); aotProcess.BeginOutputReadLine(); aotProcess.BeginErrorReadLine(); - + if (!aotProcess.HasExited) aotProcess.WaitForExit(); From ec8279f7a07073c8fd5e06b0949ec85803ef4bc2 Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Fri, 26 Jun 2026 02:27:04 +0900 Subject: [PATCH 054/101] Move vcpkg triplets dir * fix workflow for per native packaging --- .github/workflows/build-natives.yml | 92 ++++++++++++------- .../arm64-linux-musl-dynamic.cmake | 0 .../arm64-linux-musl.cmake | 0 .../x64-linux-musl-dynamic.cmake | 0 .../x64-linux-musl.cmake | 0 5 files changed, 61 insertions(+), 31 deletions(-) rename Natives/NetCord.Natives/{triplets => natives-triplets}/arm64-linux-musl-dynamic.cmake (100%) rename Natives/NetCord.Natives/{triplets => natives-triplets}/arm64-linux-musl.cmake (100%) rename Natives/NetCord.Natives/{triplets => natives-triplets}/x64-linux-musl-dynamic.cmake (100%) rename Natives/NetCord.Natives/{triplets => natives-triplets}/x64-linux-musl.cmake (100%) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index d6b97035f..fd47f748f 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -35,56 +35,48 @@ jobs: vcpkg-platform-target: x64 use-nix: false shell_command: pwsh - musl: false - rid: win-arm64 runs-on: windows-11-arm vcpkg-os-target: windows vcpkg-platform-target: arm64 use-nix: false shell_command: pwsh - musl: false - rid: osx-x64 runs-on: macos-15-intel vcpkg-os-target: osx vcpkg-platform-target: x64 use-nix: true shell_command: nix develop .#natives -c bash -eo pipefail {0} - musl: false - rid: osx-arm64 runs-on: macos-15 vcpkg-os-target: osx vcpkg-platform-target: arm64 use-nix: true shell_command: nix develop .#natives -c bash -eo pipefail {0} - musl: false - rid: linux-x64 runs-on: ubuntu-latest vcpkg-os-target: linux vcpkg-platform-target: x64 use-nix: true shell_command: nix develop .#natives -c bash -eo pipefail {0} - musl: false - rid: linux-arm64 runs-on: ubuntu-24.04-arm vcpkg-os-target: linux vcpkg-platform-target: arm64 use-nix: true shell_command: nix develop .#natives -c bash -eo pipefail {0} - musl: false - rid: linux-musl-x64 runs-on: ubuntu-latest - vcpkg-os-target: linux + vcpkg-os-target: linux-musl vcpkg-platform-target: x64 use-nix: true shell_command: nix develop .#natives-musl -c bash -eo pipefail {0} - musl: true - rid: linux-musl-arm64 runs-on: ubuntu-24.04-arm - vcpkg-os-target: linux + vcpkg-os-target: linux-musl vcpkg-platform-target: arm64 use-nix: true shell_command: nix develop .#natives-musl --option max-jobs 2 --option cores 2 -c bash -eo pipefail {0} - musl: true runs-on: ${{ matrix.runs-on }} defaults: @@ -115,7 +107,7 @@ jobs: uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6 - name: Magic Nix Cache - if: ${{ matrix.use-nix && matrix.musl }} + if: ${{ matrix.use-nix }} uses: DeterminateSystems/magic-nix-cache-action@908b263ff629f4cc17666315b7fd3ec127c6244d # v14 - name: Setup vcpkg (Windows) @@ -137,9 +129,8 @@ jobs: with: path: | .vcpkg-cache - # Unique key per run - key: vcpkg-${{ runner.os }}-${{ matrix.rid }}-${{ hashFiles('Natives/NetCord.Natives/vcpkg.json', 'Natives/NetCord.Natives/natives-ports/**') }} - # Fallback keys to grab the latest previous cache + key: vcpkg-${{ runner.os }}-${{ matrix.rid }}-${{ hashFiles('Natives/NetCord.Natives/vcpkg.json', 'Natives/NetCord.Natives/natives-ports/**', 'Natives/NetCord.Natives/natives-triplets/**') }} + # Fallback keys to grab any latest previous cache restore-keys: | vcpkg-${{ runner.os }}-${{ matrix.rid }}- vcpkg-${{ runner.os }}- @@ -173,7 +164,7 @@ jobs: - name: Test natives outputs for ${{ matrix.rid }} run: > - ${{ matrix.musl && 'docker run --rm -v $PWD:$PWD -w $PWD -e Configuration -e VCPKG_ROOT -e TARGET_MUSL -e MINVERVERSIONOVERRIDE=1.0.0 mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot' || '' }} + ${{ matrix.vcpkg-os-target == 'linux-musl' && 'docker run --rm -v $PWD:$PWD -w $PWD -e Configuration -e VCPKG_ROOT -e MINVERVERSIONOVERRIDE=1.0.0 mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot' || '' }} dotnet test Natives/NetCord.Natives.slnx --no-restore --no-build @@ -183,33 +174,28 @@ jobs: --logger GitHubActions ${{ matrix.vcpkg-os-target == 'osx' && '-p:InvariantGlobalization=true' || '' }} - - name: Pack NuGet Package for ${{ matrix.rid }} - # This forces the step to run even if 'Test' failed, as long as 'Build' succeeded. - if: ${{ always() && steps.build_step.outcome == 'success' }} - id: pack_step # Added an ID here to track the pack status for the upload step - run: > - dotnet pack Natives/NetCord.Natives/NetCord.Natives.csproj --no-restore --no-build -v ${{ env.DotnetVerbose }} - ${{ env.GenerateBinLog == 'true' && '-bl:pack.binlog' || '' }} - -o Natives/NetCord.Natives/bin/${{ matrix.rid }} - -p:CI=false - - name: Upload Binary Logs if: ${{ env.GenerateBinLog == 'true' && always()}} uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: - name: ${{ matrix.rid }}-binlogs + name: ${{ matrix.rid }}-build-binlogs path: | *.binlog - - name: Upload NuGet Package Artifact + - name: Clean Symbollic Links (Nix) + if: ${{ matrix.use-nix }} + run: | + find Natives/NetCord.Natives/bin/${{ matrix.rid }}/natives/${{ matrix.vcpkg-platform-target }}-${{ matrix.vcpkg-os-target }}-dynamic/lib/ -type l -exec rm {} \; + find Natives/NetCord.Natives/bin/${{ matrix.rid }}/natives-static/${{ matrix.vcpkg-platform-target }}-${{ matrix.vcpkg-os-target }}/lib/ -type l -exec rm {} \; + + - name: Upload Natives Artifact # This ensures we only upload if the Pack step actually finished successfully. if: ${{ always() && steps.pack_step.outcome == 'success' }} uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: NetCord.Natives.${{ matrix.rid }}.packages path: | - Natives/NetCord.Natives/bin/${{ matrix.rid }}/*.nupkg - Natives/NetCord.Natives/bin/${{ matrix.rid }}/*.snupkg + Natives/NetCord.Natives/bin/${{ matrix.rid }} - name: Save vcpkg cache if: ${{ always() && steps.build_step.outcome == 'success' }} @@ -217,5 +203,49 @@ jobs: with: path: | .vcpkg-cache - # Must match the unique key from the restore step - key: vcpkg-${{ runner.os }}-${{ matrix.rid }}-${{ hashFiles('Natives/NetCord.Natives/vcpkg.json', 'Natives/NetCord.Natives/natives-ports/**') }} + key: vcpkg-${{ runner.os }}-${{ matrix.rid }}-${{ hashFiles('Natives/NetCord.Natives/vcpkg.json', 'Natives/NetCord.Natives/natives-ports/**', 'Natives/NetCord.Natives/natives-triplets/**') }} + + pack-natives: + needs: [build-natives] + runs-on: ubuntu-latest + defaults: + run: + shell: nix develop .#natives -c bash -eo pipefail {0} + env: + Configuration: Release + DotnetVerbose: ${{ github.event.inputs.MSBuildVerbosity || inputs.MSBuildVerbosity || 'Minimal' }} + GenerateBinLog: ${{ github.event.inputs.GenerateBinLog || inputs.GenerateBinLog || false }} + + steps: + - name: Download All Natives Artifact + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + path: artifacts/natives-build + pattern: NetCord.Natives.*.packages + merge-multiple: true + + - name: Pack Natives NuGet Package + id: pack_step # Added an ID here to track the pack status for the upload step + run: > + dotnet pack Natives/NetCord.Natives/NetCord.Natives.csproj --no-restore --no-build -v ${{ env.DotnetVerbose }} + ${{ env.GenerateBinLog == 'true' && '-bl:pack.binlog' || '' }} + -p:VcpkgArtifactsRoot=${{ github.workspace }}/artifacts/natives-build/ + -o ${{ github.workspace }}/ + + - name: Upload Binary Logs + if: ${{ env.GenerateBinLog == 'true' && always()}} + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: ${{ matrix.rid }}-pack-binlogs + path: | + *.binlog + + - name: Upload NuGet Package Artifact + # This ensures we only upload if the Pack step actually finished successfully. + if: ${{ always() && steps.pack_step.outcome == 'success' }} + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: NetCord.Natives.packages + path: | + *.nupkg + *.snupkg diff --git a/Natives/NetCord.Natives/triplets/arm64-linux-musl-dynamic.cmake b/Natives/NetCord.Natives/natives-triplets/arm64-linux-musl-dynamic.cmake similarity index 100% rename from Natives/NetCord.Natives/triplets/arm64-linux-musl-dynamic.cmake rename to Natives/NetCord.Natives/natives-triplets/arm64-linux-musl-dynamic.cmake diff --git a/Natives/NetCord.Natives/triplets/arm64-linux-musl.cmake b/Natives/NetCord.Natives/natives-triplets/arm64-linux-musl.cmake similarity index 100% rename from Natives/NetCord.Natives/triplets/arm64-linux-musl.cmake rename to Natives/NetCord.Natives/natives-triplets/arm64-linux-musl.cmake diff --git a/Natives/NetCord.Natives/triplets/x64-linux-musl-dynamic.cmake b/Natives/NetCord.Natives/natives-triplets/x64-linux-musl-dynamic.cmake similarity index 100% rename from Natives/NetCord.Natives/triplets/x64-linux-musl-dynamic.cmake rename to Natives/NetCord.Natives/natives-triplets/x64-linux-musl-dynamic.cmake diff --git a/Natives/NetCord.Natives/triplets/x64-linux-musl.cmake b/Natives/NetCord.Natives/natives-triplets/x64-linux-musl.cmake similarity index 100% rename from Natives/NetCord.Natives/triplets/x64-linux-musl.cmake rename to Natives/NetCord.Natives/natives-triplets/x64-linux-musl.cmake From 0a6c53e7fd65844abf6a428ea65b91d54d3d1065 Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Fri, 26 Jun 2026 02:32:58 +0900 Subject: [PATCH 055/101] Fix workflow * clean TARGET_MUSL --- .github/workflows/build-natives.yml | 42 +++++-------------- .../NetCord.Natives/NetCord.Natives.csproj | 2 - flake.nix | 2 - 3 files changed, 10 insertions(+), 36 deletions(-) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index fd47f748f..ba8444b25 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -84,8 +84,7 @@ jobs: shell: ${{ matrix.shell_command }} env: CI: true - VCPKG_BINARY_SOURCES: clear;files,${{ github.workspace }}/.vcpkg-cache,readwrite - VCPKG_DOWNLOADS: ${{ github.workspace }}/.vcpkg-downloads + VCPKG_BINARY_SOURCES: clear;x-gha,readwrite VcpkgOSTarget: ${{ matrix.vcpkg-os-target }} VcpkgPlatformTarget: ${{ matrix.vcpkg-platform-target }} Configuration: Release @@ -110,30 +109,22 @@ jobs: if: ${{ matrix.use-nix }} uses: DeterminateSystems/magic-nix-cache-action@908b263ff629f4cc17666315b7fd3ec127c6244d # v14 + - name: Export GitHub Actions Vcpkg Cache Environment Variables + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || ''); + core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || ''); + - name: Setup vcpkg (Windows) if: ${{ !matrix.use-nix }} run: | - New-Item -ItemType Directory -Path $env:VCPKG_BINARY_SOURCES.Split(',')[1] -Force | Out-Null - New-Item -ItemType Directory -Path $env:VCPKG_DOWNLOADS -Force | Out-Null - $VCPKG_ROOT/vcpkg/bootstrap-vcpkg.bat + $env:VCPKG_ROOT/bootstrap-vcpkg.bat - name: Setup vcpkg (Nix) if: ${{ matrix.use-nix }} run: | - mkdir -p "${VCPKG_BINARY_SOURCES#*,}" - mkdir -p "${VCPKG_DOWNLOADS}" - $VCPKG_ROOT/vcpkg/bootstrap-vcpkg.sh - - - name: Restore vcpkg cache - uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 - with: - path: | - .vcpkg-cache - key: vcpkg-${{ runner.os }}-${{ matrix.rid }}-${{ hashFiles('Natives/NetCord.Natives/vcpkg.json', 'Natives/NetCord.Natives/natives-ports/**', 'Natives/NetCord.Natives/natives-triplets/**') }} - # Fallback keys to grab any latest previous cache - restore-keys: | - vcpkg-${{ runner.os }}-${{ matrix.rid }}- - vcpkg-${{ runner.os }}- + $VCPKG_ROOT/bootstrap-vcpkg.sh - name: Setup .NET Core SDK (Windows) if: ${{ !matrix.use-nix }} @@ -157,11 +148,6 @@ jobs: -p:GeneratePackageOnBuild=false -p:CI=false ${{ matrix.vcpkg-os-target == 'osx' && '-p:InvariantGlobalization=true' || '' }} - - name: List output directory (Nix) - if: ${{ matrix.use-nix }} - run: | - ls -Rlsha Natives/NetCord.Natives.Tests/bin/ - - name: Test natives outputs for ${{ matrix.rid }} run: > ${{ matrix.vcpkg-os-target == 'linux-musl' && 'docker run --rm -v $PWD:$PWD -w $PWD -e Configuration -e VCPKG_ROOT -e MINVERVERSIONOVERRIDE=1.0.0 mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot' || '' }} @@ -197,14 +183,6 @@ jobs: path: | Natives/NetCord.Natives/bin/${{ matrix.rid }} - - name: Save vcpkg cache - if: ${{ always() && steps.build_step.outcome == 'success' }} - uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 - with: - path: | - .vcpkg-cache - key: vcpkg-${{ runner.os }}-${{ matrix.rid }}-${{ hashFiles('Natives/NetCord.Natives/vcpkg.json', 'Natives/NetCord.Natives/natives-ports/**', 'Natives/NetCord.Natives/natives-triplets/**') }} - pack-natives: needs: [build-natives] runs-on: ubuntu-latest diff --git a/Natives/NetCord.Natives/NetCord.Natives.csproj b/Natives/NetCord.Natives/NetCord.Natives.csproj index fafc28127..bdb68807a 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.csproj +++ b/Natives/NetCord.Natives/NetCord.Natives.csproj @@ -36,8 +36,6 @@ osx linux - $(VcpkgOSTarget)-musl - $(VcpkgOSTarget) win diff --git a/flake.nix b/flake.nix index bae7ddba4..ce0932e27 100644 --- a/flake.nix +++ b/flake.nix @@ -110,8 +110,6 @@ DOTNET_ROOT = dotnetRoot; - TARGET_MUSL = "true"; - VCPKG_FORCE_SYSTEM_BINARIES = "1"; shellHook = '' From f3b131520128d5eee49b9c0332804df9944b0efd Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Fri, 26 Jun 2026 04:03:59 +0900 Subject: [PATCH 056/101] use nuget cache for vcpkg * fix workflow --- .github/workflows/build-natives.yml | 36 ++++++++++++++++------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index ba8444b25..ecb7fb08b 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -79,19 +79,23 @@ jobs: shell_command: nix develop .#natives-musl --option max-jobs 2 --option cores 2 -c bash -eo pipefail {0} runs-on: ${{ matrix.runs-on }} + permissions: + contents: read + packages: write defaults: run: shell: ${{ matrix.shell_command }} env: CI: true - VCPKG_BINARY_SOURCES: clear;x-gha,readwrite + VCPKG_ROOT: ${{ github.workspace }}/Natives/NetCord.Natives/vcpkg VcpkgOSTarget: ${{ matrix.vcpkg-os-target }} VcpkgPlatformTarget: ${{ matrix.vcpkg-platform-target }} + FEED_URL: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json + VCPKG_BINARY_SOURCES: "clear;nuget,https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json,readwrite" Configuration: Release TargetRID: ${{ matrix.rid }} DotnetVerbose: ${{ github.event.inputs.MSBuildVerbosity || inputs.MSBuildVerbosity || 'Minimal' }} GenerateBinLog: ${{ github.event.inputs.GenerateBinLog || inputs.GenerateBinLog || false }} - VCPKG_ROOT: ${{ github.workspace }}/Natives/NetCord.Natives/vcpkg steps: - name: Checkout @@ -109,17 +113,19 @@ jobs: if: ${{ matrix.use-nix }} uses: DeterminateSystems/magic-nix-cache-action@908b263ff629f4cc17666315b7fd3ec127c6244d # v14 - - name: Export GitHub Actions Vcpkg Cache Environment Variables - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - with: - script: | - core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || ''); - core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || ''); + + - name: Configure Github NuGet Vcpkg Cache + run: | + dotnet nuget add source "${{ env.FEED_URL }}" \ + --name "GitHubPackages" \ + -u "${{ github.repository_owner }}" \ + -p "${{ secrets.VCPKG_NUGET_TOKEN }}" \ + --store-password-in-clear-text || true - name: Setup vcpkg (Windows) if: ${{ !matrix.use-nix }} run: | - $env:VCPKG_ROOT/bootstrap-vcpkg.bat + & "$env:VCPKG_ROOT\bootstrap-vcpkg.bat" - name: Setup vcpkg (Nix) if: ${{ matrix.use-nix }} @@ -139,7 +145,7 @@ jobs: ${{ env.GenerateBinLog == 'true' && '-bl:restore.binlog' || '' }} - name: Build natives projects for ${{ matrix.rid }} - id: build_step # Added an ID here to track this step's status + id: build_step run: > dotnet build Natives/NetCord.Natives.slnx --no-restore -v ${{ env.DotnetVerbose }} @@ -161,7 +167,7 @@ jobs: ${{ matrix.vcpkg-os-target == 'osx' && '-p:InvariantGlobalization=true' || '' }} - name: Upload Binary Logs - if: ${{ env.GenerateBinLog == 'true' && always()}} + if: ${{ env.GenerateBinLog == 'true' && always() }} uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: ${{ matrix.rid }}-build-binlogs @@ -175,8 +181,7 @@ jobs: find Natives/NetCord.Natives/bin/${{ matrix.rid }}/natives-static/${{ matrix.vcpkg-platform-target }}-${{ matrix.vcpkg-os-target }}/lib/ -type l -exec rm {} \; - name: Upload Natives Artifact - # This ensures we only upload if the Pack step actually finished successfully. - if: ${{ always() && steps.pack_step.outcome == 'success' }} + if: ${{ always() && steps.build_step.outcome == 'success' }} uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: NetCord.Natives.${{ matrix.rid }}.packages @@ -203,7 +208,7 @@ jobs: merge-multiple: true - name: Pack Natives NuGet Package - id: pack_step # Added an ID here to track the pack status for the upload step + id: pack_step run: > dotnet pack Natives/NetCord.Natives/NetCord.Natives.csproj --no-restore --no-build -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:pack.binlog' || '' }} @@ -211,7 +216,7 @@ jobs: -o ${{ github.workspace }}/ - name: Upload Binary Logs - if: ${{ env.GenerateBinLog == 'true' && always()}} + if: ${{ env.GenerateBinLog == 'true' && always() }} uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: ${{ matrix.rid }}-pack-binlogs @@ -219,7 +224,6 @@ jobs: *.binlog - name: Upload NuGet Package Artifact - # This ensures we only upload if the Pack step actually finished successfully. if: ${{ always() && steps.pack_step.outcome == 'success' }} uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: From 8a6344f5989e38cd4aee5f81cd1ef79b15db45c2 Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Fri, 26 Jun 2026 04:10:14 +0900 Subject: [PATCH 057/101] fix windows workflow & disable vcpkg metrics --- .github/workflows/build-natives.yml | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index ecb7fb08b..0f4f80dd1 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -113,24 +113,23 @@ jobs: if: ${{ matrix.use-nix }} uses: DeterminateSystems/magic-nix-cache-action@908b263ff629f4cc17666315b7fd3ec127c6244d # v14 - - name: Configure Github NuGet Vcpkg Cache - run: | - dotnet nuget add source "${{ env.FEED_URL }}" \ - --name "GitHubPackages" \ - -u "${{ github.repository_owner }}" \ - -p "${{ secrets.VCPKG_NUGET_TOKEN }}" \ - --store-password-in-clear-text || true + run: > + dotnet nuget add source "${{ env.FEED_URL }}" + --name "GitHubPackages" + -u "${{ github.repository_owner }}" + -p "${{ secrets.VCPKG_NUGET_TOKEN }}" + --store-password-in-clear-text || true - name: Setup vcpkg (Windows) if: ${{ !matrix.use-nix }} run: | - & "$env:VCPKG_ROOT\bootstrap-vcpkg.bat" + & "$env:VCPKG_ROOT\bootstrap-vcpkg.bat" -disableMetrics - name: Setup vcpkg (Nix) if: ${{ matrix.use-nix }} run: | - $VCPKG_ROOT/bootstrap-vcpkg.sh + $VCPKG_ROOT/bootstrap-vcpkg.sh -disableMetrics - name: Setup .NET Core SDK (Windows) if: ${{ !matrix.use-nix }} From ac814f12373ced33895d51bc2277139c65d80f16 Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Fri, 26 Jun 2026 04:39:06 +0900 Subject: [PATCH 058/101] Use apple sdk 12 instead of 14 Run CI Run CI 2 fix dotnet nuget 2 package sources * fix pack workflow fix nuget vcpkg cache * add mono to nix fix nuget vcpkg cache integration --- .github/workflows/build-natives.yml | 34 +++++++++++++++++++---------- flake.nix | 4 ++++ 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index 0f4f80dd1..197f23a55 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -88,10 +88,10 @@ jobs: env: CI: true VCPKG_ROOT: ${{ github.workspace }}/Natives/NetCord.Natives/vcpkg - VcpkgOSTarget: ${{ matrix.vcpkg-os-target }} - VcpkgPlatformTarget: ${{ matrix.vcpkg-platform-target }} FEED_URL: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json VCPKG_BINARY_SOURCES: "clear;nuget,https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json,readwrite" + VcpkgOSTarget: ${{ matrix.vcpkg-os-target }} + VcpkgPlatformTarget: ${{ matrix.vcpkg-platform-target }} Configuration: Release TargetRID: ${{ matrix.rid }} DotnetVerbose: ${{ github.event.inputs.MSBuildVerbosity || inputs.MSBuildVerbosity || 'Minimal' }} @@ -113,23 +113,35 @@ jobs: if: ${{ matrix.use-nix }} uses: DeterminateSystems/magic-nix-cache-action@908b263ff629f4cc17666315b7fd3ec127c6244d # v14 - - name: Configure Github NuGet Vcpkg Cache - run: > - dotnet nuget add source "${{ env.FEED_URL }}" - --name "GitHubPackages" - -u "${{ github.repository_owner }}" - -p "${{ secrets.VCPKG_NUGET_TOKEN }}" - --store-password-in-clear-text || true - - name: Setup vcpkg (Windows) if: ${{ !matrix.use-nix }} run: | & "$env:VCPKG_ROOT\bootstrap-vcpkg.bat" -disableMetrics + .$(${{ env.VCPKG_ROOT }}/vcpkg fetch nuget) ` + sources add ` + -Source "${{ env.FEED_URL }}" ` + -StorePasswordInClearText ` + -Name GitHubPackages ` + -UserName "${{ github.repository_owner }}" ` + -Password "${{ secrets.VCPKG_NUGET_TOKEN }}" + .$(${{ env.VCPKG_ROOT }}/vcpkg fetch nuget) ` + setapikey "${{ secrets.VCPKG_NUGET_TOKEN }}" ` + -Source "${{ env.FEED_URL }}" - name: Setup vcpkg (Nix) if: ${{ matrix.use-nix }} run: | $VCPKG_ROOT/bootstrap-vcpkg.sh -disableMetrics + mono `${{ env.VCPKG_ROOT }}/vcpkg fetch nuget | tail -n 1` \ + sources add \ + -Source "${{ env.FEED_URL }}" \ + -StorePasswordInClearText \ + -Name GitHubPackages \ + -UserName "${{ github.repository_owner }}" \ + -Password "${{ secrets.VCPKG_NUGET_TOKEN }}" + mono `${{ env.VCPKG_ROOT }}/vcpkg fetch nuget | tail -n 1` \ + setapikey "${{ secrets.VCPKG_NUGET_TOKEN }}" \ + -Source "${{ env.FEED_URL }}" - name: Setup .NET Core SDK (Windows) if: ${{ !matrix.use-nix }} @@ -218,7 +230,7 @@ jobs: if: ${{ env.GenerateBinLog == 'true' && always() }} uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: - name: ${{ matrix.rid }}-pack-binlogs + name: pack-binlogs path: | *.binlog diff --git a/flake.nix b/flake.nix index ce0932e27..77307f616 100644 --- a/flake.nix +++ b/flake.nix @@ -62,6 +62,8 @@ } ({ packages = [ dotnet + pkgs.nuget + pkgs.mono pkgs.cmake pkgs.ninja pkgs.pkg-config @@ -94,6 +96,8 @@ } ({ packages = [ dotnet + pkgs.nuget + pkgs.mono pkgs.cmake pkgs.ninja pkgs.pkg-config From ca2d7c0d59cc37e9fa15b10bd67c1a18ec0802ce Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Thu, 25 Jun 2026 22:48:51 +0200 Subject: [PATCH 059/101] Fix vcpkg nuget cache --- flake.nix | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/flake.nix b/flake.nix index 77307f616..61dc68db2 100644 --- a/flake.nix +++ b/flake.nix @@ -36,6 +36,11 @@ dotnet-sdk = dotnet; }; + nuget = pkgs.runCommand "unwrapped-nuget" {} '' + mkdir -p $out/bin + install -m 755 ${pkgs.nuget}/lib/Nuget/nuget.exe $out/bin/nuget.exe + ''; + dotnetRoot = "${dotnet.unwrapped}/share/dotnet"; darwinPackages = pkgs.lib.optionals pkgs.stdenv.hostPlatform.isDarwin (with pkgs; [ @@ -62,7 +67,7 @@ } ({ packages = [ dotnet - pkgs.nuget + nuget pkgs.mono pkgs.cmake pkgs.ninja @@ -96,7 +101,7 @@ } ({ packages = [ dotnet - pkgs.nuget + nuget pkgs.mono pkgs.cmake pkgs.ninja From 1365b56fcf496ab2396bce5728d5f37fdbb9498d Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Fri, 26 Jun 2026 10:56:02 +0200 Subject: [PATCH 060/101] Set max jobs to 1 for musl arm64 builds and remove cores limit --- .github/workflows/build-natives.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index 197f23a55..5fcf478b0 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -76,7 +76,7 @@ jobs: vcpkg-os-target: linux-musl vcpkg-platform-target: arm64 use-nix: true - shell_command: nix develop .#natives-musl --option max-jobs 2 --option cores 2 -c bash -eo pipefail {0} + shell_command: nix develop .#natives-musl --option max-jobs 1 -c bash -eo pipefail {0} runs-on: ${{ matrix.runs-on }} permissions: From acdb52aca3a34f6da4fd1e8c8418ec8367773de4 Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Fri, 26 Jun 2026 11:06:03 +0200 Subject: [PATCH 061/101] Add setup dev env step for nix --- .github/workflows/build-natives.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index 5fcf478b0..65b335ab6 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -113,6 +113,10 @@ jobs: if: ${{ matrix.use-nix }} uses: DeterminateSystems/magic-nix-cache-action@908b263ff629f4cc17666315b7fd3ec127c6244d # v14 + - name: Setup dev environment (Nix) + if: ${{ matrix.use-nix }} + run: 'true' + - name: Setup vcpkg (Windows) if: ${{ !matrix.use-nix }} run: | @@ -218,6 +222,9 @@ jobs: pattern: NetCord.Natives.*.packages merge-multiple: true + - name: Setup dev environment + run: 'true' + - name: Pack Natives NuGet Package id: pack_step run: > From 5732313c72f3085a0a039449f2b6b0bc12bf95fa Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Fri, 26 Jun 2026 11:15:53 +0200 Subject: [PATCH 062/101] Revert "fix nuget vcpkg cache integration" This reverts commit 3c87b640ab5c7f7977bd0a44554bb383f7ad39a0. --- .github/workflows/build-natives.yml | 36 +++++++++++------------------ 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index 65b335ab6..bd095dc5b 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -88,10 +88,12 @@ jobs: env: CI: true VCPKG_ROOT: ${{ github.workspace }}/Natives/NetCord.Natives/vcpkg - FEED_URL: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json - VCPKG_BINARY_SOURCES: "clear;nuget,https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json,readwrite" VcpkgOSTarget: ${{ matrix.vcpkg-os-target }} VcpkgPlatformTarget: ${{ matrix.vcpkg-platform-target }} + FEED_URL: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json + VCPKG_BINARY_SOURCES: "clear;nuget,https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json,readwrite" + VCPKG_NUGET_REPOSITORY: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json + INPUT_TOKEN: ${{ secrets.VCPKG_NUGET_TOKEN }} Configuration: Release TargetRID: ${{ matrix.rid }} DotnetVerbose: ${{ github.event.inputs.MSBuildVerbosity || inputs.MSBuildVerbosity || 'Minimal' }} @@ -121,31 +123,21 @@ jobs: if: ${{ !matrix.use-nix }} run: | & "$env:VCPKG_ROOT\bootstrap-vcpkg.bat" -disableMetrics - .$(${{ env.VCPKG_ROOT }}/vcpkg fetch nuget) ` - sources add ` - -Source "${{ env.FEED_URL }}" ` - -StorePasswordInClearText ` - -Name GitHubPackages ` - -UserName "${{ github.repository_owner }}" ` - -Password "${{ secrets.VCPKG_NUGET_TOKEN }}" - .$(${{ env.VCPKG_ROOT }}/vcpkg fetch nuget) ` - setapikey "${{ secrets.VCPKG_NUGET_TOKEN }}" ` - -Source "${{ env.FEED_URL }}" + + - name: Configure Github NuGet Vcpkg Cache (Windows) + if: ${{ !matrix.use-nix }} + run: > + dotnet nuget add source "${{ env.FEED_URL }}" + --name "GitHubPackages" + -u "${{ github.repository_owner }}" + -p "${{ secrets.VCPKG_NUGET_TOKEN }}" + --store-password-in-clear-text + --configfile "$env:APPDATA\NuGet\NuGet.Config" || true - name: Setup vcpkg (Nix) if: ${{ matrix.use-nix }} run: | $VCPKG_ROOT/bootstrap-vcpkg.sh -disableMetrics - mono `${{ env.VCPKG_ROOT }}/vcpkg fetch nuget | tail -n 1` \ - sources add \ - -Source "${{ env.FEED_URL }}" \ - -StorePasswordInClearText \ - -Name GitHubPackages \ - -UserName "${{ github.repository_owner }}" \ - -Password "${{ secrets.VCPKG_NUGET_TOKEN }}" - mono `${{ env.VCPKG_ROOT }}/vcpkg fetch nuget | tail -n 1` \ - setapikey "${{ secrets.VCPKG_NUGET_TOKEN }}" \ - -Source "${{ env.FEED_URL }}" - name: Setup .NET Core SDK (Windows) if: ${{ !matrix.use-nix }} From 5df965dc01680ce3f389af5b44405e2563a89404 Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Fri, 26 Jun 2026 11:30:57 +0200 Subject: [PATCH 063/101] Fix vcpkg fetch nuget --- flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index 61dc68db2..9d7bbd91f 100644 --- a/flake.nix +++ b/flake.nix @@ -38,7 +38,7 @@ nuget = pkgs.runCommand "unwrapped-nuget" {} '' mkdir -p $out/bin - install -m 755 ${pkgs.nuget}/lib/Nuget/nuget.exe $out/bin/nuget.exe + install -m 755 ${pkgs.nuget}/lib/Nuget/nuget.exe $out/bin/nuget ''; dotnetRoot = "${dotnet.unwrapped}/share/dotnet"; From 0a3c8beaa12e916448b6e6d642cf715ba30bf436 Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Fri, 26 Jun 2026 16:11:12 +0200 Subject: [PATCH 064/101] Limit cores to 3 for musl arm64 in CI --- .github/workflows/build-natives.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index bd095dc5b..41bcd21cd 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -76,7 +76,7 @@ jobs: vcpkg-os-target: linux-musl vcpkg-platform-target: arm64 use-nix: true - shell_command: nix develop .#natives-musl --option max-jobs 1 -c bash -eo pipefail {0} + shell_command: nix develop .#natives-musl --option max-jobs 1 --option cores 3 -c bash -eo pipefail {0} runs-on: ${{ matrix.runs-on }} permissions: From f1321251c8897ce833f8194dddf89a9de82c3aaf Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Sat, 27 Jun 2026 11:18:34 +0200 Subject: [PATCH 065/101] Fix pack --- .github/workflows/build-natives.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index 41bcd21cd..95ce7db3a 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -217,10 +217,18 @@ jobs: - name: Setup dev environment run: 'true' + - name: Restore + run: > + dotnet restore Natives/NetCord.Natives/NetCord.Natives.slnx + -v ${{ env.DotnetVerbose }} + ${{ env.GenerateBinLog == 'true' && '-bl:restore.binlog' || '' }} + - name: Pack Natives NuGet Package id: pack_step run: > - dotnet pack Natives/NetCord.Natives/NetCord.Natives.csproj --no-restore --no-build -v ${{ env.DotnetVerbose }} + dotnet pack Natives/NetCord.Natives/NetCord.Natives.csproj + --no-restore + -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:pack.binlog' || '' }} -p:VcpkgArtifactsRoot=${{ github.workspace }}/artifacts/natives-build/ -o ${{ github.workspace }}/ From fb72ddda56f38e2a053e8d025eba477bfeddeac8 Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Sat, 27 Jun 2026 14:03:39 +0200 Subject: [PATCH 066/101] Fix the pack fix --- .github/workflows/build-natives.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index 95ce7db3a..16b10ed5d 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -227,6 +227,7 @@ jobs: id: pack_step run: > dotnet pack Natives/NetCord.Natives/NetCord.Natives.csproj + --no-build --no-restore -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:pack.binlog' || '' }} From 9762a3b8290ada562fdc20fcbec201f3cc8c0b58 Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Sat, 27 Jun 2026 21:58:41 +0900 Subject: [PATCH 067/101] add vcpkg github package caching --- .github/workflows/build-natives.yml | 46 ++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index 16b10ed5d..9ff48cc63 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -90,10 +90,8 @@ jobs: VCPKG_ROOT: ${{ github.workspace }}/Natives/NetCord.Natives/vcpkg VcpkgOSTarget: ${{ matrix.vcpkg-os-target }} VcpkgPlatformTarget: ${{ matrix.vcpkg-platform-target }} - FEED_URL: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json + GITHUB_PACKAGES_FEED: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json VCPKG_BINARY_SOURCES: "clear;nuget,https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json,readwrite" - VCPKG_NUGET_REPOSITORY: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json - INPUT_TOKEN: ${{ secrets.VCPKG_NUGET_TOKEN }} Configuration: Release TargetRID: ${{ matrix.rid }} DotnetVerbose: ${{ github.event.inputs.MSBuildVerbosity || inputs.MSBuildVerbosity || 'Minimal' }} @@ -121,23 +119,43 @@ jobs: - name: Setup vcpkg (Windows) if: ${{ !matrix.use-nix }} + shell: pwsh run: | - & "$env:VCPKG_ROOT\bootstrap-vcpkg.bat" -disableMetrics + & "${{ env.VCPKG_ROOT }}\bootstrap-vcpkg.bat" -disableMetrics - - name: Configure Github NuGet Vcpkg Cache (Windows) - if: ${{ !matrix.use-nix }} - run: > - dotnet nuget add source "${{ env.FEED_URL }}" - --name "GitHubPackages" - -u "${{ github.repository_owner }}" - -p "${{ secrets.VCPKG_NUGET_TOKEN }}" - --store-password-in-clear-text - --configfile "$env:APPDATA\NuGet\NuGet.Config" || true + # Fetch the nuget path, filter out any warning lines, and run it + $nugetPath = & "${{ env.VCPKG_ROOT }}\vcpkg" fetch nuget | Select-Object -Last 1 + + & $nugetPath sources add ` + -Source "${{ env.GITHUB_PACKAGES_FEED }}" ` + -Name "GithubPackages" ` + -UserName "${{ github.repository_owner }}" ` + -Password "${{ secrets.VCPKG_NUGET_TOKEN }}" ` + -StorePasswordInClearText + + # Set the api key for the GitHub Packages feed + & $nugetPath setapikey "${{ secrets.VCPKG_NUGET_TOKEN }}" ` + -Source "${{ env.GITHUB_PACKAGES_FEED }}" - name: Setup vcpkg (Nix) if: ${{ matrix.use-nix }} + shell: bash run: | - $VCPKG_ROOT/bootstrap-vcpkg.sh -disableMetrics + "${{ env.VCPKG_ROOT }}/bootstrap-vcpkg.sh" -disableMetrics + + # Capture the nuget.exe path to a local variable + NUGET_PATH=$("${{ env.VCPKG_ROOT }}/vcpkg" fetch nuget | tail -n 1) + + mono "$NUGET_PATH" sources add \ + -Source "${{ env.GITHUB_PACKAGES_FEED }}" \ + -Name "GithubPackages" \ + -UserName "${{ github.repository_owner }}" \ + -Password "${{ secrets.VCPKG_NUGET_TOKEN }}" \ + -StorePasswordInClearText + + # Set the api key for the GitHub Packages feed + mono "$NUGET_PATH" setapikey "${{ secrets.VCPKG_NUGET_TOKEN }}" \ + -Source "${{ env.GITHUB_PACKAGES_FEED }}" - name: Setup .NET Core SDK (Windows) if: ${{ !matrix.use-nix }} From 8923e2fbcd18040d37769ae5732c3e91b43f0e66 Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Sat, 27 Jun 2026 23:44:11 +0900 Subject: [PATCH 068/101] provide vcpkg cache nuget.config --- .github/workflows/build-natives.yml | 14 +++++++++----- Natives/NetCord.Natives/vcpkg-nuget.config | 3 +++ 2 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 Natives/NetCord.Natives/vcpkg-nuget.config diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index 9ff48cc63..cce18f9b4 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -91,7 +91,7 @@ jobs: VcpkgOSTarget: ${{ matrix.vcpkg-os-target }} VcpkgPlatformTarget: ${{ matrix.vcpkg-platform-target }} GITHUB_PACKAGES_FEED: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json - VCPKG_BINARY_SOURCES: "clear;nuget,https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json,readwrite" + VCPKG_BINARY_SOURCES: "clear;nugetconfig,${{ github.workspace }}/Natives/NetCord.Natives/vcpkg-nuget.config,readwrite" Configuration: Release TargetRID: ${{ matrix.rid }} DotnetVerbose: ${{ github.event.inputs.MSBuildVerbosity || inputs.MSBuildVerbosity || 'Minimal' }} @@ -132,10 +132,12 @@ jobs: -UserName "${{ github.repository_owner }}" ` -Password "${{ secrets.VCPKG_NUGET_TOKEN }}" ` -StorePasswordInClearText + -ConfigFile "${{ github.workspace }}\Natives\NetCord.Natives\vcpkg-nuget.config" # Set the api key for the GitHub Packages feed & $nugetPath setapikey "${{ secrets.VCPKG_NUGET_TOKEN }}" ` - -Source "${{ env.GITHUB_PACKAGES_FEED }}" + -Source "${{ env.GITHUB_PACKAGES_FEED }}" ` + -ConfigFile "${{ github.workspace }}\Natives\NetCord.Natives\vcpkg-nuget.config" - name: Setup vcpkg (Nix) if: ${{ matrix.use-nix }} @@ -144,18 +146,20 @@ jobs: "${{ env.VCPKG_ROOT }}/bootstrap-vcpkg.sh" -disableMetrics # Capture the nuget.exe path to a local variable - NUGET_PATH=$("${{ env.VCPKG_ROOT }}/vcpkg" fetch nuget | tail -n 1) + export NUGET_PATH=$("${{ env.VCPKG_ROOT }}/vcpkg" fetch nuget | tail -n 1) mono "$NUGET_PATH" sources add \ -Source "${{ env.GITHUB_PACKAGES_FEED }}" \ -Name "GithubPackages" \ -UserName "${{ github.repository_owner }}" \ -Password "${{ secrets.VCPKG_NUGET_TOKEN }}" \ - -StorePasswordInClearText + -StorePasswordInClearText \ + -ConfigFile "${{ github.workspace }}/Natives/NetCord.Natives/vcpkg-nuget.config" # Set the api key for the GitHub Packages feed mono "$NUGET_PATH" setapikey "${{ secrets.VCPKG_NUGET_TOKEN }}" \ - -Source "${{ env.GITHUB_PACKAGES_FEED }}" + -Source "${{ env.GITHUB_PACKAGES_FEED }}" \ + -ConfigFile "${{ github.workspace }}/Natives/NetCord.Natives/vcpkg-nuget.config" - name: Setup .NET Core SDK (Windows) if: ${{ !matrix.use-nix }} diff --git a/Natives/NetCord.Natives/vcpkg-nuget.config b/Natives/NetCord.Natives/vcpkg-nuget.config new file mode 100644 index 000000000..f072f570e --- /dev/null +++ b/Natives/NetCord.Natives/vcpkg-nuget.config @@ -0,0 +1,3 @@ + + + From 7684089e4702e6926aa8c6542b3bf65e1244695c Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Sat, 27 Jun 2026 23:48:33 +0900 Subject: [PATCH 069/101] fix workflow --- .github/workflows/build-natives.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index cce18f9b4..17b88889d 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -119,19 +119,20 @@ jobs: - name: Setup vcpkg (Windows) if: ${{ !matrix.use-nix }} - shell: pwsh run: | & "${{ env.VCPKG_ROOT }}\bootstrap-vcpkg.bat" -disableMetrics # Fetch the nuget path, filter out any warning lines, and run it $nugetPath = & "${{ env.VCPKG_ROOT }}\vcpkg" fetch nuget | Select-Object -Last 1 + Write-Host "NuGet path: $nugetPath" + & $nugetPath sources add ` -Source "${{ env.GITHUB_PACKAGES_FEED }}" ` -Name "GithubPackages" ` -UserName "${{ github.repository_owner }}" ` -Password "${{ secrets.VCPKG_NUGET_TOKEN }}" ` - -StorePasswordInClearText + -StorePasswordInClearText ` -ConfigFile "${{ github.workspace }}\Natives\NetCord.Natives\vcpkg-nuget.config" # Set the api key for the GitHub Packages feed @@ -141,13 +142,14 @@ jobs: - name: Setup vcpkg (Nix) if: ${{ matrix.use-nix }} - shell: bash run: | "${{ env.VCPKG_ROOT }}/bootstrap-vcpkg.sh" -disableMetrics # Capture the nuget.exe path to a local variable export NUGET_PATH=$("${{ env.VCPKG_ROOT }}/vcpkg" fetch nuget | tail -n 1) + echo "NuGet path: $NUGET_PATH" + mono "$NUGET_PATH" sources add \ -Source "${{ env.GITHUB_PACKAGES_FEED }}" \ -Name "GithubPackages" \ From edf0999f67830a9fd3a810b91b79b80f40f35019 Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Sun, 28 Jun 2026 00:02:55 +0900 Subject: [PATCH 070/101] add defaultpushsource --- .github/workflows/build-natives.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index 17b88889d..ba90894c2 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -140,6 +140,11 @@ jobs: -Source "${{ env.GITHUB_PACKAGES_FEED }}" ` -ConfigFile "${{ github.workspace }}\Natives\NetCord.Natives\vcpkg-nuget.config" + # Tell NuGet to use this feed by default for push operations + & $nugetPath config ` + -ConfigFile "${{ github.workspace }}\Natives\NetCord.Natives\vcpkg-nuget.config" ` + -Set defaultPushSource="${{ env.GITHUB_PACKAGES_FEED }}" + - name: Setup vcpkg (Nix) if: ${{ matrix.use-nix }} run: | @@ -163,6 +168,11 @@ jobs: -Source "${{ env.GITHUB_PACKAGES_FEED }}" \ -ConfigFile "${{ github.workspace }}/Natives/NetCord.Natives/vcpkg-nuget.config" + # Tell NuGet to use this feed by default for push operations + mono "$NUGET_PATH" config \ + -ConfigFile "${{ github.workspace }}/Natives/NetCord.Natives/vcpkg-nuget.config" \ + -Set defaultPushSource="${{ env.GITHUB_PACKAGES_FEED }}" + - name: Setup .NET Core SDK (Windows) if: ${{ !matrix.use-nix }} uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5.2.0 From a4f879d279e0e25c6a698e5cedeaa909db5cc82f Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Sat, 4 Jul 2026 23:05:08 +0900 Subject: [PATCH 071/101] Condense symlinking & natives handling --- .../NetCord.Natives.Symlinking.targets | 28 ++++++++++ .../NetCord.Natives/NetCord.Natives.csproj | 48 +++++------------ .../NetCord.Natives.local.targets | 7 +-- .../NetCord.Natives/NetCord.Natives.targets | 54 ++++++------------- .../NativesBuildTests.cs | 31 +++++++++++ 5 files changed, 91 insertions(+), 77 deletions(-) create mode 100644 Natives/NetCord.Natives/NetCord.Natives.Symlinking.targets diff --git a/Natives/NetCord.Natives/NetCord.Natives.Symlinking.targets b/Natives/NetCord.Natives/NetCord.Natives.Symlinking.targets new file mode 100644 index 000000000..3a18e7e0e --- /dev/null +++ b/Natives/NetCord.Natives/NetCord.Natives.Symlinking.targets @@ -0,0 +1,28 @@ + + + + + <_Symlink Include="@(FileWrites)" + Condition="$([System.Text.RegularExpressions.Regex]::IsMatch('%(Filename)%(Extension)', '\.so\.\d+'))"> + %(Filename)%(Extension) + $([System.Text.RegularExpressions.Regex]::Match('%(Filename)%(Extension)', '.*?\.so\.\d+').Value) + $([System.Text.RegularExpressions.Regex]::Replace('%(Filename)%(Extension)', '\.so\..*', '.so')) + + <_Symlink Include="@(FileWrites)" + Condition="$([System.Text.RegularExpressions.Regex]::IsMatch('%(Filename)%(Extension)', '\.dylib$'))"> + %(Filename)%(Extension) + $([System.Text.RegularExpressions.Regex]::Match('%(Filename)%(Extension)', '^(.*?\.\d+)\..*\.dylib$').Groups[1].Value + '.dylib') + $([System.Text.RegularExpressions.Regex]::Replace('%(Filename)%(Extension)', '\.\d+.*\.dylib$', '.dylib')) + + + + + + + + + \ No newline at end of file diff --git a/Natives/NetCord.Natives/NetCord.Natives.csproj b/Natives/NetCord.Natives/NetCord.Natives.csproj index bdb68807a..c316e2af2 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.csproj +++ b/Natives/NetCord.Natives/NetCord.Natives.csproj @@ -55,21 +55,21 @@ <_VcpkgStatusFile>$(VcpkgInstalledDir)\vcpkg\status - + - + - + - + @@ -198,38 +198,15 @@ - + - - - <_NativeFiles Include="$(OutDir)**\lib%(NativeLibSet.Identity)*.so.*" /> - <_NativeFiles Include="$(OutDir)**\lib%(NativeLibSet.Identity)*.dylib" /> - - - $([System.Text.RegularExpressions.Regex]::IsMatch('%(Filename)%(Extension)', '\.dylib')) - - - - %(Filename)%(Extension) - $([System.Text.RegularExpressions.Regex]::Match('%(Filename)%(Extension)', '.*\.so\.\d+')) - $([System.Text.RegularExpressions.Regex]::Replace('%(Filename)%(Extension)', '^([a-zA-Z0-9_-]+\.\d+)\..*', '$1%(Extension)')) - - $([System.Text.RegularExpressions.Regex]::Match('%(Filename)%(Extension)', '.*\.so\.\d+')) - $([System.Text.RegularExpressions.Regex]::Replace('%(Filename)%(Extension)', '^([a-zA-Z0-9_-]+\.\d+)\..*', '$1%(Extension)')) - $([System.Text.RegularExpressions.Regex]::Replace('%(Filename)%(Extension)', '\.so\..*', '.so')) - $([System.Text.RegularExpressions.Regex]::Replace('%(Filename)%(Extension)', '\.\d+.*\.dylib', '.dylib')) - - + - + - + @@ -303,15 +280,16 @@ licenses\%(NativeLibLic.Identity)_LICENSE.txt - <_BuildFiles Include="$(MSBuildProjectName).props;$(MSBuildProjectName).targets"> - true - + <_BuildFiles Include="$(MSBuildProjectName).props;$(MSBuildProjectName).targets" /> + <_BuildFiles Include="$(MSBuildProjectName).Symlinking.targets" /> build\$(PackageId)%(Extension) + true buildTransitive\$(PackageId)%(Extension) + true diff --git a/Natives/NetCord.Natives/NetCord.Natives.local.targets b/Natives/NetCord.Natives/NetCord.Natives.local.targets index 3fab9fbb6..3851855cd 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.local.targets +++ b/Natives/NetCord.Natives/NetCord.Natives.local.targets @@ -5,14 +5,12 @@ + Targets="GetStaticBuildDir"> + Targets="_AddNativeRuntimeCopyItems"> @@ -28,7 +26,6 @@ DependsOnTargets="GetNetCordNativesItems" AfterTargets="ComputeResolvedFilesToPublishList" BeforeTargets="ComputeFilesToPublish"> - diff --git a/Natives/NetCord.Natives/NetCord.Natives.targets b/Natives/NetCord.Natives/NetCord.Natives.targets index d4a1a1faa..2d55eacee 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.targets +++ b/Natives/NetCord.Natives/NetCord.Natives.targets @@ -4,43 +4,43 @@ - <_NetCordStaticLink Include="libsodium;sodium" + <_NetCordStaticLink Include="sodium" Condition="'%(DirectPInvoke.Identity)' == 'libsodium'" /> - <_NetCordStaticLink Include="libdave;dave" + <_NetCordStaticLink Include="dave" Condition="'%(DirectPInvoke.Identity)' == 'libdave'" /> - <_NetCordStaticLink Include="mlspp;hpke;bytes;tls_syntax" + <_NetCordStaticLink Include="mlspp;hpke;bytes;tls_syntax" Condition="'%(DirectPInvoke.Identity)' == 'libdave'" /> - <_NetCordStaticLink Include="opus;zstd" + <_NetCordStaticLink Include="opus;zstd" Condition="'%(DirectPInvoke.Identity)' == 'opus' or '%(DirectPInvoke.Identity)' == 'zstd'" /> - <_NetCordStaticLink Include="libcrypto;crypto;libssl;ssl" + <_NetCordStaticLink Include="crypto" Condition="'%(DirectPInvoke.Identity)' == 'libdave'" /> - <_NetCordExcluded Include="$(NetCordExcludeNatives)" + <_NetCordExcluded Include="$(NetCordExcludeNatives)" Condition="'$(NetCordExcludeNatives)' != ''" /> - <_NetCordExcluded Include="libcrypto" + <_NetCordExcluded Include="crypto;ssl" Condition="$(NetCordExcludeNatives.Contains('libdave'))" /> - <_NetCordExcluded Include="@(_NetCordStaticLink)" + <_NetCordExcluded Include="@(_NetCordStaticLink)" Condition="'$(PublishAot)' == 'true' and '%(_NetCordStaticLink.Identity)' != ''"/> - <_RunExclude Include="$(NetCordNativesRuntimesDir)\%(_NetCordExcluded.Identity)*.*" + <_RunExclude Include="$(NetCordNativesRuntimesDir)\%(_NetCordExcluded.Identity)*.*" Condition="'%(_NetCordExcluded.Identity)' != '' and '$(NetCordNativesRuntimesDir)' != ''" /> - <_RunExclude Include="$(NetCordNativesRuntimesDir)\lib%(_NetCordExcluded.Identity)*.*" + <_RunExclude Include="$(NetCordNativesRuntimesDir)\lib%(_NetCordExcluded.Identity)*.*" Condition="'%(_NetCordExcluded.Identity)' != '' and '$(NetCordNativesRuntimesDir)' != ''" /> - @@ -50,7 +50,7 @@ - true @@ -66,32 +66,12 @@ - - - <_NativeLibNames Include="dave;mlspp;bytes;tls_syntax;hpke;crypto;sodium;opus;zstd" /> - <_NativeFiles Include="$(OutDir)**\lib%(_NativeLibNames.Identity)*.so.*" /> - <_NativeFiles Include="$(OutDir)**\lib%(_NativeLibNames.Identity)*.dylib" /> - - - $([System.Text.RegularExpressions.Regex]::IsMatch('%(Filename)%(Extension)', '\.dylib')) - - - - %(Filename)%(Extension) - $([System.Text.RegularExpressions.Regex]::Match('%(Filename)%(Extension)', '.*\.so\.\d+')) - $([System.Text.RegularExpressions.Regex]::Replace('%(Filename)%(Extension)', '^([a-zA-Z0-9_-]+\.\d+)\..*', '$1%(Extension)')) - - $([System.Text.RegularExpressions.Regex]::Match('%(Filename)%(Extension)', '.*\.so\.\d+')) - $([System.Text.RegularExpressions.Regex]::Replace('%(Filename)%(Extension)', '^([a-zA-Z0-9_-]+\.\d+)\..*', '$1%(Extension)')) - $([System.Text.RegularExpressions.Regex]::Replace('%(Filename)%(Extension)', '\.so\..*', '.so')) - $([System.Text.RegularExpressions.Regex]::Replace('%(Filename)%(Extension)', '\.\d+.*\.dylib', '.dylib')) - - + + + - +
diff --git a/Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs b/Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs index a399f485a..e7b1284a6 100644 --- a/Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs +++ b/Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs @@ -13,6 +13,13 @@ namespace NetCord.Natives.Tests; [TestClass] public class NativesBuildTests { + private static readonly IReadOnlyDictionary TelemetryOptOutEnvironment = new Dictionary + { + ["DOTNET_CLI_TELEMETRY_OPTOUT"] = "1", + ["DOTNET_NOLOGO"] = "1", + ["MSBUILD_TELEMETRY_OPTOUT"] = "1", + }; + [TestMethod] [DataRow("libdave")] [DataRow("libsodium")] @@ -55,6 +62,8 @@ public void NativeAotStaticLinking(string libNames) private static void MSBuildNativeAotPublish(string libNames) { + using var _ = new EnvironmentVariableScope(TelemetryOptOutEnvironment); + // 1. Get properties from AssemblyMetadata attributes var assembly = typeof(NativesBuildTests).Assembly; @@ -195,4 +204,26 @@ private static void MSBuildNativeAotPublish(string libNames) Assert.AreEqual(0, aotProcess.ExitCode, $"Native AoT app failed to run for '{libNames}'."); } + + private sealed class EnvironmentVariableScope : IDisposable + { + private readonly Dictionary _originalValues = new(StringComparer.Ordinal); + + public EnvironmentVariableScope(IReadOnlyDictionary variables) + { + foreach (var pair in variables) + { + _originalValues[pair.Key] = Environment.GetEnvironmentVariable(pair.Key); + Environment.SetEnvironmentVariable(pair.Key, pair.Value); + } + } + + public void Dispose() + { + foreach (var pair in _originalValues) + { + Environment.SetEnvironmentVariable(pair.Key, pair.Value); + } + } + } } From 5d1ca8b84f58d142edca3771d9bdfddc1d379f85 Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Sun, 5 Jul 2026 00:33:54 +0900 Subject: [PATCH 072/101] fix build files packaged path --- Natives/NetCord.Natives/NetCord.Natives.csproj | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Natives/NetCord.Natives/NetCord.Natives.csproj b/Natives/NetCord.Natives/NetCord.Natives.csproj index c316e2af2..220d20866 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.csproj +++ b/Natives/NetCord.Natives/NetCord.Natives.csproj @@ -280,15 +280,19 @@ licenses\%(NativeLibLic.Identity)_LICENSE.txt - <_BuildFiles Include="$(MSBuildProjectName).props;$(MSBuildProjectName).targets" /> - <_BuildFiles Include="$(MSBuildProjectName).Symlinking.targets" /> + <_BuildFiles Include="$(MSBuildProjectName).props;$(MSBuildProjectName).targets"> + $(PackageId) + + <_BuildFiles Include="$(MSBuildProjectName).Symlinking.targets"> + $(PackageId).Symlinking + - build\$(PackageId)%(Extension) + build\%(_BuildFiles.PkgPath)%(_BuildFiles.Extension) true - buildTransitive\$(PackageId)%(Extension) + buildTransitive\%(_BuildFiles.PkgPath)%(_BuildFiles.Extension) true From 8ceb368d8e0dedcbc8116cab6c1a4f5617206b19 Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Sun, 5 Jul 2026 02:21:03 +0900 Subject: [PATCH 073/101] Add meta package depends on all native libs --- .../NetCord.Natives/NetCord.Natives.csproj | 43 ++++++++++++------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/Natives/NetCord.Natives/NetCord.Natives.csproj b/Natives/NetCord.Natives/NetCord.Natives.csproj index 220d20866..d3b981a7c 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.csproj +++ b/Natives/NetCord.Natives/NetCord.Natives.csproj @@ -5,7 +5,8 @@ false false false - true + true + $(NoWarn);NU5128 $([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)\..\..\..')) @@ -55,6 +56,10 @@ <_VcpkgStatusFile>$(VcpkgInstalledDir)\vcpkg\status + + + + @@ -150,7 +155,7 @@ + Condition="Exists('$(_VcpkgStatusFile)') and '$(_IsPackingNative)' == 'true'"> @@ -198,7 +203,7 @@ - + @@ -209,26 +214,32 @@ - - - - - + + PackagePerNative + + + + + + - - SkipBasePackage - - + - - - false - + + + + + + Date: Sun, 5 Jul 2026 02:58:20 +0900 Subject: [PATCH 074/101] Parallelize per natives packaging * Isolate meta packaging restore path * proper message per natives --- .../NetCord.Natives/NetCord.Natives.csproj | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/Natives/NetCord.Natives/NetCord.Natives.csproj b/Natives/NetCord.Natives/NetCord.Natives.csproj index d3b981a7c..2961ae131 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.csproj +++ b/Natives/NetCord.Natives/NetCord.Natives.csproj @@ -181,8 +181,8 @@ - + - + + + NoBuild=true;_IsPackingNative=true;PackageNativeDep=%(NativeDepsPacked.Identity) + + + + + + + $(RestoreOutputPath)/meta-nuget + - + + Properties="_NativePkgVer=$(PackageVersion);_MetaNativePkg=true;RestoreSources=$(PackageOutputPath);RestoreOutputPath=$(RestoreOutputPath)" /> - - + From 762f3cef4c690981bf21e6fc233b6938a6f86829 Mon Sep 17 00:00:00 2001 From: ha-ves <20160532+ha-ves@users.noreply.github.com> Date: Sun, 5 Jul 2026 03:12:00 +0900 Subject: [PATCH 075/101] Fix CI & osx symlink --- .github/workflows/build-natives.yml | 3 +++ Natives/NetCord.Natives/NetCord.Natives.Symlinking.targets | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index ba90894c2..184ca355c 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -87,6 +87,9 @@ jobs: shell: ${{ matrix.shell_command }} env: CI: true + DOTNET_CLI_TELEMETRY_OPTOUT: 1 + DOTNET_NOLOGO: 1 + MSBUILD_TELEMETRY_OPTOUT: 1 VCPKG_ROOT: ${{ github.workspace }}/Natives/NetCord.Natives/vcpkg VcpkgOSTarget: ${{ matrix.vcpkg-os-target }} VcpkgPlatformTarget: ${{ matrix.vcpkg-platform-target }} diff --git a/Natives/NetCord.Natives/NetCord.Natives.Symlinking.targets b/Natives/NetCord.Natives/NetCord.Natives.Symlinking.targets index 3a18e7e0e..09ef94afc 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.Symlinking.targets +++ b/Natives/NetCord.Natives/NetCord.Natives.Symlinking.targets @@ -11,7 +11,7 @@ <_Symlink Include="@(FileWrites)" Condition="$([System.Text.RegularExpressions.Regex]::IsMatch('%(Filename)%(Extension)', '\.dylib$'))"> %(Filename)%(Extension) - $([System.Text.RegularExpressions.Regex]::Match('%(Filename)%(Extension)', '^(.*?\.\d+)\..*\.dylib$').Groups[1].Value + '.dylib') + $([System.Text.RegularExpressions.Regex]::Replace('%(Filename)%(Extension)', '^(.*?\.\d+)\..*\.dylib$', '$1.dylib')) $([System.Text.RegularExpressions.Regex]::Replace('%(Filename)%(Extension)', '\.\d+.*\.dylib$', '.dylib')) From fd12cc6d466aa18f6c8bdbf4e52165c2d17793d4 Mon Sep 17 00:00:00 2001 From: ha-ves <20160532+ha-ves@users.noreply.github.com> Date: Sun, 5 Jul 2026 03:30:00 +0900 Subject: [PATCH 076/101] [skip ci] fix linux CI --- Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs b/Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs index e7b1284a6..11f9ce441 100644 --- a/Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs +++ b/Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs @@ -84,7 +84,8 @@ private static void MSBuildNativeAotPublish(string libNames) // 2. Parse MSBuild Global Properties into a Dictionary var globalProperties = new Dictionary { - { "Configuration", configuration } + { "Configuration", configuration }, + { "CI", "false" } }; var pairs = propsAttr?.Split([';', ','], StringSplitOptions.RemoveEmptyEntries) ?? []; From 88bd4644e47445ca333f0f6c2ec986db9f39c679 Mon Sep 17 00:00:00 2001 From: ha-ves <20160532+ha-ves@users.noreply.github.com> Date: Sun, 5 Jul 2026 17:49:45 +0900 Subject: [PATCH 077/101] Fix vcpkg ssl static so it doesnt conflict with dotnet * custom triplets * proper msbuild flow * revert symlink to be combined in main build files * proper symlink and prevent copy to output --- .github/workflows/build-natives.yml | 4 - .../NetCord.Natives.Symlinking.targets | 28 --- .../NetCord.Natives/NetCord.Natives.csproj | 173 ++++++++++-------- .../NetCord.Natives.local.targets | 21 ++- Natives/NetCord.Natives/NetCord.Natives.props | 2 +- .../NetCord.Natives/NetCord.Natives.targets | 56 ++++-- .../arm64-linux-dynamic.cmake | 10 + .../arm64-linux-musl-dynamic.cmake | 7 +- .../natives-triplets/arm64-linux-musl.cmake | 1 + .../natives-triplets/arm64-osx-dynamic.cmake | 10 + .../arm64-windows-dynamic.cmake | 8 + .../natives-triplets/x64-linux-dynamic.cmake | 10 + .../x64-linux-musl-dynamic.cmake | 7 +- .../natives-triplets/x64-linux-musl.cmake | 1 + .../natives-triplets/x64-osx-dynamic.cmake | 10 + .../x64-windows-dynamic.cmake | 8 + .../NativesBuildTests.cs | 31 ---- 17 files changed, 227 insertions(+), 160 deletions(-) delete mode 100644 Natives/NetCord.Natives/NetCord.Natives.Symlinking.targets create mode 100644 Natives/NetCord.Natives/natives-triplets/arm64-linux-dynamic.cmake create mode 100644 Natives/NetCord.Natives/natives-triplets/arm64-osx-dynamic.cmake create mode 100644 Natives/NetCord.Natives/natives-triplets/arm64-windows-dynamic.cmake create mode 100644 Natives/NetCord.Natives/natives-triplets/x64-linux-dynamic.cmake create mode 100644 Natives/NetCord.Natives/natives-triplets/x64-osx-dynamic.cmake create mode 100644 Natives/NetCord.Natives/natives-triplets/x64-windows-dynamic.cmake diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index 184ca355c..e9a53986a 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -86,10 +86,6 @@ jobs: run: shell: ${{ matrix.shell_command }} env: - CI: true - DOTNET_CLI_TELEMETRY_OPTOUT: 1 - DOTNET_NOLOGO: 1 - MSBUILD_TELEMETRY_OPTOUT: 1 VCPKG_ROOT: ${{ github.workspace }}/Natives/NetCord.Natives/vcpkg VcpkgOSTarget: ${{ matrix.vcpkg-os-target }} VcpkgPlatformTarget: ${{ matrix.vcpkg-platform-target }} diff --git a/Natives/NetCord.Natives/NetCord.Natives.Symlinking.targets b/Natives/NetCord.Natives/NetCord.Natives.Symlinking.targets deleted file mode 100644 index 09ef94afc..000000000 --- a/Natives/NetCord.Natives/NetCord.Natives.Symlinking.targets +++ /dev/null @@ -1,28 +0,0 @@ - - - - - <_Symlink Include="@(FileWrites)" - Condition="$([System.Text.RegularExpressions.Regex]::IsMatch('%(Filename)%(Extension)', '\.so\.\d+'))"> - %(Filename)%(Extension) - $([System.Text.RegularExpressions.Regex]::Match('%(Filename)%(Extension)', '.*?\.so\.\d+').Value) - $([System.Text.RegularExpressions.Regex]::Replace('%(Filename)%(Extension)', '\.so\..*', '.so')) - - <_Symlink Include="@(FileWrites)" - Condition="$([System.Text.RegularExpressions.Regex]::IsMatch('%(Filename)%(Extension)', '\.dylib$'))"> - %(Filename)%(Extension) - $([System.Text.RegularExpressions.Regex]::Replace('%(Filename)%(Extension)', '^(.*?\.\d+)\..*\.dylib$', '$1.dylib')) - $([System.Text.RegularExpressions.Regex]::Replace('%(Filename)%(Extension)', '\.\d+.*\.dylib$', '.dylib')) - - - - - - - - - \ No newline at end of file diff --git a/Natives/NetCord.Natives/NetCord.Natives.csproj b/Natives/NetCord.Natives/NetCord.Natives.csproj index 2961ae131..ab9cbc093 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.csproj +++ b/Natives/NetCord.Natives/NetCord.Natives.csproj @@ -58,12 +58,14 @@ + + <_ZVcpkgInstallManifestDependenciesInputs Include="natives-ports\**;natives-triplets\**" /> - + @@ -86,13 +88,6 @@ - - - <_StaticFullPath Include="$([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)\$(VcpkgOutputPath_Static)'))" /> - - - - @@ -117,20 +112,20 @@ <_BuiltRid Include="linux-%(_LibArchs.Identity)"> - %(_LibArchs.Identity)-linux-dynamic\lib\lib%(_LibArchs.LibName) - %(_LibArchs.Identity)-linux\lib\lib%(_LibArchs.LibName) + %(_LibArchs.Identity)-linux-dynamic/lib/lib%(_LibArchs.LibName) + %(_LibArchs.Identity)-linux/lib/lib%(_LibArchs.LibName) so <_BuiltRid Include="linux-musl-%(_LibArchs.Identity)"> - %(_LibArchs.Identity)-linux-dynamic\lib\lib%(_LibArchs.LibName) - %(_LibArchs.Identity)-linux\lib\lib%(_LibArchs.LibName) + %(_LibArchs.Identity)-linux-dynamic/lib/lib%(_LibArchs.LibName) + %(_LibArchs.Identity)-linux/lib/lib%(_LibArchs.LibName) so <_BuiltRid Include="osx-%(_LibArchs.Identity)"> - %(_LibArchs.Identity)-osx-dynamic\lib\lib%(_LibArchs.LibName) - %(_LibArchs.Identity)-osx\lib\lib%(_LibArchs.LibName) + %(_LibArchs.Identity)-osx-dynamic/lib/lib%(_LibArchs.LibName) + %(_LibArchs.Identity)-osx/lib/lib%(_LibArchs.LibName) dylib @@ -154,6 +149,79 @@ Condition="'$(VcpkgUseStatic)' != 'true'" /> + + + + + + + + + + + + + %(NativesRuntime.Filename)%(NativesRuntime.Extension) + PreserveNewest + + + + + + + + + + + + + runtimes\%(_BuiltRid.Identity)\native\ + + + runtimes\%(_BuiltRid.Identity)\native\ + + + + + + + + + + + staticlibs\%(_BuiltRid.Identity)\ + + + + + + + <_RuntimesPath Include="$([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)\$(VcpkgOutputPath)'))" /> + + + + + + + <_StaticFullPath Include="$([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)\$(VcpkgOutputPath_Static)'))" /> + + + + @@ -185,39 +253,12 @@ Importance="high" Condition="'%(_VcpkgPkg.Identity)' != ''"/> - - - - - - <_SymlinksToRemoveRuntime Include="@(NativesRuntime)" - Condition="Exists('%(FullPath)') and ($([MSBuild]::BitwiseAnd($([System.IO.File]::GetAttributes('%(FullPath)')), 1024)) == 1024)" /> - - - <_CopyOutput Include="%(NativesRuntime.FullPath)"> - %(NativesRuntime.Filename)%(NativesRuntime.Extension) - PreserveNewest - - - - - - - - - - - PackagePerNative - @@ -227,8 +268,8 @@ + Targets="Pack" + BuildInParallel="true" /> $(RestoreOutputPath)/meta-nuget @@ -238,13 +279,14 @@ + Properties="_NativePkgVer=$(PackageVersion);_MetaNativePkg=true;RestoreSources=$(MSBuildProjectDirectory)/$(PackageOutputPath);RestoreOutputPath=$(RestoreOutputPath)" /> - + @@ -252,12 +294,12 @@ - <_NativeLicenseSource Include="$(VcpkgOutputPath_Static)\share\%(NativeLibLic.Identity)\copyright" - Condition="Exists('$(VcpkgOutputPath_Static)\share\%(NativeLibLic.Identity)\copyright')"> + Condition="Exists('$(VcpkgOutputPath_Static)\share\%(NativeLibLic.Identity)\copyright')"> $(VcpkgOutputPath_Static)\licenses\%(NativeLibLic.Identity)_LICENSE.txt @@ -269,27 +311,11 @@ $(PackageId).$(PackageNativeDep) - - - - runtimes\%(_BuiltRid.Identity)\native\ - - - - runtimes\%(_BuiltRid.Identity)\native\ - - - - - staticlibs\%(_BuiltRid.Identity)\ - - - <_SymlinksToRemoveBuilt Include="@(NativesBuilt)" - Condition="Exists('%(FullPath)') and ($([MSBuild]::BitwiseAnd($([System.IO.File]::GetAttributes('%(FullPath)')), 1024)) == 1024)" /> - + + + + true %(NativesBuilt.PackPath)%(NativesBuilt.Filename)%(NativesBuilt.Extension) @@ -302,19 +328,14 @@ <_BuildFiles Include="$(MSBuildProjectName).props;$(MSBuildProjectName).targets"> - $(PackageId) - - <_BuildFiles Include="$(MSBuildProjectName).Symlinking.targets"> - $(PackageId).Symlinking + true - build\%(_BuildFiles.PkgPath)%(_BuildFiles.Extension) - true + build\$(PackageId)%(_BuildFiles.Extension) - buildTransitive\%(_BuildFiles.PkgPath)%(_BuildFiles.Extension) - true + buildTransitive\$(PackageId)%(_BuildFiles.Extension) diff --git a/Natives/NetCord.Natives/NetCord.Natives.local.targets b/Natives/NetCord.Natives/NetCord.Natives.local.targets index 3851855cd..2d6bf035c 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.local.targets +++ b/Natives/NetCord.Natives/NetCord.Natives.local.targets @@ -6,23 +6,22 @@ - + - + Targets="GetSharedBuildDir"> + - %(_NetCordStaticDir.Identity)\lib - $([System.IO.Path]::GetDirectoryName('%(_NetCordRuntimesDir.FullPath)')) + %(_NativeStaticDir.FullPath)\lib + %(_NativeSharedDir.FullPath)\lib - @@ -31,4 +30,12 @@ + + + <_SourceItemsToCopyToOutputDirectory Remove="%(_RunExclude.FullPath)" /> + + diff --git a/Natives/NetCord.Natives/NetCord.Natives.props b/Natives/NetCord.Natives/NetCord.Natives.props index fcfe954c0..00bb2f9a8 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.props +++ b/Natives/NetCord.Natives/NetCord.Natives.props @@ -9,7 +9,7 @@ --> - $(MSBuildThisFileDirectory)..\runtimes\$(RuntimeIdentifier)\native + $(MSBuildThisFileDirectory)..\runtimes\$(RuntimeIdentifier)\native $(MSBuildThisFileDirectory)..\staticlibs\$(RuntimeIdentifier) diff --git a/Natives/NetCord.Natives/NetCord.Natives.targets b/Natives/NetCord.Natives/NetCord.Natives.targets index 2d55eacee..4ee457b11 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.targets +++ b/Natives/NetCord.Natives/NetCord.Natives.targets @@ -2,6 +2,9 @@ + <_NativesRuntime Include="$(NetCordNativesSharedDir)\**" + Condition="'$(NetCordNativesSharedDir)' != ''" /> + <_NetCordStaticLink Include="sodium" @@ -26,17 +29,16 @@ <_NetCordExcluded Include="$(NetCordExcludeNatives)" Condition="'$(NetCordExcludeNatives)' != ''" /> - <_NetCordExcluded Include="crypto;ssl" + <_NetCordExcluded Include="crypto" Condition="$(NetCordExcludeNatives.Contains('libdave'))" /> <_NetCordExcluded Include="@(_NetCordStaticLink)" Condition="'$(PublishAot)' == 'true' and '%(_NetCordStaticLink.Identity)' != ''"/> - <_RunExclude Include="$(NetCordNativesRuntimesDir)\%(_NetCordExcluded.Identity)*.*" - Condition="'%(_NetCordExcluded.Identity)' != '' and '$(NetCordNativesRuntimesDir)' != ''" /> - <_RunExclude Include="$(NetCordNativesRuntimesDir)\lib%(_NetCordExcluded.Identity)*.*" - Condition="'%(_NetCordExcluded.Identity)' != '' and '$(NetCordNativesRuntimesDir)' != ''" /> - + <_RunExclude Include="$(NetCordNativesSharedDir)\%(_NetCordExcluded.Identity)*.*" + Condition="'%(_NetCordExcluded.Identity)' != '' and '$(NetCordNativesSharedDir)' != ''" /> + <_RunExclude Include="$(NetCordNativesSharedDir)\lib%(_NetCordExcluded.Identity)*.*" + Condition="'%(_NetCordExcluded.Identity)' != '' and '$(NetCordNativesSharedDir)' != ''" /> @@ -66,12 +68,44 @@ - + + + <_CopiedNonNatives Include="@(_SourceItemsToCopyToOutputDirectory)" + Exclude="@(_NativesRuntime)" /> + <_CopiedNatives Include="@(_SourceItemsToCopyToOutputDirectory)" + Exclude="@(_CopiedNonNatives)" /> + <_NativesShared Include="$(OutDir)%(_CopiedNatives.TargetPath)" /> + + <_Symlink Include="@(_NativesShared)" + Condition="$([System.Text.RegularExpressions.Regex]::IsMatch('%(Filename)%(Extension)', '\.so\.\d+'))"> + %(Filename)%(Extension) + $([System.Text.RegularExpressions.Regex]::Match('%(Filename)%(Extension)', '.*?\.so\.\d+').Value) + $([System.Text.RegularExpressions.Regex]::Replace('%(Filename)%(Extension)', '\.so\..*', '.so')) + + <_Symlink Include="@(_NativesShared)" + Condition="$([System.Text.RegularExpressions.Regex]::IsMatch('%(Filename)%(Extension)', '\.dylib$'))"> + %(Filename)%(Extension) + $([System.Text.RegularExpressions.Regex]::Replace('%(Filename)%(Extension)', '^(.*?\.\d+)\..*\.dylib$', '$1.dylib')) + $([System.Text.RegularExpressions.Regex]::Replace('%(Filename)%(Extension)', '\.\d+.*\.dylib$', '.dylib')) + + - + - - + + + + + + + + diff --git a/Natives/NetCord.Natives/natives-triplets/arm64-linux-dynamic.cmake b/Natives/NetCord.Natives/natives-triplets/arm64-linux-dynamic.cmake new file mode 100644 index 000000000..03934bd67 --- /dev/null +++ b/Natives/NetCord.Natives/natives-triplets/arm64-linux-dynamic.cmake @@ -0,0 +1,10 @@ +set(VCPKG_TARGET_ARCHITECTURE arm64) +set(VCPKG_CRT_LINKAGE dynamic) +if(PORT STREQUAL "openssl") + set(VCPKG_LIBRARY_LINKAGE static) +else() + set(VCPKG_LIBRARY_LINKAGE dynamic) +endif() +set(VCPKG_CMAKE_SYSTEM_NAME Linux) +set(VCPKG_FIXUP_ELF_RPATH ON) +set(VCPKG_BUILD_TYPE release) diff --git a/Natives/NetCord.Natives/natives-triplets/arm64-linux-musl-dynamic.cmake b/Natives/NetCord.Natives/natives-triplets/arm64-linux-musl-dynamic.cmake index 2e76fb3af..9b0cbcd61 100644 --- a/Natives/NetCord.Natives/natives-triplets/arm64-linux-musl-dynamic.cmake +++ b/Natives/NetCord.Natives/natives-triplets/arm64-linux-musl-dynamic.cmake @@ -1,4 +1,9 @@ set(VCPKG_TARGET_ARCHITECTURE arm64) set(VCPKG_CRT_LINKAGE dynamic) -set(VCPKG_LIBRARY_LINKAGE dynamic) +if(PORT STREQUAL "openssl") + set(VCPKG_LIBRARY_LINKAGE static) +else() + set(VCPKG_LIBRARY_LINKAGE dynamic) +endif() set(VCPKG_CMAKE_SYSTEM_NAME Linux) +set(VCPKG_BUILD_TYPE release) diff --git a/Natives/NetCord.Natives/natives-triplets/arm64-linux-musl.cmake b/Natives/NetCord.Natives/natives-triplets/arm64-linux-musl.cmake index a402a1fa4..b3ce7b56a 100644 --- a/Natives/NetCord.Natives/natives-triplets/arm64-linux-musl.cmake +++ b/Natives/NetCord.Natives/natives-triplets/arm64-linux-musl.cmake @@ -2,3 +2,4 @@ set(VCPKG_TARGET_ARCHITECTURE arm64) set(VCPKG_CRT_LINKAGE static) set(VCPKG_LIBRARY_LINKAGE static) set(VCPKG_CMAKE_SYSTEM_NAME Linux) +set(VCPKG_BUILD_TYPE release) diff --git a/Natives/NetCord.Natives/natives-triplets/arm64-osx-dynamic.cmake b/Natives/NetCord.Natives/natives-triplets/arm64-osx-dynamic.cmake new file mode 100644 index 000000000..c86e8b8fe --- /dev/null +++ b/Natives/NetCord.Natives/natives-triplets/arm64-osx-dynamic.cmake @@ -0,0 +1,10 @@ +set(VCPKG_TARGET_ARCHITECTURE arm64) +set(VCPKG_CRT_LINKAGE dynamic) +if(PORT STREQUAL "openssl") + set(VCPKG_LIBRARY_LINKAGE static) +else() + set(VCPKG_LIBRARY_LINKAGE dynamic) +endif() +set(VCPKG_CMAKE_SYSTEM_NAME Darwin) +set(VCPKG_OSX_ARCHITECTURES arm64) +set(VCPKG_BUILD_TYPE release) diff --git a/Natives/NetCord.Natives/natives-triplets/arm64-windows-dynamic.cmake b/Natives/NetCord.Natives/natives-triplets/arm64-windows-dynamic.cmake new file mode 100644 index 000000000..934e3d371 --- /dev/null +++ b/Natives/NetCord.Natives/natives-triplets/arm64-windows-dynamic.cmake @@ -0,0 +1,8 @@ +set(VCPKG_TARGET_ARCHITECTURE arm64) +set(VCPKG_CRT_LINKAGE dynamic) +if(PORT STREQUAL "openssl") + set(VCPKG_LIBRARY_LINKAGE static) +else() + set(VCPKG_LIBRARY_LINKAGE dynamic) +endif() +set(VCPKG_BUILD_TYPE release) diff --git a/Natives/NetCord.Natives/natives-triplets/x64-linux-dynamic.cmake b/Natives/NetCord.Natives/natives-triplets/x64-linux-dynamic.cmake new file mode 100644 index 000000000..945c86b22 --- /dev/null +++ b/Natives/NetCord.Natives/natives-triplets/x64-linux-dynamic.cmake @@ -0,0 +1,10 @@ +set(VCPKG_TARGET_ARCHITECTURE x64) +set(VCPKG_CRT_LINKAGE dynamic) +if(PORT STREQUAL "openssl") + set(VCPKG_LIBRARY_LINKAGE static) +else() + set(VCPKG_LIBRARY_LINKAGE dynamic) +endif() +set(VCPKG_CMAKE_SYSTEM_NAME Linux) +set(VCPKG_FIXUP_ELF_RPATH ON) +set(VCPKG_BUILD_TYPE release) diff --git a/Natives/NetCord.Natives/natives-triplets/x64-linux-musl-dynamic.cmake b/Natives/NetCord.Natives/natives-triplets/x64-linux-musl-dynamic.cmake index b6f5fc5fc..3a0138ebc 100644 --- a/Natives/NetCord.Natives/natives-triplets/x64-linux-musl-dynamic.cmake +++ b/Natives/NetCord.Natives/natives-triplets/x64-linux-musl-dynamic.cmake @@ -1,4 +1,9 @@ set(VCPKG_TARGET_ARCHITECTURE x64) set(VCPKG_CRT_LINKAGE dynamic) -set(VCPKG_LIBRARY_LINKAGE dynamic) +if(PORT STREQUAL "openssl") + set(VCPKG_LIBRARY_LINKAGE static) +else() + set(VCPKG_LIBRARY_LINKAGE dynamic) +endif() set(VCPKG_CMAKE_SYSTEM_NAME Linux) +set(VCPKG_BUILD_TYPE release) diff --git a/Natives/NetCord.Natives/natives-triplets/x64-linux-musl.cmake b/Natives/NetCord.Natives/natives-triplets/x64-linux-musl.cmake index 8361f30d4..2e7edd0f1 100644 --- a/Natives/NetCord.Natives/natives-triplets/x64-linux-musl.cmake +++ b/Natives/NetCord.Natives/natives-triplets/x64-linux-musl.cmake @@ -2,3 +2,4 @@ set(VCPKG_TARGET_ARCHITECTURE x64) set(VCPKG_CRT_LINKAGE static) set(VCPKG_LIBRARY_LINKAGE static) set(VCPKG_CMAKE_SYSTEM_NAME Linux) +set(VCPKG_BUILD_TYPE release) diff --git a/Natives/NetCord.Natives/natives-triplets/x64-osx-dynamic.cmake b/Natives/NetCord.Natives/natives-triplets/x64-osx-dynamic.cmake new file mode 100644 index 000000000..a582b3589 --- /dev/null +++ b/Natives/NetCord.Natives/natives-triplets/x64-osx-dynamic.cmake @@ -0,0 +1,10 @@ +set(VCPKG_TARGET_ARCHITECTURE x64) +set(VCPKG_CRT_LINKAGE dynamic) +if(PORT STREQUAL "openssl") + set(VCPKG_LIBRARY_LINKAGE static) +else() + set(VCPKG_LIBRARY_LINKAGE dynamic) +endif() +set(VCPKG_CMAKE_SYSTEM_NAME Darwin) +set(VCPKG_OSX_ARCHITECTURES x86_64) +set(VCPKG_BUILD_TYPE release) diff --git a/Natives/NetCord.Natives/natives-triplets/x64-windows-dynamic.cmake b/Natives/NetCord.Natives/natives-triplets/x64-windows-dynamic.cmake new file mode 100644 index 000000000..29ec64e3c --- /dev/null +++ b/Natives/NetCord.Natives/natives-triplets/x64-windows-dynamic.cmake @@ -0,0 +1,8 @@ +set(VCPKG_TARGET_ARCHITECTURE x64) +set(VCPKG_CRT_LINKAGE dynamic) +if(PORT STREQUAL "openssl") + set(VCPKG_LIBRARY_LINKAGE static) +else() + set(VCPKG_LIBRARY_LINKAGE dynamic) +endif() +set(VCPKG_BUILD_TYPE release) diff --git a/Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs b/Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs index 11f9ce441..592561f12 100644 --- a/Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs +++ b/Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs @@ -13,13 +13,6 @@ namespace NetCord.Natives.Tests; [TestClass] public class NativesBuildTests { - private static readonly IReadOnlyDictionary TelemetryOptOutEnvironment = new Dictionary - { - ["DOTNET_CLI_TELEMETRY_OPTOUT"] = "1", - ["DOTNET_NOLOGO"] = "1", - ["MSBUILD_TELEMETRY_OPTOUT"] = "1", - }; - [TestMethod] [DataRow("libdave")] [DataRow("libsodium")] @@ -62,8 +55,6 @@ public void NativeAotStaticLinking(string libNames) private static void MSBuildNativeAotPublish(string libNames) { - using var _ = new EnvironmentVariableScope(TelemetryOptOutEnvironment); - // 1. Get properties from AssemblyMetadata attributes var assembly = typeof(NativesBuildTests).Assembly; @@ -205,26 +196,4 @@ private static void MSBuildNativeAotPublish(string libNames) Assert.AreEqual(0, aotProcess.ExitCode, $"Native AoT app failed to run for '{libNames}'."); } - - private sealed class EnvironmentVariableScope : IDisposable - { - private readonly Dictionary _originalValues = new(StringComparer.Ordinal); - - public EnvironmentVariableScope(IReadOnlyDictionary variables) - { - foreach (var pair in variables) - { - _originalValues[pair.Key] = Environment.GetEnvironmentVariable(pair.Key); - Environment.SetEnvironmentVariable(pair.Key, pair.Value); - } - } - - public void Dispose() - { - foreach (var pair in _originalValues) - { - Environment.SetEnvironmentVariable(pair.Key, pair.Value); - } - } - } } From eab8fc098fc9343d8e8218ecdaaea76052fe2893 Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Tue, 7 Jul 2026 00:26:57 +0900 Subject: [PATCH 078/101] Fix windows build * fix musl builtrid path * windows path length check * nativeaotstaticlinking test remove dll check * CI & whitespace cleanup --- .github/workflows/build-natives.yml | 2 +- .../NetCord.Natives/NetCord.Natives.csproj | 17 ++++++--- .../NetCord.Natives.local.targets | 4 +- Natives/NetCord.Natives/NetCord.Natives.props | 2 +- .../NetCord.Natives/NetCord.Natives.targets | 4 +- ...dows-dynamic.cmake => arm64-windows.cmake} | 0 ...indows-dynamic.cmake => x64-windows.cmake} | 0 .../NetCord.Natives/vcpkg-non-windows.targets | 6 +-- Natives/Tests/NativeProbes.cs | 12 +++--- .../NativesBuildTests.cs | 38 +------------------ 10 files changed, 28 insertions(+), 57 deletions(-) rename Natives/NetCord.Natives/natives-triplets/{arm64-windows-dynamic.cmake => arm64-windows.cmake} (100%) rename Natives/NetCord.Natives/natives-triplets/{x64-windows-dynamic.cmake => x64-windows.cmake} (100%) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index e9a53986a..edefeb749 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -201,7 +201,7 @@ jobs: --no-restore --no-build -v ${{ env.DotnetVerbose }} - ${{ env.GenerateBinLog == 'true' && '-bl:test.binlog -p:NativeAotBinLogPath="$PWD/nativeaotapptest.binlog"' || '' }} + ${{ env.GenerateBinLog == 'true' && '-bl:test.binlog' || '' }} --logger "console;verbosity=detailed" --logger GitHubActions ${{ matrix.vcpkg-os-target == 'osx' && '-p:InvariantGlobalization=true' || '' }} diff --git a/Natives/NetCord.Natives/NetCord.Natives.csproj b/Natives/NetCord.Natives/NetCord.Natives.csproj index ab9cbc093..a1302e194 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.csproj +++ b/Natives/NetCord.Natives/NetCord.Natives.csproj @@ -118,8 +118,8 @@ <_BuiltRid Include="linux-musl-%(_LibArchs.Identity)"> - %(_LibArchs.Identity)-linux-dynamic/lib/lib%(_LibArchs.LibName) - %(_LibArchs.Identity)-linux/lib/lib%(_LibArchs.LibName) + %(_LibArchs.Identity)-linux-musl-dynamic/lib/lib%(_LibArchs.LibName) + %(_LibArchs.Identity)-linux-musl/lib/lib%(_LibArchs.LibName) so @@ -139,6 +139,13 @@ + + + <_FullVcpkgRoot>$([System.IO.Path]::GetFullPath('$(VcpkgRoot)')) + + + - @@ -282,10 +289,10 @@ Properties="_NativePkgVer=$(PackageVersion);_MetaNativePkg=true;RestoreSources=$(MSBuildProjectDirectory)/$(PackageOutputPath);RestoreOutputPath=$(RestoreOutputPath)" /> - - diff --git a/Natives/NetCord.Natives/NetCord.Natives.local.targets b/Natives/NetCord.Natives/NetCord.Natives.local.targets index 2d6bf035c..72a3c9ea2 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.local.targets +++ b/Natives/NetCord.Natives/NetCord.Natives.local.targets @@ -16,9 +16,9 @@ %(_NativeStaticDir.FullPath)\lib - %(_NativeSharedDir.FullPath)\lib + %(_NativeSharedDir.FullPath)\bin + %(_NativeSharedDir.FullPath)\lib - <_ZVcpkgTLogFileLocation>$(TLogLocation)VcpkgInstallManifest$(VcpkgTriplet).$(_ZVcpkgHostTripletSuffix)read.1u.tlog - + <_ZVcpkgExecutable Condition="Exists('$(_ZVcpkgRoot)vcpkg')">$(_ZVcpkgRoot)vcpkg <_ZVcpkgExecutable Condition="'$(_ZVcpkgExecutable)' == ''">vcpkg diff --git a/Natives/Tests/NativeProbes.cs b/Natives/Tests/NativeProbes.cs index 0f92c002a..aff4cd3f8 100644 --- a/Natives/Tests/NativeProbes.cs +++ b/Natives/Tests/NativeProbes.cs @@ -109,13 +109,13 @@ private static bool IsMatchingLibrary(string? attributeLibName, string searchLib } /* - * This method is not working on macOS due to System.Diagnostics.ProcessModule + * This method is not working on macOS due to System.Diagnostics.ProcessModule * not listing native libraries loaded by the runtime's dynamic library loader (dyld). - * This is likely because dyld does not expose these libraries to the process in the - * same way that LoadLibrary on Windows or dlopen on Linux does, and as a result they - * do not appear in the list of modules for the process. This is a known limitation - * when trying to inspect loaded native libraries on macOS using .NET, and may require - * platform-specific workarounds or tools to verify the presence of native libraries + * This is likely because dyld does not expose these libraries to the process in the + * same way that LoadLibrary on Windows or dlopen on Linux does, and as a result they + * do not appear in the list of modules for the process. This is a known limitation + * when trying to inspect loaded native libraries on macOS using .NET, and may require + * platform-specific workarounds or tools to verify the presence of native libraries * on that platform. */ internal static IntPtr GetLoadedNativeModuleHandle(string libName) diff --git a/Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs b/Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs index 592561f12..16b3b7c73 100644 --- a/Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs +++ b/Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs @@ -120,7 +120,6 @@ private static void MSBuildNativeAotPublish(string libNames) Assert.AreEqual(BuildResultCode.Success, buildResult.OverallResult, $"Native AoT build failed for '{libNames}'."); // 5. Instantly extract the 'PublishDir' property from the evaluated project state - // (This replaces the entire second "dotnet build -getProperty" process call!) var publishDirProperty = projectInstance.GetPropertyValue("PublishDir"); Assert.IsFalse(string.IsNullOrEmpty(publishDirProperty), $"PublishDir is empty for '{libNames}'."); @@ -132,42 +131,7 @@ private static void MSBuildNativeAotPublish(string libNames) Console.WriteLine($"[{NativeAotAppLogTag}/Publish] Native AoT app published to: '{runCmdOutput}'"); - // 6. Assertions on copied native binaries - var libs = libNames.Split([';', ','], StringSplitOptions.RemoveEmptyEntries).Select(l => l.Trim()); - var deps = new List(); - - foreach (var lib in libs) - { - switch (lib) - { - case "libdave": - deps.AddRange([lib, "crypto"]); - break; - case "libsodium": - case "opus": - case "zstd": - deps.Add(lib); - break; - default: - throw new InvalidOperationException($"Unknown library name '{lib}' provided to test."); - } - } - - var copiedDlls = Directory.GetFiles(Path.GetDirectoryName(runCmdOutput) ?? string.Empty, - RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "*.dll" : - RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? "lib*.so" : "lib*.dylib", - SearchOption.TopDirectoryOnly) - .Select(Path.GetFileName); - - var matchCopied = copiedDlls.Where(dll => dll != null && deps.Any(lib => - dll.StartsWith(lib, StringComparison.OrdinalIgnoreCase) || - dll.StartsWith($"lib{lib}", StringComparison.OrdinalIgnoreCase))) - .ToList(); - - Assert.IsEmpty(matchCopied, $"These should've not been copied to the publish output directory: {string.Join(", ", matchCopied)}"); - - // 7. Execute the generated Native AOT Binary - // NOTE: Running the compiled native application still requires System.Diagnostics.Process + // Execute the generated Native AOT Binary var aotProcess = new System.Diagnostics.Process(); aotProcess.StartInfo.FileName = runCmdOutput; aotProcess.StartInfo.WorkingDirectory = Path.GetDirectoryName(runCmdOutput); From 93e66694633d1803092637a81cc389d500fd2ae1 Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Mon, 6 Jul 2026 18:01:09 +0200 Subject: [PATCH 079/101] Use magic-nix-cache-action only for musl builds --- .github/workflows/build-natives.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index edefeb749..438007b1b 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -34,48 +34,56 @@ jobs: vcpkg-os-target: windows vcpkg-platform-target: x64 use-nix: false + musl: false shell_command: pwsh - rid: win-arm64 runs-on: windows-11-arm vcpkg-os-target: windows vcpkg-platform-target: arm64 use-nix: false + musl: false shell_command: pwsh - rid: osx-x64 runs-on: macos-15-intel vcpkg-os-target: osx vcpkg-platform-target: x64 use-nix: true + musl: false shell_command: nix develop .#natives -c bash -eo pipefail {0} - rid: osx-arm64 runs-on: macos-15 vcpkg-os-target: osx vcpkg-platform-target: arm64 use-nix: true + musl: false shell_command: nix develop .#natives -c bash -eo pipefail {0} - rid: linux-x64 runs-on: ubuntu-latest vcpkg-os-target: linux vcpkg-platform-target: x64 use-nix: true + musl: false shell_command: nix develop .#natives -c bash -eo pipefail {0} - rid: linux-arm64 runs-on: ubuntu-24.04-arm vcpkg-os-target: linux vcpkg-platform-target: arm64 use-nix: true + musl: false shell_command: nix develop .#natives -c bash -eo pipefail {0} - rid: linux-musl-x64 runs-on: ubuntu-latest vcpkg-os-target: linux-musl vcpkg-platform-target: x64 use-nix: true + musl: true shell_command: nix develop .#natives-musl -c bash -eo pipefail {0} - rid: linux-musl-arm64 runs-on: ubuntu-24.04-arm vcpkg-os-target: linux-musl vcpkg-platform-target: arm64 use-nix: true + musl: true shell_command: nix develop .#natives-musl --option max-jobs 1 --option cores 3 -c bash -eo pipefail {0} runs-on: ${{ matrix.runs-on }} @@ -109,7 +117,7 @@ jobs: uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6 - name: Magic Nix Cache - if: ${{ matrix.use-nix }} + if: ${{ matrix.use-nix && matrix.musl }} uses: DeterminateSystems/magic-nix-cache-action@908b263ff629f4cc17666315b7fd3ec127c6244d # v14 - name: Setup dev environment (Nix) From 2fea6d182e9bdbedc8c56b10620ef29838a30c4e Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Tue, 7 Jul 2026 03:00:39 +0900 Subject: [PATCH 080/101] Fix symlinks exclusion msbuild --- .../NetCord.Natives/NetCord.Natives.csproj | 60 +++++++++++++------ 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/Natives/NetCord.Natives/NetCord.Natives.csproj b/Natives/NetCord.Natives/NetCord.Natives.csproj index a1302e194..e2ec6c1f5 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.csproj +++ b/Natives/NetCord.Natives/NetCord.Natives.csproj @@ -129,7 +129,7 @@ dylib - <_BuiltRid Remove="%(Identity)" Condition="'$(PackageNativeDep)' == '' and '%(Identity)' != '$(VcpkgBuildOS)-$(VcpkgPlatformTarget)'" /> + <_BuiltRid Remove="%(Identity)" Condition="'$(_IsPackingNative)' != 'true' and '%(Identity)' != '$(VcpkgBuildOS)-$(VcpkgPlatformTarget)'" /> @@ -177,29 +177,54 @@ - - - - - - runtimes\%(_BuiltRid.Identity)\native\ - runtimes\%(_BuiltRid.Identity)\native\ + + + + + + + + + + <_BuiltRidBinDir Include="$([System.IO.Path]::GetFullPath('$(VcpkgArtifactsRoot)/%(_BuiltRid.Identity)/natives/'))$([System.IO.Path]::GetDirectoryName('%(_BuiltRid.BinPath)'))" /> + - + + + + + + + + + + + + + + <_ScopedSymlinksToRemove Include="@(_RawScopedSymlinks)" Condition="'@(_RawScopedSymlinks)' != ''" /> @@ -260,8 +285,6 @@ Importance="high" Condition="'%(_VcpkgPkg.Identity)' != ''"/> - - PackagePerNative @@ -279,14 +302,15 @@ BuildInParallel="true" /> - $(RestoreOutputPath)/meta-nuget + <_MetaRestoreOutputPath>$(RestoreOutputPath)\meta-nuget\ + <_MetaRestoreSource>$([System.IO.Path]::GetFullPath('$(PackageOutputPath)')) - + + Properties="_NativePkgVer=$(PackageVersion);_MetaNativePkg=true;RestoreSources=$(_MetaRestoreSource);RestoreOutputPath=$(_MetaRestoreOutputPath)" /> Date: Sat, 11 Jul 2026 19:32:34 +0200 Subject: [PATCH 081/101] Fix a tick --- Documentation/guides/installing-native-dependencies.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/guides/installing-native-dependencies.md b/Documentation/guides/installing-native-dependencies.md index 49df6e527..b0ee1c0af 100644 --- a/Documentation/guides/installing-native-dependencies.md +++ b/Documentation/guides/installing-native-dependencies.md @@ -108,5 +108,5 @@ All necessary licenses and copyright notices from the original native project so | **Opus** | BSD-3-Clause | Audio codec | | **Zstd** | BSD-3-Clause | Compression | -### How It’s Built +### How It's Built * **Reproducible builds**: Dependencies are strictly pinned using [vcpkg](https://github.com/microsoft/vcpkg) baselines. This means every build result should be identical, regardless of who or what runs the build. From ab56d4fb52542304bf553da2a41e6724f71b9bb2 Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Tue, 7 Jul 2026 22:57:56 +0900 Subject: [PATCH 082/101] [skip ci] Cleanup symlink items --- Natives/NetCord.Natives/NetCord.Natives.targets | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Natives/NetCord.Natives/NetCord.Natives.targets b/Natives/NetCord.Natives/NetCord.Natives.targets index e7fc3ca61..f6ef4d663 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.targets +++ b/Natives/NetCord.Natives/NetCord.Natives.targets @@ -90,15 +90,13 @@ $([System.Text.RegularExpressions.Regex]::Replace('%(Filename)%(Extension)', '^(.*?\.\d+)\..*\.dylib$', '$1.dylib')) $([System.Text.RegularExpressions.Regex]::Replace('%(Filename)%(Extension)', '\.\d+.*\.dylib$', '.dylib')) + <_Symlink Remove="%(Identity)" Condition="'%(RealName)' == '' or '%(SoName)' == '' or '%(LinkerName)' == ''" /> + <_Symlink Remove="%(Identity)" Condition="'%(RealName)' == '%(SoName)' or '%(SoName)' == '' or '%(LinkerName)' == '' or '%(LinkerName)' == '%(RealName)'" /> - + - + From 5140e5152571928900e5208b2bf2a4be55d6cea8 Mon Sep 17 00:00:00 2001 From: ha-ves <20160532+ha-ves@users.noreply.github.com> Date: Wed, 8 Jul 2026 03:14:54 +0900 Subject: [PATCH 083/101] Fix nativeaot static linking test & CI workflow * fix vcpkgroot defaults to submodule path * remove bootstrap vcpkg target for non windows * fix mlspp vcpkg portfile for clang/gcc flags --- .github/workflows/build-natives.yml | 14 +++---- .../NetCord.Natives/NetCord.Natives.csproj | 1 + .../natives-ports/mlspp/portfile.cmake | 11 +++++- .../natives-ports/mlspp/vcpkg.json | 4 ++ .../NetCord.Natives/vcpkg-non-windows.targets | 7 ---- .../NativesBuildTests.cs | 38 +++++++++++++------ .../NetCord.Natives.Tests.csproj | 2 +- 7 files changed, 49 insertions(+), 28 deletions(-) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index 438007b1b..894048517 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -100,7 +100,6 @@ jobs: GITHUB_PACKAGES_FEED: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json VCPKG_BINARY_SOURCES: "clear;nugetconfig,${{ github.workspace }}/Natives/NetCord.Natives/vcpkg-nuget.config,readwrite" Configuration: Release - TargetRID: ${{ matrix.rid }} DotnetVerbose: ${{ github.event.inputs.MSBuildVerbosity || inputs.MSBuildVerbosity || 'Minimal' }} GenerateBinLog: ${{ github.event.inputs.GenerateBinLog || inputs.GenerateBinLog || false }} @@ -198,13 +197,13 @@ jobs: dotnet build Natives/NetCord.Natives.slnx --no-restore -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && format('-bl:build.binlog -p:NativeAotBinLogPath={0}/nativeaotapptest.binlog', github.workspace) || '' }} - -p:AppendNativeAotAppProps="RuntimeIdentifier=${{ env.TargetRID }}" - -p:GeneratePackageOnBuild=false -p:CI=false - ${{ matrix.vcpkg-os-target == 'osx' && '-p:InvariantGlobalization=true' || '' }} + -p:AppendNativeAotAppProps="RuntimeIdentifier=${{ matrix.rid }}%3BVcpkgOSTarget=${{ env.VcpkgOSTarget }}%3BVcpkgPlatformTarget=${{ env.VcpkgPlatformTarget }}" + -p:GeneratePackageOnBuild=false + ${{ env.VcpkgOSTarget == 'osx' && '-p:InvariantGlobalization=true' || '' }} - name: Test natives outputs for ${{ matrix.rid }} run: > - ${{ matrix.vcpkg-os-target == 'linux-musl' && 'docker run --rm -v $PWD:$PWD -w $PWD -e Configuration -e VCPKG_ROOT -e MINVERVERSIONOVERRIDE=1.0.0 mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot' || '' }} + ${{ matrix.musl && 'docker run --rm -v $PWD:$PWD -w $PWD -e DotnetVerbose -e MINVERVERSIONOVERRIDE=1.0.0 mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot' || '' }} dotnet test Natives/NetCord.Natives.slnx --no-restore --no-build @@ -212,7 +211,6 @@ jobs: ${{ env.GenerateBinLog == 'true' && '-bl:test.binlog' || '' }} --logger "console;verbosity=detailed" --logger GitHubActions - ${{ matrix.vcpkg-os-target == 'osx' && '-p:InvariantGlobalization=true' || '' }} - name: Upload Binary Logs if: ${{ env.GenerateBinLog == 'true' && always() }} @@ -225,8 +223,8 @@ jobs: - name: Clean Symbollic Links (Nix) if: ${{ matrix.use-nix }} run: | - find Natives/NetCord.Natives/bin/${{ matrix.rid }}/natives/${{ matrix.vcpkg-platform-target }}-${{ matrix.vcpkg-os-target }}-dynamic/lib/ -type l -exec rm {} \; - find Natives/NetCord.Natives/bin/${{ matrix.rid }}/natives-static/${{ matrix.vcpkg-platform-target }}-${{ matrix.vcpkg-os-target }}/lib/ -type l -exec rm {} \; + find Natives/NetCord.Natives/bin/${{ matrix.rid }}/natives/${{ env.VcpkgPlatformTarget }}-${{ env.VcpkgOSTarget }}-dynamic/lib/ -type l -exec rm {} \; + find Natives/NetCord.Natives/bin/${{ matrix.rid }}/natives-static/${{ env.VcpkgPlatformTarget }}-${{ env.VcpkgOSTarget }}/lib/ -type l -exec rm {} \; - name: Upload Natives Artifact if: ${{ always() && steps.build_step.outcome == 'success' }} diff --git a/Natives/NetCord.Natives/NetCord.Natives.csproj b/Natives/NetCord.Natives/NetCord.Natives.csproj index e2ec6c1f5..d6c7dd14c 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.csproj +++ b/Natives/NetCord.Natives/NetCord.Natives.csproj @@ -28,6 +28,7 @@ bin $(VCPKG_ROOT) + $(MSBuildProjectDirectory)\vcpkg $(VcpkgRoot)\scripts\buildsystems\msbuild\vcpkg Release diff --git a/Natives/NetCord.Natives/natives-ports/mlspp/portfile.cmake b/Natives/NetCord.Natives/natives-ports/mlspp/portfile.cmake index c24466d30..7c63151f2 100644 --- a/Natives/NetCord.Natives/natives-ports/mlspp/portfile.cmake +++ b/Natives/NetCord.Natives/natives-ports/mlspp/portfile.cmake @@ -11,9 +11,18 @@ endif() set(VCPKG_LIBRARY_LINKAGE static) +vcpkg_cmake_get_vars(cmake_vars_file) +include("${cmake_vars_file}") + set(EXTRA_OPTIONS -DDISABLE_GREASE=ON -DTESTING=OFF -DBUILD_TESTING=OFF -DMLS_CXX_NAMESPACE="mlspp") if(VCPKG_HOST_IS_LINUX) - list(APPEND EXTRA_OPTIONS -DCMAKE_CXX_FLAGS="-Wno-error=uninitialized") + if(VCPKG_DETECTED_CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + # Safe for GCC: Apply both flags safely as a single quoted string + list(APPEND EXTRA_OPTIONS "-DCMAKE_CXX_FLAGS=-Wno-error=maybe-uninitialized -Wno-error=uninitialized") + else() + # Safe for Clang: Only apply the base uninitialized flag + list(APPEND EXTRA_OPTIONS "-DCMAKE_CXX_FLAGS=-Wno-error=uninitialized") + endif() endif() vcpkg_cmake_configure( diff --git a/Natives/NetCord.Natives/natives-ports/mlspp/vcpkg.json b/Natives/NetCord.Natives/natives-ports/mlspp/vcpkg.json index fca869782..eafa20d39 100644 --- a/Natives/NetCord.Natives/natives-ports/mlspp/vcpkg.json +++ b/Natives/NetCord.Natives/natives-ports/mlspp/vcpkg.json @@ -12,6 +12,10 @@ { "name": "vcpkg-cmake-config", "host": true + }, + { + "name": "vcpkg-cmake-get-vars", + "host": true } ] } diff --git a/Natives/NetCord.Natives/vcpkg-non-windows.targets b/Natives/NetCord.Natives/vcpkg-non-windows.targets index e28c8c24f..60fd36a22 100644 --- a/Natives/NetCord.Natives/vcpkg-non-windows.targets +++ b/Natives/NetCord.Natives/vcpkg-non-windows.targets @@ -1,5 +1,4 @@ - <_ZVcpkgInstallManifestDependenciesInputs Include="$(_ZVcpkgManifestFileLocation)"/> <_ZVcpkgInstallManifestDependenciesInputs Include="$(_ZVcpkgConfigurationFileLocation)" @@ -45,10 +44,4 @@ - - - - - - diff --git a/Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs b/Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs index 16b3b7c73..d127ecf15 100644 --- a/Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs +++ b/Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs @@ -76,7 +76,7 @@ private static void MSBuildNativeAotPublish(string libNames) var globalProperties = new Dictionary { { "Configuration", configuration }, - { "CI", "false" } + { "NoBuild", "true" } }; var pairs = propsAttr?.Split([';', ','], StringSplitOptions.RemoveEmptyEntries) ?? []; @@ -101,26 +101,42 @@ private static void MSBuildNativeAotPublish(string libNames) loggers.Add(new BinaryLogger { Parameters = binlogpath }); } - // 4. Evaluate and Execute the "Publish" target programmatically - Console.WriteLine($"[{NativeAotAppLogTag}/Publish] Building Native AoT app in ({projectDirectory}) via MSBuild API..."); - - using var projectCollection = new ProjectCollection(); - var projectInstance = new ProjectInstance(projectFile, globalProperties, null, projectCollection); - var buildParameters = new BuildParameters { Loggers = loggers, EnableNodeReuse = false, }; - var buildRequest = new BuildRequestData(projectInstance, ["Publish"]); - var buildResult = BuildManager.DefaultBuildManager.Build(buildParameters, buildRequest); + // Evaluate and Execute the "Restore" target first + Console.WriteLine($"[{NativeAotAppLogTag}/Publish] Restoring Native AoT app dependencies..."); + + using (var restoreCollection = new ProjectCollection()) + { + var restoreInstance = new ProjectInstance(projectFile, globalProperties, null, restoreCollection); + var restoreRequest = new BuildRequestData(restoreInstance, ["Restore"]); + + var restoreResult = BuildManager.DefaultBuildManager.Build(buildParameters, restoreRequest); + Assert.AreEqual(BuildResultCode.Success, restoreResult.OverallResult, $"Native AoT restore failed for '{libNames}'."); + } + + // Clear internal MSBuild engine caches so the next build sees the restored assets + BuildManager.DefaultBuildManager.ResetCaches(); + + // Evaluate and Execute the "Publish" target programmatically + Console.WriteLine($"[{NativeAotAppLogTag}/Publish] Building and Publishing Native AoT app in ({projectDirectory}) via MSBuild API..."); + + // We use a fresh collection so it reads the newly generated project.assets.json from disk + using var publishCollection = new ProjectCollection(); + var publishInstance = new ProjectInstance(projectFile, globalProperties, null, publishCollection); + var publishRequest = new BuildRequestData(publishInstance, ["Publish"]); + + var buildResult = BuildManager.DefaultBuildManager.Build(buildParameters, publishRequest); // Assert build success Assert.AreEqual(BuildResultCode.Success, buildResult.OverallResult, $"Native AoT build failed for '{libNames}'."); - // 5. Instantly extract the 'PublishDir' property from the evaluated project state - var publishDirProperty = projectInstance.GetPropertyValue("PublishDir"); + // Instantly extract the 'PublishDir' property from the freshly evaluated project state + var publishDirProperty = publishInstance.GetPropertyValue("PublishDir"); Assert.IsFalse(string.IsNullOrEmpty(publishDirProperty), $"PublishDir is empty for '{libNames}'."); // sanitize back-slash diff --git a/Natives/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj b/Natives/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj index 32d744637..0e01e9c61 100644 --- a/Natives/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj +++ b/Natives/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj @@ -32,7 +32,7 @@ NetCordNativesDir=$([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)\$(NetCordNativesDir)')) $(VCPKG_ROOT) - $(NativeAotAppProps);VcpkgRoot=$(VcpkgRoot) + $(NativeAotAppProps);VcpkgRoot=$(VcpkgRoot) $(NativeAotAppProps);$(AppendNativeAotAppProps) From ac4e918440e7f3ea61f781b0b356496793673237 Mon Sep 17 00:00:00 2001 From: Haves Irfan <20160532+ha-ves@users.noreply.github.com> Date: Wed, 8 Jul 2026 04:11:13 +0900 Subject: [PATCH 084/101] fix top level meta packaging --- Natives/NetCord.Natives/NetCord.Natives.csproj | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Natives/NetCord.Natives/NetCord.Natives.csproj b/Natives/NetCord.Natives/NetCord.Natives.csproj index d6c7dd14c..3f93c2a57 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.csproj +++ b/Natives/NetCord.Natives/NetCord.Natives.csproj @@ -289,7 +289,7 @@ PackagePerNative - @@ -303,15 +303,14 @@ BuildInParallel="true" /> - <_MetaRestoreOutputPath>$(RestoreOutputPath)\meta-nuget\ <_MetaRestoreSource>$([System.IO.Path]::GetFullPath('$(PackageOutputPath)')) - + + Properties="_NativePkgVer=$(PackageVersion);_MetaNativePkg=true;RestoreSources=$(_MetaRestoreSource)" /> + + + $(PackageDescription) (Includes: @(NativeDepsPacked->'%(Identity)', ', ')) + Date: Sun, 12 Jul 2026 03:41:49 +0900 Subject: [PATCH 085/101] Refactor msbuild targets for source and package * reduce packaged build files * update docs --- .../guides/installing-native-dependencies.md | 101 +++++++++++------- .../NetCord.Natives/NetCord.Natives.csproj | 12 +-- .../NetCord.Natives.local.targets | 38 +++++++ Natives/NetCord.Natives/NetCord.Natives.props | 16 --- .../NetCord.Natives/NetCord.Natives.targets | 74 +++++++------ README.md | 2 +- 6 files changed, 148 insertions(+), 95 deletions(-) delete mode 100644 Natives/NetCord.Natives/NetCord.Natives.props diff --git a/Documentation/guides/installing-native-dependencies.md b/Documentation/guides/installing-native-dependencies.md index b0ee1c0af..7ef452b44 100644 --- a/Documentation/guides/installing-native-dependencies.md +++ b/Documentation/guides/installing-native-dependencies.md @@ -2,52 +2,71 @@ NetCord relies on several native libraries for high-performance audio processing and encryption. NetCord provides prebuilt native binaries via NuGet packages, which is the recommended way to manage these dependencies. -## Native Dependencies Context +## Native Dependencies - **Libsodium**: Used for encryption and provides fallback encryption modes. NetCord attempts to use the platform's native AES-GCM encryption for voice connections. However, Libsodium becomes essential in two scenarios: - - **Server-side limitation**: When connecting to a voice channel, Discord assigns you to a voice server. Depending on the server and region, it may or may not support AES-GCM. All voice servers support XChaCha20-Poly1305, so if AES-GCM is unavailable on the server you're assigned to, Libsodium is required to use XChaCha20-Poly1305 as a fallback. - - **Hardware limitation**: If your hardware doesn't support AES-GCM (rare but possible on older CPUs), Libsodium is required to provide the XChaCha20-Poly1305 fallback encryption. - - Without Libsodium, your bot will fail to connect to voice channels if either of these conditions occur. -- **Opus**: A versatile audio codec required for any classes in NetCord prefixed with `Opus` (e.g., audio encoding/decoding). -- **Zstd**: Used for efficient payload compression. + 1. The native AES-GCM is unavailable on the system. + 2. The target Discord voice server does not support AES-GCM encryption. +- **Opus**: The standard audio codec used by Discord for voice chat. +- **Zstandard (Zstd)**: Required for compressing WebSocket payloads when enabled. ## NuGet Packages (Recommended) -NetCord distributes these dependencies as per-RID (Runtime Identifier) packages. This model automates binary resolution, ensuring the correct libraries are provided for your target platform. +NetCord distributes these dependencies as individually packaged NuGet references — one package per native library. You can reference only the libraries your project actually uses, or use the meta-package to pull them all in for convenience. + +| Package | Native library | NuGet | +|-----------------------------|-------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `NetCord.Natives` | **Meta-package** (references all below) | [![NetCord.Natives](https://img.shields.io/nuget/v/NetCord.Natives?label=NetCord.Natives)](https://www.nuget.org/packages/NetCord.Natives) | +| `NetCord.Natives.Dave` | libdave, mlspp, hpke, openssl (libcrypto) | [![NetCord.Natives.Dave](https://img.shields.io/nuget/v/NetCord.Natives.Dave?label=NetCord.Natives.Dave)](https://www.nuget.org/packages/NetCord.Natives.Dave) | +| `NetCord.Natives.Sodium` | libsodium | [![NetCord.Natives.Sodium](https://img.shields.io/nuget/v/NetCord.Natives.Sodium?label=NetCord.Natives.Sodium)](https://www.nuget.org/packages/NetCord.Natives.Sodium) | +| `NetCord.Natives.Opus` | opus | [![NetCord.Natives.Opus](https://img.shields.io/nuget/v/NetCord.Natives.Opus?label=NetCord.Natives.Opus)](https://www.nuget.org/packages/NetCord.Natives.Opus) | +| `NetCord.Natives.Zstandard` | zstd | [![NetCord.Natives.Zstandard](https://img.shields.io/nuget/v/NetCord.Natives.Zstandard?label=NetCord.Natives.Zstandard)](https://www.nuget.org/packages/NetCord.Natives.Zstandard) | ### Supported Platforms -Packages are available for: -| Platform | RID | NativeAOT Support | NuGet Package | -|----------|-----|-------------------------|-----------| -| Windows x64 | `win-x64` | ✓ (Static CRT /MT) | [![NetCord.Natives.win-x64](https://img.shields.io/nuget/v/NetCord.Natives.win-x64?label=NetCord.Natives.win-x64)](https://www.nuget.org/packages/NetCord.Natives.win-x64) | -| Windows ARM64 | `win-arm64` | ✓ (Static CRT /MT) | [![NetCord.Natives.win-arm64](https://img.shields.io/nuget/v/NetCord.Natives.win-arm64?label=NetCord.Natives.win-arm64)](https://www.nuget.org/packages/NetCord.Natives.win-arm64) | -| Linux x64 | `linux-x64` | ✓ (Dynamic CRT) | [![NetCord.Natives.linux-x64](https://img.shields.io/nuget/v/NetCord.Natives.linux-x64?label=NetCord.Natives.linux-x64)](https://www.nuget.org/packages/NetCord.Natives.linux-x64) | -| Linux ARM64 | `linux-arm64` | ✓ (Dynamic CRT) | [![NetCord.Natives.linux-arm64](https://img.shields.io/nuget/v/NetCord.Natives.linux-arm64?label=NetCord.Natives.linux-arm64)](https://www.nuget.org/packages/NetCord.Natives.linux-arm64) | -| ⓘ macOS x64 | `osx-x64` | ✓ (Dynamic CRT) | [![NetCord.Natives.osx-x64](https://img.shields.io/nuget/v/NetCord.Natives.osx-x64?label=NetCord.Natives.osx-x64)](https://www.nuget.org/packages/NetCord.Natives.osx-x64) | -| ⓘ macOS ARM64 | `osx-arm64` | ✓ (Dynamic CRT) | [![NetCord.Natives.osx-arm64](https://img.shields.io/nuget/v/NetCord.Natives.osx-arm64?label=NetCord.Natives.osx-arm64)](https://www.nuget.org/packages/NetCord.Natives.osx-arm64) | +Each package ships runtime binaries (`.dll` / `.so` / `.dylib`) for all supported platforms and static libraries for NativeAOT: -ⓘ Currently, the macOS packages are built and published, but functions verification tests are skipped due to limitations with `dyld`. -They are still expected to work correctly, but we recommend testing on macOS before production use. +| Platform | RID | NativeAOT Support | +|------------------|--------------------|--------------------| +| Windows x64 | `win-x64` | ✓ (Static CRT /MT) | +| Windows ARM64 | `win-arm64` | ✓ (Static CRT /MT) | +| Linux x64 | `linux-x64` | ✓ (Dynamic CRT) | +| Linux ARM64 | `linux-arm64` | ✓ (Dynamic CRT) | +| Linux musl x64 | `linux-musl-x64` | ✓ (Dynamic CRT) | +| Linux musl ARM64 | `linux-musl-arm64` | ✓ (Dynamic CRT) | +| ⓘ macOS x64 | `osx-x64` | ✓ (Dynamic CRT) | +| ⓘ macOS ARM64 | `osx-arm64` | ✓ (Dynamic CRT) | + +> ⓘ macOS packages are built and published, but function verification tests are skipped due to limitations with `dyld`. They are expected to work correctly, but we recommend testing on macOS before production use. ## Dynamic Linking -For standard .NET applications, you can simply reference the relevant packages for your target platforms. The runtimes will be correctly copied and loaded across platforms. +For standard .NET applications, reference the packages for the native libraries you need. The correct runtime binaries are automatically copied and loaded. + +You can add these packages using the .NET CLI or directly to your `.csproj` file: + +```bash +# Add individual packages... +dotnet add package NetCord.Natives.Dave + +# ...or just add the meta-package for all of them +dotnet add package NetCord.Natives +``` ```xml - - - + + + + + ``` -## Usage with NativeAOT (Static Linking) +## NativeAOT (Static Linking) When using [NativeAOT](https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot), static libraries are automatically linked from the NuGet package, embedding the necessary native code directly into your executable. -### Requirement for DirectPInvoke -When targeting NativeAOT, you must ensure that all used native libraries are explicitly registered using `` in your project file to ensure they are properly included during the AOT compilation process: +You must explicitly register each native library with `` so the AOT compiler includes it: ```xml @@ -58,25 +77,30 @@ When targeting NativeAOT, you must ensure that all used native libraries are exp ``` -### Excluding Bundled Dependencies -If you have provided your own native binaries and need to exclude the ones bundled in the NetCord NuGet package to avoid conflicts, use the `NetCordExcludeNativesDynamic` property. +When `DirectPInvoke` is set, the corresponding dynamic libraries are automatically excluded from the publish output. + +### Excluding libraries manually + +If you are managing dependencies via NuGet and want to exclude a library, you can simply omit its ``. + +However, if you are building NetCord (and/or NetCord.Natives) from source (or using the meta-package) and want to provide your own binaries, use the `NetCordExcludeNatives` property. This explicitly prevents the specified libraries from being copied to your output directory **and** stops them from being statically linked during NativeAOT compilation. ```xml - opus;libsodium + libdave;libsodium ``` ## Custom Manual/System-wide Installation -If you are developing for an unsupported platform or require a custom-built native binary, you may choose to handle native dependencies manually. +If you are developing for an unsupported platform or require a custom-built native binary, you may handle native dependencies manually. 1. **Obtain Binaries**: Use your system's package manager (e.g., `apt`, `brew`, `dnf`) if available, or download the binaries from the official sources listed below. 2. **Placement**: Ensure the native libraries are available to your application at runtime. On Windows, place `.dll` files in your application's output directory. On Unix-like systems, ensure shared libraries are in your `LD_LIBRARY_PATH` or system standard paths. -### Installation External Links +### Installation Links -| Library | Installation Link | +| Library | Link | |-----------|---------------------------------------------| | Libdave | https://github.com/discord/libdave/releases | | Libsodium | https://doc.libsodium.org/installation | @@ -84,7 +108,8 @@ If you are developing for an unsupported platform or require a custom-built nati | Zstd | https://github.com/facebook/zstd/releases | ## Troubleshooting -- If you encounter issues with native dependencies, ensure that the correct versions are installed and that they are accessible to your application. + +- Ensure that the correct versions are installed and accessible to your application. - Use tools like `ldd` (Linux) or `Dependency Walker` (Windows) to verify that your application is correctly linking against the native libraries. --- @@ -98,15 +123,17 @@ The native packaging model is designed to make managing dependencies as transpar * **Automatic Configuration**: MSBuild files are included in the packages to automatically handle paths and linking requirements, so you don't have to manually configure build settings. ### Built-in Compliance -All necessary licenses and copyright notices from the original native project sources are bundled automatically within each package under the `licenses/` directory. + +All necessary licenses and copyright notices from the original native project sources are bundled within each package under the `licenses/` directory. | Library | License | Remarks | -|---------------|--------------|-----------------------------| +|---------------|--------------|-----------------------------| | **Libdave** | MIT | Discord voice communication | | **Libsodium** | ISC | Used for encryption | | **OpenSSL** | Apache 2.0 | Cryptographic operations | | **Opus** | BSD-3-Clause | Audio codec | | **Zstd** | BSD-3-Clause | Compression | -### How It's Built -* **Reproducible builds**: Dependencies are strictly pinned using [vcpkg](https://github.com/microsoft/vcpkg) baselines. This means every build result should be identical, regardless of who or what runs the build. +### Reproducible Builds + +Dependencies are strictly pinned using [vcpkg](https://github.com/microsoft/vcpkg) baselines, ensuring identical build results regardless of when or where the build runs. diff --git a/Natives/NetCord.Natives/NetCord.Natives.csproj b/Natives/NetCord.Natives/NetCord.Natives.csproj index 3f93c2a57..3067ed2b6 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.csproj +++ b/Natives/NetCord.Natives/NetCord.Natives.csproj @@ -362,15 +362,13 @@ licenses\%(NativeLibLic.Identity)_LICENSE.txt - <_BuildFiles Include="$(MSBuildProjectName).props;$(MSBuildProjectName).targets"> + true - - - - build\$(PackageId)%(_BuildFiles.Extension) + build\$(PackageId).targets - - buildTransitive\$(PackageId)%(_BuildFiles.Extension) + + true + buildTransitive\$(PackageId).targets diff --git a/Natives/NetCord.Natives/NetCord.Natives.local.targets b/Natives/NetCord.Natives/NetCord.Natives.local.targets index 72a3c9ea2..9b5527ac0 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.local.targets +++ b/Natives/NetCord.Natives/NetCord.Natives.local.targets @@ -21,6 +21,44 @@ + + + + + + <_NetCordStaticLink Include="sodium" Condition="'%(DirectPInvoke.Identity)' == 'libsodium'" /> + <_NetCordStaticLink Include="dave" Condition="'%(DirectPInvoke.Identity)' == 'libdave'" /> + + + <_NetCordStaticLink Include="mlspp;hpke;bytes;tls_syntax" Condition="'%(DirectPInvoke.Identity)' == 'libdave'" /> + + + <_NetCordStaticLink Include="opus;zstd" + Condition="'%(DirectPInvoke.Identity)' == 'opus' or '%(DirectPInvoke.Identity)' == 'zstd'" /> + + + <_NetCordStaticLink Include="crypto" Condition="'%(DirectPInvoke.Identity)' == 'libdave'" /> + + <_NetCordExcluded Include="$(NetCordExcludeNatives)" Condition="'$(NetCordExcludeNatives)' != ''" /> + <_NetCordExcluded Include="crypto" + Condition="'$(NetCordExcludeNatives)' != '' and $(NetCordExcludeNatives.Contains('libdave'))" /> + <_NetCordExcluded Include="@(_NetCordStaticLink)" + Condition="'$(PublishAot)' == 'true' and '%(_NetCordStaticLink.Identity)' != ''"/> + + <_RunExclude Include="$(NetCordNativesSharedDir)\%(_NetCordExcluded.Identity)*.*" + Condition="'%(_NetCordExcluded.Identity)' != '' and '$(NetCordNativesSharedDir)' != ''" /> + <_RunExclude Include="$(NetCordNativesSharedDir)\lib%(_NetCordExcluded.Identity)*.*" + Condition="'%(_NetCordExcluded.Identity)' != '' and '$(NetCordNativesSharedDir)' != ''" /> + + <_NativesRuntime Include="$(NetCordNativesSharedDir)\**" Condition="'$(NetCordNativesSharedDir)' != ''" /> + + + + + + - - - - - - $(MSBuildThisFileDirectory)..\runtimes\$(RuntimeIdentifier)\native - $(MSBuildThisFileDirectory)..\staticlibs\$(RuntimeIdentifier) - - - diff --git a/Natives/NetCord.Natives/NetCord.Natives.targets b/Natives/NetCord.Natives/NetCord.Natives.targets index f6ef4d663..dd15e6949 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.targets +++ b/Natives/NetCord.Natives/NetCord.Natives.targets @@ -1,44 +1,50 @@ + - - - <_NativesRuntime Include="$(NetCordNativesSharedDir)\**" - Condition="'$(NetCordNativesSharedDir)' != ''" /> - - - - <_NetCordStaticLink Include="sodium" - Condition="'%(DirectPInvoke.Identity)' == 'libsodium'" /> - <_NetCordStaticLink Include="dave" - Condition="'%(DirectPInvoke.Identity)' == 'libdave'" /> - - - <_NetCordStaticLink Include="mlspp;hpke;bytes;tls_syntax" - Condition="'%(DirectPInvoke.Identity)' == 'libdave'" /> - - - <_NetCordStaticLink Include="opus;zstd" - Condition="'%(DirectPInvoke.Identity)' == 'opus' or '%(DirectPInvoke.Identity)' == 'zstd'" /> - - - <_NetCordStaticLink Include="crypto" - Condition="'%(DirectPInvoke.Identity)' == 'libdave'" /> + + + <_SharedDirToUse>$(MSBuildThisFileDirectory)..\runtimes\$(RuntimeIdentifier)\native + <_StaticDirToUse>$(MSBuildThisFileDirectory)..\staticlibs\$(RuntimeIdentifier) + - - + + <_ThisPkgStaticLink Include="dave;mlspp;hpke;bytes;tls_syntax;crypto" + Condition="'$(MSBuildThisFileName)' == 'NetCord.Natives.Dave' and '%(DirectPInvoke.Identity)' == 'libdave'" /> + <_ThisPkgStaticLink Include="sodium" + Condition="'$(MSBuildThisFileName)' == 'NetCord.Natives.Sodium' and '%(DirectPInvoke.Identity)' == 'libsodium'" /> + <_ThisPkgStaticLink Include="opus" + Condition="'$(MSBuildThisFileName)' == 'NetCord.Natives.Opus' and '%(DirectPInvoke.Identity)' == 'opus'" /> + <_ThisPkgStaticLink Include="zstd" + Condition="'$(MSBuildThisFileName)' == 'NetCord.Natives.Zstandard' and '%(DirectPInvoke.Identity)' == 'zstd'" /> + - <_NetCordExcluded Include="$(NetCordExcludeNatives)" - Condition="'$(NetCordExcludeNatives)' != ''" /> + + <_NetCordExcluded Include="$(NetCordExcludeNatives)" Condition="'$(NetCordExcludeNatives)' != ''" /> <_NetCordExcluded Include="crypto" - Condition="$(NetCordExcludeNatives.Contains('libdave'))" /> + Condition="'$(NetCordExcludeNatives)' != '' and $(NetCordExcludeNatives.Contains('libdave'))" /> + <_NetCordExcluded Include="@(_ThisPkgStaticLink)" + Condition="'$(PublishAot)' == 'true' and '%(_ThisPkgStaticLink.Identity)' != ''" /> + + <_RunExclude Include="$(_SharedDirToUse)\%(_NetCordExcluded.Identity)*.*" + Condition="Exists('$(_SharedDirToUse)') and '%(_NetCordExcluded.Identity)' != ''" /> + <_RunExclude Include="$(_SharedDirToUse)\lib%(_NetCordExcluded.Identity)*.*" + Condition="Exists('$(_SharedDirToUse)') and '%(_NetCordExcluded.Identity)' != ''" /> - <_NetCordExcluded Include="@(_NetCordStaticLink)" - Condition="'$(PublishAot)' == 'true' and '%(_NetCordStaticLink.Identity)' != ''"/> + <_NativesRuntime Include="$(_SharedDirToUse)\**" Condition="Exists('$(_SharedDirToUse)')" /> - <_RunExclude Include="$(NetCordNativesSharedDir)\%(_NetCordExcluded.Identity)*.*" - Condition="'%(_NetCordExcluded.Identity)' != '' and '$(NetCordNativesSharedDir)' != ''" /> - <_RunExclude Include="$(NetCordNativesSharedDir)\lib%(_NetCordExcluded.Identity)*.*" - Condition="'%(_NetCordExcluded.Identity)' != '' and '$(NetCordNativesSharedDir)' != ''" /> + + diff --git a/README.md b/README.md index 275ac7d16..3e12cda4e 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ You can install NetCord packages via NuGet package manager: | **[NetCord.Hosting](https://www.nuget.org/packages/NetCord.Hosting)** | Provides .NET Generic Host extensions for the NetCord package. | | **[NetCord.Hosting.Services](https://www.nuget.org/packages/NetCord.Hosting.Services)** | Provides .NET Generic Host extensions for the NetCord.Services package. | | **[NetCord.Hosting.AspNetCore](https://www.nuget.org/packages/NetCord.Hosting.AspNetCore)** | Provides ASP.NET Core extensions for seamless handling of HTTP events. | -| NetCord.Natives.<RuntimeId> | Provides pre-built native runtime dependencies binary.
[See Native Dependencies Installation Guide.](https://netcord.dev/guides/basic-concepts/installing-native-dependencies.html) | +| **[NetCord.Natives](https://www.nuget.org/packages/NetCord.Natives)** | Provides pre-built native dependency library binaries.
[See Native Dependencies Installation Guide.](https://netcord.dev/guides/basic-concepts/installing-native-dependencies.html) | ## 2. 🚀 Showcase From 1f6f4597d0f657c42835bc0e370bcb78c006e94a Mon Sep 17 00:00:00 2001 From: ha-ves <20160532+ha-ves@users.noreply.github.com> Date: Wed, 15 Jul 2026 22:17:31 +0900 Subject: [PATCH 086/101] Fix package build files * fix natives meta-package * fix build-natives.yml typo --- .github/workflows/build-natives.yml | 2 +- .../NetCord.Natives/NetCord.Natives.csproj | 5 +- .../NetCord.Natives.local.targets | 5 +- .../NetCord.Natives/NetCord.Natives.targets | 238 +++++++++++------- 4 files changed, 156 insertions(+), 94 deletions(-) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index 894048517..8d5c0910a 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -216,7 +216,7 @@ jobs: if: ${{ env.GenerateBinLog == 'true' && always() }} uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: - name: ${{ matrix.rid }}-build-binlogs + name: ${{ matrix.rid }}-binlogs path: | *.binlog diff --git a/Natives/NetCord.Natives/NetCord.Natives.csproj b/Natives/NetCord.Natives/NetCord.Natives.csproj index 3067ed2b6..b7fa16ff8 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.csproj +++ b/Natives/NetCord.Natives/NetCord.Natives.csproj @@ -290,6 +290,7 @@ PackagePerNative @@ -304,13 +305,15 @@ <_MetaRestoreSource>$([System.IO.Path]::GetFullPath('$(PackageOutputPath)')) + $([System.IO.Path]::GetFullPath('$(RestoreOutputPath)\meta-restore')) + RemoveProperties="NoRestore" + Properties="_NativePkgVer=$(PackageVersion);_MetaNativePkg=true;RestoreSources=$(_MetaRestoreSource);RestoreOutputPath=$(RestoreOutputPath)" /> + + $(ProcessNetCordNativeAot_DependsOn);GetNetCordNativesItems + @@ -59,7 +62,7 @@ - diff --git a/Natives/NetCord.Natives/NetCord.Natives.targets b/Natives/NetCord.Natives/NetCord.Natives.targets index dd15e6949..a5f763e63 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.targets +++ b/Natives/NetCord.Natives/NetCord.Natives.targets @@ -1,88 +1,121 @@ - - - - - <_SharedDirToUse>$(MSBuildThisFileDirectory)..\runtimes\$(RuntimeIdentifier)\native - <_StaticDirToUse>$(MSBuildThisFileDirectory)..\staticlibs\$(RuntimeIdentifier) - - - - <_ThisPkgStaticLink Include="dave;mlspp;hpke;bytes;tls_syntax;crypto" - Condition="'$(MSBuildThisFileName)' == 'NetCord.Natives.Dave' and '%(DirectPInvoke.Identity)' == 'libdave'" /> - <_ThisPkgStaticLink Include="sodium" - Condition="'$(MSBuildThisFileName)' == 'NetCord.Natives.Sodium' and '%(DirectPInvoke.Identity)' == 'libsodium'" /> - <_ThisPkgStaticLink Include="opus" - Condition="'$(MSBuildThisFileName)' == 'NetCord.Natives.Opus' and '%(DirectPInvoke.Identity)' == 'opus'" /> - <_ThisPkgStaticLink Include="zstd" - Condition="'$(MSBuildThisFileName)' == 'NetCord.Natives.Zstandard' and '%(DirectPInvoke.Identity)' == 'zstd'" /> - - - - <_NetCordExcluded Include="$(NetCordExcludeNatives)" Condition="'$(NetCordExcludeNatives)' != ''" /> - <_NetCordExcluded Include="crypto" - Condition="'$(NetCordExcludeNatives)' != '' and $(NetCordExcludeNatives.Contains('libdave'))" /> - <_NetCordExcluded Include="@(_ThisPkgStaticLink)" - Condition="'$(PublishAot)' == 'true' and '%(_ThisPkgStaticLink.Identity)' != ''" /> - - <_RunExclude Include="$(_SharedDirToUse)\%(_NetCordExcluded.Identity)*.*" - Condition="Exists('$(_SharedDirToUse)') and '%(_NetCordExcluded.Identity)' != ''" /> - <_RunExclude Include="$(_SharedDirToUse)\lib%(_NetCordExcluded.Identity)*.*" - Condition="Exists('$(_SharedDirToUse)') and '%(_NetCordExcluded.Identity)' != ''" /> - - <_NativesRuntime Include="$(_SharedDirToUse)\**" Condition="Exists('$(_SharedDirToUse)')" /> - - - - - - - - - - - - - - - true - - - - - - - - - - - - - - <_CopiedNonNatives Include="@(_SourceItemsToCopyToOutputDirectory)" - Exclude="@(_NativesRuntime)" /> - <_CopiedNatives Include="@(_SourceItemsToCopyToOutputDirectory)" - Exclude="@(_CopiedNonNatives)" /> - <_NativesShared Include="$(OutDir)%(_CopiedNatives.TargetPath)" /> + + + <_NetCordNativesPackage Include="$(MSBuildThisFileName)"> + $([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\')) + + + + + + + + <_StaticLinking Include="libsodium;sodium" + Condition="!$(NetCordExcludeNatives.Contains('libsodium')) and '%(DirectPInvoke.Identity)' == 'libsodium'" /> + <_StaticLinking Include="libdave;dave" + Condition="!$(NetCordExcludeNatives.Contains('libdave')) and '%(DirectPInvoke.Identity)' == 'libdave'" /> + + + <_StaticLinking Include="libmlspp;mlspp;libhpke;hpke;libbytes;bytes;libtls_syntax;tls_syntax" + Condition="!$(NetCordExcludeNatives.Contains('libdave')) and '%(DirectPInvoke.Identity)' == 'libdave'" /> + + + <_StaticLinking Include="libopus;opus" + Condition="!$(NetCordExcludeNatives.Contains('opus')) and '%(DirectPInvoke.Identity)' == 'opus'" /> + <_StaticLinking Include="libzstd;zstd" + Condition="!$(NetCordExcludeNatives.Contains('zstd')) and '%(DirectPInvoke.Identity)' == 'zstd'" /> + + + <_StaticLinking Include="libcrypto;crypto" + Condition="!$(NetCordExcludeNatives.Contains('libdave')) and '%(DirectPInvoke.Identity)' == 'libdave'" /> + + <__StaticsToLink Include="@(_StaticLinking)" Condition="'%(_StaticLinking.Identity)' != ''" /> + + + + <_NetCordExcluded Include="$(NetCordExcludeNatives)" Condition="'$(NetCordExcludeNatives)' != ''" /> + <_NetCordExcluded Include="@(_StaticLinking)" + Condition="'$(PublishAot)' == 'true' and '%(_StaticLinking.Identity)' != ''" /> + + + + + + <_CurrentSharedDir>%(_NetCordNativesPackage.PackageDir)runtimes + <_CurrentStaticDir>%(_NetCordNativesPackage.PackageDir)staticlibs + + + + <_RunExclude Include="$(_CurrentSharedDir)\*\native\%(_NetCordExcluded.Identity)*.*" Condition="'%(_NetCordExcluded.Identity)' != ''" /> + <_RunExclude Include="$(_CurrentSharedDir)\*\native\lib%(_NetCordExcluded.Identity)*.*" Condition="'%(_NetCordExcluded.Identity)' != ''" /> + + <_NativesRuntime Include="$(_CurrentSharedDir)\*\native\**" /> + + + + + + + + $(ProcessNetCordNativeAot_DependsOn);GetNetCordNativesItems_PerPackage + + + + + + + + + + true + + + + + + + + + + + + <_CopiedNonNetCord Include="@(ReferenceCopyLocalPaths)" + Exclude="@(_NativesRuntime)" /> + <_CopiedNonNetCord Include="@(_SourceItemsToCopyToOutputDirectory)" + Exclude="@(_NativesRuntime)" /> + + <_CopiedNatives Include="@(ReferenceCopyLocalPaths)" + Exclude="@(_CopiedNonNetCord)" /> + <_CopiedNatives Include="@(_SourceItemsToCopyToOutputDirectory)" + Exclude="@(_CopiedNonNetCord)" /> + + <_NativesShared Include="$(OutDir)%(_CopiedNatives.DestinationSubDirectory)%(_CopiedNatives.Filename)%(_CopiedNatives.Extension)"> + %(_CopiedNatives.DestinationSubDirectory) + <_Symlink Include="@(_NativesShared)" Condition="$([System.Text.RegularExpressions.Regex]::IsMatch('%(Filename)%(Extension)', '\.so\.\d+'))"> @@ -96,20 +129,43 @@ $([System.Text.RegularExpressions.Regex]::Replace('%(Filename)%(Extension)', '^(.*?\.\d+)\..*\.dylib$', '$1.dylib')) $([System.Text.RegularExpressions.Regex]::Replace('%(Filename)%(Extension)', '\.\d+.*\.dylib$', '.dylib')) - <_Symlink Remove="%(Identity)" Condition="'%(RealName)' == '' or '%(SoName)' == '' or '%(LinkerName)' == ''" /> - <_Symlink Remove="%(Identity)" Condition="'%(RealName)' == '%(SoName)' or '%(SoName)' == '' or '%(LinkerName)' == '' or '%(LinkerName)' == '%(RealName)'" /> - + <_Symlink Remove="%(Identity)" Condition="'%(RealName)' == '' or '%(SoName)' == '' or '%(LinkerName)' == ''" /> + <_Symlink Remove="%(Identity)" Condition="'%(RealName)' == '%(SoName)' or '%(SoName)' == '' or '%(LinkerName)' == '' or '%(LinkerName)' == '%(RealName)'" /> + + + + + + - + + - + + + + + + - + - +
From 69ce806273b47991d504209b1ff81cfa5fd2a60e Mon Sep 17 00:00:00 2001 From: ha-ves <20160532+ha-ves@users.noreply.github.com> Date: Thu, 16 Jul 2026 01:05:12 +0900 Subject: [PATCH 087/101] Add NativeAotApp test for PackageReference * fix build files redundancies & breaking changes --- .../NetCord.Natives.local.targets | 32 ++--------- .../NetCord.Natives/NetCord.Natives.targets | 15 ++++-- .../Tests/NativeAotApp/NativeAotApp.csproj | 11 +++- Natives/Tests/NativeAotApp/Program.cs | 3 +- .../NativesBuildTests.cs | 53 ++++++++++++++++--- .../NetCord.Natives.Tests.csproj | 4 ++ 6 files changed, 78 insertions(+), 40 deletions(-) diff --git a/Natives/NetCord.Natives/NetCord.Natives.local.targets b/Natives/NetCord.Natives/NetCord.Natives.local.targets index f7c517f03..df2373c40 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.local.targets +++ b/Natives/NetCord.Natives/NetCord.Natives.local.targets @@ -24,30 +24,8 @@ $(ProcessNetCordNativeAot_DependsOn);GetNetCordNativesItems - - + - - - <_NetCordStaticLink Include="sodium" Condition="'%(DirectPInvoke.Identity)' == 'libsodium'" /> - <_NetCordStaticLink Include="dave" Condition="'%(DirectPInvoke.Identity)' == 'libdave'" /> - - - <_NetCordStaticLink Include="mlspp;hpke;bytes;tls_syntax" Condition="'%(DirectPInvoke.Identity)' == 'libdave'" /> - - - <_NetCordStaticLink Include="opus;zstd" - Condition="'%(DirectPInvoke.Identity)' == 'opus' or '%(DirectPInvoke.Identity)' == 'zstd'" /> - - - <_NetCordStaticLink Include="crypto" Condition="'%(DirectPInvoke.Identity)' == 'libdave'" /> - - <_NetCordExcluded Include="$(NetCordExcludeNatives)" Condition="'$(NetCordExcludeNatives)' != ''" /> - <_NetCordExcluded Include="crypto" - Condition="'$(NetCordExcludeNatives)' != '' and $(NetCordExcludeNatives.Contains('libdave'))" /> - <_NetCordExcluded Include="@(_NetCordStaticLink)" - Condition="'$(PublishAot)' == 'true' and '%(_NetCordStaticLink.Identity)' != ''"/> - <_RunExclude Include="$(NetCordNativesSharedDir)\%(_NetCordExcluded.Identity)*.*" Condition="'%(_NetCordExcluded.Identity)' != '' and '$(NetCordNativesSharedDir)' != ''" /> <_RunExclude Include="$(NetCordNativesSharedDir)\lib%(_NetCordExcluded.Identity)*.*" @@ -55,10 +33,10 @@ <_NativesRuntime Include="$(NetCordNativesSharedDir)\**" Condition="'$(NetCordNativesSharedDir)' != ''" /> - - + + diff --git a/Natives/NetCord.Natives/NetCord.Natives.targets b/Natives/NetCord.Natives/NetCord.Natives.targets index a5f763e63..e8835ae86 100644 --- a/Natives/NetCord.Natives/NetCord.Natives.targets +++ b/Natives/NetCord.Natives/NetCord.Natives.targets @@ -60,7 +60,16 @@ <_CurrentStaticDir>%(_NetCordNativesPackage.PackageDir)staticlibs - + + <_RunExclude Include="$(_CurrentSharedDir)\$(RuntimeIdentifier)\native\%(_NetCordExcluded.Identity)*.*" Condition="'%(_NetCordExcluded.Identity)' != ''" /> + <_RunExclude Include="$(_CurrentSharedDir)\$(RuntimeIdentifier)\native\lib%(_NetCordExcluded.Identity)*.*" Condition="'%(_NetCordExcluded.Identity)' != ''" /> + + <_NativesRuntime Include="$(_CurrentSharedDir)\$(RuntimeIdentifier)\native\**" /> + + + + + <_RunExclude Include="$(_CurrentSharedDir)\*\native\%(_NetCordExcluded.Identity)*.*" Condition="'%(_NetCordExcluded.Identity)' != ''" /> <_RunExclude Include="$(_CurrentSharedDir)\*\native\lib%(_NetCordExcluded.Identity)*.*" Condition="'%(_NetCordExcluded.Identity)' != ''" /> @@ -71,12 +80,12 @@ - + $(ProcessNetCordNativeAot_DependsOn);GetNetCordNativesItems_PerPackage + BeforeTargets="SetupOSSpecificProps"> diff --git a/Natives/Tests/NativeAotApp/NativeAotApp.csproj b/Natives/Tests/NativeAotApp/NativeAotApp.csproj index 7f73b4cb6..be62c62fb 100644 --- a/Natives/Tests/NativeAotApp/NativeAotApp.csproj +++ b/Natives/Tests/NativeAotApp/NativeAotApp.csproj @@ -34,10 +34,17 @@ - + - + + + + + + diff --git a/Natives/Tests/NativeAotApp/Program.cs b/Natives/Tests/NativeAotApp/Program.cs index 6581e6975..c28a0a76b 100644 --- a/Natives/Tests/NativeAotApp/Program.cs +++ b/Natives/Tests/NativeAotApp/Program.cs @@ -6,4 +6,5 @@ Console.WriteLine($"Dave Max Supported Protocol Version: {NativeProbes.DaveMaxSupportedProtocolVersion()}"); Console.WriteLine($"Sodium Init: {NativeProbes.SodiumInit()}. 0 = OK"); Console.WriteLine($"Opus Version String: {Marshal.PtrToStringAnsi(NativeProbes.OpusGetVersionString())}"); -Console.WriteLine($"Zstd Version Number: {NativeProbes.ZstdVersionNumber()}"); +uint v = NativeProbes.ZstdVersionNumber(); +Console.WriteLine($"Zstd Version: {v / 10000}.{(v / 100) % 100}.{v % 100}"); diff --git a/Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs b/Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs index d127ecf15..9a6d481b0 100644 --- a/Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs +++ b/Natives/Tests/NetCord.Natives.Tests/NativesBuildTests.cs @@ -44,16 +44,32 @@ public void AllLibraryImportsExistInBinary(string libName) Assert.IsEmpty(missingExports, $"The following entry points were not found in '{libName}': {string.Join(", ", missingExports)}"); } + [AssemblyInitialize] + public static void AssemblyInit(TestContext context) + { + // This is guaranteed to run before any test method + MSBuildLocator.RegisterDefaults(); + } + const string NativeAotAppLogTag = nameof(NativeAotStaticLinking); + [TestMethod] + [DoNotParallelize] [DataRow("libdave;libsodium;opus;zstd")] public void NativeAotStaticLinking(string libNames) { - MSBuildLocator.RegisterDefaults(); - MSBuildNativeAotPublish(libNames); + MSBuildNativeAotPublish(libNames, false); + } + + [TestMethod] + [DoNotParallelize] + [DataRow("libdave;libsodium;opus;zstd")] + public void NativeAotStaticLinking_WithPackageVer(string libNames) + { + MSBuildNativeAotPublish(libNames, true); } - private static void MSBuildNativeAotPublish(string libNames) + private static void MSBuildNativeAotPublish(string libNames, bool testWithPackageVer) { // 1. Get properties from AssemblyMetadata attributes var assembly = typeof(NativesBuildTests).Assembly; @@ -75,8 +91,7 @@ private static void MSBuildNativeAotPublish(string libNames) // 2. Parse MSBuild Global Properties into a Dictionary var globalProperties = new Dictionary { - { "Configuration", configuration }, - { "NoBuild", "true" } + { "Configuration", configuration } }; var pairs = propsAttr?.Split([';', ','], StringSplitOptions.RemoveEmptyEntries) ?? []; @@ -98,7 +113,8 @@ private static void MSBuildNativeAotPublish(string libNames) if (!string.IsNullOrEmpty(binlogpath)) { - loggers.Add(new BinaryLogger { Parameters = binlogpath }); + var withverbinlogpath = Path.GetFileNameWithoutExtension(binlogpath) + (testWithPackageVer ? "_with_pkg_ver" : "") + Path.GetExtension(binlogpath); + loggers.Add(new BinaryLogger { Parameters = testWithPackageVer ? withverbinlogpath : binlogpath }); } var buildParameters = new BuildParameters @@ -107,6 +123,29 @@ private static void MSBuildNativeAotPublish(string libNames) EnableNodeReuse = false, }; + if (testWithPackageVer) + // Get the version of NetCord.Natives from the project file + using (var prjVerCollection = new ProjectCollection()) + { + var prjPath = assembly.GetCustomAttributes() + .FirstOrDefault(a => a.Key == "NetCordNativesPath")?.Value; + Assert.IsNotNull(prjPath, "NetCordNativesPath metadata attribute is not defined."); + + var prjVerInstance = new ProjectInstance(prjPath, globalProperties, null, prjVerCollection); + var prjVerRequest = new BuildRequestData(prjVerInstance, ["GetAssemblyVersion"]); + + var prjVerResult = BuildManager.DefaultBuildManager.Build(buildParameters, prjVerRequest); + Assert.AreEqual(BuildResultCode.Success, prjVerResult.OverallResult, $"Failed to get NetCord.Natives version from '{prjPath}'."); + + var prjVer = prjVerInstance.GetPropertyValue("Version"); + globalProperties["TestWithPackageVer"] = prjVer; + + Console.WriteLine($"[{NativeAotAppLogTag}/Publish] Using NetCord.Natives version '{prjVer}' for PackageReference testing."); + } + + // Clear internal MSBuild engine caches + BuildManager.DefaultBuildManager.ResetCaches(); + // Evaluate and Execute the "Restore" target first Console.WriteLine($"[{NativeAotAppLogTag}/Publish] Restoring Native AoT app dependencies..."); @@ -114,7 +153,7 @@ private static void MSBuildNativeAotPublish(string libNames) { var restoreInstance = new ProjectInstance(projectFile, globalProperties, null, restoreCollection); var restoreRequest = new BuildRequestData(restoreInstance, ["Restore"]); - + var restoreResult = BuildManager.DefaultBuildManager.Build(buildParameters, restoreRequest); Assert.AreEqual(BuildResultCode.Success, restoreResult.OverallResult, $"Native AoT restore failed for '{libNames}'."); } diff --git a/Natives/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj b/Natives/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj index 0e01e9c61..1ef64fff2 100644 --- a/Natives/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj +++ b/Natives/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj @@ -55,6 +55,10 @@ <_Parameter1>NativeAotBinLogPath <_Parameter2>$(NativeAotBinLogPath) + + <_Parameter1>NetCordNativesPath + <_Parameter2>$([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)/$(NetCordNativesDir)/NetCord.Natives.csproj')) + From f81d861c5dc49dc374b32dcb863fcdbd916edfa0 Mon Sep 17 00:00:00 2001 From: ha-ves <20160532+ha-ves@users.noreply.github.com> Date: Thu, 16 Jul 2026 01:57:28 +0900 Subject: [PATCH 088/101] Add package testing to CI * add github package publish --- .../workflows/build-and-publish-natives.yml | 5 + .github/workflows/build-natives.yml | 134 +++++++++++++++++- .../NetCord.Natives.Tests.csproj | 13 +- 3 files changed, 145 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build-and-publish-natives.yml b/.github/workflows/build-and-publish-natives.yml index 794860713..fd4287e9d 100644 --- a/.github/workflows/build-and-publish-natives.yml +++ b/.github/workflows/build-and-publish-natives.yml @@ -18,6 +18,8 @@ jobs: publish: needs: [build-natives] runs-on: ubuntu-latest + permissions: + packages: write steps: - name: Download All NuGet Package Artifacts @@ -30,6 +32,9 @@ jobs: - name: Publish packages env: KEY: ${{ secrets.NUGET_API_KEY }} + GH_TOKEN: ${{ github.token }} run: | dotnet nuget push artifacts/pkgs/*.nupkg -k $KEY -s https://api.nuget.org/v3/index.json --skip-duplicate dotnet nuget push artifacts/pkgs/*.snupkg -k $KEY -s https://api.nuget.org/v3/index.json --skip-duplicate + dotnet nuget push artifacts/pkgs/*.nupkg -k $GH_TOKEN -s https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json --skip-duplicate + dotnet nuget push artifacts/pkgs/*.snupkg -k $GH_TOKEN -s https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json --skip-duplicate diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index 8d5c0910a..01be9b78b 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -207,6 +207,7 @@ jobs: dotnet test Natives/NetCord.Natives.slnx --no-restore --no-build + --filter "FullyQualifiedName!~NativeAotStaticLinking_WithPackageVer" -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:test.binlog' || '' }} --logger "console;verbosity=detailed" @@ -216,7 +217,7 @@ jobs: if: ${{ env.GenerateBinLog == 'true' && always() }} uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: - name: ${{ matrix.rid }}-binlogs + name: ${{ matrix.rid }}-build-natives-binlogs path: | *.binlog @@ -230,16 +231,19 @@ jobs: if: ${{ always() && steps.build_step.outcome == 'success' }} uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: - name: NetCord.Natives.${{ matrix.rid }}.packages + name: NetCord.Natives.${{ matrix.rid }}.build path: | Natives/NetCord.Natives/bin/${{ matrix.rid }} pack-natives: needs: [build-natives] runs-on: ubuntu-latest + permissions: + contents: read + packages: write defaults: run: - shell: nix develop .#natives -c bash -eo pipefail {0} + shell: nix develop -c bash -eo pipefail {0} env: Configuration: Release DotnetVerbose: ${{ github.event.inputs.MSBuildVerbosity || inputs.MSBuildVerbosity || 'Minimal' }} @@ -277,7 +281,7 @@ jobs: if: ${{ env.GenerateBinLog == 'true' && always() }} uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: - name: pack-binlogs + name: pack-natives-binlogs path: | *.binlog @@ -289,3 +293,125 @@ jobs: path: | *.nupkg *.snupkg + + test-package: + needs: [pack-natives] + strategy: + fail-fast: false + matrix: + include: + - rid: win-x64 + runs-on: windows-latest + use-nix: false + musl: false + shell_command: pwsh + - rid: win-arm64 + runs-on: windows-11-arm + use-nix: false + musl: false + shell_command: pwsh + - rid: osx-x64 + runs-on: macos-15-intel + use-nix: true + musl: false + shell_command: nix develop -c bash -eo pipefail {0} + - rid: osx-arm64 + runs-on: macos-15 + use-nix: true + musl: false + shell_command: nix develop -c bash -eo pipefail {0} + - rid: linux-x64 + runs-on: ubuntu-latest + use-nix: true + musl: false + shell_command: nix develop -c bash -eo pipefail {0} + - rid: linux-arm64 + runs-on: ubuntu-24.04-arm + use-nix: true + musl: false + shell_command: nix develop -c bash -eo pipefail {0} + - rid: linux-musl-x64 + runs-on: ubuntu-latest + use-nix: true + musl: true + shell_command: nix develop -c bash -eo pipefail {0} + - rid: linux-musl-arm64 + runs-on: ubuntu-24.04-arm + use-nix: true + musl: true + shell_command: nix develop -c bash -eo pipefail {0} + + runs-on: ${{ matrix.runs-on }} + permissions: + contents: read + defaults: + run: + shell: ${{ matrix.shell_command }} + env: + Configuration: Release + DotnetVerbose: ${{ github.event.inputs.MSBuildVerbosity || inputs.MSBuildVerbosity || 'Minimal' }} + GenerateBinLog: ${{ github.event.inputs.GenerateBinLog || inputs.GenerateBinLog || false }} + RestoreSources: ${{ github.workspace }}/artifacts/pkgs + NoNativesBuild: true + + steps: + - name: Checkout + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + fetch-depth: 0 + filter: tree:0 + submodules: true + + - name: Download Natives Packages Artifact + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: NetCord.Natives.packages + path: artifacts/pkgs + + - name: Install Nix + if: ${{ matrix.use-nix }} + uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6 + + - name: Setup dev environment (Nix) + if: ${{ matrix.use-nix }} + run: 'true' + + - name: Setup .NET Core SDK (Windows) + if: ${{ !matrix.use-nix }} + uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5.2.0 + with: + global-json-file: global.json + + - name: Restore + run: > + dotnet restore Natives/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj + -v ${{ env.DotnetVerbose }} + ${{ env.GenerateBinLog == 'true' && '-bl:restore.binlog' || '' }} + + - name: Build tests for ${{ matrix.rid }} + run: > + dotnet build Natives/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj --no-restore + -v ${{ env.DotnetVerbose }} + ${{ env.GenerateBinLog == 'true' && format('-bl:build.binlog -p:NativeAotBinLogPath={0}/nativeaotapptest.binlog', github.workspace) || '' }} + -p:AppendNativeAotAppProps="RuntimeIdentifier=${{ matrix.rid }}" + -p:GeneratePackageOnBuild=false + + - name: Test packages for ${{ matrix.rid }} + run: > + ${{ matrix.musl && 'docker run --rm -v $PWD:$PWD -w $PWD -e DotnetVerbose -e RestoreSources mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot' || '' }} + dotnet test Natives/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj + --no-restore + --no-build + --filter "FullyQualifiedName~NativeAotStaticLinking_WithPackageVer" + -v ${{ env.DotnetVerbose }} + ${{ env.GenerateBinLog == 'true' && '-bl:test.binlog' || '' }} + --logger "console;verbosity=detailed" + --logger GitHubActions + + - name: Upload Binary Logs + if: ${{ env.GenerateBinLog == 'true' && always() }} + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: ${{ matrix.rid }}-test-package-binlogs + path: | + *.binlog diff --git a/Natives/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj b/Natives/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj index 1ef64fff2..3efa62409 100644 --- a/Natives/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj +++ b/Natives/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj @@ -39,9 +39,18 @@ - + + + + + + + + <_Parameter1>NativeAotAppDir @@ -65,6 +74,4 @@ - - From 6f60e8860620873c2a9e054ea87cebbf3b88a9c8 Mon Sep 17 00:00:00 2001 From: ha-ves <20160532+ha-ves@users.noreply.github.com> Date: Thu, 16 Jul 2026 02:19:34 +0900 Subject: [PATCH 089/101] try fix CI & small cleanup --- .github/workflows/build-natives.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index 01be9b78b..323b4a03f 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -197,21 +197,20 @@ jobs: dotnet build Natives/NetCord.Natives.slnx --no-restore -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && format('-bl:build.binlog -p:NativeAotBinLogPath={0}/nativeaotapptest.binlog', github.workspace) || '' }} - -p:AppendNativeAotAppProps="RuntimeIdentifier=${{ matrix.rid }}%3BVcpkgOSTarget=${{ env.VcpkgOSTarget }}%3BVcpkgPlatformTarget=${{ env.VcpkgPlatformTarget }}" + -p:AppendNativeAotAppProps="RuntimeIdentifier=${{ matrix.rid }}" -p:GeneratePackageOnBuild=false - ${{ env.VcpkgOSTarget == 'osx' && '-p:InvariantGlobalization=true' || '' }} - name: Test natives outputs for ${{ matrix.rid }} run: > - ${{ matrix.musl && 'docker run --rm -v $PWD:$PWD -w $PWD -e DotnetVerbose -e MINVERVERSIONOVERRIDE=1.0.0 mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot' || '' }} - dotnet test Natives/NetCord.Natives.slnx + ${{ matrix.musl && 'docker run --rm -v $PWD:$PWD -w $PWD -e DotnetVerbose mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot' || '' }} + bash -c "dotnet test Natives/NetCord.Natives.slnx --no-restore --no-build - --filter "FullyQualifiedName!~NativeAotStaticLinking_WithPackageVer" + --filter 'FullyQualifiedName!~NativeAotStaticLinking_WithPackageVer' -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:test.binlog' || '' }} - --logger "console;verbosity=detailed" - --logger GitHubActions + --logger 'console;verbosity=detailed' + --logger GitHubActions" - name: Upload Binary Logs if: ${{ env.GenerateBinLog == 'true' && always() }} From 90e369ba3e7ad2b983edb08a6768fc20804ef800 Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Thu, 16 Jul 2026 20:23:09 +0200 Subject: [PATCH 090/101] Fix CI tests for musl --- .github/workflows/build-natives.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index 323b4a03f..c5d23a045 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -203,14 +203,14 @@ jobs: - name: Test natives outputs for ${{ matrix.rid }} run: > ${{ matrix.musl && 'docker run --rm -v $PWD:$PWD -w $PWD -e DotnetVerbose mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot' || '' }} - bash -c "dotnet test Natives/NetCord.Natives.slnx + dotnet test Natives/NetCord.Natives.csproj --no-restore --no-build - --filter 'FullyQualifiedName!~NativeAotStaticLinking_WithPackageVer' + --filter "FullyQualifiedName~NativeAotStaticLinking_WithPackageVer" -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:test.binlog' || '' }} - --logger 'console;verbosity=detailed' - --logger GitHubActions" + --logger "console;verbosity=detailed" + --logger GitHubActions - name: Upload Binary Logs if: ${{ env.GenerateBinLog == 'true' && always() }} @@ -398,7 +398,7 @@ jobs: - name: Test packages for ${{ matrix.rid }} run: > ${{ matrix.musl && 'docker run --rm -v $PWD:$PWD -w $PWD -e DotnetVerbose -e RestoreSources mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot' || '' }} - dotnet test Natives/Tests/NetCord.Natives.Tests/NetCord.Natives.Tests.csproj + dotnet test Natives/NetCord.Natives.csproj --no-restore --no-build --filter "FullyQualifiedName~NativeAotStaticLinking_WithPackageVer" From 24ac992aa1ac6dfb136a0ec4662b639c587cb763 Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Thu, 16 Jul 2026 20:27:39 +0200 Subject: [PATCH 091/101] Fix tests of natives --- .github/workflows/build-natives.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index c5d23a045..eb5cf6973 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -203,7 +203,7 @@ jobs: - name: Test natives outputs for ${{ matrix.rid }} run: > ${{ matrix.musl && 'docker run --rm -v $PWD:$PWD -w $PWD -e DotnetVerbose mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot' || '' }} - dotnet test Natives/NetCord.Natives.csproj + dotnet test Natives/NetCord.Natives.slnx --no-restore --no-build --filter "FullyQualifiedName~NativeAotStaticLinking_WithPackageVer" @@ -398,7 +398,7 @@ jobs: - name: Test packages for ${{ matrix.rid }} run: > ${{ matrix.musl && 'docker run --rm -v $PWD:$PWD -w $PWD -e DotnetVerbose -e RestoreSources mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot' || '' }} - dotnet test Natives/NetCord.Natives.csproj + dotnet test Natives/NetCord.Natives.slnx --no-restore --no-build --filter "FullyQualifiedName~NativeAotStaticLinking_WithPackageVer" From 4bbdf3c7e3bc1d3f2c1a5d4de52a59dada41c275 Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Thu, 16 Jul 2026 20:45:36 +0200 Subject: [PATCH 092/101] Add missing env variables to docker run --- .github/workflows/build-natives.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index eb5cf6973..15fd8f8ec 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -202,7 +202,7 @@ jobs: - name: Test natives outputs for ${{ matrix.rid }} run: > - ${{ matrix.musl && 'docker run --rm -v $PWD:$PWD -w $PWD -e DotnetVerbose mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot' || '' }} + ${{ matrix.musl && 'docker run --rm -v $PWD:$PWD -w $PWD -e DotnetVerbose -e Configuration -e MINVERVERSIONOVERRIDE=1.0.0 mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot' || '' }} dotnet test Natives/NetCord.Natives.slnx --no-restore --no-build @@ -397,7 +397,7 @@ jobs: - name: Test packages for ${{ matrix.rid }} run: > - ${{ matrix.musl && 'docker run --rm -v $PWD:$PWD -w $PWD -e DotnetVerbose -e RestoreSources mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot' || '' }} + ${{ matrix.musl && 'docker run --rm -v $PWD:$PWD -w $PWD -e DotnetVerbose -e RestoreSources -e Configuration -e MINVERVERSIONOVERRIDE=1.0.0 mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot' || '' }} dotnet test Natives/NetCord.Natives.slnx --no-restore --no-build From 4873b8bf7cb81ab30cf7b6752e112c0822c4e239 Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Thu, 16 Jul 2026 20:57:39 +0200 Subject: [PATCH 093/101] Fix test --- .github/workflows/build-natives.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index 15fd8f8ec..90bce49e7 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -206,7 +206,7 @@ jobs: dotnet test Natives/NetCord.Natives.slnx --no-restore --no-build - --filter "FullyQualifiedName~NativeAotStaticLinking_WithPackageVer" + --filter "FullyQualifiedName!~NativeAotStaticLinking_WithPackageVer" -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:test.binlog' || '' }} --logger "console;verbosity=detailed" From a6cd0f1e0ce98558d93ddf996838d6ce555fb73d Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Thu, 16 Jul 2026 21:03:05 +0200 Subject: [PATCH 094/101] Add VCPKG_ROOT to docker tests --- .github/workflows/build-natives.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index 90bce49e7..29a2aef45 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -202,7 +202,7 @@ jobs: - name: Test natives outputs for ${{ matrix.rid }} run: > - ${{ matrix.musl && 'docker run --rm -v $PWD:$PWD -w $PWD -e DotnetVerbose -e Configuration -e MINVERVERSIONOVERRIDE=1.0.0 mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot' || '' }} + ${{ matrix.musl && 'docker run --rm -v $PWD:$PWD -w $PWD -e DotnetVerbose -e Configuration -e MINVERVERSIONOVERRIDE=1.0.0 -e VCPKG_ROOT mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot' || '' }} dotnet test Natives/NetCord.Natives.slnx --no-restore --no-build @@ -397,7 +397,7 @@ jobs: - name: Test packages for ${{ matrix.rid }} run: > - ${{ matrix.musl && 'docker run --rm -v $PWD:$PWD -w $PWD -e DotnetVerbose -e RestoreSources -e Configuration -e MINVERVERSIONOVERRIDE=1.0.0 mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot' || '' }} + ${{ matrix.musl && 'docker run --rm -v $PWD:$PWD -w $PWD -e DotnetVerbose -e RestoreSources -e Configuration -e MINVERVERSIONOVERRIDE=1.0.0 -e VCPKG_ROOT mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot' || '' }} dotnet test Natives/NetCord.Natives.slnx --no-restore --no-build From f5dc311048e7108a49bd5d93eac7d3c6ecaedad1 Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Thu, 16 Jul 2026 22:27:46 +0200 Subject: [PATCH 095/101] Use vcpkg from nixpkgs for nix --- .github/workflows/build-natives.yml | 2 -- flake.nix | 6 ++++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index 29a2aef45..eaa2a2a23 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -154,8 +154,6 @@ jobs: - name: Setup vcpkg (Nix) if: ${{ matrix.use-nix }} run: | - "${{ env.VCPKG_ROOT }}/bootstrap-vcpkg.sh" -disableMetrics - # Capture the nuget.exe path to a local variable export NUGET_PATH=$("${{ env.VCPKG_ROOT }}/vcpkg" fetch nuget | tail -n 1) diff --git a/flake.nix b/flake.nix index 9d7bbd91f..028bf8c58 100644 --- a/flake.nix +++ b/flake.nix @@ -69,6 +69,7 @@ dotnet nuget pkgs.mono + pkgs.vcpkg-tool pkgs.cmake pkgs.ninja pkgs.pkg-config @@ -89,6 +90,8 @@ shellHook = '' export VCPKG_ROOT="$PWD/Natives/NetCord.Natives/vcpkg" + + ln -sf ${pkgs.vcpkg-tool}/bin/vcpkg $VCPKG_ROOT/vcpkg ''; } // pkgs.lib.optionalAttrs pkgs.stdenv.hostPlatform.isDarwin { SDKROOT = "${pkgs.apple-sdk}/SDKs/MacOSX.sdk"; @@ -103,6 +106,7 @@ dotnet nuget pkgs.mono + pkgs.vcpkg-tool pkgs.cmake pkgs.ninja pkgs.pkg-config @@ -123,6 +127,8 @@ shellHook = '' export VCPKG_ROOT="$PWD/Natives/NetCord.Natives/vcpkg" + + ln -sf ${pkgs.vcpkg-tool}/bin/vcpkg $VCPKG_ROOT/vcpkg ''; } // pkgs.lib.optionalAttrs pkgs.stdenv.hostPlatform.isDarwin { SDKROOT = "${pkgs.apple-sdk}/SDKs/MacOSX.sdk"; From b628488950256ce6074701c59b09fa21ec448f03 Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Fri, 17 Jul 2026 20:49:49 +0200 Subject: [PATCH 096/101] Add nix store to alpine tests --- .github/workflows/build-natives.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index eaa2a2a23..423871f17 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -200,7 +200,7 @@ jobs: - name: Test natives outputs for ${{ matrix.rid }} run: > - ${{ matrix.musl && 'docker run --rm -v $PWD:$PWD -w $PWD -e DotnetVerbose -e Configuration -e MINVERVERSIONOVERRIDE=1.0.0 -e VCPKG_ROOT mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot' || '' }} + ${{ matrix.musl && 'docker run --rm -v $PWD:$PWD -v /nix/store:/nix/store -w $PWD -e DotnetVerbose -e Configuration -e MINVERVERSIONOVERRIDE=1.0.0 -e VCPKG_ROOT mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot' || '' }} dotnet test Natives/NetCord.Natives.slnx --no-restore --no-build @@ -395,7 +395,7 @@ jobs: - name: Test packages for ${{ matrix.rid }} run: > - ${{ matrix.musl && 'docker run --rm -v $PWD:$PWD -w $PWD -e DotnetVerbose -e RestoreSources -e Configuration -e MINVERVERSIONOVERRIDE=1.0.0 -e VCPKG_ROOT mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot' || '' }} + ${{ matrix.musl && 'docker run --rm -v $PWD:$PWD -v /nix/store:/nix/store -w $PWD -e DotnetVerbose -e RestoreSources -e Configuration -e MINVERVERSIONOVERRIDE=1.0.0 -e VCPKG_ROOT mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot' || '' }} dotnet test Natives/NetCord.Natives.slnx --no-restore --no-build From 75f77e8fe4a4373a05598a20cfa22209499bd105 Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Fri, 17 Jul 2026 21:30:21 +0200 Subject: [PATCH 097/101] Bootstrap vcpkg inside of an alpine container --- .github/workflows/build-natives.yml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index 423871f17..a8bcae51a 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -200,15 +200,16 @@ jobs: - name: Test natives outputs for ${{ matrix.rid }} run: > - ${{ matrix.musl && 'docker run --rm -v $PWD:$PWD -v /nix/store:/nix/store -w $PWD -e DotnetVerbose -e Configuration -e MINVERVERSIONOVERRIDE=1.0.0 -e VCPKG_ROOT mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot' || '' }} + ${{ matrix.musl && 'docker run --rm -v $PWD:$PWD -w $PWD -e DotnetVerbose -e Configuration -e MINVERVERSIONOVERRIDE=1.0.0 -e VCPKG_ROOT -e VCPKG_FORCE_SYSTEM_BINARIES=1 mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot sh -c "apk add build-base cmake ninja zip unzip curl git && ./Natives/NetCord.Natives/vcpkg/bootstrap-vcpkg.sh && ' || '' }} dotnet test Natives/NetCord.Natives.slnx --no-restore --no-build - --filter "FullyQualifiedName!~NativeAotStaticLinking_WithPackageVer" + --filter 'FullyQualifiedName!~NativeAotStaticLinking_WithPackageVer' -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:test.binlog' || '' }} - --logger "console;verbosity=detailed" + --logger 'console;verbosity=detailed' --logger GitHubActions + ${{ matrix.musl && '"' || '' }} - name: Upload Binary Logs if: ${{ env.GenerateBinLog == 'true' && always() }} @@ -395,15 +396,16 @@ jobs: - name: Test packages for ${{ matrix.rid }} run: > - ${{ matrix.musl && 'docker run --rm -v $PWD:$PWD -v /nix/store:/nix/store -w $PWD -e DotnetVerbose -e RestoreSources -e Configuration -e MINVERVERSIONOVERRIDE=1.0.0 -e VCPKG_ROOT mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot' || '' }} + ${{ matrix.musl && 'docker run --rm -v $PWD:$PWD -w $PWD -e DotnetVerbose -e RestoreSources -e Configuration -e MINVERVERSIONOVERRIDE=1.0.0 -e VCPKG_ROOT -e VCPKG_FORCE_SYSTEM_BINARIES=1 mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot sh -c "apk add build-base cmake ninja zip unzip curl git && ./Natives/NetCord.Natives/vcpkg/bootstrap-vcpkg.sh && ' || '' }} dotnet test Natives/NetCord.Natives.slnx --no-restore --no-build - --filter "FullyQualifiedName~NativeAotStaticLinking_WithPackageVer" + --filter 'FullyQualifiedName~NativeAotStaticLinking_WithPackageVer' -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:test.binlog' || '' }} - --logger "console;verbosity=detailed" + --logger 'console;verbosity=detailed' --logger GitHubActions + ${{ matrix.musl && '"' || '' }} - name: Upload Binary Logs if: ${{ env.GenerateBinLog == 'true' && always() }} From d5958108588281e75bff3fefdcec64b4751810d1 Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Fri, 17 Jul 2026 21:46:14 +0200 Subject: [PATCH 098/101] Pass vcpkg env variables to docker --- .github/workflows/build-natives.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index a8bcae51a..4fc932ad5 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -200,7 +200,7 @@ jobs: - name: Test natives outputs for ${{ matrix.rid }} run: > - ${{ matrix.musl && 'docker run --rm -v $PWD:$PWD -w $PWD -e DotnetVerbose -e Configuration -e MINVERVERSIONOVERRIDE=1.0.0 -e VCPKG_ROOT -e VCPKG_FORCE_SYSTEM_BINARIES=1 mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot sh -c "apk add build-base cmake ninja zip unzip curl git && ./Natives/NetCord.Natives/vcpkg/bootstrap-vcpkg.sh && ' || '' }} + ${{ matrix.musl && 'docker run --rm -v $PWD:$PWD -w $PWD -e DotnetVerbose -e Configuration -e MINVERVERSIONOVERRIDE=1.0.0 -e VCPKG_ROOT -e VCPKG_FORCE_SYSTEM_BINARIES=1 -e VcpkgOSTarget -e VcpkgPlatformTarget mcr.microsoft.com/dotnet/sdk:10.0-alpine3.23-aot sh -c "apk add build-base cmake ninja zip unzip curl git perl linux-headers && ./Natives/NetCord.Natives/vcpkg/bootstrap-vcpkg.sh && ' || '' }} dotnet test Natives/NetCord.Natives.slnx --no-restore --no-build From befa965ca531b51cd435d0582646b578b9dd28a2 Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Fri, 17 Jul 2026 22:15:41 +0200 Subject: [PATCH 099/101] Install nix for pack-natives --- .github/workflows/build-natives.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index 4fc932ad5..50cbe5206 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -255,6 +255,9 @@ jobs: pattern: NetCord.Natives.*.packages merge-multiple: true + - name: Install Nix + uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6 + - name: Setup dev environment run: 'true' From 77d5a7f41dffccd5799c9eb50343a9a94dba42b0 Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Fri, 17 Jul 2026 22:23:52 +0200 Subject: [PATCH 100/101] Checkout in pack for flake.nix --- .github/workflows/build-natives.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index 50cbe5206..d5ab410c9 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -248,6 +248,12 @@ jobs: GenerateBinLog: ${{ github.event.inputs.GenerateBinLog || inputs.GenerateBinLog || false }} steps: + - name: Checkout + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + fetch-depth: 0 + filter: tree:0 + - name: Download All Natives Artifact uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: From 92a1aa58fb66d910fe70e75685f5da82c7b8e30a Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Fri, 17 Jul 2026 22:31:40 +0200 Subject: [PATCH 101/101] Fix restore in pack --- .github/workflows/build-natives.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-natives.yml b/.github/workflows/build-natives.yml index d5ab410c9..31c953dba 100644 --- a/.github/workflows/build-natives.yml +++ b/.github/workflows/build-natives.yml @@ -269,7 +269,7 @@ jobs: - name: Restore run: > - dotnet restore Natives/NetCord.Natives/NetCord.Natives.slnx + dotnet restore Natives/NetCord.Natives/NetCord.Natives.csproj -v ${{ env.DotnetVerbose }} ${{ env.GenerateBinLog == 'true' && '-bl:restore.binlog' || '' }}