public void Run()
        {
            var outputDirectory = GetCppOutputDirectoryInStagingArea();
            var managedDir      = Path.GetFullPath(Path.Combine(m_StagingAreaData, "Managed"));

            // Make all assemblies in Staging/Managed writable for stripping.
            foreach (var file in Directory.GetFiles(managedDir))
            {
                var fileInfo = new FileInfo(file);
                fileInfo.IsReadOnly = false;
            }

            var buildTargetGroup = BuildPipeline.GetBuildTargetGroup(m_PlatformProvider.target);

            var managedStrippingLevel = PlayerSettings.GetManagedStrippingLevel(buildTargetGroup);

            // IL2CPP does not support a managed stripping level of disabled. If the player settings
            // do try this (which should not be possible from the editor), use Low instead.
            if (managedStrippingLevel == ManagedStrippingLevel.Disabled)
            {
                managedStrippingLevel = ManagedStrippingLevel.Low;
            }
            AssemblyStripper.StripAssemblies(managedDir, m_PlatformProvider.CreateUnityLinkerPlatformProvider(), m_PlatformProvider, m_RuntimeClassRegistry, managedStrippingLevel);

            // The IL2CPP editor integration here is responsible to give il2cpp.exe an empty directory to use.
            FileUtil.CreateOrCleanDirectory(outputDirectory);

            if (m_ModifyOutputBeforeCompile != null)
            {
                m_ModifyOutputBeforeCompile(outputDirectory);
            }

            var pipelineData = new Il2CppBuildPipelineData(m_PlatformProvider.target, managedDir);

            ConvertPlayerDlltoCpp(pipelineData, outputDirectory, managedDir, m_PlatformProvider.supportsManagedDebugging);

            var compiler = m_PlatformProvider.CreateNativeCompiler();

            if (compiler != null && m_PlatformProvider.CreateIl2CppNativeCodeBuilder() == null)
            {
                var nativeLibPath = OutputFileRelativePath();

                var includePaths = new List <string>(m_PlatformProvider.includePaths);
                includePaths.Add(outputDirectory);

                m_PlatformProvider.CreateNativeCompiler().CompileDynamicLibrary(
                    nativeLibPath,
                    NativeCompiler.AllSourceFilesIn(outputDirectory),
                    includePaths,
                    m_PlatformProvider.libraryPaths,
                    new string[0]);
            }
        }
Beispiel #2
0
        public void RunCompileAndLink(string il2cppBuildCacheSource)
        {
            if (string.Equals(Path.GetFullPath(il2cppBuildCacheSource), Path.GetFullPath(m_PlatformProvider.il2cppBuildCacheDirectory), StringComparison.OrdinalIgnoreCase))
            {
                throw new ArgumentException("IIl2CppPlatformProvider.il2cppBuildCacheDirectory cannot be the same as il2cppBuildCacheDirectory. You probably forgot to override il2cppBuildCacheDirectory on your IIl2CppPlatformProvider.");
            }

            var il2CppNativeCodeBuilder = m_PlatformProvider.CreateIl2CppNativeCodeBuilder();

            if (il2CppNativeCodeBuilder != null)
            {
                Il2CppNativeCodeBuilderUtils.ClearAndPrepareCacheDirectory(il2CppNativeCodeBuilder);

                var buildCacheDirectory = m_PlatformProvider.il2cppBuildCacheDirectory;
                Directory.CreateDirectory(buildCacheDirectory);

                var buildCacheNativeOutputFile = Path.Combine(GetNativeOutputRelativeDirectory(buildCacheDirectory), m_PlatformProvider.nativeLibraryFileName);
                var buildTargetGroup           = BuildPipeline.GetBuildTargetGroup(m_PlatformProvider.target);
                var compilerConfiguration      = PlayerSettings.GetIl2CppCompilerConfiguration(buildTargetGroup);
                var arguments = Il2CppNativeCodeBuilderUtils.AddBuilderArguments(il2CppNativeCodeBuilder, buildCacheNativeOutputFile, m_PlatformProvider.includePaths, m_PlatformProvider.libraryPaths, compilerConfiguration).ToList();

                var additionalArgs = IL2CPPUtils.GetAdditionalArguments();
                if (!string.IsNullOrEmpty(additionalArgs))
                {
                    arguments.Add(additionalArgs);
                }

                foreach (var buildingArgument in IL2CPPUtils.GetBuildingIL2CPPArguments(m_PlatformProvider, buildTargetGroup))
                {
                    if (!arguments.Contains(buildingArgument))
                    {
                        arguments.Add(buildingArgument);
                    }
                }

                arguments.Add($"--generatedcppdir={CommandLineFormatter.PrepareFileName(GetCppOutputDirectory(il2cppBuildCacheSource))}");
                arguments.Add($"--dotnetprofile=\"{IL2CPPUtils.ApiCompatibilityLevelToDotNetProfileArgument(PlayerSettings.GetApiCompatibilityLevel(buildTargetGroup), m_PlatformProvider.target)}\"");
                arguments.AddRange(IL2CPPUtils.GetDebuggerIL2CPPArguments(m_PlatformProvider, buildTargetGroup));
                Action <ProcessStartInfo> setupStartInfo = il2CppNativeCodeBuilder.SetupStartInfo;

                RunIl2CppWithArguments(arguments, setupStartInfo);
            }
        }
