// Copyright (c) Wojciech Figat. All rights reserved. using System.Collections.Generic; using System.IO; using System.Linq; using Flax.Build; using Flax.Build.Platforms; namespace Flax.Deps.Dependencies { /// /// NVIDIA NvCloth /// /// class NvCloth : Dependency { private string root, nvCloth; /// public override TargetPlatform[] Platforms { get { switch (BuildPlatform) { case TargetPlatform.Windows: return new[] { TargetPlatform.Windows, TargetPlatform.XboxOne, TargetPlatform.XboxScarlett, TargetPlatform.PS4, TargetPlatform.PS5, TargetPlatform.Switch, TargetPlatform.Android, }; case TargetPlatform.Linux: return new[] { TargetPlatform.Linux, }; case TargetPlatform.Mac: return new[] { TargetPlatform.Mac, TargetPlatform.iOS, }; default: return new TargetPlatform[0]; } } } /// public override void Build(BuildOptions options) { root = options.IntermediateFolder; nvCloth = Path.Combine(root, "NvCloth"); // Get the source CloneGitRepoSingleBranch(root, "https://github.com/FlaxEngine/NvCloth.git", "master"); foreach (var platform in options.Platforms) { BuildStarted(platform); switch (platform) { case TargetPlatform.Windows: Build(options, platform, TargetArchitecture.x64); Build(options, platform, TargetArchitecture.ARM64); break; case TargetPlatform.XboxOne: case TargetPlatform.XboxScarlett: Build(options, platform, TargetArchitecture.x64); break; case TargetPlatform.PS4: case TargetPlatform.PS5: Utilities.DirectoryCopy(Path.Combine(GetBinariesFolder(options, platform), "Data", "NvCloth"), root, true, true); Build(options, platform, TargetArchitecture.x64); break; case TargetPlatform.Switch: Utilities.DirectoryCopy(Path.Combine(GetBinariesFolder(options, platform), "Data", "NvCloth"), root, true, true); Build(options, platform, TargetArchitecture.ARM64); break; case TargetPlatform.Android: Build(options, platform, TargetArchitecture.ARM64); break; case TargetPlatform.Mac: Build(options, platform, TargetArchitecture.x64); Build(options, platform, TargetArchitecture.ARM64); break; case TargetPlatform.iOS: Build(options, platform, TargetArchitecture.ARM64); break; case TargetPlatform.Linux: Build(options, platform, TargetArchitecture.x64); break; } } // Copy header files var dstIncludePath = Path.Combine(options.ThirdPartyFolder, "NvCloth"); Directory.GetFiles(dstIncludePath, "*.h", SearchOption.AllDirectories).ToList().ForEach(File.Delete); Utilities.FileCopy(Path.Combine(nvCloth, "license.txt"), Path.Combine(dstIncludePath, "License.txt")); Utilities.DirectoryCopy(Path.Combine(nvCloth, "include", "NvCloth"), dstIncludePath, true, true, "*.h"); Utilities.DirectoryCopy(Path.Combine(nvCloth, "extensions", "include"), dstIncludePath, true, true, "*.h"); } private void Build(BuildOptions options, TargetPlatform platform, TargetArchitecture architecture) { // Peek options var binariesPrefix = string.Empty; var binariesPostfix = string.Empty; var cmakeArgs = "-DNV_CLOTH_ENABLE_DX11=0 -DNV_CLOTH_ENABLE_CUDA=0 -DPX_GENERATE_GPU_PROJECTS=0"; var cmakeName = string.Empty; var buildFolder = Path.Combine(nvCloth, "compiler", platform.ToString() + '_' + architecture.ToString()); var envVars = new Dictionary(); envVars["GW_DEPS_ROOT"] = root; switch (platform) { case TargetPlatform.Windows: case TargetPlatform.XboxOne: case TargetPlatform.XboxScarlett: cmakeArgs += " -DTARGET_BUILD_PLATFORM=windows -DSTATIC_WINCRT=0"; cmakeName = "windows"; binariesPostfix = "_x64"; break; case TargetPlatform.PS4: cmakeArgs += " -DTARGET_BUILD_PLATFORM=ps4"; cmakeArgs += $" -DCMAKE_TOOLCHAIN_FILE=\"{Path.Combine(nvCloth, "Externals/CMakeModules/ps4/PS4Toolchain.txt").Replace('\\', '/')}\""; cmakeName = "ps4"; binariesPrefix = "lib"; break; case TargetPlatform.PS5: cmakeArgs += " -DTARGET_BUILD_PLATFORM=ps5"; cmakeArgs += $" -DCMAKE_TOOLCHAIN_FILE=\"{Path.Combine(nvCloth, "Externals/CMakeModules/ps5/PS5Toolchain.txt").Replace('\\', '/')}\""; cmakeName = "ps5"; binariesPrefix = "lib"; break; case TargetPlatform.Switch: cmakeArgs += " -DTARGET_BUILD_PLATFORM=NX64"; cmakeName = "switch"; binariesPrefix = "lib"; envVars.Add("NintendoSdkRoot", Sdk.Get("SwitchSdk").RootPath + '\\'); break; case TargetPlatform.Android: cmakeArgs += " -DTARGET_BUILD_PLATFORM=android"; cmakeName = "android"; binariesPrefix = "lib"; if (AndroidNdk.Instance.IsValid) { envVars.Add("ANDROID_NDK_HOME", AndroidNdk.Instance.RootPath); envVars.Add("PM_ANDROIDNDK_PATH", AndroidNdk.Instance.RootPath); } break; case TargetPlatform.Mac: cmakeArgs += " -DTARGET_BUILD_PLATFORM=mac"; cmakeName = "mac"; binariesPrefix = "lib"; break; case TargetPlatform.iOS: cmakeArgs += " -DTARGET_BUILD_PLATFORM=ios"; cmakeName = "ios"; binariesPrefix = "lib"; break; case TargetPlatform.Linux: cmakeArgs += " -DTARGET_BUILD_PLATFORM=linux"; cmakeName = "linux"; binariesPrefix = "lib"; break; default: throw new InvalidPlatformException(platform); } var cmakeFolder = Path.Combine(nvCloth, "compiler", "cmake", cmakeName); // Setup build environment variables for the build system switch (BuildPlatform) { case TargetPlatform.Windows: { GetMsBuildForPlatform(platform, out var vsVersion, out var msBuild); if (File.Exists(msBuild)) { envVars.Add("PATH", Path.GetDirectoryName(msBuild)); } break; } } // Print the NvCloth version Log.Info($"Building {File.ReadAllLines(Path.Combine(root, "README.md"))[0].Trim()} to {platform} {architecture}"); // Generate project files SetupDirectory(buildFolder, false); Utilities.FileDelete(Path.Combine(cmakeFolder, "CMakeCache.txt")); cmakeArgs += $" -DPX_STATIC_LIBRARIES=1 -DPX_OUTPUT_DLL_DIR=\"{Path.Combine(buildFolder, "bin")}\" -DPX_OUTPUT_LIB_DIR=\"{Path.Combine(buildFolder, "lib")}\" -DPX_OUTPUT_EXE_DIR=\"{Path.Combine(buildFolder, "bin")}\""; RunCmake(cmakeFolder, platform, architecture, " -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF " + cmakeArgs, envVars); // Run build BuildCmake(cmakeFolder, envVars: envVars); // Deploy binaries var libs = new[] { "NvCloth", }; var dstBinaries = GetThirdPartyFolder(options, platform, architecture); var srcBinaries = Path.Combine(buildFolder, "lib"); var platformObj = Platform.GetPlatform(platform); var binariesExtension = platformObj.StaticLibraryFileExtension; foreach (var lib in libs) { var filename = binariesPrefix + lib + binariesPostfix + binariesExtension; Utilities.FileCopy(Path.Combine(srcBinaries, filename), Path.Combine(dstBinaries, filename)); var filenamePdb = Path.ChangeExtension(filename, "pdb"); if (File.Exists(Path.Combine(srcBinaries, filenamePdb))) Utilities.FileCopy(Path.Combine(srcBinaries, filenamePdb), Path.Combine(dstBinaries, filenamePdb)); } } } }