From 55339ae93faa908149a1af3d0a974327cc95c996 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Sat, 6 Apr 2024 01:39:08 +0200 Subject: [PATCH 01/20] Native/Assimp: Build for linux-arm, linux-arm64, and win-arm64. Also clean up the build script. --- .github/workflows/assimp.yml | 29 +++++-- build/nuke/Native/Assimp.cs | 76 ++++++++++--------- build/nuke/Native/Core.cs | 5 ++ .../Silk.NET.Assimp.Native.csproj | 7 +- 4 files changed, 75 insertions(+), 42 deletions(-) diff --git a/.github/workflows/assimp.yml b/.github/workflows/assimp.yml index 95c560dec3..9863c61790 100644 --- a/.github/workflows/assimp.yml +++ b/.github/workflows/assimp.yml @@ -17,17 +17,34 @@ jobs: fail-fast: false matrix: env: - - os: ubuntu-latest + - os: ubuntu-22.04 name: Linux nuke_invoke: ./build.sh extras: | - sudo apt-get update - sudo apt-get install -y xorg-dev - - os: windows-latest + sudo tee /etc/apt/sources.list << EOF + deb [arch=amd64] http://archive.ubuntu.com/ubuntu jammy main universe + deb [arch=amd64] http://archive.ubuntu.com/ubuntu jammy-backports main universe + deb [arch=amd64] http://archive.ubuntu.com/ubuntu jammy-security main universe + deb [arch=amd64] http://archive.ubuntu.com/ubuntu jammy-updates main universe + deb [arch=arm64,armhf] http://ports.ubuntu.com jammy main universe + deb [arch=arm64,armhf] http://ports.ubuntu.com jammy-backports main universe + deb [arch=arm64,armhf] http://ports.ubuntu.com jammy-security main universe + deb [arch=arm64,armhf] http://ports.ubuntu.com jammy-updates main universe + deb [arch=amd64] http://security.ubuntu.com/ubuntu jammy main universe + deb [arch=amd64] http://security.ubuntu.com/ubuntu jammy-backports main universe + deb [arch=amd64] http://security.ubuntu.com/ubuntu jammy-security main universe + deb [arch=amd64] http://security.ubuntu.com/ubuntu jammy-updates main universe + EOF + sudo dpkg --add-architecture arm64 + sudo dpkg --add-architecture armhf + sudo apt update + sudo apt install -y gcc-aarch64-linux-gnu gcc-arm-linux-gnueabihf + sudo apt install -y g++-aarch64-linux-gnu g++-arm-linux-gnueabihf + - os: windows-2022 name: Windows nuke_invoke: ./build.cmd extras: "" - - os: macos-latest + - os: macos-14 name: Darwin nuke_invoke: ./build.sh extras: "" @@ -41,7 +58,7 @@ jobs: run: | git -c submodule.third_party/git-hooks.update=none submodule update --init --recursive --depth 0 build/submodules/Assimp git config --local user.email "9011267+dotnet-bot@users.noreply.github.com" - git config --local user.name "The Silk.NET Automaton" + git config --local user.name "The Silk.NET Automaton" - name: Extra prerequisites run: | echo running extras diff --git a/build/nuke/Native/Assimp.cs b/build/nuke/Native/Assimp.cs index 15d92957d2..bd3818ee69 100644 --- a/build/nuke/Native/Assimp.cs +++ b/build/nuke/Native/Assimp.cs @@ -36,57 +36,65 @@ partial class Build { ( () => { - var @out = AssimpPath / "build"; - var prepare = "cmake -S. -B build -D BUILD_SHARED_LIBS=ON -DASSIMP_WARNINGS_AS_ERRORS=OFF"; - var build = $"cmake --build build --config Release{JobsArg}"; - EnsureCleanDirectory(@out); + var buildDir = AssimpPath / "build"; var runtimes = RootDirectory / "src" / "Native" / "Silk.NET.Assimp.Native" / "runtimes"; + + var prepare = "cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DASSIMP_WARNINGS_AS_ERRORS=OFF"; + var build = $"cmake --build . --config Release{JobsArg}"; + if (OperatingSystem.IsWindows()) { - InheritedShell($"{prepare} -A X64", AssimpPath) - .AssertZeroExitCode(); - InheritedShell(build, AssimpPath) - .AssertZeroExitCode(); - - CopyAs(@out, "bin/Release/assimp-*-mt.dll", runtimes / "win-x64" / "native" / "Assimp64.dll"); - EnsureCleanDirectory(@out); + foreach (var (platform, rid) in new[] + { + ("Win32", "win-x86"), + ("x64", "win-x64"), + ("ARM64", "win-arm64"), + }) + { + EnsureCleanDirectory(buildDir); - InheritedShell($"{prepare} -A Win32", AssimpPath) - .AssertZeroExitCode(); - InheritedShell(build, AssimpPath) - .AssertZeroExitCode(); + InheritedShell($"{prepare} -A {platform}", buildDir).AssertZeroExitCode(); + InheritedShell(build, buildDir).AssertZeroExitCode(); - CopyAs(@out, "bin/Release/assimp-*-mt.dll", runtimes / "win-x86" / "native" / "Assimp32.dll"); + CopyAs(buildDir / "bin" / "Release", "assimp-*-mt.dll", runtimes / rid / "native" / $"Assimp{(rid.Contains("64") ? 64 : 32)}.dll"); + } } else if (OperatingSystem.IsLinux()) { - InheritedShell($"{prepare} -DCMAKE_SYSTEM_PROCESSOR=x86_64", AssimpPath) - .AssertZeroExitCode(); - InheritedShell(build, AssimpPath) - .AssertZeroExitCode(); + foreach (var (triple, rid) in new[] + { + ("x86_64-linux-gnu", "linux-x64"), + ("arm-linux-gnueabihf", "linux-arm"), + ("aarch64-linux-gnu", "linux-arm64"), + }) + { + EnsureCleanDirectory(buildDir); - CopyAll(@out.GlobFiles("bin/libassimp.so.5"), runtimes / "linux-x64" / "native"); + InheritedShell($"{prepare} {GetCMakeToolchainFlag(triple)}", buildDir).AssertZeroExitCode(); + InheritedShell(build, buildDir).AssertZeroExitCode(); + + CopyAll((buildDir / "bin").GlobFiles("libassimp.so.5"), runtimes / rid / "native"); + } } else if (OperatingSystem.IsMacOS()) { - InheritedShell($"{prepare} -DCMAKE_OSX_ARCHITECTURES=x86_64", AssimpPath) - .AssertZeroExitCode(); - InheritedShell(build, AssimpPath) - .AssertZeroExitCode(); - CopyAll(@out.GlobFiles("bin/libassimp.5.dylib"), runtimes / "osx-x64" / "native"); - - EnsureCleanDirectory(@out); + foreach (var (arch, rid) in new[] + { + ("x86_64", "osx-x64"), + ("arm64", "osx-arm64"), + }) + { + EnsureCleanDirectory(buildDir); - InheritedShell($"{prepare} -DCMAKE_OSX_ARCHITECTURES=arm64", AssimpPath) - .AssertZeroExitCode(); - InheritedShell(build, AssimpPath) - .AssertZeroExitCode(); + InheritedShell($"{prepare} -DCMAKE_OSX_ARCHITECTURES={arch}", buildDir).AssertZeroExitCode(); + InheritedShell(build, buildDir).AssertZeroExitCode(); - CopyAll(@out.GlobFiles("bin/libassimp.5.dylib"), runtimes / "osx-arm64" / "native"); + CopyAll((buildDir / "bin").GlobFiles("libassimp.5.dylib"), runtimes / rid / "native"); + } } PrUpdatedNativeBinary("Assimp"); } ) ); -} \ No newline at end of file +} diff --git a/build/nuke/Native/Core.cs b/build/nuke/Native/Core.cs index 3544ad290f..30d9223eb3 100644 --- a/build/nuke/Native/Core.cs +++ b/build/nuke/Native/Core.cs @@ -39,6 +39,11 @@ partial class Build { ? Environment.ProcessorCount - 1 : 1; + public string GetCMakeToolchainFlag(string target) + { + return $"-DCMAKE_TOOLCHAIN_FILE={RootDirectory / "build" / "cmake" / target}.cmake"; + } + public void CopyAs(AbsolutePath @out, string from, string to) { var file = @out.GlobFiles(from).First(); diff --git a/src/Native/Silk.NET.Assimp.Native/Silk.NET.Assimp.Native.csproj b/src/Native/Silk.NET.Assimp.Native/Silk.NET.Assimp.Native.csproj index 52195a9276..d19cbd65b4 100644 --- a/src/Native/Silk.NET.Assimp.Native/Silk.NET.Assimp.Native.csproj +++ b/src/Native/Silk.NET.Assimp.Native/Silk.NET.Assimp.Native.csproj @@ -20,12 +20,15 @@ false true - + + + - + + From 5f579bdc8da5f562f9b3ca4e8a4ea333ee887a2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Mon, 8 Apr 2024 08:16:01 +0200 Subject: [PATCH 02/20] Native/Assimp: Don't build tests. --- build/nuke/Native/Assimp.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/nuke/Native/Assimp.cs b/build/nuke/Native/Assimp.cs index bd3818ee69..3162e304e8 100644 --- a/build/nuke/Native/Assimp.cs +++ b/build/nuke/Native/Assimp.cs @@ -39,7 +39,7 @@ partial class Build { var buildDir = AssimpPath / "build"; var runtimes = RootDirectory / "src" / "Native" / "Silk.NET.Assimp.Native" / "runtimes"; - var prepare = "cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DASSIMP_WARNINGS_AS_ERRORS=OFF"; + var prepare = "cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DASSIMP_WARNINGS_AS_ERRORS=OFF -DASSIMP_BUILD_TESTS=OFF"; var build = $"cmake --build . --config Release{JobsArg}"; if (OperatingSystem.IsWindows()) From b8d1c2f40e43289345113d1c9f9e5aebad52348d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Sun, 7 Apr 2024 00:29:27 +0200 Subject: [PATCH 03/20] Native/Assimp: Strip Linux/macOS binaries after build. --- build/nuke/Native/Assimp.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build/nuke/Native/Assimp.cs b/build/nuke/Native/Assimp.cs index 3162e304e8..ed1fb21d95 100644 --- a/build/nuke/Native/Assimp.cs +++ b/build/nuke/Native/Assimp.cs @@ -73,6 +73,8 @@ partial class Build { InheritedShell($"{prepare} {GetCMakeToolchainFlag(triple)}", buildDir).AssertZeroExitCode(); InheritedShell(build, buildDir).AssertZeroExitCode(); + InheritedShell($"{triple}-strip bin/libassimp.so.5", buildDir).AssertZeroExitCode(); + CopyAll((buildDir / "bin").GlobFiles("libassimp.so.5"), runtimes / rid / "native"); } } @@ -89,6 +91,8 @@ partial class Build { InheritedShell($"{prepare} -DCMAKE_OSX_ARCHITECTURES={arch}", buildDir).AssertZeroExitCode(); InheritedShell(build, buildDir).AssertZeroExitCode(); + InheritedShell($"strip bin/libassimp.5.dylib", buildDir).AssertZeroExitCode(); + CopyAll((buildDir / "bin").GlobFiles("libassimp.5.dylib"), runtimes / rid / "native"); } } From b22bf966eb8559b312a4197759be9f0b142e4342 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Sat, 6 Apr 2024 01:40:04 +0200 Subject: [PATCH 04/20] Native/GLFW: Build for linux-arm and linux-arm64. Also clean up the build script. --- .github/workflows/glfw.yml | 33 +++++-- build/nuke/Native/GLFW.cs | 87 +++++++++---------- .../Silk.NET.GLFW.Native.csproj | 6 +- 3 files changed, 74 insertions(+), 52 deletions(-) diff --git a/.github/workflows/glfw.yml b/.github/workflows/glfw.yml index b05d8871c5..e005f86566 100644 --- a/.github/workflows/glfw.yml +++ b/.github/workflows/glfw.yml @@ -17,17 +17,38 @@ jobs: fail-fast: false matrix: env: - - os: ubuntu-latest + - os: ubuntu-22.04 name: Linux nuke_invoke: ./build.sh extras: | - sudo apt-get update - sudo apt-get install -y xorg-dev libwayland-dev libxkbcommon-dev - - os: windows-latest + sudo tee /etc/apt/sources.list << EOF + deb [arch=amd64,i386] http://archive.ubuntu.com/ubuntu jammy main multiverse restricted universe + deb [arch=amd64,i386] http://archive.ubuntu.com/ubuntu jammy-backports main multiverse restricted universe + deb [arch=amd64,i386] http://archive.ubuntu.com/ubuntu jammy-security main multiverse restricted universe + deb [arch=amd64,i386] http://archive.ubuntu.com/ubuntu jammy-updates main multiverse restricted universe + deb [arch=arm64,armhf] http://ports.ubuntu.com jammy main multiverse restricted universe + deb [arch=arm64,armhf] http://ports.ubuntu.com jammy-backports main multiverse restricted universe + deb [arch=arm64,armhf] http://ports.ubuntu.com jammy-security main multiverse restricted universe + deb [arch=arm64,armhf] http://ports.ubuntu.com jammy-updates main multiverse restricted universe + deb [arch=amd64,i386] http://security.ubuntu.com/ubuntu jammy main multiverse restricted universe + deb [arch=amd64,i386] http://security.ubuntu.com/ubuntu jammy-backports main multiverse restricted universe + deb [arch=amd64,i386] http://security.ubuntu.com/ubuntu jammy-security main multiverse restricted universe + deb [arch=amd64,i386] http://security.ubuntu.com/ubuntu jammy-updates main multiverse restricted universe + EOF + sudo dpkg --add-architecture arm64 + sudo dpkg --add-architecture armhf + sudo apt update + sudo apt install -y gcc-aarch64-linux-gnu gcc-arm-linux-gnueabihf + sudo apt install -y extra-cmake-modules wayland-protocols + for arch in amd64 arm64 armhf; do + sudo apt install -y libwayland-dev:$arch libxcursor-dev:$arch libxi-dev:$arch + sudo apt install -y libxinerama-dev:$arch libxrandr-dev:$arch libxkbcommon-dev:$arch + done + - os: windows-2022 name: Windows nuke_invoke: ./build.cmd extras: "" - - os: macos-latest + - os: macos-14 name: Darwin nuke_invoke: ./build.sh extras: "" @@ -41,7 +62,7 @@ jobs: run: | git -c submodule.third_party/git-hooks.update=none submodule update --init --recursive --depth 0 build/submodules/GLFW git config --local user.email "9011267+dotnet-bot@users.noreply.github.com" - git config --local user.name "The Silk.NET Automaton" + git config --local user.name "The Silk.NET Automaton" - name: Extra prerequisites run: | echo running extras diff --git a/build/nuke/Native/GLFW.cs b/build/nuke/Native/GLFW.cs index 57b472de5e..c0131aecc1 100644 --- a/build/nuke/Native/GLFW.cs +++ b/build/nuke/Native/GLFW.cs @@ -36,66 +36,65 @@ partial class Build { ( () => { - var @out = GLFWPath / "build"; - var prepare = "cmake -S. -B build -D BUILD_SHARED_LIBS=ON"; - var build = $"cmake --build build --config Release{JobsArg}"; - EnsureCleanDirectory(@out); + var buildDir = GLFWPath / "build"; var runtimes = RootDirectory / "src" / "Native" / "Silk.NET.GLFW.Native" / "runtimes"; - if (OperatingSystem.IsWindows()) - { - InheritedShell($"{prepare} -A X64", GLFWPath) - .AssertZeroExitCode(); - InheritedShell(build, GLFWPath) - .AssertZeroExitCode(); - - CopyAll(@out.GlobFiles("src/Release/glfw3.dll"), runtimes / "win-x64" / "native"); - EnsureCleanDirectory(@out); + var prepare = "cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON"; + var build = $"cmake --build . --config Release{JobsArg}"; - InheritedShell($"{prepare} -A Win32", GLFWPath) - .AssertZeroExitCode(); - InheritedShell(build, GLFWPath) - .AssertZeroExitCode(); + if (OperatingSystem.IsWindows()) + { + foreach (var (platform, rid) in new[] + { + ("Win32", "win-x86"), + ("x64", "win-x64"), + ("ARM64", "win-arm64"), + }) + { + EnsureCleanDirectory(buildDir); - CopyAll(@out.GlobFiles("src/Release/glfw3.dll"), runtimes / "win-x86" / "native"); - - EnsureCleanDirectory(@out); - - InheritedShell($"{prepare} -A arm64", GLFWPath) - .AssertZeroExitCode(); - InheritedShell(build, GLFWPath) - .AssertZeroExitCode(); + InheritedShell($"{prepare} -A {platform}", buildDir).AssertZeroExitCode(); + InheritedShell(build, buildDir).AssertZeroExitCode(); - CopyAll(@out.GlobFiles("src/Release/glfw3.dll"), runtimes / "win-arm64" / "native"); + CopyAll((buildDir / "src" / "Release").GlobFiles("glfw3.dll"), runtimes / rid / "native"); + } } else if (OperatingSystem.IsLinux()) { - InheritedShell($"{prepare} -DCMAKE_SYSTEM_PROCESSOR=x86_64", GLFWPath) - .AssertZeroExitCode(); - InheritedShell(build, GLFWPath) - .AssertZeroExitCode(); - CopyAll(@out.GlobFiles("src/libglfw.so"), runtimes / "linux-x64" / "native"); + foreach (var (triple, rid) in new[] + { + ("x86_64-linux-gnu", "linux-x64"), + ("arm-linux-gnueabihf", "linux-arm"), + ("aarch64-linux-gnu", "linux-arm64"), + }) + { + EnsureCleanDirectory(buildDir); + + InheritedShell($"{prepare} {GetCMakeToolchainFlag(triple)}", buildDir).AssertZeroExitCode(); + InheritedShell(build, buildDir).AssertZeroExitCode(); + + CopyAll((buildDir / "src").GlobFiles("libglfw.so"), runtimes / rid / "native"); + } } else if (OperatingSystem.IsMacOS()) { - InheritedShell($"{prepare} -DCMAKE_OSX_ARCHITECTURES=x86_64", GLFWPath) - .AssertZeroExitCode(); - InheritedShell(build, GLFWPath) - .AssertZeroExitCode(); - CopyAll(@out.GlobFiles("src/libglfw.3.dylib"), runtimes / "osx-x64" / "native"); - - EnsureCleanDirectory(@out); + foreach (var (arch, rid) in new[] + { + ("x86_64", "osx-x64"), + ("arm64", "osx-arm64"), + }) + { + EnsureCleanDirectory(buildDir); - InheritedShell($"{prepare} -DCMAKE_OSX_ARCHITECTURES=arm64", GLFWPath) - .AssertZeroExitCode(); - InheritedShell(build, GLFWPath) - .AssertZeroExitCode(); + InheritedShell($"{prepare} -DCMAKE_OSX_ARCHITECTURES={arch}", buildDir).AssertZeroExitCode(); + InheritedShell(build, buildDir).AssertZeroExitCode(); - CopyAll(@out.GlobFiles("src/libglfw.3.dylib"), runtimes / "osx-arm64" / "native"); + CopyAll((buildDir / "src").GlobFiles("libglfw.3.dylib"), runtimes / rid / "native"); + } } PrUpdatedNativeBinary("GLFW"); } ) ); -} \ No newline at end of file +} diff --git a/src/Native/Silk.NET.GLFW.Native/Silk.NET.GLFW.Native.csproj b/src/Native/Silk.NET.GLFW.Native/Silk.NET.GLFW.Native.csproj index 1f89567c9d..0e29cc5055 100644 --- a/src/Native/Silk.NET.GLFW.Native/Silk.NET.GLFW.Native.csproj +++ b/src/Native/Silk.NET.GLFW.Native/Silk.NET.GLFW.Native.csproj @@ -23,11 +23,13 @@ + + - - + + From 05fc8978eef653bfed3e91a37e3f0a4d22e2a00f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Mon, 8 Apr 2024 08:16:17 +0200 Subject: [PATCH 05/20] Native/GLFW: Don't build examples, tests, and docs. --- build/nuke/Native/GLFW.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/nuke/Native/GLFW.cs b/build/nuke/Native/GLFW.cs index c0131aecc1..d28933e77e 100644 --- a/build/nuke/Native/GLFW.cs +++ b/build/nuke/Native/GLFW.cs @@ -39,7 +39,7 @@ partial class Build { var buildDir = GLFWPath / "build"; var runtimes = RootDirectory / "src" / "Native" / "Silk.NET.GLFW.Native" / "runtimes"; - var prepare = "cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON"; + var prepare = "cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DGLFW_BUILD_EXAMPLES=OFF -DGLFW_BUILD_TESTS=OFF -DGLFW_BUILD_DOCS=OFF"; var build = $"cmake --build . --config Release{JobsArg}"; if (OperatingSystem.IsWindows()) From f2405d48bd7881fc13b404c434d3b35b9ef9179b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Sun, 7 Apr 2024 00:06:32 +0200 Subject: [PATCH 06/20] Native/GLFW: Strip Linux/macOS binaries after build. --- build/nuke/Native/GLFW.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build/nuke/Native/GLFW.cs b/build/nuke/Native/GLFW.cs index d28933e77e..5086b92215 100644 --- a/build/nuke/Native/GLFW.cs +++ b/build/nuke/Native/GLFW.cs @@ -73,6 +73,8 @@ partial class Build { InheritedShell($"{prepare} {GetCMakeToolchainFlag(triple)}", buildDir).AssertZeroExitCode(); InheritedShell(build, buildDir).AssertZeroExitCode(); + InheritedShell($"{triple}-strip src/libglfw.so", buildDir).AssertZeroExitCode(); + CopyAll((buildDir / "src").GlobFiles("libglfw.so"), runtimes / rid / "native"); } } @@ -89,6 +91,8 @@ partial class Build { InheritedShell($"{prepare} -DCMAKE_OSX_ARCHITECTURES={arch}", buildDir).AssertZeroExitCode(); InheritedShell(build, buildDir).AssertZeroExitCode(); + InheritedShell($"strip src/libglfw.3.dylib", buildDir).AssertZeroExitCode(); + CopyAll((buildDir / "src").GlobFiles("libglfw.3.dylib"), runtimes / rid / "native"); } } From d06e508549693e15b603875d340ba655c437c533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Sun, 7 Apr 2024 04:13:57 +0200 Subject: [PATCH 07/20] Native/OpenAL Soft: Add submodule tracking 1.23.1. --- .gitmodules | 3 +++ build/submodules/openal-soft | 1 + 2 files changed, 4 insertions(+) create mode 160000 build/submodules/openal-soft diff --git a/.gitmodules b/.gitmodules index de5272891d..1489f22dd3 100644 --- a/.gitmodules +++ b/.gitmodules @@ -52,3 +52,6 @@ [submodule "build/submodules/MoltenVK"] path = build/submodules/MoltenVK url = https://github.com/KhronosGroup/MoltenVK +[submodule "build/submodules/openal-soft"] + path = build/submodules/openal-soft + url = https://github.com/kcat/openal-soft diff --git a/build/submodules/openal-soft b/build/submodules/openal-soft new file mode 160000 index 0000000000..d3875f333f --- /dev/null +++ b/build/submodules/openal-soft @@ -0,0 +1 @@ +Subproject commit d3875f333fb6abe2f39d82caca329414871ae53b From cd67863e2b4db15bfa20485f74b97c3c53ddcb83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Sun, 7 Apr 2024 05:01:24 +0200 Subject: [PATCH 08/20] Native/OpenAL Soft: Add build script and workflow. --- .github/workflows/openal-soft.yml | 80 +++++++++++++ .nuke/build.schema.json | 2 + build/nuke/Native/OpenALSoft.cs | 106 ++++++++++++++++++ .../Silk.NET.OpenAL.Soft.Native.csproj | 4 + 4 files changed, 192 insertions(+) create mode 100644 .github/workflows/openal-soft.yml create mode 100644 build/nuke/Native/OpenALSoft.cs diff --git a/.github/workflows/openal-soft.yml b/.github/workflows/openal-soft.yml new file mode 100644 index 0000000000..625ad52db9 --- /dev/null +++ b/.github/workflows/openal-soft.yml @@ -0,0 +1,80 @@ +name: OpenAL Soft +on: + push: + branches-ignore: + - "ci/*" + - "develop/*" + - "main" + paths: + - build/submodules/openal-soft + - build/nuke/Native/Core.cs + - build/nuke/Native/OpenALSoft.cs + - .github/workflows/openal-soft.yml +jobs: + Build: + if: github.repository == 'dotnet/Silk.NET' + strategy: + fail-fast: false + matrix: + env: + - os: ubuntu-22.04 + name: Linux + nuke_invoke: ./build.sh + extras: | + sudo tee /etc/apt/sources.list << EOF + deb [arch=amd64] http://archive.ubuntu.com/ubuntu jammy main multiverse restricted universe + deb [arch=amd64] http://archive.ubuntu.com/ubuntu jammy-backports main multiverse restricted universe + deb [arch=amd64] http://archive.ubuntu.com/ubuntu jammy-security main multiverse restricted universe + deb [arch=amd64] http://archive.ubuntu.com/ubuntu jammy-updates main multiverse restricted universe + deb [arch=arm64,armhf] http://ports.ubuntu.com jammy main multiverse restricted universe + deb [arch=arm64,armhf] http://ports.ubuntu.com jammy-backports main multiverse restricted universe + deb [arch=arm64,armhf] http://ports.ubuntu.com jammy-security main multiverse restricted universe + deb [arch=arm64,armhf] http://ports.ubuntu.com jammy-updates main multiverse restricted universe + deb [arch=amd64] http://security.ubuntu.com/ubuntu jammy main multiverse restricted universe + deb [arch=amd64] http://security.ubuntu.com/ubuntu jammy-backports main multiverse restricted universe + deb [arch=amd64] http://security.ubuntu.com/ubuntu jammy-security main multiverse restricted universe + deb [arch=amd64] http://security.ubuntu.com/ubuntu jammy-updates main multiverse restricted universe + EOF + sudo dpkg --add-architecture arm64 + sudo dpkg --add-architecture armhf + sudo apt update + sudo apt install -y gcc-aarch64-linux-gnu gcc-arm-linux-gnueabihf + sudo apt install -y g++-aarch64-linux-gnu g++-arm-linux-gnueabihf + for arch in amd64 arm64 armhf; do + sudo apt install -y libasound2-dev:$arch libpulse-dev:$arch libjack-dev:$arch libsoundio-dev:$arch + sudo apt install -y portaudio19-dev:$arch libsndfile1-dev:$arch libmysofa-dev:$arch qtbase5-dev:$arch + done + - os: windows-2022 + name: Windows + nuke_invoke: ./build.cmd + extras: "" + - os: macos-14 + name: Darwin + nuke_invoke: ./build.sh + extras: "" + name: ${{ matrix.env.name }} Build + runs-on: ${{ matrix.env.os }} + steps: + - uses: actions/checkout@v2 + with: + token: ${{ secrets.PUSHABLE_GITHUB_TOKEN }} + - name: Checkout submodules, configure git. + run: | + git -c submodule.third_party/git-hooks.update=none submodule update --init --recursive --depth 0 build/submodules/openal-soft + git config --local user.email "9011267+dotnet-bot@users.noreply.github.com" + git config --local user.name "The Silk.NET Automaton" + - name: Extra prerequisites + run: | + echo running extras + ${{ matrix.env.extras }} + - name: Setup .NET 6.0 and .NET 7.0 + uses: actions/setup-dotnet@v1 + with: + dotnet-version: | + 6.0.201 + 7.0.* + - name: Build OpenAL Soft + run: ${{ matrix.env.nuke_invoke }} openalsoft + env: + PUSHABLE_GITHUB_TOKEN: ${{ secrets.PUSHABLE_GITHUB_TOKEN }} + diff --git a/.nuke/build.schema.json b/.nuke/build.schema.json index e18f4e81b8..09c66fc913 100644 --- a/.nuke/build.schema.json +++ b/.nuke/build.schema.json @@ -154,6 +154,7 @@ "FullPushToNuGet", "GLFW", "MoltenVK", + "OpenALSoft", "Pack", "Prerequisites", "PushToNuGet", @@ -197,6 +198,7 @@ "FullPushToNuGet", "GLFW", "MoltenVK", + "OpenALSoft", "Pack", "Prerequisites", "PushToNuGet", diff --git a/build/nuke/Native/OpenALSoft.cs b/build/nuke/Native/OpenALSoft.cs new file mode 100644 index 0000000000..164e7139cd --- /dev/null +++ b/build/nuke/Native/OpenALSoft.cs @@ -0,0 +1,106 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using JetBrains.Annotations; +using Nuke.Common; +using Nuke.Common.CI.GitHubActions; +using Nuke.Common.Git; +using Nuke.Common.IO; +using Nuke.Common.Tooling; +using Nuke.Common.Tools.DotNet; +using Nuke.Common.Tools.Git; +using Octokit; +using Octokit.Internal; +using static Nuke.Common.IO.CompressionTasks; +using static Nuke.Common.IO.FileSystemTasks; +using static Nuke.Common.IO.HttpTasks; +using static Nuke.Common.Tooling.ProcessTasks; +using static Nuke.Common.Tools.DotNet.DotNetTasks; +using static Nuke.Common.Tools.Git.GitTasks; +using static Nuke.Common.Tools.GitHub.GitHubTasks; + +partial class Build { + AbsolutePath OpenALSoftPath => RootDirectory / "build" / "submodules" / "openal-soft"; + + Target OpenALSoft => CommonTarget + ( + x => x.Before(Compile) + .After(Clean) + .Executes + ( + () => + { + var buildDir = OpenALSoftPath / "build"; + var runtimes = RootDirectory / "src" / "Native" / "Silk.NET.OpenAL.Soft.Native" / "runtimes"; + + var prepare = "cmake .. -DCMAKE_BUILD_TYPE=Release -DALSOFT_UTILS=OFF -DALSOFT_NO_CONFIG_UTIL=ON -DALSOFT_EXAMPLES=OFF"; + var build = $"cmake --build . --config Release{JobsArg}"; + + if (OperatingSystem.IsWindows()) + { + foreach (var (platform, rid) in new[] + { + ("Win32", "win-x86"), + ("x64", "win-x64"), + ("ARM64", "win-arm64"), + }) + { + EnsureCleanDirectory(buildDir); + + InheritedShell($"{prepare} -A {platform}", buildDir).AssertZeroExitCode(); + InheritedShell(build, buildDir).AssertZeroExitCode(); + + CopyFile(buildDir / "Release" / "openal.dll", runtimes / rid / "native" / "soft_oal.dll", FileExistsPolicy.Overwrite); + } + } + else if (OperatingSystem.IsLinux()) + { + foreach (var (triple, rid) in new[] + { + ("x86_64-linux-gnu", "linux-x64"), + ("arm-linux-gnueabihf", "linux-arm"), + ("aarch64-linux-gnu", "linux-arm64"), + }) + { + EnsureCleanDirectory(buildDir); + + InheritedShell($"{prepare} {GetCMakeToolchainFlag(triple)}", buildDir).AssertZeroExitCode(); + InheritedShell(build, buildDir).AssertZeroExitCode(); + + InheritedShell($"{triple}-strip libopenal.so", buildDir).AssertZeroExitCode(); + + CopyFile(buildDir / "libopenal.so", runtimes / rid / "native" / "libopenal.so", FileExistsPolicy.Overwrite); + } + } + else if (OperatingSystem.IsMacOS()) + { + foreach (var (arch, rid) in new[] + { + ("x86_64", "osx-x64"), + ("arm64", "osx-arm64"), + }) + { + EnsureCleanDirectory(buildDir); + + InheritedShell($"{prepare} -DCMAKE_OSX_ARCHITECTURES={arch}", buildDir).AssertZeroExitCode(); + InheritedShell(build, buildDir).AssertZeroExitCode(); + + InheritedShell($"strip libopenal.dylib", buildDir).AssertZeroExitCode(); + + CopyFile(buildDir / "libopenal.dylib", runtimes / rid / "native" / "libopenal.dylib", FileExistsPolicy.Overwrite); + } + } + + Git("checkout HEAD build/", OpenALSoftPath); + + PrUpdatedNativeBinary("GLFW"); + } + ) + ); +} diff --git a/src/Native/Silk.NET.OpenAL.Soft.Native/Silk.NET.OpenAL.Soft.Native.csproj b/src/Native/Silk.NET.OpenAL.Soft.Native/Silk.NET.OpenAL.Soft.Native.csproj index 9c47a4aba0..f04889ff0f 100644 --- a/src/Native/Silk.NET.OpenAL.Soft.Native/Silk.NET.OpenAL.Soft.Native.csproj +++ b/src/Native/Silk.NET.OpenAL.Soft.Native/Silk.NET.OpenAL.Soft.Native.csproj @@ -22,8 +22,12 @@ + + + + From d63b98bed2d99225f8013dc44def5e73b33332e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Sat, 6 Apr 2024 22:03:15 +0200 Subject: [PATCH 09/20] Native/SDL: Build for linux-arm and linux-arm64. Also clean up the Linux/Windows build script logic. --- .github/workflows/sdl2.yml | 37 +++++- build/nuke/Native/SDL2.cs | 121 ++++++++---------- .../Silk.NET.SDL.Native.csproj | 12 +- 3 files changed, 91 insertions(+), 79 deletions(-) diff --git a/.github/workflows/sdl2.yml b/.github/workflows/sdl2.yml index 2c3321efde..25c3e0af05 100644 --- a/.github/workflows/sdl2.yml +++ b/.github/workflows/sdl2.yml @@ -17,15 +17,15 @@ jobs: fail-fast: false matrix: env: - - os: ubuntu-latest + - os: ubuntu-22.04 name: Linux nuke_invoke: ./build.sh - - os: windows-latest + - os: windows-2022 name: Windows nuke_invoke: ./build.cmd extras: | pwsh build\Install-WindowsSDK.ps1 - - os: macos-latest + - os: macos-14 name: Darwin nuke_invoke: ./build.sh extras: "" @@ -56,8 +56,35 @@ jobs: uses: Beyley/run-as-1804@239b211a2ca687388b6251d6dab22cb90ac0391d with: command: | + tee /etc/apt/sources.list << EOF + deb [arch=amd64,i386] http://archive.ubuntu.com/ubuntu bionic main multiverse restricted universe + deb [arch=amd64,i386] http://archive.ubuntu.com/ubuntu bionic-backports main multiverse restricted universe + deb [arch=amd64,i386] http://archive.ubuntu.com/ubuntu bionic-security main multiverse restricted universe + deb [arch=amd64,i386] http://archive.ubuntu.com/ubuntu bionic-updates main multiverse restricted universe + deb [arch=arm64,armhf] http://ports.ubuntu.com bionic main multiverse restricted universe + deb [arch=arm64,armhf] http://ports.ubuntu.com bionic-backports main multiverse restricted universe + deb [arch=arm64,armhf] http://ports.ubuntu.com bionic-security main multiverse restricted universe + deb [arch=arm64,armhf] http://ports.ubuntu.com bionic-updates main multiverse restricted universe + deb [arch=amd64,i386] http://security.ubuntu.com/ubuntu bionic main multiverse restricted universe + deb [arch=amd64,i386] http://security.ubuntu.com/ubuntu bionic-backports main multiverse restricted universe + deb [arch=amd64,i386] http://security.ubuntu.com/ubuntu bionic-security main multiverse restricted universe + deb [arch=amd64,i386] http://security.ubuntu.com/ubuntu bionic-updates main multiverse restricted universe + EOF + dpkg --add-architecture arm64 + dpkg --add-architecture armhf + dpkg --add-architecture i386 apt update - apt install -y python3 curl wget build-essential git make autoconf gcc-multilib g++-multilib automake libtool pkg-config ninja-build gnome-desktop-testing libasound2-dev libpulse-dev libaudio-dev libjack-dev libsndio-dev libsamplerate0-dev libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxfixes-dev libxi-dev libxss-dev libwayland-dev libxkbcommon-dev libdrm-dev libgbm-dev libgl1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libdbus-1-dev libibus-1.0-dev libudev-dev fcitx-libs-dev + apt install -y gcc gcc-aarch64-linux-gnu gcc-arm-linux-gnueabihf gcc-i686-linux-gnu + apt install -y g++ g++-aarch64-linux-gnu g++-arm-linux-gnueabihf gcc-i686-linux-gnu + apt install -y automake build-essential curl git libtool pkg-config python3 wget + for arch in amd64 arm64 armhf i386; do + apt install -y libasound2-dev:$arch libpulse-dev:$arch libaudio-dev:$arch libjack-dev:$arch + apt install -y libsndio-dev:$arch libsamplerate0-dev:$arch libx11-dev:$arch libxext-dev:$arch + apt install -y libxrandr-dev:$arch libxcursor-dev:$arch libxfixes-dev:$arch libxi-dev:$arch + apt install -y libxss-dev:$arch libwayland-dev:$arch libxkbcommon-dev:$arch libdrm-dev:$arch + apt install -y libgbm-dev:$arch libgl1-mesa-dev:$arch libgles2-mesa-dev:$arch libegl1-mesa-dev:$arch + apt install -y libdbus-1-dev:$arch libibus-1.0-dev:$arch libudev-dev:$arch + done wget https://dot.net/v1/dotnet-install.sh -O dotnet-install.sh chmod +x ./dotnet-install.sh @@ -82,5 +109,5 @@ jobs: run: ${{ matrix.env.nuke_invoke }} SDL2 env: PUSHABLE_GITHUB_TOKEN: ${{ secrets.PUSHABLE_GITHUB_TOKEN }} - + diff --git a/build/nuke/Native/SDL2.cs b/build/nuke/Native/SDL2.cs index 1f6b50b152..0c1e294fd4 100644 --- a/build/nuke/Native/SDL2.cs +++ b/build/nuke/Native/SDL2.cs @@ -58,100 +58,83 @@ static readonly (string Sdk, string Arch, string Rid, string Args)[] iPhoneConfi { var runtimes = RootDirectory / "src" / "Native" / "Silk.NET.SDL.Native" / "runtimes"; - var x86BuildDir = SDL2Path / "buildx86"; - var x64BuildDir = SDL2Path / "buildx64"; - var ARM64BuildDir = SDL2Path / "buildARM64"; - EnsureCleanDirectory(x86BuildDir); - EnsureCleanDirectory(x64BuildDir); - EnsureCleanDirectory(ARM64BuildDir); - if (OperatingSystem.IsWindows()) { - var prepare = "cmake .. -DBUILD_SHARED_LIBS=ON"; - var build = $"cmake --build . --config Release{JobsArg}"; - - InheritedShell($"{prepare} -A Win32", x86BuildDir).AssertZeroExitCode(); - InheritedShell(build, x86BuildDir).AssertZeroExitCode(); + foreach (var (platform, rid) in new[] + { + ("Win32", "win-x86"), + ("x64", "win-x64"), + ("ARM64", "win-arm64"), + }) + { + var buildDir = SDL2Path / "build"; - InheritedShell($"{prepare} -A X64", x64BuildDir).AssertZeroExitCode(); - InheritedShell(build, x64BuildDir).AssertZeroExitCode(); + EnsureCleanDirectory(buildDir); - InheritedShell($"{prepare} -A arm64", ARM64BuildDir).AssertZeroExitCode(); - InheritedShell(build, ARM64BuildDir).AssertZeroExitCode(); + InheritedShell($"cmake .. -A {platform} -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON", buildDir).AssertZeroExitCode(); + InheritedShell($"cmake --build . --config Release{JobsArg}", buildDir).AssertZeroExitCode(); - CopyFile(x86BuildDir / "Release" / "SDL2.dll", runtimes / "win-x86" / "native" / "SDL2.dll", FileExistsPolicy.Overwrite); - CopyFile(x64BuildDir / "Release" / "SDL2.dll", runtimes / "win-x64" / "native" / "SDL2.dll", FileExistsPolicy.Overwrite); - CopyFile(ARM64BuildDir / "Release" / "SDL2.dll", runtimes / "win-arm64" / "native" / "SDL2.dll", FileExistsPolicy.Overwrite); + CopyFile(buildDir / "Release" / "SDL2.dll", runtimes / rid / "native" / "SDL2.dll", FileExistsPolicy.Overwrite); + } } - - if (OperatingSystem.IsLinux()) + else if (OperatingSystem.IsLinux()) { - if (RuntimeInformation.OSArchitecture == Architecture.Arm64) + foreach (var (triple, rid) in new[] { - InheritedShell("cmake ..", x86BuildDir).AssertZeroExitCode(); - InheritedShell("cmake --build .", x86BuildDir).AssertZeroExitCode(); - - CopyFile(ARM64BuildDir.GlobFiles("libSDL2-2.0.so*").First(), runtimes / "linux-arm64" / "native" / "libSDL2-2.0.so", FileExistsPolicy.Overwrite); - } - else if (RuntimeInformation.OSArchitecture == Architecture.X64) + ("i686-linux-gnu", "linux-x86"), + ("x86_64-linux-gnu", "linux-x64"), + ("arm-linux-gnueabihf", "linux-arm"), + ("aarch64-linux-gnu", "linux-arm64"), + }) { - var envVars32bit = "CFLAGS='-m32 -O2' CXXFLAGS='-m32 -O2' LDFLAGS=-m32"; - var envVars64bit = "CFLAGS=-O2 CXXFLAGS=-O2"; + var buildDir = SDL2Path / "build"; - InheritedShell($"{envVars32bit} ./configure --prefix={x86BuildDir}", SDL2Path).AssertZeroExitCode(); - InheritedShell($"{envVars32bit} make {JobsArg}", SDL2Path).AssertZeroExitCode(); - InheritedShell($"make install", SDL2Path).AssertZeroExitCode(); + EnsureCleanDirectory(buildDir); - InheritedShell($"{envVars64bit} ./configure --prefix={x64BuildDir}", SDL2Path).AssertZeroExitCode(); - InheritedShell($"{envVars64bit} make {JobsArg}", SDL2Path).AssertZeroExitCode(); + InheritedShell($"./configure --prefix={buildDir} --host={triple}", SDL2Path).AssertZeroExitCode(); + InheritedShell($"make {JobsArg}", SDL2Path).AssertZeroExitCode(); InheritedShell($"make install", SDL2Path).AssertZeroExitCode(); - //Strip the libraries - InheritedShell($"strip {x86BuildDir / "lib" / "libSDL2-2.0.so*"}", SDL2Path).AssertZeroExitCode(); - InheritedShell($"strip {x64BuildDir / "lib" / "libSDL2-2.0.so*"}", SDL2Path).AssertZeroExitCode(); + InheritedShell($"{triple}-strip lib/libSDL2-2.0.so*", buildDir).AssertZeroExitCode(); - CopyFile((x86BuildDir / "lib").GlobFiles("libSDL2-2.0.so*").First(), runtimes / "linux-x86" / "native" / "libSDL2-2.0.so", FileExistsPolicy.Overwrite); - CopyFile((x64BuildDir / "lib").GlobFiles("libSDL2-2.0.so*").First(), runtimes / "linux-x64" / "native" / "libSDL2-2.0.so", FileExistsPolicy.Overwrite); - } - else - { - throw new Exception($"Unable to build SDL libs on your architecture ({RuntimeInformation.OSArchitecture})."); + CopyFile((buildDir / "lib").GlobFiles("libSDL2-2.0.so*").First(), runtimes / rid / "native" / "libSDL2-2.0.so", FileExistsPolicy.Overwrite); } } - - if (OperatingSystem.IsMacOS()) + else if (OperatingSystem.IsMacOS()) { // iOS build/hackery ported from https://github.com/Ultz/SDL-Xamarin.iOS - var mainH = File.ReadAllText(SDL2Path / "include" / "SDL_main.h"); - try + + File.WriteAllText( + SDL2Path / "include" / "SDL_main.h", + $"#define SDL_MAIN_HANDLED\n{File.ReadAllText(SDL2Path / "include" / "SDL_main.h")}"); + + EnsureCleanDirectory(SDL2Path / "allbuild"); + + foreach (var (sdk, arch, rid, args) in iPhoneConfigs) { - File.WriteAllText(SDL2Path / "include" / "SDL_main.h", $"#define SDL_MAIN_HANDLED\n{mainH}"); - EnsureCleanDirectory(SDL2Path / "allbuild"); - foreach (var (sdk, arch, rid, args) in iPhoneConfigs) - { - InheritedShell($"xcodebuild -project SDL.xcodeproj {args} -sdk {sdk} -arch {arch} -configuration Release clean build -jobs {Jobs}", SDL2Path / "XCode" / "SDL") - .AssertZeroExitCode(); - var ext = rid is "maccatalyst" or "osx" ? "dylib" : "a"; - var cfg = rid is "maccatalyst" or "osx" ? "Release" : $"Release-{sdk}"; - CopyFile(SDL2Path / "XCode" / "SDL" / "build" / cfg / $"libSDL2.{ext}", SDL2Path / "allbuild" / $"libSDL2.{sdk}.{arch}.{rid}.{ext}"); - } - foreach (var rid in iPhoneConfigs.GroupBy(x => x.Rid)) - { - var ext = rid.Key is "maccatalyst" or "osx" ? "dylib" : "a"; - var @in = string.Join("\" \"", rid.Select(x => SDL2Path / "allbuild" / $"libSDL2.{x.Sdk}.{x.Arch}.{rid.Key}.{ext}")); - var @out = runtimes / rid.Key / "native" / (ext is "dylib" ? "libSDL2-2.0.dylib" : "libSDL2.a"); - EnsureCleanDirectory(Path.GetDirectoryName(@out)); - InheritedShell($"lipo -create -output \"{@out}\" \"{@in}\"").AssertZeroExitCode(); - } + InheritedShell($"xcodebuild -project SDL.xcodeproj {args} -sdk {sdk} -arch {arch} -configuration Release clean build -jobs {Jobs}", SDL2Path / "XCode" / "SDL").AssertZeroExitCode(); + + var ext = rid is "maccatalyst" or "osx" ? "dylib" : "a"; + var cfg = rid is "maccatalyst" or "osx" ? "Release" : $"Release-{sdk}"; + + CopyFile(SDL2Path / "XCode" / "SDL" / "build" / cfg / $"libSDL2.{ext}", SDL2Path / "allbuild" / $"libSDL2.{sdk}.{arch}.{rid}.{ext}"); } - finally + + foreach (var rid in iPhoneConfigs.GroupBy(x => x.Rid)) { - File.WriteAllText(SDL2Path / "include" / "SDL_main.h", mainH); + var ext = rid.Key is "maccatalyst" or "osx" ? "dylib" : "a"; + var @in = string.Join("\" \"", rid.Select(x => SDL2Path / "allbuild" / $"libSDL2.{x.Sdk}.{x.Arch}.{rid.Key}.{ext}")); + var @out = runtimes / rid.Key / "native" / (ext is "dylib" ? "libSDL2-2.0.dylib" : "libSDL2.a"); + + EnsureCleanDirectory(Path.GetDirectoryName(@out)); + InheritedShell($"lipo -create -output \"{@out}\" \"{@in}\"").AssertZeroExitCode(); } } + Git("checkout HEAD include/", SDL2Path); + PrUpdatedNativeBinary("SDL2"); } ) ); -} \ No newline at end of file +} diff --git a/src/Native/Silk.NET.SDL.Native/Silk.NET.SDL.Native.csproj b/src/Native/Silk.NET.SDL.Native/Silk.NET.SDL.Native.csproj index 38b06f2a05..8aea8e6cb9 100644 --- a/src/Native/Silk.NET.SDL.Native/Silk.NET.SDL.Native.csproj +++ b/src/Native/Silk.NET.SDL.Native/Silk.NET.SDL.Native.csproj @@ -24,16 +24,18 @@ + - + + + - - - + - + + From 8d04fb8d1cbddec22fb548654d89a5301f4dece3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Mon, 8 Apr 2024 08:56:22 +0200 Subject: [PATCH 10/20] Native/SDL: Build with dynamically-loaded Wayland and X11 support. --- build/nuke/Native/SDL2.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/nuke/Native/SDL2.cs b/build/nuke/Native/SDL2.cs index 0c1e294fd4..4baae91ea5 100644 --- a/build/nuke/Native/SDL2.cs +++ b/build/nuke/Native/SDL2.cs @@ -91,7 +91,7 @@ static readonly (string Sdk, string Arch, string Rid, string Args)[] iPhoneConfi EnsureCleanDirectory(buildDir); - InheritedShell($"./configure --prefix={buildDir} --host={triple}", SDL2Path).AssertZeroExitCode(); + InheritedShell($"./configure --prefix={buildDir} --host={triple} --enable-wayland-shared --enable-x11-shared", SDL2Path).AssertZeroExitCode(); InheritedShell($"make {JobsArg}", SDL2Path).AssertZeroExitCode(); InheritedShell($"make install", SDL2Path).AssertZeroExitCode(); From b5bd0568bf6f4879e01cde6e97fdd9fa66dc0d74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Mon, 8 Apr 2024 08:07:05 +0200 Subject: [PATCH 11/20] Native/SDL: Disable assertions when building on Windows/Linux. --- build/nuke/Native/SDL2.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/nuke/Native/SDL2.cs b/build/nuke/Native/SDL2.cs index 4baae91ea5..5bd4c04663 100644 --- a/build/nuke/Native/SDL2.cs +++ b/build/nuke/Native/SDL2.cs @@ -71,7 +71,7 @@ static readonly (string Sdk, string Arch, string Rid, string Args)[] iPhoneConfi EnsureCleanDirectory(buildDir); - InheritedShell($"cmake .. -A {platform} -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON", buildDir).AssertZeroExitCode(); + InheritedShell($"cmake .. -A {platform} -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DSDL_ASSERTIONS=disabled", buildDir).AssertZeroExitCode(); InheritedShell($"cmake --build . --config Release{JobsArg}", buildDir).AssertZeroExitCode(); CopyFile(buildDir / "Release" / "SDL2.dll", runtimes / rid / "native" / "SDL2.dll", FileExistsPolicy.Overwrite); @@ -91,7 +91,7 @@ static readonly (string Sdk, string Arch, string Rid, string Args)[] iPhoneConfi EnsureCleanDirectory(buildDir); - InheritedShell($"./configure --prefix={buildDir} --host={triple} --enable-wayland-shared --enable-x11-shared", SDL2Path).AssertZeroExitCode(); + InheritedShell($"./configure --prefix={buildDir} --host={triple} --enable-assertions=disabled --enable-wayland-shared --enable-x11-shared", SDL2Path).AssertZeroExitCode(); InheritedShell($"make {JobsArg}", SDL2Path).AssertZeroExitCode(); InheritedShell($"make install", SDL2Path).AssertZeroExitCode(); From c203fa92b373a62c9b6ce578541b71e9f916b6bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Tue, 9 Apr 2024 11:43:57 +0200 Subject: [PATCH 12/20] Native/SDL: Don't build static libraries on Linux. --- build/nuke/Native/SDL2.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/nuke/Native/SDL2.cs b/build/nuke/Native/SDL2.cs index 5bd4c04663..3d170e8687 100644 --- a/build/nuke/Native/SDL2.cs +++ b/build/nuke/Native/SDL2.cs @@ -91,7 +91,7 @@ static readonly (string Sdk, string Arch, string Rid, string Args)[] iPhoneConfi EnsureCleanDirectory(buildDir); - InheritedShell($"./configure --prefix={buildDir} --host={triple} --enable-assertions=disabled --enable-wayland-shared --enable-x11-shared", SDL2Path).AssertZeroExitCode(); + InheritedShell($"./configure --prefix={buildDir} --disable-static --host={triple} --enable-assertions=disabled --enable-wayland-shared --enable-x11-shared", SDL2Path).AssertZeroExitCode(); InheritedShell($"make {JobsArg}", SDL2Path).AssertZeroExitCode(); InheritedShell($"make install", SDL2Path).AssertZeroExitCode(); From 04ac4f951ea8b2f0761474191ce344527db0c19a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Sun, 7 Apr 2024 01:02:57 +0200 Subject: [PATCH 13/20] Native/SDL: Strip macOS binaries after build. --- build/nuke/Native/SDL2.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/build/nuke/Native/SDL2.cs b/build/nuke/Native/SDL2.cs index 3d170e8687..e32599d331 100644 --- a/build/nuke/Native/SDL2.cs +++ b/build/nuke/Native/SDL2.cs @@ -128,6 +128,7 @@ static readonly (string Sdk, string Arch, string Rid, string Args)[] iPhoneConfi EnsureCleanDirectory(Path.GetDirectoryName(@out)); InheritedShell($"lipo -create -output \"{@out}\" \"{@in}\"").AssertZeroExitCode(); + InheritedShell($"strip \"{@out}\"").AssertZeroExitCode(); } } From a444bf14ec5b5a71a44f9c8ade4d44f06902493b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Tue, 9 Apr 2024 12:50:34 +0200 Subject: [PATCH 14/20] Native/SwiftShader: Build for linux-arm, linux-arm64, osx-arm64, win-arm64, and win-x86. Also clean up the build script. --- .github/workflows/swiftshader.yml | 32 ++++++-- build/nuke/Native/SwiftShader.cs | 120 +++++++++++++++--------------- 2 files changed, 85 insertions(+), 67 deletions(-) diff --git a/.github/workflows/swiftshader.yml b/.github/workflows/swiftshader.yml index 2f0a416105..625308daca 100644 --- a/.github/workflows/swiftshader.yml +++ b/.github/workflows/swiftshader.yml @@ -17,17 +17,37 @@ jobs: fail-fast: false matrix: env: - - os: ubuntu-latest + - os: ubuntu-22.04 name: Linux nuke_invoke: ./build.sh extras: | - sudo apt-get update - sudo apt-get install -y libx11-xcb-dev - - os: windows-latest + sudo tee /etc/apt/sources.list << EOF + deb [arch=amd64] http://archive.ubuntu.com/ubuntu jammy main multiverse restricted universe + deb [arch=amd64] http://archive.ubuntu.com/ubuntu jammy-backports main multiverse restricted universe + deb [arch=amd64] http://archive.ubuntu.com/ubuntu jammy-security main multiverse restricted universe + deb [arch=amd64] http://archive.ubuntu.com/ubuntu jammy-updates main multiverse restricted universe + deb [arch=arm64,armhf] http://ports.ubuntu.com jammy main multiverse restricted universe + deb [arch=arm64,armhf] http://ports.ubuntu.com jammy-backports main multiverse restricted universe + deb [arch=arm64,armhf] http://ports.ubuntu.com jammy-security main multiverse restricted universe + deb [arch=arm64,armhf] http://ports.ubuntu.com jammy-updates main multiverse restricted universe + deb [arch=amd64] http://security.ubuntu.com/ubuntu jammy main multiverse restricted universe + deb [arch=amd64] http://security.ubuntu.com/ubuntu jammy-backports main multiverse restricted universe + deb [arch=amd64] http://security.ubuntu.com/ubuntu jammy-security main multiverse restricted universe + deb [arch=amd64] http://security.ubuntu.com/ubuntu jammy-updates main multiverse restricted universe + EOF + sudo dpkg --add-architecture arm64 + sudo dpkg --add-architecture armhf + sudo apt update + sudo apt install -y gcc-aarch64-linux-gnu gcc-arm-linux-gnueabihf + sudo apt install -y g++-aarch64-linux-gnu g++-arm-linux-gnueabihf + for arch in amd64 arm64 armhf; do + sudo apt install -y libx11-xcb-dev:$arch + done + - os: windows-2022 name: Windows nuke_invoke: ./build.cmd extras: "" - - os: macos-latest + - os: macos-14 name: Darwin nuke_invoke: ./build.sh extras: "" @@ -41,7 +61,7 @@ jobs: run: | git -c submodule.third_party/git-hooks.update=none submodule update --init --recursive --depth 0 build/submodules/SwiftShader git config --local user.email "9011267+dotnet-bot@users.noreply.github.com" - git config --local user.name "The Silk.NET Automaton" + git config --local user.name "The Silk.NET Automaton" - name: Extra prerequisites run: | echo running extras diff --git a/build/nuke/Native/SwiftShader.cs b/build/nuke/Native/SwiftShader.cs index 2874904ce6..1ea3b91345 100644 --- a/build/nuke/Native/SwiftShader.cs +++ b/build/nuke/Native/SwiftShader.cs @@ -26,7 +26,7 @@ using static Nuke.Common.Tools.GitHub.GitHubTasks; partial class Build { - AbsolutePath SwiftShaderBuildPath => RootDirectory / "build" / "submodules" / "SwiftShader" / "build"; + AbsolutePath SwiftShaderPath => RootDirectory / "build" / "submodules" / "SwiftShader"; Target SwiftShader => CommonTarget ( @@ -36,78 +36,76 @@ partial class Build { ( () => { - var sysName = OperatingSystem.IsLinux() ? "Linux" : - OperatingSystem.IsWindows() ? "Windows" : - OperatingSystem.IsMacOS() ? "Darwin" : throw new PlatformNotSupportedException(); - DeleteDirectory(SwiftShaderBuildPath); - Git("checkout HEAD build/", SwiftShaderBuildPath / ".."); - StartProcess("cmake", ".. -DCMAKE_BUILD_TYPE=Release", SwiftShaderBuildPath) - .AssertZeroExitCode(); - StartProcess("cmake", $"--build .{JobsArg} --config Release", SwiftShaderBuildPath) - .AssertWaitForExit(); // might fail... as long as the output exists we're happy - var fname = sysName switch - { - "Linux" => "libvk_swiftshader.so", - "Windows" => "vk_swiftshader.dll", - "Darwin" => "libvk_swiftshader.dylib", - _ => throw new("what") - }; - + var buildDir = SwiftShaderPath / "build"; var runtimes = RootDirectory / "src" / "Native" / "Silk.NET.Vulkan.SwiftShader.Native" / "runtimes"; - var outputPath = SwiftShaderBuildPath / sysName; - const string icd = "vk_swiftshader_icd.json"; + + var prepare = "cmake .. -DSWIFTSHADER_WARNINGS_AS_ERRORS=FALSE"; + var build = $"cmake --build . --config Release{JobsArg}"; + + // Work around SwiftShader's silly Git hook installation logic that fails as a submodule. + File.WriteAllText( + SwiftShaderPath / "CMakeLists.txt", + File.ReadAllText(SwiftShaderPath / "CMakeLists.txt") + .Replace("if(NOT EXISTS ${CMAKE_SOURCE_DIR}/.git/hooks/commit-msg)", "if(FALSE)")); + if (OperatingSystem.IsWindows()) { - CopyFile - ( - outputPath / fname, runtimes / "win-x64" / "native" / fname, - FileExistsPolicy.Overwrite - ); // we'll use WOW64 - CopyFile - ( - outputPath / fname, runtimes / "win-x86" / "native" / fname, - FileExistsPolicy.Overwrite - ); - CopyFile - ( - outputPath / icd, runtimes / "win-x64" / "native" / icd, - FileExistsPolicy.Overwrite - ); - CopyFile - ( - outputPath / icd, runtimes / "win-x86" / "native" / icd, - FileExistsPolicy.Overwrite - ); + foreach (var (platform, rid) in new[] + { + ("Win32", "win-x86"), + ("x64", "win-x64"), + ("ARM64", "win-arm64"), + }) + { + EnsureCleanDirectory(buildDir); + + InheritedShell($"{prepare} -A {platform}", buildDir).AssertZeroExitCode(); + InheritedShell(build, buildDir).AssertZeroExitCode(); + + CopyFile(buildDir / "Windows" / "vk_swiftshader.dll", runtimes / rid / "native" / "vk_swiftshader.dll", FileExistsPolicy.Overwrite); + CopyFile(buildDir / "Windows" / "vk_swiftshader_icd.json", runtimes / rid / "native" / "vk_swiftshader_icd.json", FileExistsPolicy.Overwrite); + } } else if (OperatingSystem.IsLinux()) { - CopyFile - ( - outputPath / fname, runtimes / "linux-x64" / "native" / fname, - FileExistsPolicy.Overwrite - ); - CopyFile - ( - outputPath / icd, runtimes / "linux-x64" / "native" / icd, - FileExistsPolicy.Overwrite - ); + foreach (var (triple, rid) in new[] + { + ("x86_64-linux-gnu", "linux-x64"), + ("arm-linux-gnueabihf", "linux-arm"), + ("aarch64-linux-gnu", "linux-arm64"), + }) + { + EnsureCleanDirectory(buildDir); + + InheritedShell($"{prepare} {GetCMakeToolchainFlag(triple)}", buildDir).AssertZeroExitCode(); + InheritedShell(build, buildDir).AssertZeroExitCode(); + + CopyFile(buildDir / "Linux" / "libvk_swiftshader.so", runtimes / rid / "native" / "libvk_swiftshader.so", FileExistsPolicy.Overwrite); + CopyFile(buildDir / "Linux" / "vk_swiftshader_icd.json", runtimes / rid / "native" / "vk_swiftshader_icd.json", FileExistsPolicy.Overwrite); + } } else if (OperatingSystem.IsMacOS()) { - CopyFile - ( - outputPath / fname, runtimes / "osx-x64" / "native" / fname, - FileExistsPolicy.Overwrite - ); - CopyFile - ( - outputPath / icd, runtimes / "osx-x64" / "native" / icd, - FileExistsPolicy.Overwrite - ); + foreach (var (arch, rid) in new[] + { + ("x86_64", "osx-x64"), + ("arm64", "osx-arm64"), + }) + { + EnsureCleanDirectory(buildDir); + + InheritedShell($"{prepare} -DCMAKE_OSX_ARCHITECTURES={arch}", buildDir).AssertZeroExitCode(); + InheritedShell(build, buildDir).AssertZeroExitCode(); + + CopyFile(buildDir / "Darwin" / "libvk_swiftshader.dylib", runtimes / rid / "native" / "libvk_swiftshader.dylib", FileExistsPolicy.Overwrite); + CopyFile(buildDir / "Darwin" / "vk_swiftshader_icd.json", runtimes / rid / "native" / "vk_swiftshader_icd.json", FileExistsPolicy.Overwrite); + } } + Git("checkout HEAD CMakeLists.txt build/", SwiftShaderPath); + PrUpdatedNativeBinary("SwiftShader"); } ) ); -} \ No newline at end of file +} From 99fc3ff19dd9dfbc7e18f2ac5fba4b67ba51cd36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Tue, 9 Apr 2024 12:58:03 +0200 Subject: [PATCH 15/20] Native/SwiftShader: Don't build tests. --- build/nuke/Native/SwiftShader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/nuke/Native/SwiftShader.cs b/build/nuke/Native/SwiftShader.cs index 1ea3b91345..1adf1f57bb 100644 --- a/build/nuke/Native/SwiftShader.cs +++ b/build/nuke/Native/SwiftShader.cs @@ -39,7 +39,7 @@ partial class Build { var buildDir = SwiftShaderPath / "build"; var runtimes = RootDirectory / "src" / "Native" / "Silk.NET.Vulkan.SwiftShader.Native" / "runtimes"; - var prepare = "cmake .. -DSWIFTSHADER_WARNINGS_AS_ERRORS=FALSE"; + var prepare = "cmake .. -DSWIFTSHADER_WARNINGS_AS_ERRORS=FALSE -DSWIFTSHADER_BUILD_TESTS=FALSE"; var build = $"cmake --build . --config Release{JobsArg}"; // Work around SwiftShader's silly Git hook installation logic that fails as a submodule. From 15d84c8a3bfe4e896dff00b2dff1500774f29f88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Tue, 9 Apr 2024 13:01:23 +0200 Subject: [PATCH 16/20] Native/SwiftShader: Strip Linux/macOS binaries after build. --- build/nuke/Native/SwiftShader.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build/nuke/Native/SwiftShader.cs b/build/nuke/Native/SwiftShader.cs index 1adf1f57bb..0ff770777d 100644 --- a/build/nuke/Native/SwiftShader.cs +++ b/build/nuke/Native/SwiftShader.cs @@ -80,6 +80,8 @@ partial class Build { InheritedShell($"{prepare} {GetCMakeToolchainFlag(triple)}", buildDir).AssertZeroExitCode(); InheritedShell(build, buildDir).AssertZeroExitCode(); + InheritedShell($"{triple}-strip Linux/libvk_swiftshader.so", buildDir).AssertZeroExitCode(); + CopyFile(buildDir / "Linux" / "libvk_swiftshader.so", runtimes / rid / "native" / "libvk_swiftshader.so", FileExistsPolicy.Overwrite); CopyFile(buildDir / "Linux" / "vk_swiftshader_icd.json", runtimes / rid / "native" / "vk_swiftshader_icd.json", FileExistsPolicy.Overwrite); } @@ -97,6 +99,8 @@ partial class Build { InheritedShell($"{prepare} -DCMAKE_OSX_ARCHITECTURES={arch}", buildDir).AssertZeroExitCode(); InheritedShell(build, buildDir).AssertZeroExitCode(); + InheritedShell($"-strip Darwin/libvk_swiftshader.dylib", buildDir).AssertZeroExitCode(); + CopyFile(buildDir / "Darwin" / "libvk_swiftshader.dylib", runtimes / rid / "native" / "libvk_swiftshader.dylib", FileExistsPolicy.Overwrite); CopyFile(buildDir / "Darwin" / "vk_swiftshader_icd.json", runtimes / rid / "native" / "vk_swiftshader_icd.json", FileExistsPolicy.Overwrite); } From f98f3f41dd73cd924f46793f0f0bff816e6f935d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Tue, 9 Apr 2024 12:15:44 +0200 Subject: [PATCH 17/20] Native/Vulkan Loader: Build for linux-arm64, osx-arm64, and win-x86. Also clean up the build script. --- .github/workflows/vulkan-loader.yml | 32 ++++-- build/nuke/Native/VulkanLoader.cs | 98 ++++++++++++------- .../Silk.NET.Vulkan.Loader.Native.csproj | 2 + 3 files changed, 92 insertions(+), 40 deletions(-) diff --git a/.github/workflows/vulkan-loader.yml b/.github/workflows/vulkan-loader.yml index 8c48f00d2a..d1ea6cd4f4 100644 --- a/.github/workflows/vulkan-loader.yml +++ b/.github/workflows/vulkan-loader.yml @@ -17,17 +17,37 @@ jobs: fail-fast: false matrix: env: - - os: ubuntu-latest + - os: ubuntu-22.04 name: Linux nuke_invoke: ./build.sh extras: | - sudo apt-get update - sudo apt-get install -y build-essential libx11-xcb-dev libxkbcommon-dev libwayland-dev libxrandr-dev - - os: windows-latest + sudo tee /etc/apt/sources.list << EOF + deb [arch=amd64] http://archive.ubuntu.com/ubuntu jammy main multiverse restricted universe + deb [arch=amd64] http://archive.ubuntu.com/ubuntu jammy-backports main multiverse restricted universe + deb [arch=amd64] http://archive.ubuntu.com/ubuntu jammy-security main multiverse restricted universe + deb [arch=amd64] http://archive.ubuntu.com/ubuntu jammy-updates main multiverse restricted universe + deb [arch=arm64,armhf] http://ports.ubuntu.com jammy main multiverse restricted universe + deb [arch=arm64,armhf] http://ports.ubuntu.com jammy-backports main multiverse restricted universe + deb [arch=arm64,armhf] http://ports.ubuntu.com jammy-security main multiverse restricted universe + deb [arch=arm64,armhf] http://ports.ubuntu.com jammy-updates main multiverse restricted universe + deb [arch=amd64] http://security.ubuntu.com/ubuntu jammy main multiverse restricted universe + deb [arch=amd64] http://security.ubuntu.com/ubuntu jammy-backports main multiverse restricted universe + deb [arch=amd64] http://security.ubuntu.com/ubuntu jammy-security main multiverse restricted universe + deb [arch=amd64] http://security.ubuntu.com/ubuntu jammy-updates main multiverse restricted universe + EOF + sudo dpkg --add-architecture arm64 + sudo dpkg --add-architecture armhf + sudo apt update + sudo apt install -y gcc-aarch64-linux-gnu gcc-arm-linux-gnueabihf + for arch in amd64 arm64 armhf; do + sudo apt install -y pkg-config:$arch + sudo apt install -y libx11-xcb-dev:$arch libxkbcommon-dev:$arch libwayland-dev:$arch libxrandr-dev:$arch + done + - os: windows-2022 name: Windows nuke_invoke: ./build.cmd extras: "" - - os: macos-latest + - os: macos-14 name: Darwin nuke_invoke: ./build.sh extras: "" @@ -41,7 +61,7 @@ jobs: run: | git -c submodule.third_party/git-hooks.update=none submodule update --init --recursive --depth 0 build/submodules/Vulkan-Loader git config --local user.email "9011267+dotnet-bot@users.noreply.github.com" - git config --local user.name "The Silk.NET Automaton" + git config --local user.name "The Silk.NET Automaton" - name: Extra prerequisites run: | echo running extras diff --git a/build/nuke/Native/VulkanLoader.cs b/build/nuke/Native/VulkanLoader.cs index eb589de50d..4573843b7b 100644 --- a/build/nuke/Native/VulkanLoader.cs +++ b/build/nuke/Native/VulkanLoader.cs @@ -31,39 +31,69 @@ partial class Build { Target VulkanLoader => CommonTarget ( x => x.Before(Compile) - .After(Clean) - .Executes - ( - () => - { - var @out = VulkanLoaderPath / "build"; - EnsureCleanDirectory(@out); - var abi = OperatingSystem.IsWindows() ? " -DCMAKE_GENERATOR_PLATFORM=Win32" : string.Empty; - InheritedShell - ( - $"cmake -S. -Bbuild -DUPDATE_DEPS=On -DCMAKE_BUILD_TYPE=Release{abi}", - VulkanLoaderPath - ) - .AssertZeroExitCode(); - InheritedShell($"cmake --build build --config Release{JobsArg}", VulkanLoaderPath) - .AssertZeroExitCode(); - var runtimes = RootDirectory / "src" / "Native" / "Silk.NET.Vulkan.Loader.Native" / "runtimes"; - if (OperatingSystem.IsWindows()) - { - CopyAll(@out.GlobFiles("loader/Release/vulkan-1.dll"), runtimes / "win-x64" / "native"); - CopyAll(@out.GlobFiles("loader/Release/vulkan-1.dll"), runtimes / "win-x86" / "native"); - } - else - { - CopyAll - ( - @out.GlobFiles("loader/libvulkan.so", "loader/libvulkan.dylib"), - runtimes / (OperatingSystem.IsMacOS() ? "osx-x64" : "linux-x64") / "native" - ); - } + .After(Clean) + .Executes + ( + () => + { + var buildDir = VulkanLoaderPath / "build"; + var runtimes = RootDirectory / "src" / "Native" / "Silk.NET.Vulkan.Loader.Native" / "runtimes"; - PrUpdatedNativeBinary("Vulkan Loader"); - } - ) + var prepare = "cmake .. -DCMAKE_BUILD_TYPE=Release -DUPDATE_DEPS=ON"; + var build = $"cmake --build . --config Release{JobsArg}"; + + if (OperatingSystem.IsWindows()) + { + foreach (var (platform, rid) in new[] + { + ("Win32", "win-x86"), + ("x64", "win-x64"), + }) + { + EnsureCleanDirectory(buildDir); + + InheritedShell($"{prepare} -A {platform}", buildDir).AssertZeroExitCode(); + InheritedShell(build, buildDir).AssertZeroExitCode(); + + CopyAll((buildDir / "loader" / "Release").GlobFiles("vulkan-1.dll"), runtimes / rid / "native"); + } + } + else if (OperatingSystem.IsLinux()) + { + + foreach (var (triple, rid) in new[] + { + ("x86_64-linux-gnu", "linux-x64"), + ("aarch64-linux-gnu", "linux-arm64"), + }) + { + EnsureCleanDirectory(buildDir); + + InheritedShell($"{prepare} {GetCMakeToolchainFlag(triple)}", buildDir).AssertZeroExitCode(); + InheritedShell(build, buildDir).AssertZeroExitCode(); + + CopyAll((buildDir / "loader").GlobFiles("libvulkan.so"), runtimes / rid / "native"); + } + } + else if (OperatingSystem.IsMacOS()) + { + foreach (var (arch, rid) in new[] + { + ("x86_64", "osx-x64"), + ("arm64", "osx-arm64"), + }) + { + EnsureCleanDirectory(buildDir); + + InheritedShell($"{prepare} -DCMAKE_OSX_ARCHITECTURES={arch}", buildDir).AssertZeroExitCode(); + InheritedShell(build, buildDir).AssertZeroExitCode(); + + CopyAll((buildDir / "loader").GlobFiles("libvulkan.dylib"), runtimes / rid / "native"); + } + } + + PrUpdatedNativeBinary("Vulkan Loader"); + } + ) ); -} \ No newline at end of file +} diff --git a/src/Native/Silk.NET.Vulkan.Loader.Native/Silk.NET.Vulkan.Loader.Native.csproj b/src/Native/Silk.NET.Vulkan.Loader.Native/Silk.NET.Vulkan.Loader.Native.csproj index c65e2e3cbd..4ab9b2f9bd 100644 --- a/src/Native/Silk.NET.Vulkan.Loader.Native/Silk.NET.Vulkan.Loader.Native.csproj +++ b/src/Native/Silk.NET.Vulkan.Loader.Native/Silk.NET.Vulkan.Loader.Native.csproj @@ -18,7 +18,9 @@ + + From 94c7454ac1e51ce2531fceea51dfc95edc1f24e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Tue, 9 Apr 2024 12:17:02 +0200 Subject: [PATCH 18/20] Native/Vulkan Loader: Strip Linux/macOS binaries after build. --- build/nuke/Native/VulkanLoader.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build/nuke/Native/VulkanLoader.cs b/build/nuke/Native/VulkanLoader.cs index 4573843b7b..b91286bcc5 100644 --- a/build/nuke/Native/VulkanLoader.cs +++ b/build/nuke/Native/VulkanLoader.cs @@ -72,6 +72,8 @@ partial class Build { InheritedShell($"{prepare} {GetCMakeToolchainFlag(triple)}", buildDir).AssertZeroExitCode(); InheritedShell(build, buildDir).AssertZeroExitCode(); + InheritedShell($"{triple}-strip loader/libvulkan.so", buildDir).AssertZeroExitCode(); + CopyAll((buildDir / "loader").GlobFiles("libvulkan.so"), runtimes / rid / "native"); } } @@ -88,6 +90,8 @@ partial class Build { InheritedShell($"{prepare} -DCMAKE_OSX_ARCHITECTURES={arch}", buildDir).AssertZeroExitCode(); InheritedShell(build, buildDir).AssertZeroExitCode(); + InheritedShell($"strip loader/libvulkan.dylib", buildDir).AssertZeroExitCode(); + CopyAll((buildDir / "loader").GlobFiles("libvulkan.dylib"), runtimes / rid / "native"); } } From 0446db0191d672aabc2ef881f3a9ea188538e583 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Sun, 7 Apr 2024 03:51:14 +0200 Subject: [PATCH 19/20] Native/wgpu-native: Build for linux-arm and linux-arm64. Also clean up the build script to be table-driven. --- .github/workflows/wgpu.yml | 27 +++++-- build/nuke/Native/Wgpu.cs | 72 ++++++++++++------- .../Silk.NET.WebGPU.Native.WGPU.csproj | 10 +-- 3 files changed, 75 insertions(+), 34 deletions(-) diff --git a/.github/workflows/wgpu.yml b/.github/workflows/wgpu.yml index 82188b4f46..4d018c2891 100644 --- a/.github/workflows/wgpu.yml +++ b/.github/workflows/wgpu.yml @@ -17,17 +17,34 @@ jobs: fail-fast: false matrix: env: - - os: ubuntu-latest + - os: ubuntu-22.04 name: Linux nuke_invoke: ./build.sh extras: | - sudo apt-get update - sudo apt-get install -y gcc-multilib - - os: windows-latest + sudo tee /etc/apt/sources.list << EOF + deb [arch=amd64,i386] http://archive.ubuntu.com/ubuntu jammy main multiverse restricted universe + deb [arch=amd64,i386] http://archive.ubuntu.com/ubuntu jammy-backports main multiverse restricted universe + deb [arch=amd64,i386] http://archive.ubuntu.com/ubuntu jammy-security main multiverse restricted universe + deb [arch=amd64,i386] http://archive.ubuntu.com/ubuntu jammy-updates main multiverse restricted universe + deb [arch=arm64,armhf] http://ports.ubuntu.com jammy main multiverse restricted universe + deb [arch=arm64,armhf] http://ports.ubuntu.com jammy-backports main multiverse restricted universe + deb [arch=arm64,armhf] http://ports.ubuntu.com jammy-security main multiverse restricted universe + deb [arch=arm64,armhf] http://ports.ubuntu.com jammy-updates main multiverse restricted universe + deb [arch=amd64,i386] http://security.ubuntu.com/ubuntu jammy main multiverse restricted universe + deb [arch=amd64,i386] http://security.ubuntu.com/ubuntu jammy-backports main multiverse restricted universe + deb [arch=amd64,i386] http://security.ubuntu.com/ubuntu jammy-security main multiverse restricted universe + deb [arch=amd64,i386] http://security.ubuntu.com/ubuntu jammy-updates main multiverse restricted universe + EOF + sudo dpkg --add-architecture arm64 + sudo dpkg --add-architecture armhf + sudo dpkg --add-architecture i386 + sudo apt update + sudo apt install -y gcc-aarch64-linux-gnu gcc-arm-linux-gnueabihf gcc-i686-linux-gnu + - os: windows-2022 name: Windows nuke_invoke: ./build.cmd extras: "" - - os: macos-latest + - os: macos-14 name: Darwin nuke_invoke: ./build.sh extras: "" diff --git a/build/nuke/Native/Wgpu.cs b/build/nuke/Native/Wgpu.cs index 29f4e185bb..48cc289ca5 100644 --- a/build/nuke/Native/Wgpu.cs +++ b/build/nuke/Native/Wgpu.cs @@ -36,45 +36,67 @@ partial class Build { ( () => { + var target = WgpuPath / "target"; var runtimes = RootDirectory / "src" / "Native" / "Silk.NET.WebGPU.Native.WGPU" / "runtimes"; - var target = WgpuPath / "target"; EnsureCleanDirectory(target); - if(OperatingSystem.IsWindows()) - { - //Compile Windows libraries - InheritedShell("cargo build --release --target=i686-pc-windows-msvc", WgpuPath).AssertZeroExitCode(); - InheritedShell("cargo build --release --target=x86_64-pc-windows-msvc", WgpuPath).AssertZeroExitCode(); - InheritedShell("cargo build --release --target=aarch64-pc-windows-msvc", WgpuPath).AssertZeroExitCode(); + (string Triple, string Rid)[] targets; + string library; - CopyFile(target / "i686-pc-windows-msvc" / "release" / "wgpu_native.dll", runtimes / "win-x86" / "native" / "wgpu_native.dll", FileExistsPolicy.Overwrite); - CopyFile(target / "x86_64-pc-windows-msvc" / "release" / "wgpu_native.dll", runtimes / "win-x64" / "native" / "wgpu_native.dll", FileExistsPolicy.Overwrite); - CopyFile(target / "aarch64-pc-windows-msvc" / "release" / "wgpu_native.dll", runtimes / "win-arm64" / "native" / "wgpu_native.dll", FileExistsPolicy.Overwrite); + if (OperatingSystem.IsWindows()) + { + targets = new[] + { + ("i686-pc-windows-msvc", "win-x86"), + ("x86_64-pc-windows-msvc", "win-x64"), + ("aarch64-pc-windows-msvc", "win-arm64"), + }; + library = "wgpu_native.dll"; } - - if(OperatingSystem.IsLinux()) + else if (OperatingSystem.IsLinux()) { - //Compile Linux libraries - InheritedShell("cargo build --release --target=i686-unknown-linux-gnu", WgpuPath).AssertZeroExitCode(); - InheritedShell("cargo build --release --target=x86_64-unknown-linux-gnu", WgpuPath).AssertZeroExitCode(); - - CopyFile(target / "i686-unknown-linux-gnu" / "release" / "libwgpu_native.so", runtimes / "linux-x86" / "native" / "libwgpu_native.so", FileExistsPolicy.Overwrite); - CopyFile(target / "x86_64-unknown-linux-gnu" / "release" / "libwgpu_native.so", runtimes / "linux-x64" / "native" / "libwgpu_native.so", FileExistsPolicy.Overwrite); + targets = new[] + { + ("i686-unknown-linux-gnu", "linux-x86"), + ("x86_64-unknown-linux-gnu", "linux-x64"), + ("arm-unknown-linux-gnueabihf", "linux-arm"), + ("aarch64-unknown-linux-gnu", "linux-arm64"), + }; + library = "libwgpu_native.so"; + } + else if (OperatingSystem.IsMacOS()) + { + targets = new[] + { + ("x86_64-apple-darwin", "osx-x64"), + ("aarch64-apple-darwin", "osx-arm64"), + }; + library = "libwgpu_native.dylib"; } + else + throw new Exception("Unsupported OS!"); - if(OperatingSystem.IsMacOS()) + foreach (var (triple, rid) in targets) { - //Compile MacOS libraries - InheritedShell("cargo build --release --target=aarch64-apple-darwin", WgpuPath).AssertZeroExitCode(); - InheritedShell("cargo build --release --target=x86_64-apple-darwin", WgpuPath).AssertZeroExitCode(); + // Cross-compiling to these targets on linux-x64 will fail if a proper linker is not set. + var linker = rid switch + { + "linux-arm" => "arm-linux-gnueabihf-gcc", + "linux-arm64" => "aarch64-linux-gnu-gcc", + _ => null, + }; + + if (linker != null) + linker = $" --config \"target.{triple}.linker = '{linker}'\""; + + InheritedShell($"cargo build --release --target {triple}{linker}", WgpuPath).AssertZeroExitCode(); - CopyFile(target / "x86_64-apple-darwin" / "release" / "libwgpu_native.dylib", runtimes / "osx-x64" / "native" / "libwgpu_native.dylib", FileExistsPolicy.Overwrite); - CopyFile(target / "aarch64-apple-darwin" / "release" / "libwgpu_native.dylib", runtimes / "osx-arm64" / "native" / "libwgpu_native.dylib", FileExistsPolicy.Overwrite); + CopyFile(target / triple / "release" / library, runtimes / rid / "native" / library, FileExistsPolicy.Overwrite); } PrUpdatedNativeBinary("Wgpu"); } ) ); -} \ No newline at end of file +} diff --git a/src/Native/Silk.NET.WebGPU.Native.WGPU/Silk.NET.WebGPU.Native.WGPU.csproj b/src/Native/Silk.NET.WebGPU.Native.WGPU/Silk.NET.WebGPU.Native.WGPU.csproj index 1da340b171..fb538f23cc 100644 --- a/src/Native/Silk.NET.WebGPU.Native.WGPU/Silk.NET.WebGPU.Native.WGPU.csproj +++ b/src/Native/Silk.NET.WebGPU.Native.WGPU/Silk.NET.WebGPU.Native.WGPU.csproj @@ -22,13 +22,15 @@ - + + - + - - + + + From e13afad3d78aef2e26de7fdb6fae4a883fc4397a Mon Sep 17 00:00:00 2001 From: "The Silk.NET Automaton" <9011267+dotnet-bot@users.noreply.github.com> Date: Sat, 13 Apr 2024 17:23:06 +0000 Subject: [PATCH 20/20] New binaries for SDL2 on Microsoft Windows 10.0.20348 --- .../runtimes/win-arm64/native/SDL2.dll | Bin 1520640 -> 1520640 bytes .../runtimes/win-x64/native/SDL2.dll | Bin 1690624 -> 1690624 bytes .../runtimes/win-x86/native/SDL2.dll | Bin 1431552 -> 1431552 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/src/Native/Silk.NET.SDL.Native/runtimes/win-arm64/native/SDL2.dll b/src/Native/Silk.NET.SDL.Native/runtimes/win-arm64/native/SDL2.dll index 1422dd851710b604f1205929dafda51d17d20101..1b9f5418f69ed0b4d6cd71e3acebb75504d0e610 100644 GIT binary patch delta 94 zcmWm6xebB<06@_wa*GF7;Yu*w`06@VgsC*O@(1e+!wxV$pC|+zS?1@7dN0JdpUV|3bUN^Pf)DCm-yw$z9 r!ZijM;s&?4!w6$cFvUF{FvA>=c)|k9x7F+VKOSRK{hU8zbGd&P0|G9T diff --git a/src/Native/Silk.NET.SDL.Native/runtimes/win-x64/native/SDL2.dll b/src/Native/Silk.NET.SDL.Native/runtimes/win-x64/native/SDL2.dll index ce187995e604874d949d1b585f9dcc15b8240541..add70fd5a5285db6a5ba0407911a0f173307f01c 100644 GIT binary patch delta 104508 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 OPHwUyJ9gIZXa65U1?bQK delta 104475 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 diff --git a/src/Native/Silk.NET.SDL.Native/runtimes/win-x86/native/SDL2.dll b/src/Native/Silk.NET.SDL.Native/runtimes/win-x86/native/SDL2.dll index b7dcf8ac7e738ff512ec61e4d431c0f55beae755..fb2a084e66e0d704a103bc895db76f88aee9bdd4 100644 GIT binary patch delta 119 zcmWlRJr06k6a*iF|03##jg6&Tz?x%l1J41)hQ!L!LzqZo>`dr6h{;^S=Ook2CR=w^ z-Bq`5{P-LiL?lKc7Ks>(iI|F+n2Uv2ij_#kT4Z7)wqo}poKHtTxR{f=d1N-+gALd4 QPv%=&7QxNmWwGy{Ke%%*NdN!< delta 119 zcmZqJ5Zdswe>Yy>udJb*Bq^{Ia^