Beispiel #3
0
        public void Run()
        {
            var outputDirectory = GetCppOutputDirectoryInStagingArea();
            var managedDir      = Path.GetFullPath(Path.Combine(m_StagingAreaData, "Managed"));

            // Make all assemblies in Staging/Managed writable for stripping.
            foreach (var file in Directory.GetFiles(managedDir))
            {
                var fileInfo = new FileInfo(file);
                fileInfo.IsReadOnly = false;
            }

            AssemblyStripper.StripAssemblies(managedDir, m_PlatformProvider, m_RuntimeClassRegistry);

            // The IL2CPP editor integration here is responsible to give il2cpp.exe an empty directory to use.
            FileUtil.CreateOrCleanDirectory(outputDirectory);

            if (m_ModifyOutputBeforeCompile != null)
            {
                m_ModifyOutputBeforeCompile(outputDirectory);
            }

            ConvertPlayerDlltoCpp(GetUserAssembliesToConvert(managedDir), outputDirectory, managedDir, m_PlatformProvider.supportsManagedDebugging);

            var compiler = m_PlatformProvider.CreateNativeCompiler();

            if (compiler != null && m_PlatformProvider.CreateIl2CppNativeCodeBuilder() == null)
            {
                var nativeLibPath = OutputFileRelativePath();

                var includePaths = new List <string>(m_PlatformProvider.includePaths);
                includePaths.Add(outputDirectory);

                m_PlatformProvider.CreateNativeCompiler().CompileDynamicLibrary(
                    nativeLibPath,
                    NativeCompiler.AllSourceFilesIn(outputDirectory),
                    includePaths,
                    m_PlatformProvider.libraryPaths,
                    new string[0]);
            }
        }
