public override void Customize(DotsRuntimeCSharpProgram program) { if (program.MainSourcePath.FileName != "Unity.ZeroJobs") { return; } program.NativeProgram.Libraries.Add(c => c.Platform is LinuxPlatform, new SystemLibrary("rt")); program.NativeProgram.Libraries.Add(c => c.Platform is WindowsPlatform, new SystemLibrary("ws2_32.lib")); NativeJobsPrebuiltLibrary.Add(program.NativeProgram); }
public Il2CppOutputProgram(string name) : base(name) { AddLibIl2CppAsLibraryFor(this); var distRoot = Distribution.Path.ResolveWithFileSystem(); Libraries.Add(BoehmGCProgram); Sources.Add(distRoot.Combine("external").Combine("xxHash/xxhash.c")); this.DynamicLinkerSettingsForMsvc() .Add(l => l.WithSubSystemType(SubSystemType.Console).WithEntryPoint("wWinMainCRTStartup")); Libraries.Add(c => c.ToolChain.Platform is WindowsPlatform, new SystemLibrary("kernel32.lib")); this.DynamicLinkerSettingsForMsvc().Add(l => l .WithSubSystemType(SubSystemType.Console) .WithEntryPoint("wWinMainCRTStartup") ); Defines.Add(c => c.ToolChain.DynamicLibraryFormat == null, "FORCE_PINVOKE_INTERNAL=1"); this.DynamicLinkerSettingsForAndroid().Add(c => ((DotsRuntimeNativeProgramConfiguration)c).CSharpConfig.DotsConfiguration == DotsConfiguration.Release, l => l.WithStripAll(true)); Libraries.Add(c => c.Platform is WebGLPlatform, new PreJsLibrary(BuildProgram.BeeRoot.Parent.Combine("LowLevelSupport~", "WebSupport", "tiny_runtime.js"))); Defines.Add(ManagedDebuggingIsEnabled, "IL2CPP_MONO_DEBUGGER=1"); Defines.Add(ManagedDebuggingIsEnabled, "IL2CPP_DEBUGGER_PORT=56000"); // Remove this comment to enable the managed debugger log file. It will be written to the working directory. For Web builds, the output will go to the browser's console. //Defines.Add(ManagedDebuggingIsEnabled, "IL2CPP_MONO_DEBUGGER_LOGFILE=il2cpp-debugger.log"); Defines.Add(c => ((DotsRuntimeNativeProgramConfiguration)c).CSharpConfig.DotsConfiguration != DotsConfiguration.Release, "IL2CPP_TINY_DEBUG_METADATA"); CompilerSettings().Add(ManagedDebuggingIsEnabled, c => c.WithExceptions(true)); CompilerSettings().Add(ManagedDebuggingIsEnabled, c => c.WithRTTI(true)); IncludeDirectories.Add(ManagedDebuggingIsEnabled, distRoot.Combine("libil2cpp/pch")); CompilerSettings().Add(s => s.WithCppLanguageVersion(CppLanguageVersion.Cpp11)); this.CompilerSettingsForMsvc().Add(c => c.WithWarningPolicies(new [] { new WarningAndPolicy("4102", WarningPolicy.Silent) })); this.CompilerSettingsForGcc().Add(s => s.WithWarningPolicies(GetGccLikeWarningPolicies())); this.CompilerSettingsForClang().Add(s => s.WithWarningPolicies(GetGccLikeWarningPolicies())); this.CompilerSettingsForEmscripten().Add(s => s.WithWarningPolicies(GetGccLikeWarningPolicies())); this.CompilerSettingsForIos().Add(s => s.WithWarningPolicies(GetGccLikeWarningPolicies())); NativeJobsPrebuiltLibrary.AddToNativeProgram(this); // Only required for managed debugging this.CompilerSettingsForEmscripten().Add(ManagedDebuggingIsEnabled, c => c.WithMultithreading_Compiler(EmscriptenMultithreadingMode.Enabled)); this.CompilerSettingsForGccLike().Add(s => s.WithCustomFlags(new[] { "-fno-strict-overflow" })); }
private static DotsRuntimeCSharpProgram SetupGame(AsmDefDescription game) { var gameProgram = GetOrMakeDotsRuntimeCSharpProgramFor(game); var configToSetupGame = new Dictionary <DotsRuntimeCSharpProgramConfiguration, DotNetAssembly>(); if (!PerConfigBuildSettings.ContainsKey(game.Name)) { return(null); } var configsToUse = PerConfigBuildSettings[game.Name].Where(config => !CanSkipSetupOf(game.Name, config)); foreach (var config in configsToUse) { var withoutExt = new NPath(new NPath(gameProgram.FileName).FileNameWithoutExtension).Combine(config.Identifier); NPath exportManifest = withoutExt.Combine("export.manifest"); Backend.Current.RegisterFileInfluencingGraph(exportManifest); if (exportManifest.FileExists()) { var dataFiles = exportManifest.MakeAbsolute().ReadAllLines(); foreach (var dataFile in dataFiles.Select(d => new NPath(d))) { gameProgram.SupportFiles.Add( c => c.Equals(config), new DeployableFile(dataFile, GetDeployPathFromExportPath(dataFile))); } } gameProgram.ProjectFile.StartInfo.Add( c => c == config, StartInfoFor(config, EntryPointExecutableFor(gameProgram, config))); gameProgram.ProjectFile.BuildCommand.Add( c => c == config, new BeeBuildCommand(GameDeployBinaryFor(gameProgram, config).ToString(), false, false).ToExecuteArgs()); } foreach (var config in configsToUse) { DotNetAssembly setupGame = gameProgram.SetupSpecificConfiguration(config); if (config.TargetFramework == TargetFramework.Tiny) { var tinyStandard = new DotNetAssembly(Il2Cpp.Distribution.Path.Combine("build/profiles/Tiny/Facades/netstandard.dll"), Framework.FrameworkNone); setupGame = setupGame.WithDeployables(tinyStandard); } var postILProcessedGame = ILPostProcessorTool.SetupInvocation( setupGame, config, gameProgram.Defines.For(config).ToArray()); var postTypeRegGenGame = TypeRegistrationTool.SetupInvocation(postILProcessedGame, config); configToSetupGame[config] = postTypeRegGenGame; } var il2CppOutputProgram = new Il2Cpp.Il2CppOutputProgram(gameProgram.AsmDefDescription.Name); var configToSetupGameBursted = new Dictionary <DotsRuntimeCSharpProgramConfiguration, DotNetAssembly>(); foreach (var kvp in configToSetupGame) { var config = kvp.Key; var setupGame = kvp.Value; if (config.UseBurst) { BurstCompiler burstCompiler = null; if (config.Platform is WindowsPlatform) { burstCompiler = new BurstCompilerForWindows64(); burstCompiler.Link = false; } else if (config.Platform is MacOSXPlatform) { burstCompiler = new BurstCompilerForMac(); burstCompiler.Link = false; } else if (config.Platform is IosPlatform) { burstCompiler = new BurstCompilerForiOS(); burstCompiler.EnableStaticLinkage = true; burstCompiler.ObjectFileExtension = "a"; } else if (config.Platform is LinuxPlatform) { burstCompiler = new BurstCompilerForLinuxWaitingForBurstRelease(); } else if (config.Platform is AndroidPlatform) { burstCompiler = new BurstCompilerForAndroid(); burstCompiler.EnableStaticLinkage = false; burstCompiler.Link = false; burstCompiler.EnableDirectExternalLinking = true; if (config.NativeProgramConfiguration.ToolChain.Architecture is Arm64Architecture) { burstCompiler.TargetArchitecture = "ARMV8A_AARCH64"; } } else if (config.Platform is WebGLPlatform) { burstCompiler = new BurstCompilerForEmscripten(); burstCompiler.EnableStaticLinkage = true; burstCompiler.DisableVectors = false; } // Only generate marshaling info for platforms that require marshalling (e.g. Windows DotNet) // but also if collection checks are enabled (as that is why we need marshalling) burstCompiler.EnableJobMarshalling &= config.EnableUnityCollectionsChecks; burstCompiler.SafetyChecks = config.EnableUnityCollectionsChecks; burstCompiler.DisableWarnings = "BC1370"; // Suppress warning for burst function throwing an exception var outputDir = $"artifacts/{game.Name}/{config.Identifier}_bursted"; var burstLibName = "lib_burst_generated"; DotNetAssembly burstedGame = setupGame; var burstlib = BurstCompiler.SetupBurstCompilationForAssemblies( burstCompiler, setupGame, new NPath(outputDir).Combine("bclobj"), outputDir, burstLibName, out burstedGame); if ((config.Platform is IosPlatform || config.Platform is AndroidPlatform) && config.NativeProgramConfiguration.ToolChain.DynamicLibraryFormat.Extension == "a") // static lib based toolchain { il2CppOutputProgram.Libraries.Add(c => c.Equals(config.NativeProgramConfiguration), burstlib); il2CppOutputProgram.Defines.Add( c => c.Equals(config.NativeProgramConfiguration), $"FORCE_PINVOKE_{burstLibName}_INTERNAL"); } else if (config.Platform is WebGLPlatform) { il2CppOutputProgram.Libraries.Add(c => c.Equals(config.NativeProgramConfiguration), burstlib); } else { var burstDynamicLib = new NativeProgram(burstLibName); burstDynamicLib.Libraries.Add(c => c.Equals(config.NativeProgramConfiguration), burstlib); burstDynamicLib.Libraries.Add( c => c.Equals(config.NativeProgramConfiguration), gameProgram.TransitiveReferencesFor(config) .Where( p => p is DotsRuntimeCSharpProgram && ((DotsRuntimeCSharpProgram)p).NativeProgram != null) .Select( p => new NativeProgramAsLibrary(((DotsRuntimeCSharpProgram)p).NativeProgram) { BuildMode = NativeProgramLibraryBuildMode.Dynamic })); if (config.Platform is IosPlatform || config.Platform is AndroidPlatform) { NativeJobsPrebuiltLibrary.AddToNativeProgram(burstDynamicLib); } DotsRuntimeCSharpProgram.SetupDotsRuntimeNativeProgram(burstLibName, burstDynamicLib); var builtBurstLib = burstDynamicLib.SetupSpecificConfiguration( config.NativeProgramConfiguration, config.NativeProgramConfiguration.ToolChain.DynamicLibraryFormat); burstedGame = burstedGame.WithDeployables(builtBurstLib); } configToSetupGameBursted[config] = burstedGame; } else { configToSetupGameBursted[config] = setupGame; } } var configToSetupGameStripped = new Dictionary <DotsRuntimeCSharpProgramConfiguration, DotNetAssembly>(); foreach (var kvp in configToSetupGameBursted) { var config = kvp.Key; var setupGame = kvp.Value; if (config.ScriptingBackend == ScriptingBackend.TinyIl2cpp) { setupGame = Il2Cpp.UnityLinker.SetupInvocation(setupGame, $"artifacts/{game.Name}/{config.Identifier}_stripped", config.NativeProgramConfiguration); il2CppOutputProgram.SetupConditionalSourcesAndLibrariesForConfig(config, setupGame); configToSetupGameStripped[kvp.Key] = setupGame; } else { configToSetupGameStripped[kvp.Key] = kvp.Value; } } foreach (var kvp in configToSetupGameStripped) { var config = kvp.Key; var setupGame = kvp.Value; NPath deployPath = GameDeployDirectoryFor(gameProgram, config); IDeployable deployedGame; NPath entryPointExecutable = null; if (config.ScriptingBackend == ScriptingBackend.TinyIl2cpp) { var tinyShellFileName = "tiny_shell.html"; NPath tinyShellPath = new NPath(new NPath(gameProgram.FileName).FileNameWithoutExtension).Combine(config.Identifier, "WebTemplate", tinyShellFileName); il2CppOutputProgram.DynamicLinkerSettingsForEmscripten().Add(c => c.WithShellFile(tinyShellPath)); var builtNativeProgram = il2CppOutputProgram.SetupSpecificConfiguration( config.NativeProgramConfiguration, config.NativeProgramConfiguration.ExecutableFormat ) .WithDeployables(setupGame.RecursiveRuntimeDependenciesIncludingSelf.SelectMany(a => a.Deployables.Where(d => !(d is DotNetAssembly) && !(d is StaticLibrary))) .ToArray()); if (builtNativeProgram is IPackagedAppExtension) { (builtNativeProgram as IPackagedAppExtension).SetAppPackagingParameters( gameProgram.AsmDefDescription.Name, config.DotsConfiguration); } if (config.PlatformBuildConfig is WebBuildConfig webBuildConfig) { if (webBuildConfig.SingleFile) { deployedGame = new DeployableFile(GameDeployBinaryFor(gameProgram, config)); CopyTool.Instance().Setup(deployedGame.Path, (builtNativeProgram as EmscriptenExecutable).Path); } else { deployedGame = builtNativeProgram.DeployTo(deployPath); } var webTemplateFolder = webBuildConfig.WebTemplateFolder; if (String.IsNullOrEmpty(webTemplateFolder)) { webTemplateFolder = LowLevelRoot.Combine("WebSupport", "WebTemplates", "Default").ToString(); } if (new NPath(webTemplateFolder).IsRelative) { webTemplateFolder = new NPath("../..").Combine(webTemplateFolder).MakeAbsolute().ToString(); } if (!new NPath(webTemplateFolder).Combine(tinyShellFileName).FileExists()) { throw new InvalidProgramException($"Web template folder \"{webTemplateFolder}\" doesn't contain \"{tinyShellFileName}\" file."); } foreach (var templateFilePath in new NPath(webTemplateFolder).Files(recurse:true)) { string fileRelativePath = templateFilePath.ToString().Substring(webTemplateFolder.Length + 1); if (fileRelativePath == tinyShellFileName) { NPath shellPackager = LowLevelRoot.Combine("WebSupport", "package_shell_file.js"); NPath tinyShellJS = LowLevelRoot.Combine("WebSupport", "tiny_shell.js"); var inputs = new List <NPath> { TinyEmscripten.NodeExe, shellPackager, templateFilePath, tinyShellJS }; var commandLineArguments = new List <string> { shellPackager.ToString(), "--outputHtml", tinyShellPath.ToString(), "--inputShellHtml", templateFilePath.ToString(), "--inputShellJs", tinyShellJS.ToString() }; NPath exportManifest = new NPath(new NPath(gameProgram.FileName).FileNameWithoutExtension).Combine(config.Identifier, "export.manifest"); if (webBuildConfig.SingleFile && exportManifest.FileExists()) { inputs.Add(exportManifest.MakeAbsolute().ReadAllLines().Select(d => new NPath(d))); NPath assetRootDirectory = new NPath(new NPath(gameProgram.FileName).FileNameWithoutExtension).Combine(config.Identifier); commandLineArguments.AddRange(new List <string> { "--assetRootDirectory", assetRootDirectory.ToString(), "--assetManifest", exportManifest.ToString() }); } Backend.Current.AddAction( actionName: "Package Shell File", targetFiles: new NPath[] { tinyShellPath }, inputs: inputs.ToArray(), executableStringFor: TinyEmscripten.NodeExe.InQuotes(), commandLineArguments: commandLineArguments.Select(d => d.InQuotes()).ToArray() ); Backend.Current.AddDependency(deployedGame.Path, tinyShellPath); } else if (!templateFilePath.HasExtension("meta")) { var targetPath = deployPath.Combine(fileRelativePath); CopyTool.Instance().Setup(targetPath, templateFilePath); Backend.Current.AddDependency(deployedGame.Path, targetPath); } } } else { deployedGame = builtNativeProgram.DeployTo(deployPath); } entryPointExecutable = deployedGame.Path; if (config.EnableManagedDebugging && !(builtNativeProgram is IPackagedAppExtension)) { Backend.Current.AddDependency(deployedGame.Path, Il2Cpp.CopyIL2CPPMetadataFile(deployPath, setupGame)); } // make sure http-server gets fetched from stevedore. this should probably go elsewhere, but this is // a convenient quick hack place. if (config.PlatformBuildConfig is WebBuildConfig) { var httpserver = new StevedoreArtifact("http-server"); httpserver.GenerateUnusualPath(); var httpserverpath = httpserver.GetUnusualPath().Combine("bin", "http-server"); Backend.Current.AddDependency(deployedGame.Path, httpserverpath); } } else { deployedGame = setupGame.DeployTo(deployPath); var dotNetAssembly = (DotNetAssembly)deployedGame; //Usually a dotnet runtime game does not have a static void main(), and instead references another "entrypoint asmdef" that provides it. //This is convenient, but what makes it weird is that you have to start YourEntryPoint.exe instead of YourGame.exe. Until we have a better //solution for this, we're going to copy YourEntryPoint.exe to YourGame.exe, so that it's easier to find, and so that when it runs and you look //at the process name you understand what it is. if (deployedGame.Path.HasExtension("dll")) { var to = deployPath.Combine(deployedGame.Path.ChangeExtension("exe").FileName); // Do an explicit check for the entrypoint.exe as a program may refer to other exes as assembly references var from = dotNetAssembly.RecursiveRuntimeDependenciesIncludingSelf.SingleOrDefault(a => a.Path.FileName == "Unity.Runtime.EntryPoint.exe")?.Path; if (from == null) { throw new InvalidProgramException($"Program {dotNetAssembly.Path} is an executable-like thing, but doesn't reference anything with Main"); } Backend.Current.AddDependency(deployedGame.Path, CopyTool.Instance().Setup(to, from)); entryPointExecutable = to; } else { entryPointExecutable = deployedGame.Path; } } //Because we use multidag, and try to not run all the setupcode when we just want to create projectfiles, we have a bit of a challenge. //Projectfiles require exact start and build commands. So we need to have a cheap way to calculate those. However, it's important that they //exactly match the actual place where the buildprogram is going to place our files. If these don't match things break down. The checks //in this block, they compare the "quick way to determine where the binary will be placed, and what the start executable is", with the //actual return values returned from .DeployTo(), when we do run the actual buildcode. NPath deployedGamePath = GameDeployBinaryFor(gameProgram, config); //Identifier with slash means that this is complementary target and we should skip steps which are main target specific. //See comment in DotsConfigs.cs DotsConfigs.MakeConfigs() method for details. if (config.Identifier.IndexOf('/') != -1) { continue; } if (deployedGame.Path != deployedGamePath) { throw new InvalidProgramException($"We expected deployPath to be {deployedGamePath}, but in reality it was {deployedGame.Path}"); } var expectedEntryPointExecutable = EntryPointExecutableFor(gameProgram, config); if (entryPointExecutable != expectedEntryPointExecutable) { throw new InvalidProgramException($"We expected entryPointExecutable to be {expectedEntryPointExecutable}, but in reality it was {entryPointExecutable}"); } Backend.Current.AddAliasDependency(config.Identifier, deployedGamePath); } return(gameProgram); }
protected void Construct(string name, bool isExe) { FileName = name + (isExe ? ".exe" : ".dll"); Framework.Add(c => GetTargetFramework(c, this) == TargetFramework.Tiny, Bee.DotNet.Framework.FrameworkNone); References.Add(c => GetTargetFramework(c, this) == TargetFramework.Tiny, Il2Cpp.TinyCorlib); Framework.Add( c => GetTargetFramework(c, this) == TargetFramework.NetStandard20, BuildProgram.HackedFrameworkToUseForProjectFilesIfNecessary); ProjectFile.Path = DeterminePathForProjectFile(); ProjectFile.ReferenceModeCallback = arg => { // Most projects are AsmDefCSharpProgram. For everything else we'll look up their // packagestatus by the fact that we know it's in the same package as Unity.Entities.CPlusPlus // XXX This is not true any more! //var asmdefDotsProgram = (arg as AsmDefCSharpProgram)?.AsmDefDescription ?? AsmDefConfigFile.AsmDefDescriptionFor("Unity.Entities.CPlusPlus"); return(ProjectFile.ReferenceMode.ByCSProj); }; LanguageVersion = "7.3"; Defines.Add( "UNITY_DOTSPLAYER", // this is deprecated and we should remove in the distant future "UNITY_DOTSRUNTIME", "UNITY_2018_3_OR_NEWER", "UNITY_2019_1_OR_NEWER", "UNITY_2019_2_OR_NEWER", "UNITY_2019_3_OR_NEWER", "UNITY_2020_1_OR_NEWER", "UNITY_ENTITIES_0_12_OR_NEWER" ); Defines.Add(c => GetTargetFramework(c, this) == TargetFramework.Tiny, "NET_DOTS"); Defines.Add(c => GetTargetFramework(c, this) == TargetFramework.NetStandard20, "NET_STANDARD_2_0"); // Managed components are unsupported when using the Tiny BCL Defines.Add(c => GetTargetFramework(c, this) == TargetFramework.Tiny, "UNITY_DISABLE_MANAGED_COMPONENTS"); Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.NativeProgramConfiguration?.ToolChain.Architecture.Bits == 32, "UNITY_DOTSPLAYER32"); Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.NativeProgramConfiguration?.ToolChain.Architecture.Bits == 32, "UNITY_DOTSRUNTIME32"); Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.NativeProgramConfiguration?.ToolChain.Architecture.Bits == 64, "UNITY_DOTSPLAYER64"); Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.NativeProgramConfiguration?.ToolChain.Architecture.Bits == 64, "UNITY_DOTSRUNTIME64"); Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.Platform is WebGLPlatform, "UNITY_WEBGL"); Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.Platform is WindowsPlatform, "UNITY_WINDOWS"); Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.Platform is MacOSXPlatform, "UNITY_MACOSX"); Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.Platform is LinuxPlatform, "UNITY_LINUX"); Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.Platform is IosPlatform, "UNITY_IOS"); Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.Platform is AndroidPlatform, "UNITY_ANDROID"); Defines.Add(c => !((DotsRuntimeCSharpProgramConfiguration)c).MultiThreadedJobs, "UNITY_SINGLETHREADED_JOBS"); // Adds stack traces to mallocs until we get a better system for memory leaks //Defines.Add("UNITY_DOTSRUNTIME_TRACEMALLOCS"); CopyReferencesNextToTarget = false; WarningsAsErrors = ShouldEnableWarningsAsErrors(name); foreach (var sourcePath in AllSourcePaths) { if (sourcePath.FileName == "Unity.Mathematics") { Sources.Add(sourcePath.Files("*.cs", true) .Where(f => f.FileName != "math_unity_conversion.cs" && f.FileName != "PropertyAttributes.cs")); } else { Sources.Add(new CustomProvideFiles(sourcePath)); } } bool hasCpp = false; foreach (var sourcePath in AllSourcePaths) { var cppFolder = sourcePath.Combine("cpp~"); var androidFolder = sourcePath.Combine("android~"); var prejsFolder = sourcePath.Combine("prejs~"); var jsFolder = sourcePath.Combine("js~"); var postjsFolder = sourcePath.Combine("postjs~"); var beeFolder = sourcePath.Combine("bee~"); var includeFolder = cppFolder.Combine("include"); var bindingsFolder = sourcePath.Combine("bindings~"); if (cppFolder.DirectoryExists()) { ProjectFile.AdditionalFiles.AddRange(cppFolder.Files(true)); var cppFiles = cppFolder.Files("*.c*", true); GetOrMakeNativeProgram().Sources.Add(cppFiles); var mmFiles = cppFolder.Files("*.m*", true); GetOrMakeNativeProgram().Sources.Add(c => (c.Platform is MacOSXPlatform || c.Platform is IosPlatform), mmFiles); GetOrMakeNativeProgram().DynamicLinkerSettingsForAndroid().Add(c => ((DotsRuntimeNativeProgramConfiguration)c).CSharpConfig.DotsConfiguration == DotsConfiguration.Release, l => l.WithStripAll(true)); hasCpp = true; } if (prejsFolder.DirectoryExists()) { var jsFiles = prejsFolder.Files("*.js", true); ProjectFile.AdditionalFiles.AddRange(prejsFolder.Files(true)); GetOrMakeNativeProgram() .Libraries.Add(c => c.Platform is WebGLPlatform, jsFiles.Select(jsFile => new PreJsLibrary(jsFile))); } //todo: get rid of having both a regular js and a prejs folder if (jsFolder.DirectoryExists()) { var jsFiles = jsFolder.Files("*.js", true); ProjectFile.AdditionalFiles.AddRange(jsFolder.Files(true)); GetOrMakeNativeProgram() .Libraries.Add(c => c.Platform is WebGLPlatform, jsFiles.Select(jsFile => new JavascriptLibrary(jsFile))); } if (postjsFolder.DirectoryExists()) { var jsFiles = postjsFolder.Files("*.js", true); ProjectFile.AdditionalFiles.AddRange(postjsFolder.Files(true)); GetOrMakeNativeProgram() .Libraries.Add(c => c.Platform is WebGLPlatform, jsFiles.Select(jsFile => new PostJsLibrary(jsFile))); } // .jslib files in asmdef dir, like Unity var jslibFiles = sourcePath.Files("*.jslib", true); if (jslibFiles.Any()) { ProjectFile.AdditionalFiles.AddRange(jslibFiles); GetOrMakeNativeProgram() .Libraries.Add(c => c.Platform is WebGLPlatform, jslibFiles.Select(jsFile => new JavascriptLibrary(jsFile))); } if (beeFolder.DirectoryExists()) { ProjectFile.AdditionalFiles.AddRange(beeFolder.Files("*.cs")); } if (includeFolder.DirectoryExists()) { GetOrMakeNativeProgram().PublicIncludeDirectories.Add(includeFolder); } if (bindingsFolder.DirectoryExists()) { NativeJobsPrebuiltLibrary.AddBindings(this, bindingsFolder); } if (androidFolder.DirectoryExists()) { foreach (var extraFile in androidFolder.Files(true).Where(f => f.HasExtension("java", "kt", "aar", "jar"))) { SupportFiles.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.Platform is AndroidPlatform, new DeployableFile(extraFile, extraFile.RelativeTo(androidFolder))); } } } if (hasCpp) { GetOrMakeNativeProgram().Libraries.Add(c => c.Platform is LinuxPlatform, new SystemLibrary("rt")); GetOrMakeNativeProgram().Libraries.Add(c => c.Platform is LinuxPlatform, new SystemLibrary("atomic")); GetOrMakeNativeProgram().Libraries.Add(c => c.Platform is WindowsPlatform, new SystemLibrary("ws2_32.lib")); NativeJobsPrebuiltLibrary.AddToNativeProgram(GetOrMakeNativeProgram()); } SupportFiles.Add(AllSourcePaths.SelectMany(p => p.Files() .Where(f => f.HasExtension("jpg", "png", "wav", "mp3", "jpeg", "mp4", "webm", "ogg", "ttf", "json")))); Defines.Add(c => ((DotsRuntimeCSharpProgramConfiguration)c).EnableUnityCollectionsChecks, "ENABLE_UNITY_COLLECTIONS_CHECKS"); bool isConfigDebug(CSharpProgramConfiguration c) => c.CodeGen == CSharpCodeGen.Debug || (c as DotsRuntimeCSharpProgramConfiguration)?.DotsConfiguration < DotsConfiguration.Release; Defines.Add(isConfigDebug, "DEBUG"); bool isConfigDevelop(CSharpProgramConfiguration c) => (c as DotsRuntimeCSharpProgramConfiguration)?.DotsConfiguration == DotsConfiguration.Develop; Defines.Add(isConfigDevelop, "DEVELOP"); Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.EnableProfiler == true, "ENABLE_PROFILER"); // Many systems needs their own DOTS Runtime specific profiler define since they will get scanned by // the hybrid builds/editor, but they will use the DOTS Runtime-specific profiler API. Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.EnableProfiler == true, "ENABLE_DOTSRUNTIME_PROFILER"); // Only enable player connection when we need it // - To support logging ("debug" builds) // - To support profiling // - To support il2cpp managed debugging (multicast) Defines.Add(c => isConfigDebug(c) || (c as DotsRuntimeCSharpProgramConfiguration)?.EnableProfiler == true || IsManagedDebuggingWithIL2CPPEnabled(c), "ENABLE_PLAYERCONNECTION"); // Multicasting // - Is a supplement to player connection in non-webgl builds // - Is needed for identification in webgl builds, too, if il2cpp managed debugging is enabled Defines.Add(c => !((c as DotsRuntimeCSharpProgramConfiguration).Platform is WebGLPlatform) || IsManagedDebuggingWithIL2CPPEnabled(c), "ENABLE_MULTICAST"); // Special define used mainly for debugging multithread jobs without bursting them Defines.Add(c => !(c as DotsRuntimeCSharpProgramConfiguration).UseBurst && (c as DotsRuntimeCSharpProgramConfiguration).MultiThreadedJobs, "UNITY_DOTSRUNTIME_MULTITHREAD_NOBURST"); Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.ScriptingBackend == ScriptingBackend.TinyIl2cpp, "UNITY_DOTSPLAYER_IL2CPP"); // deprecated version Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.ScriptingBackend == ScriptingBackend.TinyIl2cpp, "UNITY_DOTSRUNTIME_IL2CPP"); Defines.Add(c => IsManagedDebuggingWithIL2CPPEnabled(c), "UNITY_DOTSPLAYER_IL2CPP_MANAGED_DEBUGGER"); // deprecated version Defines.Add(c => IsManagedDebuggingWithIL2CPPEnabled(c), "UNITY_DOTSRUNTIME_IL2CPP_MANAGED_DEBUGGER"); Defines.Add(c => IsManagedDebuggingWithIL2CPPEnabled(c) && (c as DotsRuntimeCSharpProgramConfiguration).WaitForManagedDebugger, "UNITY_DOTSPLAYER_IL2CPP_WAIT_FOR_MANAGED_DEBUGGER"); // deprecated version Defines.Add(c => IsManagedDebuggingWithIL2CPPEnabled(c) && (c as DotsRuntimeCSharpProgramConfiguration).WaitForManagedDebugger, "UNITY_DOTSRUNTIME_IL2CPP_WAIT_FOR_MANAGED_DEBUGGER"); Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.ScriptingBackend == ScriptingBackend.Dotnet, "UNITY_DOTSPLAYER_DOTNET"); // deprecated version Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.ScriptingBackend == ScriptingBackend.Dotnet, "UNITY_DOTSRUNTIME_DOTNET"); Defines.Add(c => (c as DotsRuntimeCSharpProgramConfiguration)?.Defines ?? new List <string>()); ProjectFile.RedirectMSBuildBuildTargetToBee = true; ProjectFile.AddCustomLinkRoot(MainSourcePath, "."); ProjectFile.RootNameSpace = ""; DotsRuntimeCSharpProgramCustomizer.RunAllCustomizersOn(this); }
static NativeProgram CreateLibIl2CppProgram(bool useExceptions, NativeProgram boehmGcProgram = null, string libil2cppname = "libil2cpptiny") { var fileList = Distribution.GetFileList(libil2cppname).ResolveWithFileSystem().ToArray(); var nPaths = fileList.Where(f => f.HasExtension("cpp")).ToArray(); var win32Sources = nPaths.Where(p => p.HasDirectory("Win32")).ToArray(); var posixSources = nPaths.Where(p => p.HasDirectory("Posix")).ToArray(); nPaths = nPaths.Except(win32Sources).Except(posixSources).ToArray(); var program = new NativeProgram(libil2cppname) { Sources = { nPaths, { c => c.Platform.HasPosix,posixSources }, { c => c.Platform is WindowsPlatform,win32Sources } }, Exceptions = { useExceptions }, PublicIncludeDirectories = { Distribution.Path.Combine(libil2cppname), Distribution.Path.Combine("libil2cpp") }, PublicDefines = { "NET_4_0", "GC_NOT_DLL", "RUNTIME_IL2CPP", "LIBIL2CPP_IS_IN_EXECUTABLE=1", { c => c.ToolChain is VisualStudioToolchain,"NOMINMAX", "WIN32_THREADS", "IL2CPP_TARGET_WINDOWS=1" }, { c => c.CodeGen == CodeGen.Debug,"DEBUG", "IL2CPP_DEBUG" }, { c => ((DotsRuntimeNativeProgramConfiguration)c).CSharpConfig.DotsConfiguration != DotsConfiguration.Release,"IL2CPP_TINY_DEBUG_METADATA" }, }, Libraries = { { c => c.Platform is WindowsPlatform, new[] { "user32.lib", "advapi32.lib", "ole32.lib", "oleaut32.lib", "Shell32.lib", "Crypt32.lib", "psapi.lib", "version.lib", "MsWSock.lib", "ws2_32.lib", "Iphlpapi.lib", "Dbghelp.lib" }.Select(s => new SystemLibrary(s)) }, { c => c.Platform is MacOSXPlatform, new PrecompiledLibrary[] { new SystemFramework("CoreFoundation") } }, { c => c.Platform is LinuxPlatform, new SystemLibrary("dl") }, { c => c.Platform is AndroidPlatform, new[] { new SystemLibrary("log") } } }, Defines = { { c => c.Platform is AndroidPlatform && c.ToolChain.Architecture is Arm64Architecture && ManagedDebuggingIsEnabled(c), "TARGET_ARM64" }, } }; program.Libraries.Add(BoehmGCProgram); program.RTTI.Set(c => useExceptions && c.ToolChain.EnablingExceptionsRequiresRTTI); if (libil2cppname == "libil2cpptiny") { program.Sources.Add(Distribution.GetFileList("libil2cpp/os").ResolveWithFileSystem()); program.Sources.Add(Distribution.GetFileList("libil2cpp/gc").ResolveWithFileSystem()); program.Sources.Add(Distribution.GetFileList("libil2cpp/utils").ResolveWithFileSystem()); program.Sources.Add(Distribution.GetFileList("libil2cpp/vm-utils").ResolveWithFileSystem()); program.Sources.Add(Distribution.GetFileList("libil2cpp/codegen").ResolveWithFileSystem()); program.PublicIncludeDirectories.Add(Distribution.Path.Combine("libil2cpp")); program.PublicIncludeDirectories.Add(Distribution.Path.Combine("libil2cpp", "pch")); } else { program.Defines.Add(ManagedDebuggingIsEnabled, "IL2CPP_MONO_DEBUGGER=1", "PLATFORM_UNITY", "UNITY_USE_PLATFORM_STUBS", "ENABLE_OVERRIDABLE_ALLOCATORS", "IL2CPP_ON_MONO=1", "DISABLE_JIT=1", "DISABLE_REMOTING=1", "HAVE_CONFIG_H", "MONO_DLL_EXPORT=1"); program.IncludeDirectories.Add(ManagedDebuggingIsEnabled, new[] { Distribution.Path.Combine("external/mono/mono/eglib"), Distribution.Path.Combine("external/mono/mono"), Distribution.Path.Combine("external/mono/"), Distribution.Path.Combine("external/mono/mono/sgen"), Distribution.Path.Combine("external/mono/mono/utils"), Distribution.Path.Combine("external/mono/mono/metadata"), Distribution.Path.Combine("external/mono/metadata/private"), Distribution.Path.Combine("libmono/config"), Distribution.Path.Combine("libil2cpp/os/c-api"), Distribution.Path.Combine("libil2cpp/pch"), }.ResolveWithFileSystem()); var MonoSourceDir = Distribution.Path.Combine("external/mono").ResolveWithFileSystem(); program.Sources.Add(ManagedDebuggingIsEnabled, new [] { "mono/eglib/garray.c", "mono/eglib/gbytearray.c", "mono/eglib/gdate-unity.c", "mono/eglib/gdir-unity.c", "mono/eglib/gerror.c", "mono/eglib/gfile-unity.c", "mono/eglib/gfile.c", "mono/eglib/ghashtable.c", "mono/eglib/giconv.c", "mono/eglib/glist.c", "mono/eglib/gmarkup.c", "mono/eglib/gmem.c", "mono/eglib/gmisc-unity.c", "mono/eglib/goutput.c", "mono/eglib/gpath.c", "mono/eglib/gpattern.c", "mono/eglib/gptrarray.c", "mono/eglib/gqsort.c", "mono/eglib/gqueue.c", "mono/eglib/gshell.c", "mono/eglib/gslist.c", "mono/eglib/gspawn.c", "mono/eglib/gstr.c", "mono/eglib/gstring.c", "mono/eglib/gunicode.c", "mono/eglib/gutf8.c", "mono/metadata/mono-hash.c", "mono/metadata/profiler.c", "mono/mini/debugger-agent.c", "mono/utils/atomic.c", "mono/utils/bsearch.c", "mono/utils/dlmalloc.c", "mono/utils/hazard-pointer.c", "mono/utils/json.c", "mono/utils/lock-free-alloc.c", "mono/utils/lock-free-array-queue.c", "mono/utils/lock-free-queue.c", "mono/utils/memfuncs.c", "mono/utils/mono-codeman.c", "mono/utils/mono-conc-hashtable.c", "mono/utils/mono-context.c", "mono/utils/mono-counters.c", "mono/utils/mono-dl.c", "mono/utils/mono-error.c", "mono/utils/mono-filemap.c", "mono/utils/mono-hwcap.c", "mono/utils/mono-internal-hash.c", "mono/utils/mono-io-portability.c", "mono/utils/mono-linked-list-set.c", "mono/utils/mono-log-common.c", "mono/utils/mono-logger.c", "mono/utils/mono-math.c", "mono/utils/mono-md5.c", "mono/utils/mono-mmap-windows.c", "mono/utils/mono-mmap.c", "mono/utils/mono-networkinterfaces.c", "mono/utils/mono-os-mutex.c", "mono/utils/mono-path.c", "mono/utils/mono-poll.c", "mono/utils/mono-proclib-windows.c", "mono/utils/mono-proclib.c", "mono/utils/mono-property-hash.c", "mono/utils/mono-publib.c", "mono/utils/mono-sha1.c", "mono/utils/mono-stdlib.c", "mono/utils/mono-threads-coop.c", "mono/utils/mono-threads-state-machine.c", "mono/utils/mono-threads.c", "mono/utils/mono-tls.c", "mono/utils/mono-uri.c", "mono/utils/mono-value-hash.c", "mono/utils/monobitset.c", "mono/utils/networking-missing.c", "mono/utils/networking.c", "mono/utils/parse.c", "mono/utils/strenc.c", "mono/utils/unity-rand.c", "mono/utils/unity-time.c", "mono/utils/mono-dl-unity.c", "mono/utils/mono-log-unity.c", "mono/utils/mono-threads-unity.c", "mono/utils/networking-unity.c", "mono/utils/os-event-unity.c", "mono/metadata/console-unity.c", "mono/metadata/file-mmap-unity.c", "mono/metadata/w32error-unity.c", "mono/metadata/w32event-unity.c", "mono/metadata/w32file-unity.c", "mono/metadata/w32mutex-unity.c", "mono/metadata/w32process-unity.c", "mono/metadata/w32semaphore-unity.c", "mono/metadata/w32socket-unity.c" }.Select(path => MonoSourceDir.Combine(path))); program.Sources.Add(c => c.ToolChain.Platform is WindowsPlatform && ManagedDebuggingIsEnabled(c), MonoSourceDir.Combine("mono/eglib/gunicode-win32.c")); program.Sources.Add(c => c.ToolChain.Platform is WindowsPlatform && ManagedDebuggingIsEnabled(c), MonoSourceDir.Combine("mono/utils/mono-os-wait-win32.c")); program.Sources.Add(c => c.ToolChain.Platform is WebGLPlatform && ManagedDebuggingIsEnabled(c), MonoSourceDir.Combine("mono/utils/mono-hwcap-web.c")); program.Sources.Add(c => c.ToolChain.Architecture is IntelArchitecture && ManagedDebuggingIsEnabled(c), MonoSourceDir.Combine("mono/utils/mono-hwcap-x86.c")); program.Sources.Add(c => c.ToolChain.Architecture is ARMv7Architecture && ManagedDebuggingIsEnabled(c), MonoSourceDir.Combine("mono/utils/mono-hwcap-arm.c")); program.Sources.Add(c => c.ToolChain.Architecture is Arm64Architecture && ManagedDebuggingIsEnabled(c), MonoSourceDir.Combine("mono/utils/mono-hwcap-arm64.c")); program.IncludeDirectories.Add(ManagedDebuggingIsEnabled, Distribution.Path.Combine("libil2cpp/debugger")); } program.PublicDefines.Add("IL2CPP_TINY"); program.PublicIncludeDirectories.Add(Distribution.Path.Combine("external").Combine("xxHash")); program.CompilerSettings().Add(s => s.WithCppLanguageVersion(CppLanguageVersion.Cpp11)); program.CompilerSettingsForGcc().Add(s => s.WithWarningPolicies(GetGccLikeWarningPolicies())); // Use Baselib headers and library code from the NativeJobs library. NativeJobsPrebuiltLibrary.AddToNativeProgram(program); //program.CompilerSettingsForMsvc().Add(l => l.WithCompilerRuntimeLibrary(CompilerRuntimeLibrary.None)); program.CompilerSettingsForEmscripten().Add(ManagedDebuggingIsEnabled, c => c.WithMultithreading_Compiler(EmscriptenMultithreadingMode.Enabled)); program.StaticLinkerSettings().Add(c => c.ToolChain is EmscriptenToolchain && ManagedDebuggingIsEnabled(c), s => s.WithCustomFlags_workaround(new[] { "-s", "USE_PTHREADS=1" })); return(program); }