diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fd95c0d3..7afc42c8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -340,6 +340,118 @@ jobs: name: Tests - macOS path: /Users/runner/cesium/CesiumForUnityBuildProject/TestResults.xml reporter: dotnet-nunit + Linux: + needs: [QuickChecks] + runs-on: ubuntu-latest + # Only allow a single Linux build at a time, for Unity licensing reasons + concurrency: linux + steps: + - name: Check out repository code + uses: actions/checkout@v4 + with: + submodules: recursive + - name: Set up .NET SDK + uses: actions/setup-dotnet@v4 + with: + dotnet-version: "10.0.103" + - name: Cache vcpkg artifacts + uses: actions/cache@v4 + with: + path: "~/.ezvcpkg" + key: vcpkg-linux-alma-${{ hashFiles('native~/vcpkg/ports/**/vcpkg.json', 'native~/vcpkg/triplets/**/*', 'native~/extern/*toolchain.cmake') }}-${{ hashFiles('native~/extern/cesium-native/CMakeLists.txt', 'native~/CMakeLists.txt') }} + restore-keys: | + vcpkg-linux-alma-${{ hashFiles('native~/vcpkg/ports/**/vcpkg.json', 'native~/vcpkg/triplets/**/*', 'native~/extern/*toolchain.cmake') }}- + - name: Install Unity Hub + run: | + sudo apt-get install -y gnupg libgbm1 xvfb + wget -qO - https://hub.unity3d.com/linux/keys/public | gpg --dearmor | sudo tee /usr/share/keyrings/Unity_Technologies_ApS.gpg > /dev/null + sudo sh -c 'echo "deb [signed-by=/usr/share/keyrings/Unity_Technologies_ApS.gpg] https://hub.unity3d.com/linux/repos/deb stable main" > /etc/apt/sources.list.d/unityhub.list' + sudo apt-get update + sudo apt-get install -y unityhub + - name: Install Unity 2022.3.41f1 + # This command sometimes returns exit code 130, despite actually succeeding. + # unityhub-bin requires a virtual display even in headless mode. + continue-on-error: true + run: | + xvfb-run -a /opt/unityhub/unityhub-bin --no-sandbox --headless install --version 2022.3.41f1 --changeset 0f988161febf + - name: Configure Unity to Use the License Server + run: | + sudo mkdir -p /usr/share/unity3d/config + sudo bash -c 'echo "{\"licensingServiceBaseUrl\": \"http://localhost:12331\",\"enableEntitlementLicensing\": true,\"clientConnectTimeoutSec\": 60,\"clientHandshakeTimeoutSec\": 120,\"toolset\":\"UnityLicenseServer_16768262570522_9\"}" > /usr/share/unity3d/config/services-config.json' + - name: Create SSH tunnel to Unity License Server + env: + UNITY_LICENSE_SERVER_SSH_KEY: ${{ secrets.UNITY_LICENSE_SERVER_SSH_KEY }} + run: | + echo "$UNITY_LICENSE_SERVER_SSH_KEY" > ~/unity-client-ssh-key + chmod 600 ~/unity-client-ssh-key + # Without StrictHostKeyChecking, OpenSSH will sit forever waiting for local input to confirm the server key is ok. + # We don't really care if the server is authentic, because we're not sending anything sensitive to it. + # The license server VM's sshd_config also needed to be modified with the following options, in order to prevent + # the tunnel from being closed between here and when we're ready to use it. + # TCPKeepAlive yes + # ClientAliveInterval 30 + # ClientAliveCountMax 9999 + ssh -fNT -o StrictHostKeyChecking=no -i ~/unity-client-ssh-key -L 127.0.0.1:12331:127.0.0.1:8080 unity-client@ec2-44-204-244-196.compute-1.amazonaws.com + sleep 5 + - name: Test Connection to Unity License Server + run: | + wget http://127.0.0.1:12331/v1/admin/status + cat status + rm status + - name: Update the version in Cesium.cpp + run: | + export VERSION=$(jq -r ".version" package.json) + export COMMIT=$(git rev-parse --short HEAD) + sed -i 's/Cesium::version = "Development Build"/Cesium::version = "'$VERSION'"/g' native~/src/Runtime/Cesium.cpp + sed -i 's/Cesium::commit = "Unknown"/Cesium::commit = "'$COMMIT'"/g' native~/src/Runtime/Cesium.cpp + # Sanity check that the replacements happened + grep $VERSION native~/src/Runtime/Cesium.cpp + grep $COMMIT native~/src/Runtime/Cesium.cpp + - name: Move cesium-unity Repo Under Empty Project + run: | + mkdir -p ~/cesium/CesiumForUnityBuildProject/Packages/com.cesium.unity + mv $GITHUB_WORKSPACE/* ~/cesium/CesiumForUnityBuildProject/Packages/com.cesium.unity + # Disable Unity audio + mkdir -p ~/cesium/CesiumForUnityBuildProject/Packages/com.cesium.unity/ProjectSettings + echo '%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!11 &1\nAudioManager:\n m_DisableAudio: 1\n' > ~/cesium/CesiumForUnityBuildProject/Packages/com.cesium.unity/ProjectSettings/AudioManager.asset + - name: Build Reinterop + run: | + cd ~/cesium/CesiumForUnityBuildProject/Packages/com.cesium.unity + dotnet publish Reinterop~ -o . + - name: Build Package + env: + CESIUM_NATIVE_BUILD_CONTAINER: almalinux:8 + run: | + # We only need a release build of vcpkg dependencies + export CESIUM_VCPKG_RELEASE_ONLY="TRUE" + cd ~/cesium/CesiumForUnityBuildProject/Packages/com.cesium.unity + dotnet run --project Build~ package --platform Editor --platform Linux + ls -l ~/cesium/CesiumForUnityBuildProject + - name: Publish Logs + if: success() || failure() # run this step even if previous step failed + uses: actions/upload-artifact@v4 + with: + name: Native Build Logs - Linux + path: ~/cesium/CesiumForUnityBuildProject/Packages/com.cesium.unity/native~/build-*/build.log + - name: Publish package artifact + if: ${{ success() }} + uses: actions/upload-artifact@v4 + with: + name: Linux Package + path: ~/cesium/CesiumForUnityBuildProject/*.tgz + - name: Run Tests + env: + CESIUM_ION_TOKEN_FOR_TESTS: ${{ secrets.CESIUM_ION_TOKEN_FOR_TESTS }} + run: | + xvfb-run -a ~/Unity/Hub/Editor/2022.3.41f1/Editor/Unity -runTests -batchmode -projectPath ~/cesium/CesiumForUnityBuildProject -testResults ~/cesium/CesiumForUnityBuildProject/TestResults.xml -testPlatform PlayMode -logFile ~/cesium/CesiumForUnityBuildProject/test-log.txt + cat ~/cesium/CesiumForUnityBuildProject/test-log.txt + - name: Test Report + uses: kring/test-reporter@v1.6.2-kring + if: success() || failure() # run this step even if previous step failed + with: + name: Tests - Linux + path: /home/runner/cesium/CesiumForUnityBuildProject/TestResults.xml + reporter: dotnet-nunit Emscripten: needs: [QuickChecks] runs-on: windows-latest @@ -466,7 +578,7 @@ jobs: path: d:\cesium\CesiumForUnityBuildProject\*.tgz Combine: runs-on: ubuntu-latest - needs: [Windows, MacOS, Emscripten] + needs: [Windows, MacOS, Linux, Emscripten] steps: - name: Check out repository code uses: actions/checkout@v4 @@ -492,6 +604,16 @@ jobs: cd combine/emscripten tar xzf *.tgz rm *.tgz + - name: Download Linux build + uses: actions/download-artifact@v4 + with: + name: Linux Package + path: combine/linux + - name: Extract Linux build + run: | + cd combine/linux + tar xzf *.tgz + rm *.tgz - name: Download Windows build uses: actions/download-artifact@v4 with: @@ -510,6 +632,7 @@ jobs: # Copy the everything. For files that exist in multiple packages, the Windows one will win. cp -r ../macos/* . cp -r ../emscripten/* . + cp -r ../linux/* . cp -r ../windows/* . # Remove the generated C# files @@ -534,6 +657,14 @@ jobs: cat "$file" >> "../merged/$file" done; + cd ../linux + for file in $(find package/Source/generated -name '*.cs'); + do + echo Merging $file + mkdir -p $(dirname "../merged/$file") + cat "$file" >> "../merged/$file" + done; + cd ../windows for file in $(find package/Source/generated -name '*.cs'); do diff --git a/Build~/Package.cs b/Build~/Package.cs index 6c833f03..8ab7f0e2 100644 --- a/Build~/Package.cs +++ b/Build~/Package.cs @@ -181,8 +181,14 @@ public void Run(Options options) else { // On other platforms, just build once. - Utility.Run("cmake", configureArgs); - Utility.Run("cmake", buildArgs); + string? containerImage = Environment.GetEnvironmentVariable("CESIUM_NATIVE_BUILD_CONTAINER"); + if (OperatingSystem.IsLinux() && !string.IsNullOrEmpty(containerImage)) + RunCmakeInContainer(containerImage, configureArgs, buildArgs); + else + { + Utility.Run("cmake", configureArgs); + Utility.Run("cmake", buildArgs); + } } } @@ -279,6 +285,29 @@ public void Run(Options options) Directory.CreateDirectory(generatedPath); } + if (options.Platforms.Contains("Linux")) + { + Console.WriteLine("**** Compiling for Linux Player"); + unity.Run(new[] + { + "-batchmode", + "-nographics", + "-projectPath", + Utility.ProjectRoot, + "-buildTarget", + "Linux64", + "-executeMethod", + "CesiumForUnity.BuildCesiumForUnity.CompileForLinuxAndExit" + }); + + Console.WriteLine("**** Adding generated files (for the Linux Player) to the package"); + AddGeneratedFiles("!UNITY_EDITOR && UNITY_STANDALONE_LINUX", generatedPath, outputGeneratedPath); + + // Clean the generated code directory. + Directory.Delete(generatedPath, true); + Directory.CreateDirectory(generatedPath); + } + if (options.Platforms.Contains("macOS")) { Console.WriteLine("**** Compiling for macOS Player"); @@ -368,6 +397,74 @@ private static void TraverseDirectoryRecursively(string directory, string builtP } } + private static void RunCmakeInContainer( + string containerImage, + IEnumerable configureArgs, + IEnumerable buildArgs) + { + string packageRoot = Utility.PackageRoot; + string ezvcpkgHostPath = Path.Combine( + Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".ezvcpkg"); + + // Write cmake commands to a script file to avoid shell quoting complexity. + string scriptPath = Path.Combine(Path.GetTempPath(), $"cesium-cmake-{Guid.NewGuid():N}.sh"); + File.WriteAllText(scriptPath, + "#!/bin/bash\n" + + "set -e\n" + + "dnf install -q -y dnf-plugins-core\n" + + "dnf config-manager --set-enabled powertools\n" + + "dnf module enable -y llvm-toolset\n" + + "dnf install -q -y clang make nasm git curl zip unzip tar kernel-headers perl-core ninja-build python3 pkgconfig autoconf automake libtool patch\n" + + "curl -fsSL https://github.com/Kitware/CMake/releases/download/v3.31.12/cmake-3.31.12-linux-x86_64.tar.gz | tar -xz -C /usr/local --strip-components=1\n" + + "curl -fsSL https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -o /tmp/awscliv2.zip && unzip -q /tmp/awscliv2.zip -d /tmp && /tmp/aws/install && rm -rf /tmp/awscliv2.zip /tmp/aws\n" + + $"cmake {string.Join(' ', configureArgs)}\n" + + $"cmake {string.Join(' ', buildArgs)}\n", + new UTF8Encoding(false)); + + try + { + ProcessStartInfo dockerInfo = new ProcessStartInfo("docker"); + dockerInfo.WorkingDirectory = packageRoot; + + dockerInfo.ArgumentList.Add("run"); + dockerInfo.ArgumentList.Add("--rm"); + dockerInfo.ArgumentList.Add("--workdir"); + dockerInfo.ArgumentList.Add(packageRoot); + dockerInfo.ArgumentList.Add("-v"); + dockerInfo.ArgumentList.Add($"{packageRoot}:{packageRoot}"); + dockerInfo.ArgumentList.Add("-v"); + dockerInfo.ArgumentList.Add($"{ezvcpkgHostPath}:/root/.ezvcpkg"); + dockerInfo.ArgumentList.Add("-v"); + dockerInfo.ArgumentList.Add($"{scriptPath}:/tmp/cesium-build.sh:ro"); + dockerInfo.ArgumentList.Add("-e"); + dockerInfo.ArgumentList.Add("CC=clang"); + dockerInfo.ArgumentList.Add("-e"); + dockerInfo.ArgumentList.Add("CXX=clang++"); + + foreach (string envVarName in new[] { + "VCPKG_BINARY_SOURCES", "AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", + "AWS_REGION", "CESIUM_VCPKG_RELEASE_ONLY" }) + { + string? value = Environment.GetEnvironmentVariable(envVarName); + if (!string.IsNullOrEmpty(value)) + { + dockerInfo.ArgumentList.Add("-e"); + dockerInfo.ArgumentList.Add($"{envVarName}={value}"); + } + } + + dockerInfo.ArgumentList.Add(containerImage); + dockerInfo.ArgumentList.Add("bash"); + dockerInfo.ArgumentList.Add("/tmp/cesium-build.sh"); + + Utility.RunAndLog(dockerInfo); + } + finally + { + try { File.Delete(scriptPath); } catch (Exception) { } + } + } + private static void AddGeneratedFiles(string condition, string source, string target) { TraverseDirectoryRecursively( diff --git a/Build~/Unity.cs b/Build~/Unity.cs index d5e753dd..5a0149ad 100644 --- a/Build~/Unity.cs +++ b/Build~/Unity.cs @@ -133,6 +133,11 @@ private class UnityVersion unityDefaultBaseDirectory = new DirectoryInfo("/Applications/Unity/Hub/Editor"); unityExecutableSubPath = "Unity.app/Contents/MacOS/Unity"; } + else if (OperatingSystem.IsLinux()) + { + unityDefaultBaseDirectory = new DirectoryInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Unity", "Hub", "Editor")); + unityExecutableSubPath = "Editor/Unity"; + } else { return null; @@ -141,6 +146,9 @@ private class UnityVersion if (unityDir == null) unityDir = unityDefaultBaseDirectory; + if (!unityDir.Exists) + return null; + if (version != null) { FileInfo unityExecutable = new FileInfo(Path.Combine(unityDir.FullName, version, unityExecutableSubPath)); diff --git a/CHANGES.md b/CHANGES.md index 3e665852..5a47fa62 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,11 @@ # Change Log {#changes} +## ? - ? + +##### Additions :tada: + +- Added support for the Linux platform (x86-64 only). + ## v1.23.1 - 2026-04-01 This release updates [cesium-native](https://github.com/CesiumGS/cesium-native) from v0.58.0 to v0.59.0. See the [changelog](https://github.com/CesiumGS/cesium-native/blob/main/CHANGES.md) for a complete list of changes in cesium-native. diff --git a/EditorTests/CesiumEditorTests.asmdef b/EditorTests/CesiumEditorTests.asmdef index bd7e50ee..b045a4b9 100644 --- a/EditorTests/CesiumEditorTests.asmdef +++ b/EditorTests/CesiumEditorTests.asmdef @@ -18,8 +18,7 @@ ], "autoReferenced": false, "defineConstraints": [ - "UNITY_INCLUDE_TESTS", - "!UNITY_EDITOR_LINUX" + "UNITY_INCLUDE_TESTS" ], "versionDefines": [], "noEngineReferences": false diff --git a/Source/CesiumForUnity.asmdef b/Source/CesiumForUnity.asmdef index 9da72537..0d2d017c 100644 --- a/Source/CesiumForUnity.asmdef +++ b/Source/CesiumForUnity.asmdef @@ -10,6 +10,7 @@ "Android", "Editor", "iOS", + "LinuxStandalone64", "macOSStandalone", "WSA", "WindowsStandalone64", @@ -20,9 +21,7 @@ "overrideReferences": false, "precompiledReferences": [], "autoReferenced": true, - "defineConstraints": [ - "!UNITY_EDITOR_LINUX" - ], + "defineConstraints": [], "versionDefines": [ { "name": "com.unity.splines", diff --git a/Source/Editor/BuildCesiumForUnity.cs b/Source/Editor/BuildCesiumForUnity.cs index d35946fe..42f935a8 100644 --- a/Source/Editor/BuildCesiumForUnity.cs +++ b/Source/Editor/BuildCesiumForUnity.cs @@ -126,6 +126,23 @@ public static void CompileForWindowsAndExit() EditorApplication.Exit(0); } + public static void CompileForLinuxAndExit() + { + CompileCesiumForUnityNative.ExitAfterCompile = true; + + string buildPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); + Directory.CreateDirectory(buildPath); + try + { + BuildPlayer(BuildTargetGroup.Standalone, BuildTarget.StandaloneLinux64, Path.Combine(buildPath, "Linux")); + } + finally + { + Directory.Delete(buildPath, true); + } + EditorApplication.Exit(0); + } + public static void CompileForMacAndExit() { CompileCesiumForUnityNative.ExitAfterCompile = true; diff --git a/Source/Editor/CompileCesiumForUnityNative.cs b/Source/Editor/CompileCesiumForUnityNative.cs index 3ad409e1..85e0aaaf 100644 --- a/Source/Editor/CompileCesiumForUnityNative.cs +++ b/Source/Editor/CompileCesiumForUnityNative.cs @@ -632,8 +632,15 @@ internal static void BuildNativeLibrary(LibraryToBuild library) args.Add($"-DCMAKE_TOOLCHAIN_FILE=\"{library.Toolchain}\""); startInfo.Arguments = string.Join(' ', args); + string configureArgsStr = startInfo.Arguments; - RunAndLog(startInfo, log, logFilename); + string? containerImage = Environment.GetEnvironmentVariable("CESIUM_NATIVE_BUILD_CONTAINER"); + bool useContainer = !string.IsNullOrEmpty(containerImage) && + SystemInfo.operatingSystemFamily == OperatingSystemFamily.Linux && + library.Platform == BuildTarget.StandaloneLinux64; + + if (!useContainer) + RunAndLog(startInfo, log, logFilename); if (library.Platform == BuildTarget.WebGL) startInfo.FileName = "cmake"; @@ -651,7 +658,12 @@ internal static void BuildNativeLibrary(LibraryToBuild library) }; args.AddRange(library.ExtraBuildArgs); startInfo.Arguments = string.Join(' ', args); - RunAndLog(startInfo, log, logFilename); + string buildArgsStr = startInfo.Arguments; + + if (useContainer) + RunCmakeInContainer(containerImage!, library, configureArgsStr, buildArgsStr, log, logFilename); + else + RunAndLog(startInfo, log, logFilename); // Refresh the asset database for platforms that use static linking so the Unity // builder can find the libraries. @@ -682,6 +694,70 @@ internal static void BuildNativeLibrary(LibraryToBuild library) } } + private static void RunCmakeInContainer( + string containerImage, + LibraryToBuild library, + string configureArgs, + string buildArgs, + StreamWriter log, + string logFilename) + { + string packageRoot = Path.GetDirectoryName(library.SourceDirectory)!; + string ezvcpkgHostPath = Path.Combine( + Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".ezvcpkg"); + + // Write cmake commands to a script file to avoid shell quoting complexity. + string scriptPath = Path.Combine(Path.GetTempPath(), $"cesium-cmake-{Guid.NewGuid():N}.sh"); + File.WriteAllText(scriptPath, + "#!/bin/bash\n" + + "set -e\n" + + "dnf install -q -y dnf-plugins-core\n" + + "dnf config-manager --set-enabled powertools\n" + + "dnf module enable -y llvm-toolset\n" + + "dnf install -q -y clang make nasm git curl zip unzip tar kernel-headers perl-core ninja-build python3 pkgconfig autoconf automake libtool patch\n" + + "curl -fsSL https://github.com/Kitware/CMake/releases/download/v3.31.12/cmake-3.31.12-linux-x86_64.tar.gz | tar -xz -C /usr/local --strip-components=1\n" + + "curl -fsSL https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -o /tmp/awscliv2.zip && unzip -q /tmp/awscliv2.zip -d /tmp && /tmp/aws/install && rm -rf /tmp/awscliv2.zip /tmp/aws\n" + + $"cmake {configureArgs}\n" + + $"cmake {buildArgs}\n", + new UTF8Encoding(false)); + + try + { + ProcessStartInfo dockerInfo = new ProcessStartInfo("docker"); + dockerInfo.UseShellExecute = false; + dockerInfo.CreateNoWindow = true; + dockerInfo.WorkingDirectory = library.SourceDirectory; + dockerInfo.RedirectStandardError = true; + dockerInfo.RedirectStandardOutput = true; + + StringBuilder dockerArgsBuilder = new StringBuilder("run --rm"); + dockerArgsBuilder.Append($" --workdir \"{library.SourceDirectory}\""); + dockerArgsBuilder.Append($" -v \"{packageRoot}:{packageRoot}\""); + dockerArgsBuilder.Append($" -v \"{ezvcpkgHostPath}:/root/.ezvcpkg\""); + dockerArgsBuilder.Append($" -v \"{scriptPath}:/tmp/cesium-build.sh:ro\""); + dockerArgsBuilder.Append(" -e CC=clang"); + dockerArgsBuilder.Append(" -e CXX=clang++"); + + foreach (string envVarName in new[] { + "VCPKG_BINARY_SOURCES", "AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", + "AWS_REGION", "CESIUM_VCPKG_RELEASE_ONLY" }) + { + string? value = Environment.GetEnvironmentVariable(envVarName); + if (!string.IsNullOrEmpty(value)) + dockerArgsBuilder.Append($" -e \"{envVarName}={value}\""); + } + + dockerArgsBuilder.Append($" {containerImage} bash /tmp/cesium-build.sh"); + dockerInfo.Arguments = dockerArgsBuilder.ToString(); + + RunAndLog(dockerInfo, log, logFilename); + } + finally + { + try { File.Delete(scriptPath); } catch (Exception) { } + } + } + private static void RunAndLog(ProcessStartInfo startInfo, StreamWriter log, string logFilename) { using (Process configure = new Process()) diff --git a/Tests/CesiumTests.asmdef b/Tests/CesiumTests.asmdef index f184b0b8..001e8466 100644 --- a/Tests/CesiumTests.asmdef +++ b/Tests/CesiumTests.asmdef @@ -17,8 +17,7 @@ ], "autoReferenced": false, "defineConstraints": [ - "UNITY_INCLUDE_TESTS", - "!UNITY_EDITOR_LINUX" + "UNITY_INCLUDE_TESTS" ], "versionDefines": [ { diff --git a/native~/src/Runtime/UnityPrepareRendererResources.cpp b/native~/src/Runtime/UnityPrepareRendererResources.cpp index 7efe023a..7eead7e0 100644 --- a/native~/src/Runtime/UnityPrepareRendererResources.cpp +++ b/native~/src/Runtime/UnityPrepareRendererResources.cpp @@ -73,6 +73,7 @@ #include #include +#include #include #include @@ -151,7 +152,7 @@ template struct CopyVertexColors { uint8_t a; }; - bool operator()(AccessorView&& invalidView) { return false; } + bool operator()(AccessorView&& invalidView) { return false; } template bool operator()(TColorView&& colorView) { if (colorView.status() != AccessorViewStatus::Valid) { diff --git a/native~/vcpkg/triplets/x64-linux-unity.cmake b/native~/vcpkg/triplets/x64-linux-unity.cmake new file mode 100644 index 00000000..6d18ae28 --- /dev/null +++ b/native~/vcpkg/triplets/x64-linux-unity.cmake @@ -0,0 +1,7 @@ +include("${CMAKE_CURRENT_LIST_DIR}/shared/common.cmake") + +set(VCPKG_TARGET_ARCHITECTURE x64) +set(VCPKG_CRT_LINKAGE dynamic) +set(VCPKG_LIBRARY_LINKAGE static) + +set(VCPKG_CMAKE_SYSTEM_NAME Linux)