Beispiel #4
0
        private static bool StripAssembliesTo(string[] assemblies, string[] searchDirs, string outputFolder, string workingDirectory, out string output, out string error, string linkerPath, IIl2CppPlatformProvider platformProvider, IEnumerable <string> additionalBlacklist, BuildTargetGroup buildTargetGroup, ManagedStrippingLevel managedStrippingLevel)
        {
            if (!Directory.Exists(outputFolder))
            {
                Directory.CreateDirectory(outputFolder);
            }

            additionalBlacklist = additionalBlacklist.Select(s => Path.IsPathRooted(s) ? s : Path.Combine(workingDirectory, s)).Where(File.Exists);

            var userBlackLists = GetUserBlacklistFiles();

            foreach (var ub in userBlackLists)
            {
                Console.WriteLine("UserBlackList: " + ub);
            }

            additionalBlacklist = additionalBlacklist.Concat(userBlackLists);

            var args = new List <string>
            {
                "-out=\"" + outputFolder + "\"",
                "-x=\"" + GetModuleWhitelist("Core", platformProvider.moduleStrippingInformationFolder) + "\"",
            };

            args.AddRange(additionalBlacklist.Select(path => "-x \"" + path + "\""));

            args.AddRange(searchDirs.Select(d => "-d \"" + d + "\""));
            args.AddRange(assemblies.Select(assembly => "--include-unity-root-assembly=\"" + Path.GetFullPath(assembly) + "\""));
            args.Add($"--dotnetruntime={GetRuntimeArgumentValueForLinker(buildTargetGroup)}");
            args.Add($"--dotnetprofile={GetProfileArgumentValueForLinker(buildTargetGroup)}");
            args.Add("--use-editor-options");
            args.Add($"--include-directory={CommandLineFormatter.PrepareFileName(workingDirectory)}");

            if (EditorUserBuildSettings.allowDebugging)
            {
                args.Add("--editor-settings-flag=AllowDebugging");
            }

            if (EditorUserBuildSettings.development)
            {
                args.Add("--editor-settings-flag=Development");
            }

            args.Add($"--rule-set={GetRuleSetForStrippingLevel(managedStrippingLevel)}");

            // One final check to make sure we only run high on latest runtime.
            if ((managedStrippingLevel == ManagedStrippingLevel.High) && (PlayerSettingsEditor.IsLatestApiCompatibility(PlayerSettings.GetApiCompatibilityLevel(buildTargetGroup))))
            {
                // Prepare the arguments to run the UnityLinker.  When in high mode, need to also
                // supply the IL2CPP compiler platform and compiler architecture.  When the scripting backend
                // is not IL2CPP, we have to map those strings and use a utility function to figure out proper strings.

                // Currently only need to do this on the non aot platforms of Android, Windows, Mac, Linux.
                var compilerPlatform     = "";
                var compilerArchitecture = "";
                Il2CppNativeCodeBuilder il2cppNativeCodeBuilder = platformProvider.CreateIl2CppNativeCodeBuilder();
                if (il2cppNativeCodeBuilder != null)
                {
                    compilerPlatform     = il2cppNativeCodeBuilder.CompilerPlatform;
                    compilerArchitecture = il2cppNativeCodeBuilder.CompilerArchitecture;
                }
                else
                {
                    GetUnityLinkerPlatformStringsFromBuildTarget(platformProvider.target, out compilerPlatform, out compilerArchitecture);
                }

                args.Add($"--platform={compilerPlatform}");
                if (platformProvider.target != BuildTarget.Android)
                {
                    args.Add($"--architecture={compilerArchitecture}");
                }
            }

            var additionalArgs = System.Environment.GetEnvironmentVariable("UNITYLINKER_ADDITIONAL_ARGS");

            if (!string.IsNullOrEmpty(additionalArgs))
            {
                args.Add(additionalArgs);
            }

            additionalArgs = Debug.GetDiagnosticSwitch("VMUnityLinkerAdditionalArgs") as string;
            if (!string.IsNullOrEmpty(additionalArgs))
            {
                args.Add(additionalArgs.Trim('\''));
            }

            return(RunAssemblyLinker(args, out output, out error, linkerPath, workingDirectory));
        }
        private static bool StripAssembliesTo(string[] assemblies, string[] searchDirs, string outputFolder, string workingDirectory, out string output, out string error, string linkerPath, IIl2CppPlatformProvider platformProvider, IEnumerable <string> additionalBlacklist, BuildTargetGroup buildTargetGroup, ManagedStrippingLevel managedStrippingLevel, bool stripEngineCode, string editorToLinkerDataPath)
        {
            if (!Directory.Exists(outputFolder))
            {
                Directory.CreateDirectory(outputFolder);
            }

            additionalBlacklist = additionalBlacklist.Select(s => Path.IsPathRooted(s) ? s : Path.Combine(workingDirectory, s)).Where(File.Exists);

            var userBlackLists = GetUserBlacklistFiles();

            foreach (var ub in userBlackLists)
            {
                Console.WriteLine("UserBlackList: " + ub);
            }

            additionalBlacklist = additionalBlacklist.Concat(userBlackLists);

            var args = new List <string>
            {
                $"-out={CommandLineFormatter.PrepareFileName(outputFolder)}",
            };

            if (!UseUnityLinkerEngineModuleStripping)
            {
                args.Add($"-x={CommandLineFormatter.PrepareFileName(GetModuleWhitelist("Core", platformProvider.moduleStrippingInformationFolder))}");
            }

            args.AddRange(additionalBlacklist.Select(path => $"-x={CommandLineFormatter.PrepareFileName(path)}"));

            args.AddRange(searchDirs.Select(d => $"-d={CommandLineFormatter.PrepareFileName(d)}"));
            args.AddRange(assemblies.Select(assembly => $"--include-unity-root-assembly={CommandLineFormatter.PrepareFileName(Path.GetFullPath(assembly))}"));
            args.Add($"--dotnetruntime={GetRuntimeArgumentValueForLinker(buildTargetGroup)}");
            args.Add($"--dotnetprofile={GetProfileArgumentValueForLinker(buildTargetGroup)}");
            args.Add("--use-editor-options");
            args.Add($"--include-directory={CommandLineFormatter.PrepareFileName(workingDirectory)}");

            if (EditorUserBuildSettings.allowDebugging)
            {
                args.Add("--editor-settings-flag=AllowDebugging");
            }

            if (EditorUserBuildSettings.development)
            {
                args.Add("--editor-settings-flag=Development");
            }

            args.Add($"--rule-set={GetRuleSetForStrippingLevel(managedStrippingLevel)}");
            args.Add($"--editor-data-file={CommandLineFormatter.PrepareFileName(editorToLinkerDataPath)}");

            var compilerPlatform     = "";
            var compilerArchitecture = "";
            Il2CppNativeCodeBuilder il2cppNativeCodeBuilder = platformProvider.CreateIl2CppNativeCodeBuilder();

            if (il2cppNativeCodeBuilder != null)
            {
                compilerPlatform     = il2cppNativeCodeBuilder.CompilerPlatform;
                compilerArchitecture = il2cppNativeCodeBuilder.CompilerArchitecture;
            }
            else
            {
                // When the scripting backend is not IL2CPP, we have to map those strings and use a utility function to figure out proper strings.
                GetUnityLinkerPlatformStringsFromBuildTarget(platformProvider.target, out compilerPlatform, out compilerArchitecture);
            }

            args.Add($"--platform={compilerPlatform}");
            if (!string.IsNullOrEmpty(compilerArchitecture))
            {
                args.Add($"--architecture={compilerArchitecture}");
            }

            if (!UseUnityLinkerEngineModuleStripping)
            {
                args.Add("--disable-engine-module-support");
            }

            if (stripEngineCode)
            {
                args.Add("--enable-engine-module-stripping");

                if (UnityEngine.Connect.UnityConnectSettings.enabled)
                {
                    args.Add("--engine-stripping-flag=EnableUnityConnect");
                }

                if (UnityEngine.Analytics.PerformanceReporting.enabled)
                {
                    args.Add("--engine-stripping-flag=EnablePerformanceReporting");
                }

                if (UnityEngine.Analytics.Analytics.enabled)
                {
                    args.Add("--engine-stripping-flag=EnableAnalytics");
                }

                if (UnityEditor.CrashReporting.CrashReportingSettings.enabled)
                {
                    args.Add("--engine-stripping-flag=EnableCrashReporting");
                }

                if (UnityEditorInternal.VR.VRModule.ShouldInjectVRDependenciesForBuildTarget(platformProvider.target))
                {
                    args.Add("--engine-stripping-flag=EnableVR");
                }
            }

            var modulesAssetPath = Path.Combine(platformProvider.moduleStrippingInformationFolder, "../modules.asset");

            if (File.Exists(modulesAssetPath))
            {
                args.Add($"--engine-modules-asset-file={CommandLineFormatter.PrepareFileName(modulesAssetPath)}");
            }

            var additionalArgs = System.Environment.GetEnvironmentVariable("UNITYLINKER_ADDITIONAL_ARGS");

            if (!string.IsNullOrEmpty(additionalArgs))
            {
                args.Add(additionalArgs);
            }

            additionalArgs = Debug.GetDiagnosticSwitch("VMUnityLinkerAdditionalArgs") as string;
            if (!string.IsNullOrEmpty(additionalArgs))
            {
                args.Add(additionalArgs.Trim('\''));
            }

            return(RunAssemblyLinker(args, out output, out error, linkerPath, workingDirectory));
        }