コード例 #1
0
    private void ReplaceAssembly(string assemblyDefinitionFilePath)
    {
        Debug.LogFormat("Replacing scripts for assembly definition file {0}", assemblyDefinitionFilePath);
        string   asmdefDirectory   = Path.GetDirectoryName(assemblyDefinitionFilePath);
        string   assemblyName      = Path.GetFileNameWithoutExtension(assemblyDefinitionFilePath);
        Assembly assemblyToReplace = CompilationPipeline.GetAssemblies().ToList().Find(assembly => assembly.name.ToLower().Equals(assemblyName.ToLower()));
        string   assemblyPath      = assemblyToReplace.outputPath;
        string   assemblyFileName  = Path.GetFileName(assemblyPath);

        string[] assemblyFilePathInAssets = Directory.GetFiles("./Assets", assemblyFileName, SearchOption.AllDirectories);

        // save the guid/classname correspondance of the scripts that we will remove
        Dictionary <string, string> oldGUIDToClassNameMap = new Dictionary <string, string>();

        if (assemblyFilePathInAssets.Length <= 0)
        {
            // Move all script files outside the asset folder
            foreach (string sourceFile in assemblyToReplace.sourceFiles)
            {
                string tempScriptPath = Path.Combine(TempSourceFilePath, sourceFile);
                Directory.CreateDirectory(Path.GetDirectoryName(tempScriptPath));
                if (!File.Exists(sourceFile))
                {
                    Debug.LogErrorFormat("File {0} does not exist while the assembly {1} references it.", sourceFile, assemblyToReplace.name);
                }
                Debug.Log("will move " + sourceFile + " to " + tempScriptPath);
                // save the guid of the file because we may need to replace it later
                MonoScript monoScript = AssetDatabase.LoadAssetAtPath <MonoScript>(sourceFile);
                if (monoScript != null && monoScript.GetClass() != null)
                {
                    oldGUIDToClassNameMap.Add(AssetDatabase.AssetPathToGUID(sourceFile), monoScript.GetClass().FullName);
                }
                FileUtil.MoveFileOrDirectory(sourceFile, tempScriptPath);
            }

            Debug.Log("Map of GUID/Class : \n" + String.Join("\n", oldGUIDToClassNameMap.Select(pair => pair.Key + " : " + pair.Value).ToArray()));

            string finalAssemblyPath = Path.Combine(asmdefDirectory, assemblyFileName);
            Debug.Log("will move " + assemblyPath + " to " + finalAssemblyPath);
            FileUtil.MoveFileOrDirectory(assemblyPath, finalAssemblyPath);
            string tempAsmdefPath = Path.Combine(TempSourceFilePath, Path.GetFileName(assemblyDefinitionFilePath));
            Debug.Log("will move " + assemblyDefinitionFilePath + " to " + tempAsmdefPath);
            FileUtil.MoveFileOrDirectory(assemblyDefinitionFilePath, tempAsmdefPath);
            // Rename the asmdef meta file to the dll meta file so that the dll guid stays the same
            FileUtil.MoveFileOrDirectory(assemblyDefinitionFilePath + ".meta", finalAssemblyPath + ".meta");
            pathsOfAssemblyFilesInAssetFolder.Add(finalAssemblyPath);
            pathsOfAssemblyFilesCreatedByUnity.Add(assemblyPath);


            // We need to refresh before accessing the assets in the new assembly
            AssetDatabase.Refresh();


            // We need to remove .\ when using LoadAsslAssetsAtPath
            string cleanFinalAssemblyPath = finalAssemblyPath.Replace(".\\", "");
            var    assetsInAssembly       = AssetDatabase.LoadAllAssetsAtPath(cleanFinalAssemblyPath);

            // list all components in the assembly file.
            var assemblyObjects = assetsInAssembly.OfType <MonoScript>().ToArray();

            // save the new GUID and file ID for the MonoScript in the new assembly
            Dictionary <string, KeyValuePair <string, long> > newMonoScriptToIDsMap = new Dictionary <string, KeyValuePair <string, long> >();
            // for each component, replace the guid and fileID file
            for (var i = 0; i < assemblyObjects.Length; i++)
            {
                long   dllFileId;
                string dllGuid = null;
                if (AssetDatabase.TryGetGUIDAndLocalFileIdentifier(assemblyObjects[i], out dllGuid, out dllFileId))
                {
                    string fullClassName = assemblyObjects[i].GetClass().FullName;
                    newMonoScriptToIDsMap.Add(fullClassName, new KeyValuePair <string, long>(dllGuid, dllFileId));
                }
            }

            Debug.Log("Map of Class/GUID:FILEID : \n" + String.Join("\n", newMonoScriptToIDsMap.Select(pair => pair.Key + " : " + pair.Value.Key + " - " + pair.Value.Value).ToArray()));

            ReplaceIdsInAssets(oldGUIDToClassNameMap, newMonoScriptToIDsMap);
        }


        else
        {
            Debug.Log("Already found an assembly file named " + assemblyFileName + " in asset folder");
        }
    }
コード例 #2
0
 public IEnumerable <Assembly> GetAssemblies(Func <string, bool> shouldFileBePartOfSolution)
 {
     // CompilationPipeline.GetAssemblies(AssembliesType.Player).Where(i => 0 < i.sourceFiles.Length && i.sourceFiles.Any(shouldFileBePartOfSolution));
     return(CompilationPipeline.GetAssemblies().Where(i => 0 < i.sourceFiles.Length && i.sourceFiles.Any(shouldFileBePartOfSolution)));
 }
コード例 #3
0
        private Dictionary <string, CSProjectInfo> CreateUnityProjects(string projectOutputPath)
        {
            // Not all of these will be converted to C# objects, only the ones found to be referenced
            Dictionary <string, AssemblyDefinitionInfo> asmDefInfoMap = new Dictionary <string, AssemblyDefinitionInfo>();
            HashSet <string> builtInPackagesWithoutSource             = new HashSet <string>();

            // Parse the builtInPackagesFirst
            DirectoryInfo builtInPackagesDirectory = new DirectoryInfo(Utilities.BuiltInPackagesPath);

            foreach (DirectoryInfo packageDirectory in builtInPackagesDirectory.GetDirectories())
            {
                FileInfo[] asmDefFiles = packageDirectory.GetFiles("*.asmdef", SearchOption.AllDirectories);

                if (asmDefFiles.Length == 0)
                {
                    builtInPackagesWithoutSource.Add(packageDirectory.Name.ToLower());
                    continue;
                }

                foreach (FileInfo fileInfo in asmDefFiles)
                {
                    AssemblyDefinitionInfo assemblyDefinitionInfo = AssemblyDefinitionInfo.Parse(fileInfo, this, null, true);
                    asmDefInfoMap.Add(Path.GetFileNameWithoutExtension(fileInfo.Name), assemblyDefinitionInfo);
                }
            }

            Dictionary <string, Assembly>      unityAssemblies = CompilationPipeline.GetAssemblies().ToDictionary(t => t.name);
            Dictionary <string, CSProjectInfo> projectsMap     = new Dictionary <string, CSProjectInfo>();
            Queue <string> projectsToProcess = new Queue <string>();

            // Parse the unity assemblies
            foreach (KeyValuePair <string, Assembly> pair in unityAssemblies)
            {
                if (!asmDefInfoMap.TryGetValue(pair.Key, out AssemblyDefinitionInfo assemblyDefinitionInfo))
                {
                    string asmDefPath = CompilationPipeline.GetAssemblyDefinitionFilePathFromAssemblyName(pair.Key);
                    if (string.IsNullOrEmpty(asmDefPath))
                    {
                        if (!pair.Key.StartsWith("Assembly-CSharp"))
                        {
                            throw new InvalidOperationException($"Failed to retrieve AsmDef for script assembly: {pair.Key}");
                        }

                        assemblyDefinitionInfo = AssemblyDefinitionInfo.GetDefaultAssemblyCSharpInfo(pair.Value);
                        projectsToProcess.Enqueue(pair.Key);
                    }
                    else
                    {
                        assemblyDefinitionInfo = AssemblyDefinitionInfo.Parse(new FileInfo(Utilities.GetFullPathFromKnownRelative(asmDefPath)), this, pair.Value);

                        if (asmDefPath.StartsWith("Assets/"))
                        {
                            // Add as mandatory
                            projectsToProcess.Enqueue(pair.Key);
                        }
                    }

                    asmDefInfoMap.Add(pair.Key, assemblyDefinitionInfo);
                }
            }

            while (projectsToProcess.Count > 0)
            {
                string projectKey = projectsToProcess.Dequeue();

                if (!projectsMap.ContainsKey(projectKey))
                {
                    GetProjectInfo(projectsMap, asmDefInfoMap, builtInPackagesWithoutSource, projectKey, projectOutputPath);
                }
            }

            // Ignore test projects when generating docs with Unity 2019
#if UNITY_2019_3_OR_NEWER
            projectsMap.Remove("Microsoft.MixedReality.Toolkit.Tests.EditModeTests");
            projectsMap.Remove("Microsoft.MixedReality.Toolkit.Tests.PlayModeTests");
#endif
            return(projectsMap);
        }
コード例 #4
0
        private void OnPostBuildPlayerScriptDLLsImpl(BuildReport report)
        {
            BurstPlatformAotSettings aotSettingsForTarget = BurstPlatformAotSettings.GetOrCreateSettings(report.summary.platform);

            // Early exit if burst is not activated or the platform is not supported
            if (aotSettingsForTarget.DisableBurstCompilation || !IsSupportedPlatform(report.summary.platform))
            {
                return;
            }

            // Collect all method signatures
            var methodsToCompile = BurstReflection.FindExecuteMethods(AssembliesType.Player);

            if (methodsToCompile.Count == 0)
            {
                return; // Nothing to do
            }

            // Prepare options

            // We are grouping methods per their compiler options (float precision...etc)
            var methodGroups = new Dictionary <string, List <string> >();

            for (var i = 0; i < methodsToCompile.Count; i++)
            {
                var burstCompileTarget = methodsToCompile[i];
                if (!burstCompileTarget.IsSupported)
                {
                    continue;
                }

                var methodStr           = BurstCompilerService.GetMethodSignature(burstCompileTarget.Method);
                var methodFullSignature = methodStr + "--" + Hash128.Compute(methodStr);

                if (aotSettingsForTarget.DisableOptimisations)
                {
                    burstCompileTarget.Options.DisableOptimizations = true;
                }

                burstCompileTarget.Options.EnableBurstSafetyChecks = !aotSettingsForTarget.DisableSafetyChecks;

                string optionsAsStr;
                if (burstCompileTarget.TryGetOptionsAsString(false, out optionsAsStr))
                {
                    List <string> methodOptions;
                    if (!methodGroups.TryGetValue(optionsAsStr, out methodOptions))
                    {
                        methodOptions = new List <string>();
                        methodGroups.Add(optionsAsStr, methodOptions);
                    }
                    methodOptions.Add(GetOption(OptionAotMethod, methodFullSignature));
                }
            }

            var methodGroupOptions = new List <string>();

            // We should have something like this in the end:
            //
            // --group                1st group of method with the following shared options
            // --float-mode=xxx
            // --method=...
            // --method=...
            //
            // --group                2nd group of methods with the different shared options
            // --float-mode=yyy
            // --method=...
            // --method=...
            if (methodGroups.Count == 1)
            {
                var methodGroup = methodGroups.FirstOrDefault();
                // No need to create a group if we don't have multiple
                methodGroupOptions.Add(methodGroup.Key);
                foreach (var methodOption in methodGroup.Value)
                {
                    methodGroupOptions.Add(methodOption);
                }
            }
            else
            {
                foreach (var methodGroup in methodGroups)
                {
                    methodGroupOptions.Add(GetOption(OptionGroup));
                    methodGroupOptions.Add(methodGroup.Key);
                    foreach (var methodOption in methodGroup.Value)
                    {
                        methodGroupOptions.Add(methodOption);
                    }
                }
            }

            var commonOptions  = new List <string>();
            var targetCpu      = TargetCpu.Auto;
            var targetPlatform = GetTargetPlatformAndDefaultCpu(report.summary.platform, out targetCpu);

            commonOptions.Add(GetOption(OptionPlatform, targetPlatform));

            // TODO: Add support for configuring the optimizations/CPU
            // TODO: Add support for per method options

            var stagingFolder = Path.GetFullPath(TempStagingManaged);
            //Debug.Log($"Burst CompileAot - To Folder {stagingFolder}");

            // Prepare assembly folder list
            var assemblyFolders = new List <string>();

            assemblyFolders.Add(stagingFolder);

            var playerAssemblies = CompilationPipeline.GetAssemblies(AssembliesType.Player);

            foreach (var assembly in playerAssemblies)
            {
                foreach (var assemblyRef in assembly.compiledAssemblyReferences)
                {
                    // Exclude folders with assemblies already compiled in the `folder`
                    var assemblyName = Path.GetFileName(assemblyRef);
                    if (assemblyName != null && File.Exists(Path.Combine(stagingFolder, assemblyName)))
                    {
                        continue;
                    }

                    var directory = Path.GetDirectoryName(assemblyRef);
                    if (directory != null)
                    {
                        var fullPath = Path.GetFullPath(directory);
                        if (IsMonoReferenceAssemblyDirectory(fullPath) || IsDotNetStandardAssemblyDirectory(fullPath))
                        {
                            // Don't pass reference assemblies to burst because they contain methods without implementation
                            // If burst accidentally resolves them, it will emit calls to burst_abort.
                            fullPath = Path.Combine(EditorApplication.applicationContentsPath, "MonoBleedingEdge/lib/mono/unityaot");
                            fullPath = Path.GetFullPath(fullPath); // GetFullPath will normalize path separators to OS native format
                            if (!assemblyFolders.Contains(fullPath))
                            {
                                assemblyFolders.Add(fullPath);
                            }

                            fullPath = Path.Combine(fullPath, "Facades");
                            if (!assemblyFolders.Contains(fullPath))
                            {
                                assemblyFolders.Add(fullPath);
                            }
                        }
                        else if (!assemblyFolders.Contains(fullPath))
                        {
                            assemblyFolders.Add(fullPath);
                        }
                    }
                }
            }

            commonOptions.AddRange(assemblyFolders.Select(folder => GetOption(OptionAotAssemblyFolder, folder)));

            var combinations = new List <BurstOutputCombination>();

            if (targetPlatform == TargetPlatform.macOS)
            {
                // NOTE: OSX has a special folder for the plugin
                // Declared in GetStagingAreaPluginsFolder
                // PlatformDependent\OSXPlayer\Extensions\Managed\OSXDesktopStandalonePostProcessor.cs
                combinations.Add(new BurstOutputCombination("UnityPlayer.app/Contents/Plugins", targetCpu));
            }
            else if (targetPlatform == TargetPlatform.iOS)
            {
                if (Application.platform != RuntimePlatform.OSXEditor)
                {
                    Debug.LogWarning("Burst Cross Compilation to iOS for standalone player, is only supported on OSX Editor at this time, burst is disabled for this build.");
                }
                else
                {
                    var targetArchitecture = (IOSArchitecture)UnityEditor.PlayerSettings.GetArchitecture(report.summary.platformGroup);
                    if (targetArchitecture == IOSArchitecture.ARMv7 || targetArchitecture == IOSArchitecture.Universal)
                    {
                        // PlatformDependent\iPhonePlayer\Extensions\Common\BuildPostProcessor.cs
                        combinations.Add(new BurstOutputCombination("StaticLibraries", TargetCpu.ARMV7A_NEON32, DefaultLibraryName + "32"));
                    }
                    if (targetArchitecture == IOSArchitecture.ARM64 || targetArchitecture == IOSArchitecture.Universal)
                    {
                        // PlatformDependent\iPhonePlayer\Extensions\Common\BuildPostProcessor.cs
                        combinations.Add(new BurstOutputCombination("StaticLibraries", TargetCpu.ARMV8A_AARCH64, DefaultLibraryName + "64"));
                    }
                }
            }
            else if (targetPlatform == TargetPlatform.Android)
            {
                //TODO: would be better to query AndroidNdkRoot (but thats not exposed from unity)
                string ndkRoot = null;

                // 2019.1 now has an embedded ndk
#if UNITY_2019_1_OR_NEWER
                if (EditorPrefs.HasKey("NdkUseEmbedded"))
                {
                    if (EditorPrefs.GetBool("NdkUseEmbedded"))
                    {
                        ndkRoot = Path.Combine(BuildPipeline.GetPlaybackEngineDirectory(BuildTarget.Android, BuildOptions.None), "NDK");
                    }
                    else
                    {
                        ndkRoot = EditorPrefs.GetString("AndroidNdkRootR16b");
                    }
                }
#endif

                // If we still don't have a valid root, try the old key
                if (string.IsNullOrEmpty(ndkRoot))
                {
                    ndkRoot = EditorPrefs.GetString("AndroidNdkRoot");
                }


                // Verify the directory at least exists, if not we fall back to ANDROID_NDK_ROOT current setting
                if (!string.IsNullOrEmpty(ndkRoot) && !Directory.Exists(ndkRoot))
                {
                    ndkRoot = null;
                }

                // Always set the ANDROID_NDK_ROOT (if we got a valid result from above), so BCL knows where to find the Android toolchain and its the one the user expects
                if (!string.IsNullOrEmpty(ndkRoot))
                {
                    Environment.SetEnvironmentVariable("ANDROID_NDK_ROOT", ndkRoot);
                }

                var androidTargetArch = UnityEditor.PlayerSettings.Android.targetArchitectures;
                if ((androidTargetArch & AndroidArchitecture.ARMv7) != 0)
                {
                    combinations.Add(new BurstOutputCombination("libs/armeabi-v7a", TargetCpu.ARMV7A_NEON32));
                }
                if ((androidTargetArch & AndroidArchitecture.ARM64) != 0)
                {
                    combinations.Add(new BurstOutputCombination("libs/arm64-v8a", TargetCpu.ARMV8A_AARCH64));
                }
#if !UNITY_2019_2_OR_NEWER
                if ((androidTargetArch & AndroidArchitecture.X86) != 0)
                {
                    combinations.Add(new BurstOutputCombination("libs/x86", TargetCpu.X86_SSE2));
                }
#endif
            }
            else if (targetPlatform == TargetPlatform.UWP)
            {
                // TODO: Make it configurable for x86 (sse2, sse4)
                combinations.Add(new BurstOutputCombination("Plugins/x64", TargetCpu.X64_SSE4));
                combinations.Add(new BurstOutputCombination("Plugins/x86", TargetCpu.X86_SSE2));
                combinations.Add(new BurstOutputCombination("Plugins/ARM", TargetCpu.THUMB2_NEON32));
                combinations.Add(new BurstOutputCombination("Plugins/ARM64", TargetCpu.ARMV8A_AARCH64));
            }
            else
            {
                combinations.Add(new BurstOutputCombination("Data/Plugins/", targetCpu));
            }

            foreach (var combination in combinations)
            {
                // Gets the output folder
                var stagingOutputFolder = Path.GetFullPath(Path.Combine(TempStaging, combination.OutputPath));
                var outputFilePrefix    = Path.Combine(stagingOutputFolder, combination.LibraryName);

                var options = new List <string>(commonOptions);
                options.Add(GetOption(OptionAotOutputPath, outputFilePrefix));
                options.Add(GetOption(OptionTarget, combination.TargetCpu));

                if (targetPlatform == TargetPlatform.iOS)
                {
                    options.Add(GetOption(OptionStaticLinkage));
                }

                // finally add method group options
                options.AddRange(methodGroupOptions);

                var responseFile = Path.GetTempFileName();
                File.WriteAllLines(responseFile, options);

                //Debug.Log("Burst compile with response file: " + responseFile);

                try
                {
                    string generatedDebugInformationInOutput = "";
                    if ((report.summary.options & BuildOptions.Development) != 0)
                    {
                        // Workaround for clang >6 development issue (due to latest being 7.0.0) - IOS & newer PS4 SDKS are affected because its a source level IR compatability issue
                        if ((targetPlatform != TargetPlatform.iOS) && (targetPlatform != TargetPlatform.PS4))
                        {
                            generatedDebugInformationInOutput = GetOption(OptionDebug);
                        }
                    }

                    BclRunner.RunManagedProgram(Path.Combine(BurstLoader.RuntimePath, BurstAotCompilerExecutable),
                                                $"{generatedDebugInformationInOutput} @{responseFile}",
                                                new BclOutputErrorParser(),
                                                report);
                }
                catch (Exception e)
                {
                    // We don't expect any error, but in case we have one, we identify that it is burst and we print the details here
                    Debug.LogError("Unexpected error while running the burst compiler: " + e);
                }
            }
        }
コード例 #5
0
        public IEnumerable <AssemblyInfo> Compile(IProgressBar progressBar = null)
        {
#if UNITY_2018_1_OR_NEWER
            var assemblies = CompilationPipeline.GetAssemblies(AssembliesType.Player);
#else
            var assemblies = CompilationPipeline.GetAssemblies();
#endif

#if UNITY_2018_2_OR_NEWER
            if (progressBar != null)
            {
                var numAssemblies = assemblies.Length;
                progressBar.Initialize("Assembly Compilation", "Compiling project scripts",
                                       numAssemblies);
                m_OnAssemblyCompilationStarted = (s) =>
                {
                    progressBar.AdvanceProgressBar(Path.GetFileName(s));
                };
                CompilationPipeline.assemblyCompilationStarted += m_OnAssemblyCompilationStarted;
            }
            CompilationPipeline.assemblyCompilationFinished += OnAssemblyCompilationFinished;

            m_OutputFolder = FileUtil.GetUniqueTempPathInProject();

            var input = new ScriptCompilationSettings
            {
                target = EditorUserBuildSettings.activeBuildTarget,
                group  = EditorUserBuildSettings.selectedBuildTargetGroup
            };

            var compilationResult = PlayerBuildInterface.CompilePlayerScripts(input, m_OutputFolder);

            if (progressBar != null)
            {
                progressBar.ClearProgressBar();
            }

            if (!m_Success)
            {
                Dispose();
                throw new AssemblyCompilationException();
            }

            var compiledAssemblyPaths = compilationResult.assemblies.Select(assembly => Path.Combine(m_OutputFolder, assembly));
#else
            // fallback to CompilationPipeline assemblies
            var compiledAssemblyPaths = CompilationPipeline.GetAssemblies()
                                        .Where(a => a.flags != AssemblyFlags.EditorAssembly).Select(assembly => assembly.outputPath);
#endif

            var assemblyInfos = new List <AssemblyInfo>();
            foreach (var compiledAssemblyPath in compiledAssemblyPaths)
            {
                var assemblyInfo = AssemblyHelper.GetAssemblyInfoFromAssemblyPath(compiledAssemblyPath);
                var assembly     = assemblies.First(a => a.name.Equals(assemblyInfo.name));
                var sourcePaths  = assembly.sourceFiles.Select(file => file.Remove(0, assemblyInfo.relativePath.Length + 1));

                assemblyInfo.sourcePaths = sourcePaths.ToArray();
                assemblyInfos.Add(assemblyInfo);
            }

            return(assemblyInfos);
        }
コード例 #6
0
        private static HashSet <string> GetReferencedAssemblyNameSet()
        {
            if (s_referencedAssemblyNameSet != null)
            {
                return(s_referencedAssemblyNameSet);
            }

            s_referencedAssemblyNameSet = new HashSet <string>();
            Assembly playerAssembly = typeof(VRModule).Assembly;
            Assembly editorAssembly = typeof(VRModuleManagerEditor).Assembly;

            // C# player referenced assemblies
            foreach (AssemblyName asmName in playerAssembly.GetReferencedAssemblies())
            {
                s_referencedAssemblyNameSet.Add(asmName.Name);
            }

            // C# editor referenced assemblies
            foreach (AssemblyName asmName in editorAssembly.GetReferencedAssemblies())
            {
                s_referencedAssemblyNameSet.Add(asmName.Name);
            }

#if UNITY_2018_1_OR_NEWER
            // Unity player referenced assemblies
            UnityEditor.Compilation.Assembly playerUnityAsm = FindUnityAssembly(playerAssembly.GetName().Name, AssembliesType.Player);
            if (playerUnityAsm != null)
            {
                foreach (UnityEditor.Compilation.Assembly asm in playerUnityAsm.assemblyReferences)
                {
                    s_referencedAssemblyNameSet.Add(asm.name);
                }
            }
            else
            {
                Debug.LogWarning("Player assembly not found.");
            }

            // Unity editor referenced assemblies
            UnityEditor.Compilation.Assembly editorUnityAsm = FindUnityAssembly(editorAssembly.GetName().Name, AssembliesType.Editor);
            if (editorUnityAsm != null)
            {
                foreach (UnityEditor.Compilation.Assembly asm in editorUnityAsm.assemblyReferences)
                {
                    s_referencedAssemblyNameSet.Add(asm.name);
                }
            }
            else
            {
                Debug.LogWarning("Editor assembly not found.");
            }
#elif UNITY_2017_3_OR_NEWER
            UnityEditor.Compilation.Assembly[] assemblies = CompilationPipeline.GetAssemblies();
            foreach (UnityEditor.Compilation.Assembly asm in assemblies)
            {
                s_referencedAssemblyNameSet.Add(asm.name);
            }
#endif

            return(s_referencedAssemblyNameSet);
        }
コード例 #7
0
        public void OnPostBuildPlayerScriptDLLs(BuildReport report)
        {
            BurstPlatformAotSettings aotSettingsForTarget = BurstPlatformAotSettings.GetOrCreateSettings(report.summary.platform);

            // Early exit if burst is not activated or the platform is not supported
            if (aotSettingsForTarget.DisableBurstCompilation || !IsSupportedPlatform(report.summary.platform))
            {
                return;
            }

            // Collect all method signatures
            var methodsToCompile = BurstReflection.FindExecuteMethods(AssembliesType.Player);

            if (methodsToCompile.Count == 0)
            {
                return; // Nothing to do
            }

            // Prepare options
            var commonOptions = new List <string>();

            for (var i = 0; i < methodsToCompile.Count; i++)
            {
                var burstCompileTarget = methodsToCompile[i];
                if (!burstCompileTarget.SupportsBurst)
                {
                    continue;
                }

                var methodStr           = BurstCompilerService.GetMethodSignature(burstCompileTarget.Method);
                var methodFullSignature = methodStr + "--" + Hash128.Compute(methodStr);
                commonOptions.Add(GetOption(OptionAotMethod, methodFullSignature));
            }

            var targetCpu      = TargetCpu.Auto;
            var targetPlatform = GetTargetPlatformAndDefaultCpu(report.summary.platform, out targetCpu);

            commonOptions.Add(GetOption(OptionPlatform, targetPlatform));

            if (!BurstEditorOptions.EnableBurstSafetyChecks)
            {
                commonOptions.Add(GetOption(OptionDisableSafetyChecks));
            }

            // TODO: Add support for configuring the optimizations/CPU
            // TODO: Add support for per method options

            var stagingFolder = Path.GetFullPath(TempStagingManaged);
            //Debug.Log($"Burst CompileAot - To Folder {stagingFolder}");

            // Prepare assembly folder list
            var assemblyFolders = new List <string>();

            assemblyFolders.Add(stagingFolder);

            var playerAssemblies = CompilationPipeline.GetAssemblies(AssembliesType.Player);

            foreach (var assembly in playerAssemblies)
            {
                foreach (var assemblyRef in assembly.compiledAssemblyReferences)
                {
                    // Exclude folders with assemblies already compiled in the `folder`
                    var assemblyName = Path.GetFileName(assemblyRef);
                    if (assemblyName != null && File.Exists(Path.Combine(stagingFolder, assemblyName)))
                    {
                        continue;
                    }

                    var directory = Path.GetDirectoryName(assemblyRef);
                    if (directory != null)
                    {
                        var fullPath = Path.GetFullPath(directory);
                        if (IsMonoReferenceAssemblyDirectory(fullPath) || IsDotNetStandardAssemblyDirectory(fullPath))
                        {
                            // Don't pass reference assemblies to burst because they contain methods without implementation
                            // If burst accidentally resolves them, it will emit calls to burst_abort.
                            fullPath = Path.Combine(EditorApplication.applicationContentsPath, "MonoBleedingEdge/lib/mono/unityaot");
                            fullPath = Path.GetFullPath(fullPath); // GetFullPath will normalize path separators to OS native format
                            if (!assemblyFolders.Contains(fullPath))
                            {
                                assemblyFolders.Add(fullPath);
                            }

                            fullPath = Path.Combine(fullPath, "Facades");
                            if (!assemblyFolders.Contains(fullPath))
                            {
                                assemblyFolders.Add(fullPath);
                            }
                        }
                        else if (!assemblyFolders.Contains(fullPath))
                        {
                            assemblyFolders.Add(fullPath);
                        }
                    }
                }
            }

            commonOptions.AddRange(assemblyFolders.Select(folder => GetOption(OptionAotAssemblyFolder, folder)));

            // Gets platform specific IL2CPP plugin folder
            // Only the following platforms are providing a dedicated Tools directory
            switch (report.summary.platform)
            {
            case BuildTarget.XboxOne:
            case BuildTarget.PS4:
            case BuildTarget.Android:
            case BuildTarget.iOS:
                var pluginFolder = BuildPipeline.GetBuildToolsDirectory(report.summary.platform);
                commonOptions.Add(GetOption(OptionAotIL2CPPPluginFolder, pluginFolder));
                break;
            }

            var combinations = new List <BurstOutputCombination>();

            if (targetPlatform == TargetPlatform.macOS)
            {
                // NOTE: OSX has a special folder for the plugin
                // Declared in GetStagingAreaPluginsFolder
                // PlatformDependent\OSXPlayer\Extensions\Managed\OSXDesktopStandalonePostProcessor.cs
                combinations.Add(new BurstOutputCombination("UnityPlayer.app/Contents/Plugins", targetCpu));
            }
            else if (targetPlatform == TargetPlatform.iOS)
            {
                var targetArchitecture = (IOSArchitecture)UnityEditor.PlayerSettings.GetArchitecture(report.summary.platformGroup);
                if (targetArchitecture == IOSArchitecture.ARMv7 || targetArchitecture == IOSArchitecture.Universal)
                {
                    // PlatformDependent\iPhonePlayer\Extensions\Common\BuildPostProcessor.cs
                    combinations.Add(new BurstOutputCombination("StaticLibraries", TargetCpu.ARMV7A_NEON32, DefaultLibraryName + "32"));
                }
                if (targetArchitecture == IOSArchitecture.ARM64 || targetArchitecture == IOSArchitecture.Universal)
                {
                    // PlatformDependent\iPhonePlayer\Extensions\Common\BuildPostProcessor.cs
                    combinations.Add(new BurstOutputCombination("StaticLibraries", TargetCpu.ARMV8A_AARCH64, DefaultLibraryName + "64"));
                }
            }
            else if (targetPlatform == TargetPlatform.Android)
            {
                // Set the ANDROID_NDK_ROOT so IL2CPP knows where to find the Android toolchain
                if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("ANDROID_NDK_ROOT")))
                {
                    var ndkRoot = EditorPrefs.GetString("AndroidNdkRoot");
                    if (!string.IsNullOrEmpty(ndkRoot))
                    {
                        Environment.SetEnvironmentVariable("ANDROID_NDK_ROOT", ndkRoot);
                    }
                }

                var androidTargetArch = UnityEditor.PlayerSettings.Android.targetArchitectures;
                if ((androidTargetArch & AndroidArchitecture.ARMv7) != 0)
                {
                    combinations.Add(new BurstOutputCombination("libs/armeabi-v7a", TargetCpu.ARMV7A_NEON32));
                }
                if ((androidTargetArch & AndroidArchitecture.ARM64) != 0)
                {
                    combinations.Add(new BurstOutputCombination("libs/arm64-v8a", TargetCpu.ARMV8A_AARCH64));
                }
                if ((androidTargetArch & AndroidArchitecture.X86) != 0)
                {
                    combinations.Add(new BurstOutputCombination("libs/x86", TargetCpu.X86_SSE2));
                }
            }
            else if (targetPlatform == TargetPlatform.UWP)
            {
                // TODO: Make it configurable for x86 (sse2, sse4)
                combinations.Add(new BurstOutputCombination("Plugins/x64", TargetCpu.X64_SSE4));
                combinations.Add(new BurstOutputCombination("Plugins/x86", TargetCpu.X86_SSE2));
                combinations.Add(new BurstOutputCombination("Plugins/ARM", TargetCpu.THUMB2_NEON32));
                combinations.Add(new BurstOutputCombination("Plugins/ARM64", TargetCpu.ARMV8A_AARCH64));
            }
            else
            {
                combinations.Add(new BurstOutputCombination("Data/Plugins/", targetCpu));
            }

            foreach (var combination in combinations)
            {
                // Gets the output folder
                var stagingOutputFolder = Path.GetFullPath(Path.Combine(TempStaging, combination.OutputPath));
                var outputFilePrefix    = Path.Combine(stagingOutputFolder, combination.LibraryName);

                var options = new List <string>(commonOptions);
                options.Add(GetOption(OptionAotOutputPath, outputFilePrefix));
                options.Add(GetOption(OptionTarget, combination.TargetCpu));

                if (aotSettingsForTarget.DisableOptimisations)
                {
                    options.Add(GetOption(OptionDisableOpt));
                }
                if (aotSettingsForTarget.DisableSafetyChecks)
                {
                    options.Add(GetOption(OptionDisableSafetyChecks));
                }
                else
                {
                    options.Add(GetOption(OptionSafetyChecks));
                }

                if (targetPlatform == TargetPlatform.iOS)
                {
                    options.Add(GetOption(OptionStaticLinkage));
                }

                var responseFile = Path.GetTempFileName();
                File.WriteAllLines(responseFile, options);

                //Debug.Log("Burst compile with response file: " + responseFile);

                try
                {
                    Runner.RunManagedProgram(Path.Combine(BurstLoader.RuntimePath, BurstAotCompilerExecutable), "--debug=true " + "@" + responseFile, Application.dataPath + "/..", new BclParser(), null);
                }
                catch (Exception e)
                {
                    Debug.LogError(e.ToString());
                }
            }
        }
コード例 #8
0
        static void BuildTypeTreeTools()
        {
            var settings = new XmlWriterSettings
            {
                OmitXmlDeclaration = true,
                Indent             = true,
                IndentChars        = "  ",
            };

            using (var xw = XmlWriter.Create(Path.Combine(ProjectDirectory, "Generated.props"), settings))
            {
                xw.WriteStartDocument();
                xw.WriteStartElement("Project");
                xw.WriteStartElement("PropertyGroup");

                var version = Application.unityVersion;
                var split   = Application.unityVersion.Split(VersionSplitChars, StringSplitOptions.RemoveEmptyEntries);
                xw.WriteStartElement("EditorVersion");
                xw.WriteString(version);
                xw.WriteEndElement();
                xw.WriteStartElement("EditorVersionMajor");
                xw.WriteString(split[0]);
                xw.WriteEndElement();
                xw.WriteStartElement("EditorVersionMinor");
                xw.WriteString(split[1]);
                xw.WriteEndElement();

                xw.WriteStartElement("EditorContentsDir");
                xw.WriteString(EditorApplication.applicationContentsPath);
                xw.WriteEndElement();

                foreach (var assembly in CompilationPipeline.GetAssemblies())
                {
                    if (assembly.name != "Assembly-CSharp-Editor")
                    {
                        continue;
                    }

                    var defines = string.Join(";", assembly.defines);
                    xw.WriteStartElement("DefineConstants");
                    xw.WriteString(defines);
                    xw.WriteEndElement();
                    xw.WriteEndElement();

                    xw.WriteStartElement("ItemGroup");
                    foreach (var reference in assembly.allReferences)
                    {
                        var name = Path.GetFileNameWithoutExtension(reference);
                        var path = Path.GetFullPath(reference);

                        if (name == ProjectName)
                        {
                            continue;
                        }

                        xw.WriteStartElement("Reference");
                        xw.WriteAttributeString("Private", bool.FalseString);
                        xw.WriteAttributeString("Include", name);
                        xw.WriteAttributeString("HintPath", path);
                        xw.WriteEndElement();
                    }
                }

                xw.WriteEndElement();
                xw.WriteEndElement();
                xw.WriteEndDocument();
            }

            var process = new Process
            {
                StartInfo = new ProcessStartInfo
                {
                    FileName         = "dotnet",
                    Arguments        = "build",
                    WorkingDirectory = ProjectDirectory
                }
            };

            process.Start();
            process.WaitForExit();
        }
コード例 #9
0
        public AssemblySelector(Options options)
        {
            if (options == null)
            {
                throw new ArgumentException("options must not be null", "options");
            }
            if (options.compiledAssemblies == null)
            {
                throw new ArgumentException(
                          "options.compiledAssemblies must not be null", "options");
            }
            if (options.assemblies == null)
            {
                throw new ArgumentException(
                          "options.assemblies must not be null", "options");
            }
            if (Application.dataPath == null)
            {
                throw new ArgumentException("Application.dataPath must not be null");
            }

            foreach (string assemblyName in options.compiledAssemblies)
            {
                _compiledAssemblyPaths.Add(FindDllLocation(assemblyName));
            }
            foreach (string assemblyName in options.assemblies)
            {
                _assemblyPaths.Add(FindDllLocation(assemblyName));
            }

#if UNITY_2017_3_OR_NEWER
            if (!options.includeCompilationPipelineAssemblies)
            {
                return;
            }

            string projectDir = Path.GetDirectoryName(Application.dataPath);

#if UNITY_2018_1_OR_NEWER
            foreach (UnityEditor.Compilation.Assembly assembly in CompilationPipeline.GetAssemblies(AssembliesType.Player))
            {
#else
            foreach (UnityEditor.Compilation.Assembly assembly in CompilationPipeline.GetAssemblies())
            {
                if ((assembly.flags & AssemblyFlags.EditorAssembly) != 0)
                {
                    continue;
                }
#endif
                if (assembly.name.Contains("-firstpass"))
                {
                    continue;
                }

                if (assembly.sourceFiles.Length == 0)
                {
                    continue;
                }

                if (assembly.sourceFiles[0].StartsWith("Packages"))
                {
                    continue;
                }

                string dllLocation = Path.Combine(projectDir, assembly.outputPath).Replace('\\', '/');

                // If the assembly is for a different build target platform, oddly it will still be in the compilation
                // pipeline, however the file won't actually exist.
                if (File.Exists(dllLocation))
                {
                    _assemblyPaths.Add(dllLocation);
                }
            }
#endif
        }
コード例 #10
0
        protected override AdvancedDropdownItem BuildRoot()
        {
            AdvancedDropdownItem root = new AdvancedDropdownItem("Assemblies");
            Dictionary <Group, AdvancedDropdownItem> groupDropdowns = new Dictionary <Group, AdvancedDropdownItem>(new Group.Comparer());

            var allAssemblies = AppDomain.CurrentDomain.GetAssemblies().OrderBy(assembly => assembly.FullName);

            // Populate Unity-compiled assemblies.
            // This includes assemblies in the Assets and Packages directories that are not plugins.
            UAssembly[] assemblies = CompilationPipeline.GetAssemblies();
            Dictionary <string, UAssembly> nameToAssembly = new Dictionary <string, UAssembly>();

            foreach (UAssembly assembly in assemblies)
            {
                nameToAssembly.Add(assembly.name, assembly);
            }

            // Append root locations
            foreach (Location location in Enum.GetValues(typeof(Location)))
            {
                var locationRoot = new AdvancedDropdownItem(location.ToString());
                root.AddChild(locationRoot);
                groupDropdowns.Add(new Group(location), locationRoot);
            }

            foreach (Assembly assembly in allAssemblies)
            {
                Group group = GetGroup(assembly, nameToAssembly);

                Type[]      types         = assembly.GetTypes();
                List <Type> filteredTypes = new List <Type>();
                foreach (Type type in types)
                {
                    bool requirementsMet = true;
                    foreach (Type constraint in constraints)
                    {
                        if (!type.IsSubclassOf(constraint) && type != constraint)
                        {
                            requirementsMet = false;
                        }
                    }

                    foreach (Type requiredInterface in requiredInterfaces)
                    {
                        if (!type.GetInterfaces().Contains(requiredInterface))
                        {
                            requirementsMet = false;
                        }
                    }

                    if (requirementsMet)
                    {
                        filteredTypes.Add(type);
                    }
                }

                if (filteredTypes.Count != 0)
                {
                    if (!groupDropdowns.TryGetValue(group, out AdvancedDropdownItem groupRoot))
                    {
                        groupDropdowns.Add(group, groupRoot = new AdvancedDropdownItem(group.Context));
                        groupDropdowns[new Group(group.Location)].AddChild(groupRoot);
                    }

                    string assemblyName         = assembly.GetName().Name;
                    var    assemblyDropdownItem = new AdvancedDropdownItem(assemblyName);
                    groupRoot.AddChild(assemblyDropdownItem);

                    foreach (Type type in filteredTypes)
                    {
                        assemblyDropdownItem.AddChild(new TypeDropdownItem(type));
                    }
                }
            }

            root.AddSeparator();

            AdvancedDropdownItem initializeOnLoad = new AdvancedDropdownItem("Initialize On Load");

            foreach (Type type in TypeCache.GetTypesWithAttribute <InitializeOnLoadAttribute>())
            {
                initializeOnLoad.AddChild(new TypeDropdownItem(type));
            }

            foreach (MethodInfo method in TypeCache.GetMethodsWithAttribute <InitializeOnLoadMethodAttribute>())
            {
                initializeOnLoad.AddChild(new TypeDropdownItem(method.DeclaringType));
            }

            root.AddChild(initializeOnLoad);

            AdvancedDropdownItem runtimeInitializeOnLoad = new AdvancedDropdownItem("Runtime Initialize On Load");

            foreach (MethodInfo method in TypeCache.GetMethodsWithAttribute <RuntimeInitializeOnLoadMethodAttribute>())
            {
                runtimeInitializeOnLoad.AddChild(new TypeDropdownItem(method.DeclaringType));
            }

            root.AddChild(runtimeInitializeOnLoad);

            return(root);
        }
コード例 #11
0
        static DateTime GetAssemblyBuildTime(string assemblyName)
        {
            var assembly = CompilationPipeline.GetAssemblies(AssembliesType.PlayerWithoutTestAssemblies).FirstOrDefault(a => a.name == assemblyName);

            return(assembly != null?File.GetLastWriteTimeUtc(assembly.outputPath) : DateTime.MinValue);
        }
コード例 #12
0
        private static void TryWeaveAssembly(string assPath)
        {
            //check if assembly is editor only for applying the InitializeOnLoadMethodAttribute method instead of RuntimeInitializeOnLoadMethodAttribute.
            //used mainly assemblies that run tests.
            bool isEditor = CompilationPipeline.GetAssemblies().Any(a => a.flags == AssemblyFlags.EditorAssembly && assPath.EndsWith(a.outputPath));

            using (var assembly = AssemblyDefinition.ReadAssembly(assPath, new ReaderParameters()
            {
                ReadWrite = true,
                ReadingMode = ReadingMode.Immediate,
                AssemblyResolver = new DefaultAssemblyResolver(),
                SymbolReaderProvider = new PdbReaderProvider(),
                //need to keep it in memory so we can write it back to the file. Otherwise it throws a sharing violation.
                InMemory = true,
                ReadSymbols = true
            }))
            {
                var sourceModule    = assembly.MainModule;
                var injectionModule = assembly.MainModule;

                var attributeType      = isEditor ? typeof(InitializeOnLoadMethodAttribute) : typeof(RuntimeInitializeOnLoadMethodAttribute);
                var construction       = injectionModule.ImportReference(attributeType.GetConstructor(Type.EmptyTypes));
                var customAttribute    = new CustomAttribute(injectionModule.ImportReference(construction));
                var containerParameter = new ParameterDefinition("container", ParameterAttributes.None,
                                                                 injectionModule.ImportReference(typeof(Container)));

                var constructorTypes = new List <TypeDefinition>();
                var injectionTypes   = new List <TypeDefinition>();

                foreach (var type in sourceModule.GetTypes())
                {
                    var injectRef = sourceModule.ImportReference(typeof(InjectAttribute));
                    if (NeedsConstructor(type, injectRef))
                    {
                        constructorTypes.Add(type);
                        Debug.Log($"Baking Factory for type: {type.FullName}");
                    }

                    if (NeedsFields(type, injectRef))
                    {
                        injectionTypes.Add(type);
                        Debug.Log($"Baking Injector for type: {type.FullName}");
                    }
                }

                if (constructorTypes.Count > 0)
                {
                    var injectAttributeRef = injectionModule.ImportReference(typeof(InjectAttribute));
                    var factoryMethods     = new List <KeyValuePair <TypeReference, MethodDefinition> >();
                    var injectionMethods   = new List <KeyValuePair <TypeReference, MethodDefinition> >();

                    //type where all static injection baking processing is done.
                    var typeAdder = new TypeDefinition("Injection", "Baker",
                                                       TypeAttributes.Class | TypeAttributes.Public, injectionModule.TypeSystem.Object);
                    injectionModule.Types.Add(typeAdder);

                    //method where all registration is done.
                    var bakerMethod = new MethodDefinition("BakeInjection",
                                                           MethodAttributes.Static | MethodAttributes.Private | MethodAttributes.HideBySig,
                                                           injectionModule.TypeSystem.Void);
                    typeAdder.Methods.Add(bakerMethod);

                    //create factories for constructor marked with the inject attribute.
                    foreach (var type in constructorTypes)
                    {
                        ExposeType(type);

                        var typeRef       = injectionModule.ImportReference(type);
                        var factoryMethod = new MethodDefinition(type.Name + "FactoryMethod",
                                                                 MethodAttributes.Static | MethodAttributes.Assembly,
                                                                 injectionModule.TypeSystem.Object);

                        factoryMethod.Parameters.Add(containerParameter);
                        type.Methods.Add(factoryMethod);
                        CreateFactoryMethodBody(factoryMethod, type, injectionModule, injectAttributeRef);
                        factoryMethods.Add(new KeyValuePair <TypeReference, MethodDefinition>(typeRef, factoryMethod));
                    }

                    //create injection static methods that resolve each field marked with inject attribute.
                    foreach (var type in injectionTypes)
                    {
                        ExposeType(type);

                        var typeRef         = injectionModule.ImportReference(type);
                        var injectionMethod = new MethodDefinition(type.Name + "InjectionMethod",
                                                                   MethodAttributes.Static | MethodAttributes.Assembly,
                                                                   injectionModule.TypeSystem.Void);
                        injectionMethod.Parameters.Add(new ParameterDefinition("instance", ParameterAttributes.None, injectionModule.TypeSystem.Object));
                        injectionMethod.Parameters.Add(containerParameter);
                        type.Methods.Add(injectionMethod);
                        CreateInjectionMethodBody(injectionMethod, type, injectionModule, injectAttributeRef);
                        injectionMethods.Add(new KeyValuePair <TypeReference, MethodDefinition>(typeRef, injectionMethod));
                    }

                    CreateBakeMethodBody(bakerMethod, factoryMethods, injectionMethods, injectionModule);
                    bakerMethod.CustomAttributes.Add(customAttribute);

                    var writeParams = new WriterParameters()
                    {
                        //write symbols for debugging to work
                        WriteSymbols         = true,
                        SymbolWriterProvider = new PdbWriterProvider()
                    };

                    assembly.Write(assPath, writeParams);
                }
            }
        }
コード例 #13
0
 private static Assembly[] GetAllProjectAssemblies()
 {
     Assembly[] assemblies = CompilationPipeline.GetAssemblies();
     Array.Sort(assemblies, (x, y) => String.Compare(x.name, y.name));
     return(assemblies);
 }
コード例 #14
0
        public UnityProjectInfo(IEnumerable <CompilationPlatformInfo> availablePlatforms, string projectOutputPath)
        {
            this.availablePlatforms = availablePlatforms;

            Dictionary <string, Assembly> unityAssemblies = CompilationPipeline.GetAssemblies().ToDictionary(t => t.name);

            Dictionary <string, CSProjectInfo> csProjects = new Dictionary <string, CSProjectInfo>();

            CSProjects = new ReadOnlyDictionary <string, CSProjectInfo>(csProjects);

            foreach (KeyValuePair <string, Assembly> pair in unityAssemblies)
            {
                CSProjectInfo toAdd;
                string        asmDefPath = CompilationPipeline.GetAssemblyDefinitionFilePathFromAssemblyName(pair.Key);
                if (string.IsNullOrEmpty(asmDefPath))
                {
                    if (!pair.Key.StartsWith("Assembly-CSharp"))
                    {
                        Debug.LogError($"Failed to retrieve AsmDef for script assembly: {pair.Key}");
                    }

                    toAdd = new CSProjectInfo(availablePlatforms, Guid.NewGuid(), null, pair.Value, projectOutputPath);
                }
                else
                {
                    string guid = AssetDatabase.AssetPathToGUID(asmDefPath);
                    if (!Guid.TryParse(guid, out Guid guidResult))
                    {
                        Debug.LogError($"Failed to get GUID of the AsmDef at '{asmDefPath}' for assembly: {pair.Key}");
                    }
                    else
                    {
                        guidResult = Guid.NewGuid();
                    }

                    AssemblyDefinitionAsset assemblyDefinitionAsset = AssetDatabase.LoadAssetAtPath <AssemblyDefinitionAsset>(asmDefPath);
                    AssemblyDefinitionInfo  assemblyDefinitionInfo  = assemblyDefinitionAsset == null ? null : JsonUtility.FromJson <AssemblyDefinitionInfo>(assemblyDefinitionAsset.text);
                    assemblyDefinitionInfo?.Validate(availablePlatforms);
                    toAdd = new CSProjectInfo(availablePlatforms, guidResult, assemblyDefinitionInfo, pair.Value, projectOutputPath);
                }

                csProjects.Add(pair.Key, toAdd);
            }

            Plugins = new ReadOnlyCollection <PluginAssemblyInfo>(ScanForPluginDLLs());

            foreach (PluginAssemblyInfo plugin in Plugins)
            {
                if (plugin.Type == PluginType.Native)
                {
                    Debug.LogWarning($"Native plugin {plugin.ReferencePath.AbsolutePath} not yet supported for MSBuild project.");
                }
            }

            foreach (CSProjectInfo project in CSProjects.Values)
            {
                // Get the assembly references first from AssemblyDefinitionInfo if available (it's actually more correct), otherwise fallback to Assemby
                IEnumerable <string> references = project.AssemblyDefinitionInfo == null
                    ? project.Assembly.assemblyReferences.Select(t => t.name)
                    : (project.AssemblyDefinitionInfo.references ?? Array.Empty <string>());

                foreach (string reference in references)
                {
                    if (CSProjects.TryGetValue(reference, out CSProjectInfo dependency))
                    {
                        project.AddDependency(dependency);
                    }
                    else
                    {
                        Debug.LogError($"Failed to get dependency '{reference}' for project '{project.Name}'.");
                    }
                }

                foreach (PluginAssemblyInfo plugin in Plugins)
                {
                    if (plugin.AutoReferenced && plugin.Type != PluginType.Native)
                    {
                        project.AddDependency(plugin);
                    }
                }
            }
        }
コード例 #15
0
 public IEnumerable <UnityEditor.Compilation.Assembly> GetAssemblies()
 {
     return(CompilationPipeline.
            GetAssemblies(AssembliesType.Editor).Where(WillProcess));
 }
コード例 #16
0
        public void SetupCodegeneration(BuildContext context, Mode mode)
        {
            var classicContext = context.GetValue <IncrementalClassicSharedData>();
            var assemblyGraph  =
                new List <Assembly>(CompilationPipeline.GetAssemblies(AssembliesType.PlayerWithoutTestAssemblies));
            var editorAssemblies = CompilationPipeline.GetAssemblies(AssembliesType.Editor);

            //codegen assemblies are not part of the CompilationPipeline.GetAssemblies(Player) graph. we need to grab them from the editor one.
            //it would be kind of a waste to compile all the many assemblies they reference from the editorgraph, as they are all also in the player one.
            var codeGenAssemblies = editorAssemblies.Where(e => e.IsCodeGenAssembly())
                                    .Select(assembly => TransplantFromEditorGraphIntoPlayerGraph(assembly, assemblyGraph)).ToList();
            var assembliesToCompile = assemblyGraph.Where(a => !Path.GetFileName(a.outputPath).Contains("Test"))
                                      .OrderByDependencies().ToList();

            //We should probably at some point switch back to using the roslyn that ships in the editor, however that has a bug where it crashes
            //with /refout on our postprocessing code. To work around that for now, we're going to compile with the latest roslyn from stevedore.
            var csharpCompiler = Csc.Latest; //new UnityEditorCsc

            CSharpProgram.DefaultConfig = new CSharpProgramConfiguration(CSharpCodeGen.Release, csharpCompiler, DebugFormat.PortablePdb);

            Dictionary <Assembly, (CSharpProgram program, DotNetAssembly assembly)> unityAssemblyToCSharpProgramAndBuiltAssembly = SetupCSharpProgramsFor(context, assembliesToCompile);

            ScriptAssembliesJsonGenerator.Setup(unityAssemblyToCSharpProgramAndBuiltAssembly, classicContext.DataDeployDirectory);

            var postProcessedPlayerAssemblies = SetupPostProcessPlayerAssembliesFor(assembliesToCompile, classicContext,
                                                                                    codeGenAssemblies, unityAssemblyToCSharpProgramAndBuiltAssembly, context.UsesIL2CPP());

            var playerAssemblies = postProcessedPlayerAssemblies.Where(kvp => !IsEditorAssembly(kvp.unityAssembly)).Select(w => w.dotNetAssembly).ToArray();

            SetupTypeResourcesFor(playerAssemblies, classicContext.DataDeployDirectory, classicContext.TypeDBOutputDirectory);
            if (mode == Mode.EnoughToProduceTypeDB)
            {
                return;
            }

            postProcessedPlayerAssemblies.FilterByBool(p => IsExternal(p.unityAssembly), out var external, out var locals);

            var localAssemblies    = locals.Select(l => l.dotNetAssembly).ToArray();
            var externalAssemblies = external.Select(l => l.dotNetAssembly).ToArray();
            var burstSettings      = context.GetOrCreateValue <BurstSettings>();

            using (new ProfilerMarker(nameof(BurstCompiler)).Auto())
            {
                foreach (var arch in classicContext.Architectures)
                {
                    var a             = arch.Value;
                    var burstCompiler = new BurstCompiler(a.BurstTarget, classicContext.PlatformName, a.DynamicLibraryDeployDirectory);

                    switch (burstSettings.BurstGranularity)
                    {
                    case BurstGranularity.One:
                        burstCompiler.Setup(arch.Key, localAssemblies.Concat(externalAssemblies).ToArray(), 0, "wholeprogram",
                                            burstSettings.EnvironmentVariables, BurstCompiler.BurstOutputMode.SingleLibrary);
                        break;

                    case BurstGranularity.OnePerJob:
                        int assemblyIndex = 0;

                        //compile all exeternal assemblies into one big burst library
                        burstCompiler.Setup(arch.Key, externalAssemblies, assemblyIndex++, "externalassemblies",
                                            burstSettings.EnvironmentVariables, BurstCompiler.BurstOutputMode.SingleLibrary);

                        //and the local ones, in one burst library per assembly.
                        foreach (var localAssembly in localAssemblies)
                        {
                            var producedLibraries = burstCompiler.Setup(arch.Key, new[] { localAssembly }, assemblyIndex,
                                                                        localAssembly.Path.FileNameWithoutExtension, burstSettings.EnvironmentVariables,
                                                                        BurstCompiler.BurstOutputMode.LibraryPerJob);
                            if (producedLibraries.Length > 0)
                            {
                                assemblyIndex++;
                            }
                        }

                        break;
                    }
                }
            }

            var copiedPrebuiltAssemblies = SetupCopyPrebuiltAssemblies(classicContext,
                                                                       GetDestinationDirectoryForManagedAssemblies(classicContext, context.UsesIL2CPP()), assemblyGraph, context.UsesIL2CPP()).ToList();

            context.SetValue(new Il2CppInputAssemblies()
            {
                prebuiltAssemblies = copiedPrebuiltAssemblies, processedAssemblies = postProcessedPlayerAssemblies
            });
        }
コード例 #17
0
        public void OnPostBuildPlayerScriptDLLs(BuildReport report)
        {
            // Early exit if burst is not activated or the platform is not supported
            if (!BurstEditorOptions.EnableBurstCompilation || !IsSupportedPlatform(report.summary.platform))
            {
                return;
            }

            // Collect all method signatures
            var methodsToCompile = BurstReflection.FindExecuteMethods(AssembliesType.Player);

            if (methodsToCompile.Count == 0)
            {
                return; // Nothing to do
            }

            // Prepare options
            var commonOptions = new List <string>();

            for (var i = 0; i < methodsToCompile.Count; i++)
            {
                var burstCompileTarget = methodsToCompile[i];
                if (!burstCompileTarget.SupportsBurst)
                {
                    continue;
                }

                var methodStr           = BurstCompilerService.GetMethodSignature(burstCompileTarget.Method);
                var methodFullSignature = methodStr + "--" + Hash128.Compute(methodStr);
                commonOptions.Add(GetOption(OptionAotMethod, methodFullSignature));
            }

            var targetCpu      = TargetCpu.Auto;
            var targetPlatform = GetTargetPlatformAndDefaultCpu(report.summary.platform, out targetCpu);

            commonOptions.Add(GetOption(OptionPlatform, targetPlatform));

            if (!BurstEditorOptions.EnableBurstSafetyChecks)
            {
                commonOptions.Add(GetOption(OptionDisableSafetyChecks));
            }

            // TODO: Add support for configuring the optimizations/CPU
            // TODO: Add support for per method options

            var stagingFolder = Path.GetFullPath(TempStagingManaged);
            //Debug.Log($"Burst CompileAot - To Folder {stagingFolder}");

            // Prepare assembly folder list
            var assemblyFolders = new List <string>();

            assemblyFolders.Add(stagingFolder);

            var playerAssemblies = CompilationPipeline.GetAssemblies(AssembliesType.Player);

            foreach (var assembly in playerAssemblies)
            {
                foreach (var assemblyRef in assembly.compiledAssemblyReferences)
                {
                    // Exclude folders with assemblies already compiled in the `folder`
                    var assemblyName = Path.GetFileName(assemblyRef);
                    if (assemblyName != null && File.Exists(Path.Combine(stagingFolder, assemblyName)))
                    {
                        continue;
                    }

                    var directory = Path.GetDirectoryName(assemblyRef);
                    if (directory != null)
                    {
                        var fullPath = Path.GetFullPath(directory);
                        if (!assemblyFolders.Contains(fullPath))
                        {
                            assemblyFolders.Add(fullPath);
                        }
                    }
                }
            }

            commonOptions.AddRange(assemblyFolders.Select(folder => GetOption(OptionAotAssemblyFolder, folder)));

            // Gets platform specific IL2CPP plugin folder
            // Only the following platforms are providing a dedicated Tools directory
            switch (report.summary.platform)
            {
            case BuildTarget.XboxOne:
            case BuildTarget.PS4:
            case BuildTarget.Android:
            case BuildTarget.iOS:
                var pluginFolder = BuildPipeline.GetBuildToolsDirectory(report.summary.platform);
                commonOptions.Add(GetOption(OptionAotIL2CPPPluginFolder, pluginFolder));
                break;
            }

            var combinations = new List <BurstOutputCombination>();

            if (targetPlatform == TargetPlatform.macOS)
            {
                // NOTE: OSX has a special folder for the plugin
                // Declared in GetStagingAreaPluginsFolder
                // PlatformDependent\OSXPlayer\Extensions\Managed\OSXDesktopStandalonePostProcessor.cs
                combinations.Add(new BurstOutputCombination("UnityPlayer.app/Contents/Plugins", targetCpu));
            }
            else if (targetPlatform == TargetPlatform.iOS)
            {
                // Check if we are under il2cpp as we may have to force a CPU backend for it
                // TODO: Should use report.summary.platformGroup instead?
                bool isUsingIL2CPP = PlayerSettings.GetScriptingBackend(BuildTargetGroup.Standalone) == ScriptingImplementation.IL2CPP;

                if (!isUsingIL2CPP)
                {
                    var targetArchitecture = (IOSArchitecture)UnityEditor.PlayerSettings.GetArchitecture(report.summary.platformGroup);
                    switch (targetArchitecture)
                    {
                    case IOSArchitecture.ARMv7:
                        targetCpu = TargetCpu.ARMV7A_NEON32;
                        break;

                    case IOSArchitecture.ARM64:
                        targetCpu = TargetCpu.ARMV8A_AARCH64;
                        break;

                    case IOSArchitecture.Universal:
                        // TODO: How do we proceed here?
                        targetCpu = TargetCpu.ARMV7A_NEON32;
                        break;
                    }
                }

                // PlatformDependent\iPhonePlayer\Extensions\Common\BuildPostProcessor.cs
                combinations.Add(new BurstOutputCombination("Frameworks", targetCpu));
            }
            else if (targetPlatform == TargetPlatform.Android)
            {
                // Set the ANDROID_NDK_ROOT so IL2CPP knows where to find the Android toolchain

                var ndkRoot = EditorPrefs.GetString("AndroidNdkRoot");
                if (!string.IsNullOrEmpty(ndkRoot))
                {
                    Environment.SetEnvironmentVariable("ANDROID_NDK_ROOT", ndkRoot);
                }

                var androidTargetArch = UnityEditor.PlayerSettings.Android.targetArchitectures;
                if ((androidTargetArch & AndroidArchitecture.ARMv7) != 0)
                {
                    combinations.Add(new BurstOutputCombination("libs/armeabi-v7a", TargetCpu.ARMV7A_NEON32));
                }
                if ((androidTargetArch & AndroidArchitecture.ARM64) != 0)
                {
                    combinations.Add(new BurstOutputCombination("libs/arm64-v8a", TargetCpu.ARMV8A_AARCH64));
                }
                if ((androidTargetArch & AndroidArchitecture.X86) != 0)
                {
                    combinations.Add(new BurstOutputCombination("libs/x86", TargetCpu.X86_SSE2));
                }
            }
            else if (targetPlatform == TargetPlatform.UWP)
            {
                // TODO: Make it configurable for x86 (sse2, sse4)
                combinations.Add(new BurstOutputCombination("Plugins/x64", TargetCpu.X64_SSE4));
                combinations.Add(new BurstOutputCombination("Plugins/x86", TargetCpu.X86_SSE2));
                combinations.Add(new BurstOutputCombination("Plugins/ARM", TargetCpu.THUMB2_NEON32));
            }
            else
            {
                combinations.Add(new BurstOutputCombination("Data/Plugins/", targetCpu));
            }

            foreach (var combination in combinations)
            {
                // Gets the output folder
                var stagingOutputFolder = Path.GetFullPath(Path.Combine(TempStaging, combination.OutputPath));
                var outputFilePrefix    = Path.Combine(stagingOutputFolder, DefaultLibraryName);

                var options = new List <string>(commonOptions);
                options.Add(GetOption(OptionAotOutputPath, outputFilePrefix));
                options.Add(GetOption(OptionTarget, combination.TargetCpu));

                var responseFile = Path.GetTempFileName();
                File.WriteAllLines(responseFile, options);

                //Debug.Log("Burst compile with response file: " + responseFile);

                Runner.RunManagedProgram(Path.Combine(BurstLoader.RuntimePath, BurstAotCompilerExecutable), "@" + responseFile, Application.dataPath + "/..", new BclParser(), null);
            }
        }
コード例 #18
0
ファイル: EditorWeaver.cs プロジェクト: D-Bantz/Malimbe
 private static IEnumerable <Assembly> GetAllAssemblies() =>
 CompilationPipeline.GetAssemblies(AssembliesType.Editor)
 .GroupBy(assembly => assembly.outputPath)
 .Select(grouping => grouping.First());
コード例 #19
0
        private static bool IsReferenced(Assembly assembly)
        {
            // C# player referenced assemblies
            foreach (AssemblyName asmName in typeof(VRModule).Assembly.GetReferencedAssemblies())
            {
                if (assembly.GetName().Name == asmName.Name)
                {
                    return(true);
                }
            }

            // C# editor referenced assemblies
            foreach (AssemblyName asmName in typeof(VRModuleManagerEditor).Assembly.GetReferencedAssemblies())
            {
                if (assembly.GetName().Name == asmName.Name)
                {
                    return(true);
                }
            }

#if UNITY_2018_1_OR_NEWER
            // Unity player referenced assemblies
            UnityEditor.Compilation.Assembly playerUnityAsm = FindUnityAssembly(typeof(VRModule).Assembly.GetName().Name, AssembliesType.Player);
            if (playerUnityAsm != null)
            {
                foreach (UnityEditor.Compilation.Assembly asm in playerUnityAsm.assemblyReferences)
                {
                    if (assembly.GetName().Name == asm.name)
                    {
                        return(true);
                    }
                }
            }
            else
            {
                Debug.LogWarning("Player assembly not found.");
            }

            // Unity editor referenced assemblies
            UnityEditor.Compilation.Assembly editorUnityAsm = FindUnityAssembly(typeof(VRModuleManagerEditor).Assembly.GetName().Name, AssembliesType.Editor);
            if (editorUnityAsm != null)
            {
                foreach (UnityEditor.Compilation.Assembly asm in editorUnityAsm.assemblyReferences)
                {
                    if (assembly.GetName().Name == asm.name)
                    {
                        return(true);
                    }
                }
            }
            else
            {
                Debug.LogWarning("Editor assembly not found.");
            }
#elif UNITY_2017_3_OR_NEWER
            UnityEditor.Compilation.Assembly[] assemblies = CompilationPipeline.GetAssemblies();
            foreach (UnityEditor.Compilation.Assembly asm in assemblies)
            {
                if (assembly.GetName().Name == asm.name)
                {
                    return(true);
                }
            }
#endif

            return(false);
        }
コード例 #20
0
        // This shouldn't be exposed normally, but if AsmRefPreprocessor ever breaks this is useful for debugging
        // [MenuItem("Debug/Fix optional dependencies")]
        private static void FixOptionalDependencies()
        {
            const string MAGIC           = "OPT_REF_";
            var          assemblies      = CompilationPipeline.GetAssemblies();
            var          optionalRefs    = new List <OptionalRefMetadata>();
            var          foundAssemblies = new List <string>();

            // go over all assemblies, scan for optional references
            foreach (var assembly in assemblies)
            {
                var asmRef = CompilationPipeline.GetAssemblyDefinitionFilePathFromAssemblyName(assembly.name);

                if (asmRef != null)
                {
                    var path = CompilationPipeline.GetAssemblyDefinitionFilePathFromAssemblyName(assembly.name);
                    var obj  = JsonConvert.DeserializeObject(File.ReadAllText(path)) as dynamic;
                    foundAssemblies.Add((obj.name as JValue).Value <string>());
                    if (obj.versionDefines == null)
                    {
                        continue;
                    }
                    foreach (var define in obj.versionDefines)
                    {
                        var d = (define.define as JValue).Value <string>();
                        if (d.StartsWith(MAGIC))
                        {
                            // found one to resolve!
                            optionalRefs.Add(new OptionalRefMetadata(path, assembly.name, d.Substring(MAGIC.Length, d.Length - MAGIC.Length).Replace("_", ".")));
                        }
                    }
                }
            }

            // go over the found optional references and fix asmrefs
            foreach (var optionalRef in optionalRefs)
            {
                var defineString = optionalRef.ReferenceTo.Replace(".", "_").ToUpper();
                var obj          = JsonConvert.DeserializeObject(File.ReadAllText(optionalRef.AsmRefPath)) as dynamic;

                // does a reference exist?
                var foundRefIndex = -1;
                for (int i = 0; i < obj.references.Count; i++)
                {
                    if (obj.references[i] == optionalRef.ReferenceTo)
                    {
                        foundRefIndex = i;
                        break;
                    }
                }

                // does the conditional-compilation define exist?
                var foundDefineIndex = -1;
                for (int i = 0; i < obj.versionDefines.Count; i++)
                {
                    if (obj.versionDefines[i].name == optionalRef.ReferencedBy && obj.versionDefines[i].define == defineString)
                    {
                        foundDefineIndex = i;
                        break;
                    }
                }

                // if the assembly is loaded, make sure we have the reference and the define, add them if not
                if (foundAssemblies.Contains(optionalRef.ReferenceTo))
                {
                    if (foundRefIndex == -1)
                    {
                        obj.references.Add(optionalRef.ReferenceTo);
                    }
                    if (foundDefineIndex == -1)
                    {
                        // this is ugly but using an anonymous type here breaks jsonconvert, so we do it directly instead
                        obj.versionDefines.Add(new JObject
                        {
                            { "name", optionalRef.ReferencedBy },
                            { "expression", "" },
                            { "define", defineString }
                        });
                    }
                }
                else
                {
                    // if it's not loaded, remove any reference that exists
                    if (foundRefIndex != -1)
                    {
                        obj.references.RemoveAt(foundRefIndex);
                    }
                    if (foundDefineIndex != -1)
                    {
                        obj.versionDefines.RemoveAt(foundDefineIndex);
                    }
                }
                // done
                File.WriteAllText(optionalRef.AsmRefPath, JsonConvert.SerializeObject(obj));
            }
        }
コード例 #21
0
        static void OnCompilationFinished(string assemblyPath, CompilerMessage[] messages)
        {
            // Do nothing if there were compile errors on the target
            if (CompilerMessagesContainError(messages))
            {
                Debug.Log("Weaver: stop because compile errors on target");
                return;
            }

            // Should not run on the editor only assemblies
            if (assemblyPath.Contains("-Editor") || assemblyPath.Contains(".Editor"))
            {
                return;
            }

            // don't weave mirror files
            string assemblyName = Path.GetFileNameWithoutExtension(assemblyPath);

            if (assemblyName == MirrorRuntimeAssemblyName || assemblyName == MirrorWeaverAssemblyName)
            {
                return;
            }

            // find Mirror.dll
            string mirrorRuntimeDll = FindMirrorRuntime();

            if (string.IsNullOrEmpty(mirrorRuntimeDll))
            {
                Debug.LogError("Failed to find Mirror runtime assembly");
                return;
            }
            if (!File.Exists(mirrorRuntimeDll))
            {
                // this is normal, it happens with any assembly that is built before mirror
                // such as unity packages or your own assemblies
                // those don't need to be weaved
                // if any assembly depends on mirror, then it will be built after
                return;
            }

            // find UnityEngine.CoreModule.dll
            string unityEngineCoreModuleDLL = UnityEditorInternal.InternalEditorUtility.GetEngineCoreModuleAssemblyPath();

            if (string.IsNullOrEmpty(unityEngineCoreModuleDLL))
            {
                Debug.LogError("Failed to find UnityEngine assembly");
                return;
            }

            // build directory list for later asm/symbol resolving using CompilationPipeline refs
            HashSet <string> dependencyPaths = new HashSet <string>();

            dependencyPaths.Add(Path.GetDirectoryName(assemblyPath));
            foreach (UnityAssembly unityAsm in CompilationPipeline.GetAssemblies())
            {
                if (unityAsm.outputPath != assemblyPath)
                {
                    continue;
                }

                foreach (string unityAsmRef in unityAsm.compiledAssemblyReferences)
                {
                    dependencyPaths.Add(Path.GetDirectoryName(unityAsmRef));
                }
            }

            // passing null in the outputDirectory param will do an in-place update of the assembly
            if (Program.Process(unityEngineCoreModuleDLL, mirrorRuntimeDll, null, new[] { assemblyPath }, dependencyPaths.ToArray(), HandleWarning, HandleError))
            {
                WeaveFailed = false;
                //Debug.Log("Weaving succeeded for: " + assemblyPath);
            }
            else
            {
                WeaveFailed = true;
                if (UnityLogEnabled)
                {
                    Debug.LogError("Weaving failed for: " + assemblyPath);
                }
            }
        }
コード例 #22
0
        /// <returns>Returns a dictionary of type name inside MRTK DLLs mapped to additional data.</returns>
        private static Dictionary <string, ClassInformation> ProcessCompiledDLLs(string temporaryDirectoryName, string outputDirectory, Dictionary <string, string> asmDefMappings)
        {
            Assembly[] dlls = CompilationPipeline.GetAssemblies();

            string tmpDirPath = Path.Combine(Application.dataPath, temporaryDirectoryName);

            if (Directory.Exists(tmpDirPath))
            {
                Directory.Delete(tmpDirPath);
            }

            Directory.CreateDirectory(tmpDirPath);

            try
            {
                foreach (Assembly dll in dlls)
                {
                    if (dll.name.Contains("MixedReality"))
                    {
                        File.Copy(dll.outputPath, Path.Combine(tmpDirPath, $"{dll.name}.dll"), true);
                    }
                }

                // Load these directories
                AssetDatabase.Refresh();

                Dictionary <string, ClassInformation> toReturn = new Dictionary <string, ClassInformation>();

                if (Directory.Exists(outputDirectory))
                {
                    Directory.Delete(outputDirectory, true);
                }

                Directory.CreateDirectory(outputDirectory);
                foreach (Assembly dll in dlls)
                {
                    if (dll.name.Contains("MixedReality"))
                    {
                        if (!asmDefMappings.TryGetValue($"{dll.name}.dll", out string newDllGuid))
                        {
                            throw new InvalidOperationException($"No guid based on .asmdef was generated for DLL '{dll.name}'.");
                        }

                        File.Copy(Path.Combine(tmpDirPath, $"{dll.name}.dll"), Path.Combine(outputDirectory, $"{dll.name}.dll"));
                        File.Copy(Path.Combine(tmpDirPath, $"{dll.name}.dll.meta"), Path.Combine(outputDirectory, $"{dll.name}.dll.meta"));

                        Object[] assets = AssetDatabase.LoadAllAssetsAtPath(Path.Combine("Assets", temporaryDirectoryName, $"{dll.name}.dll"));

                        foreach (Object asset in assets)
                        {
                            MonoScript monoScript = asset as MonoScript;
                            if (!(monoScript is null) && AssetDatabase.TryGetGUIDAndLocalFileIdentifier(monoScript, out string guid, out long fileId))
                            {
                                Type type = monoScript.GetClass();

                                if (type.Namespace == null || !type.Namespace.Contains("Microsoft.MixedReality.Toolkit"))
                                {
                                    throw new InvalidDataException($"Type {type.Name} is not a member of the Microsoft.MixedReality.Toolkit namespace");
                                }
                                toReturn.Add(type.FullName, new ClassInformation()
                                {
                                    Name = type.Name, Namespace = type.Namespace, FileId = fileId, Guid = newDllGuid
                                });
                            }
                        }
                    }
                }

                return(toReturn);
            }
            finally
            {
                Directory.Delete(tmpDirPath, true);
                AssetDatabase.Refresh();
            }
        }
コード例 #23
0
 static Assembly FindCompilationPipelineAssembly(string assemblyName) =>
 CompilationPipeline.GetAssemblies().First(assembly => assembly.name == assemblyName);
コード例 #24
0
        public override void Execute(Pipeline pipeline)
        {
            var mani = pipeline.Manifest;
            var allThunderstoreManifests = pipeline.Datums.OfType <ThunderstoreManifest>();
            var thunderstoreManifest     = mani.Data.OfType <ThunderstoreManifest>().First();
            var dependencies             = thunderstoreManifest.dependencies;

            bool IsDependency(string dependency, ThunderstoreManifest man) => $"{man.author}-{man.name}-{man.versionNumber}".Equals(dependency);

            var dependantManifests = pipeline.manifests
                                     .Where(man => man.Data.OfType <ThunderstoreManifest>().Any())
                                     .Select(man => (manifest: man, tsManifest: man.Data.OfType <ThunderstoreManifest>().First()))
                                     .Where(projection => dependencies.Any(dep => IsDependency(dep, projection.tsManifest)))
                                     .Select(projection => projection.manifest);

            var explicitDownstreamAssets = dependantManifests
                                           .SelectMany(man => man.Data.OfType <AssetBundleDefs>())
                                           .SelectMany(mabd => mabd.assetBundles)
                                           .SelectMany(ab => ab.assets)
                                           .Select(asset => AssetDatabase.GetAssetPath(asset))
                                           .ToArray();

            AssetDatabase.SaveAssets();
            foreach (var assetBundleDef in mani.Data.OfType <AssetBundleDefs>())
            {
                var playerAssemblies   = CompilationPipeline.GetAssemblies();
                var assemblyFiles      = playerAssemblies.Select(pa => pa.outputPath).ToArray();
                var sourceFiles        = playerAssemblies.SelectMany(pa => pa.sourceFiles).ToArray();
                var excludedExtensions = new[] { ".dll" };

                var builds    = new AssetBundleBuild[assetBundleDef.assetBundles.Length];
                var fileCount = 0;

                var logBuilder = new StringBuilder();
                logBuilder.AppendLine("Constructing AssetBundles");

                for (int i = 0; i < assetBundleDef.assetBundles.Length; i++)
                {
                    var def            = assetBundleDef.assetBundles[i];
                    var explicitAssets = assetBundleDef.assetBundles.Where((ab, abi) => abi != i).SelectMany(ab => ab.assets).Select(asset => AssetDatabase.GetAssetPath(asset)).ToArray();
                    var build          = builds[i];
                    var assets         = new List <string>();
                    logBuilder.AppendLine($"Building bundle: {def.assetBundleName}");
                    if (def.assets.OfType <SceneAsset>().Any())
                    {
                        assets.Add(AssetDatabase.GetAssetPath(def.assets.OfType <SceneAsset>().First()));
                    }
                    else
                    {
                        foreach (var asset in def.assets)
                        {
                            var  assetPath = AssetDatabase.GetAssetPath(asset);
                            bool isFolder  = AssetDatabase.IsValidFolder(assetPath);

                            logBuilder.AppendLine($"Asset: {asset.name} is a {(isFolder ? "Folder" : "File")}");
                            if (isFolder)
                            {
                                var bundleAssets = AssetDatabase.GetAllAssetPaths()
                                                   .Where(ap => !AssetDatabase.IsValidFolder(ap))
                                                   .Where(ap => ap.StartsWith(assetPath))
                                                   .Where(ap => !assets.Contains(ap))
                                                   .Where(ap => !sourceFiles.Contains(ap))
                                                   .Where(ap => !assemblyFiles.Contains(ap))
                                                   .Where(ap => recurseDirectories || Path.GetDirectoryName(ap).Replace('\\', '/').Equals(assetPath))
                                                   .SelectMany(ap => AssetDatabase.GetDependencies(ap)
                                                               .Where(dap => !explicitAssets.Contains(dap))
                                                               .Where(dap => !explicitDownstreamAssets.Contains(dap))
                                                               )
                                                   .Where(ap =>
                                {
                                    var extension = Path.GetExtension(ap);
                                    return(!excludedExtensions.Contains(extension));
                                })

                                                   .Where(ap => !assets.Contains(ap))
                                ;
                                assets.AddRange(bundleAssets);
                            }
                            else
                            {
                                var validAssets = AssetDatabase.GetDependencies(assetPath)
                                                  .Where(dap => !explicitDownstreamAssets.Contains(dap))
                                                  .Where(dap => !explicitAssets.Contains(dap))
                                                  .Where(ap => !assets.Contains(ap))
                                                  .Where(ap =>
                                {
                                    var extension = Path.GetExtension(ap);
                                    return(!excludedExtensions.Contains(extension));
                                })
                                                  .Where(ap => !sourceFiles.Contains(ap))
                                                  .Where(ap => !assemblyFiles.Contains(ap))
                                                  .Where(ap => AssetDatabase.GetMainAssetTypeAtPath(ap) != typeof(UnityPackage))
                                ;
                                assets.AddRange(validAssets);
                            }
                        }
                    }
                    build.assetNames      = assets.ToArray();
                    build.assetBundleName = def.assetBundleName;
                    builds[i]             = build;
                    fileCount            += build.assetNames.Length;
                    foreach (var asset in build.assetNames)
                    {
                        logBuilder.AppendLine(asset);
                    }
                }

                logBuilder.AppendLine($"Constructed {builds.Length} AssetBundleBuilds with {fileCount} files.");

                if (!simulate)
                {
                    var stablePath = BundleArtifactPath.Resolve(pipeline, this);
                    Directory.CreateDirectory(stablePath);
                    BuildPipeline.BuildAssetBundles(stablePath, builds, AssetBundleBuildOptions, buildTarget);

                    foreach (var outputPath in assetBundleDef.StagingPaths.Select(path => path.Resolve(pipeline, this)))
                    {
                        CopyFilesRecursively(stablePath, outputPath);
                    }
                }

                Debug.Log(logBuilder.ToString());
            }
        }
コード例 #25
0
        /// <returns>Returns a dictionary of type name inside MRTK DLLs mapped to additional data.</returns>
        private static Dictionary <string, AssemblyInformation> ProcessCompiledDLLs(string temporaryDirectoryName, string outputDirectory, Dictionary <string, string> asmDefMappings)
        {
            Assembly[] dlls = CompilationPipeline.GetAssemblies();

            string tmpDirPath = Path.Combine(Application.dataPath, temporaryDirectoryName);

            if (Directory.Exists(tmpDirPath))
            {
                Directory.Delete(tmpDirPath);
            }

            Directory.CreateDirectory(tmpDirPath);

            try
            {
                Utilities.EnsureCleanDirectory(outputDirectory);

                foreach (Assembly dll in dlls)
                {
                    if (dll.name.Contains("MixedReality"))
                    {
                        string dllPath = Utilities.GetFullPathFromAssetsRelative($"Assets/../MSBuild/Publish/InEditor/WindowsStandalone32/{dll.name}.dll");
                        File.Copy(dllPath, Path.Combine(tmpDirPath, $"{dll.name}.dll"), true);
                        File.Copy(dllPath, Path.Combine(outputDirectory, $"{dll.name}.dll"));
                        File.Copy(Path.ChangeExtension(dllPath, ".pdb"), Path.Combine(outputDirectory, $"{dll.name}.pdb"));
                    }
                }

                // Load these directories
                AssetDatabase.Refresh();

                Dictionary <string, AssemblyInformation> toReturn = new Dictionary <string, AssemblyInformation>();

                foreach (Assembly dll in dlls)
                {
                    if (dll.name.Contains("MixedReality"))
                    {
                        if (!asmDefMappings.TryGetValue($"{dll.name}.dll", out string newDllGuid))
                        {
                            throw new InvalidOperationException($"No guid based on .asmdef was generated for DLL '{dll.name}'.");
                        }

                        AssemblyInformation assemblyInformation = new AssemblyInformation(dll.name, newDllGuid);

                        Object[] assets = AssetDatabase.LoadAllAssetsAtPath(Path.Combine("Assets", temporaryDirectoryName, $"{dll.name}.dll"));

                        foreach (Object asset in assets)
                        {
                            MonoScript monoScript = asset as MonoScript;
                            if (!(monoScript is null) && AssetDatabase.TryGetGUIDAndLocalFileIdentifier(monoScript, out string guid, out long fileId))
                            {
                                Type type = monoScript.GetClass();

                                if (type == null)
                                {
                                    Debug.LogError($"Encountered a MonoScript we get a null Type from: '{monoScript.name}'");
                                }
                                // check for a namespace, MRTK or the DotNetAdapter namespace
                                else if ((type.Namespace == null) || (!type.Namespace.Contains("Microsoft.MixedReality.Toolkit") && !type.Namespace.Contains("Microsoft.Windows.MixedReality")))
                                {
                                    throw new InvalidDataException($"Type {type.Name} is not a member of an approved (typically, 'Microsoft.MixedReality.Toolkit') namespace");
                                }
                                else
                                {
                                    assemblyInformation.CompiledClasses.Add(type.FullName, new ClassInformation()
                                    {
                                        Name = type.Name, Namespace = type.Namespace, FileId = fileId, Guid = newDllGuid
                                    });
                                }
                            }
                        }

                        toReturn.Add(dll.name, assemblyInformation);
                    }
                }

                return(toReturn);
            }
            finally
            {
                Directory.Delete(tmpDirPath, true);
                AssetDatabase.Refresh();
            }
        }
コード例 #26
0
        private Dictionary <string, CSProjectInfo> CreateUnityProjects()
        {
            // Not all of these will be converted to C# objects, only the ones found to be referenced
            Dictionary <string, AssemblyDefinitionInfo> asmDefInfoMap           = new Dictionary <string, AssemblyDefinitionInfo>();
            SortedSet <AssemblyDefinitionInfo>          asmDefDirectoriesSorted = new SortedSet <AssemblyDefinitionInfo>(Comparer <AssemblyDefinitionInfo> .Create((a, b) => a.Directory.FullName.CompareTo(b.Directory.FullName)));

            HashSet <string> builtInPackagesWithoutSource = new HashSet <string>();

            // Parse the builtInPackagesFirst
            DirectoryInfo builtInPackagesDirectory = new DirectoryInfo(Utilities.BuiltInPackagesPath);

            foreach (DirectoryInfo packageDirectory in builtInPackagesDirectory.GetDirectories())
            {
                FileInfo[] asmDefFiles = packageDirectory.GetFiles("*.asmdef", SearchOption.AllDirectories);

                if (asmDefFiles.Length == 0)
                {
                    builtInPackagesWithoutSource.Add(packageDirectory.Name.ToLower());
                    continue;
                }

                foreach (FileInfo fileInfo in asmDefFiles)
                {
                    AssemblyDefinitionInfo assemblyDefinitionInfo = AssemblyDefinitionInfo.Parse(fileInfo, this, null, true);
                    asmDefDirectoriesSorted.Add(assemblyDefinitionInfo);
                    asmDefInfoMap.Add(Path.GetFileNameWithoutExtension(fileInfo.Name), assemblyDefinitionInfo);
                }
            }

            Dictionary <string, string> packageCacheVersionedMap = new Dictionary <string, string>();

            foreach (string directory in Directory.GetDirectories(Utilities.PackageLibraryCachePath))
            {
                string directoryName = Path.GetFileName(directory);
                packageCacheVersionedMap.Add(directoryName.Split('@')[0], directoryName);
            }

            Dictionary <string, Assembly>      unityAssemblies = CompilationPipeline.GetAssemblies().ToDictionary(t => t.name);
            Dictionary <string, CSProjectInfo> projectsMap     = new Dictionary <string, CSProjectInfo>();
            Queue <string> projectsToProcess = new Queue <string>();

            // Parse the unity assemblies
            foreach (KeyValuePair <string, Assembly> pair in unityAssemblies)
            {
                if (!asmDefInfoMap.TryGetValue(pair.Key, out AssemblyDefinitionInfo assemblyDefinitionInfo))
                {
                    string asmDefPath = CompilationPipeline.GetAssemblyDefinitionFilePathFromAssemblyName(pair.Key);
                    if (string.IsNullOrEmpty(asmDefPath))
                    {
                        if (!pair.Key.StartsWith("Assembly-CSharp"))
                        {
                            throw new InvalidOperationException($"Failed to retrieve AsmDef for script assembly: {pair.Key}");
                        }

                        Guid guid;
                        switch (pair.Key)
                        {
                        case "Assembly-CSharp":
                            guid = config.AssemblyCSharpGuid;
                            break;

                        case "Assembly-CSharp-firstpass":
                            guid = config.AssemblyCSharpFirstPassGuid;
                            break;

                        case "Assembly-CSharp-Editor":
                            guid = config.AssemblyCSharpEditorGuid;
                            break;

                        case "Assembly-CSharp-Editor-firstpass":
                            guid = config.AssemblyCSharpFirstPassEditorGuid;
                            break;

                        default:
                            throw new InvalidOperationException($"Predefined assembly '{assemblyDefinitionInfo.Name}' was not recognized, this generally means it should be added to the switch statement in CSProjectInfo:GetProjectType.");
                        }

                        assemblyDefinitionInfo = AssemblyDefinitionInfo.GetDefaultAssemblyCSharpInfo(pair.Value, guid);
                        projectsToProcess.Enqueue(pair.Key);
                    }
                    else
                    {
                        assemblyDefinitionInfo = AssemblyDefinitionInfo.Parse(new FileInfo(Utilities.GetFullPathFromKnownRelative(asmDefPath)), this, pair.Value);

                        if (asmDefPath.StartsWith("Assets/"))
                        {
                            // Add as mandatory
                            projectsToProcess.Enqueue(pair.Key);
                        }
                    }

                    asmDefDirectoriesSorted.Add(assemblyDefinitionInfo);
                    asmDefInfoMap.Add(pair.Key, assemblyDefinitionInfo);
                }
            }

            // This will parse additional asmdefs that are not part of current compilation set, but we still need
            foreach (string asmdefGuid in AssetDatabase.FindAssets("t:asmdef"))
            {
                string asmDefPath = AssetDatabase.GUIDToAssetPath(asmdefGuid);
                string asmDefKey  = Path.GetFileNameWithoutExtension(asmDefPath);
                if (!asmDefInfoMap.ContainsKey(asmDefKey))
                {
                    AssemblyDefinitionInfo assemblyDefinitionInfo = AssemblyDefinitionInfo.Parse(new FileInfo(Utilities.GetFullPathFromKnownRelative(asmDefPath)), this, null);
                    asmDefDirectoriesSorted.Add(assemblyDefinitionInfo);
                    asmDefInfoMap.Add(asmDefKey, assemblyDefinitionInfo);
                }
            }

            // Now we have all of the assembly definiton files, let's run a quick validation.
            ValidateAndPatchAssemblyDefinitions(asmDefInfoMap);

            int index = 0;

            ProcessSortedAsmDef(asmDefDirectoriesSorted.ToArray(), ref index, (uri) => true, (a) => { });

            while (projectsToProcess.Count > 0)
            {
                string projectKey = projectsToProcess.Dequeue();

                if (!projectsMap.ContainsKey(projectKey))
                {
                    GetProjectInfo(projectsMap, asmDefInfoMap, builtInPackagesWithoutSource, projectKey);
                }
            }

            return(projectsMap);
        }
コード例 #27
0
        private void DrawOptions(DllManipulatorOptions options)
        {
            var guiEnabledStack = new Stack <bool>();

            guiEnabledStack.Push(GUI.enabled);
            if (EditorApplication.isPlaying)
            {
                GUI.enabled = false;
            }
            options.mockAllNativeFunctions = EditorGUILayout.Toggle(TARGET_ALL_NATIVE_FUNCTIONS_GUI_CONTENT, options.mockAllNativeFunctions);

            if (EditorGUILayout.Toggle(TARGET_ONLY_EXECUTING_ASSEMBLY_GUI_CONTENT, options.assemblyPaths.Length == 0))
            {
                options.assemblyPaths = new string[0];
            }
            else
            {
                var prevIndent1 = EditorGUI.indentLevel;
                EditorGUI.indentLevel++;

                if (_allKnownAssemblies == null || _lastKnownAssembliesRefreshTime + ASSEMBLIES_REFRESH_INTERVAL < DateTime.Now)
                {
                    var playerCompiledAssemblies = CompilationPipeline.GetAssemblies(AssembliesType.Player)
                                                   .Select(a => PathUtils.NormallizeUnityAssemblyPath(a.outputPath));

                    var editorCompiledAssemblies = CompilationPipeline.GetAssemblies(AssembliesType.Editor)
                                                   .Select(a => PathUtils.NormallizeUnityAssemblyPath(a.outputPath));

                    var assemblyAssets = Resources.FindObjectsOfTypeAll <PluginImporter>()
                                         .Where(p => !p.isNativePlugin)
                                         .Select(p => PathUtils.NormallizeUnityAssemblyPath(p.assetPath));

                    string[] defaultAssemblyPrefixes = { "UnityEngine.", "UnityEditor.", "Unity.", "com.unity.", "Mono.", "nunit." };

                    _allKnownAssemblies = playerCompiledAssemblies
                                          .Concat(assemblyAssets)
                                          .Concat(editorCompiledAssemblies)
                                          .OrderBy(path => Array.FindIndex(defaultAssemblyPrefixes, p => path.Substring(path.LastIndexOf('/') + 1).StartsWith(p)))
                                          .ToArray();
                    _lastKnownAssembliesRefreshTime = DateTime.Now;
                }

                if (options.assemblyPaths.Length == 0)
                {
                    var first = GetFirstAssemblyToList(_allKnownAssemblies);
                    if (first != null)
                    {
                        options.assemblyPaths = new[] { first }
                    }
                    ;
                }

                _showTargetAssemblies = EditorGUILayout.Foldout(_showTargetAssemblies, TARGET_ASSEMBLIES_GUI_CONTENT);
                if (_showTargetAssemblies)
                {
                    var prevIndent2 = EditorGUI.indentLevel;
                    EditorGUI.indentLevel++;

                    var selectedAssemblies    = options.assemblyPaths.Where(p => _allKnownAssemblies.Any(a => PathUtils.DllPathsEqual(a, p))).ToList();
                    var notSelectedAssemblies = _allKnownAssemblies.Except(selectedAssemblies).ToArray();
                    DrawList(selectedAssemblies, i =>
                    {
                        var values = new[] { selectedAssemblies[i] }
                        .Concat(notSelectedAssemblies)
                        .Select(a => a.Substring(a.LastIndexOf('/') + 1))
                        .ToArray();

                        var selectedIndex = EditorGUILayout.Popup(0, values);
                        return(selectedIndex == 0 ? selectedAssemblies[i] : notSelectedAssemblies[selectedIndex - 1]);
                    }, notSelectedAssemblies.Length > 0, () => notSelectedAssemblies[0]);
                    options.assemblyPaths = selectedAssemblies.ToArray();

                    EditorGUI.indentLevel = prevIndent2;
                }

                EditorGUI.indentLevel = prevIndent1;
            }

            options.onlyInEditor = EditorGUILayout.Toggle(ONLY_IN_EDITOR, options.onlyInEditor);

            options.dllPathPattern = EditorGUILayout.TextField(DLL_PATH_PATTERN_GUI_CONTENT, options.dllPathPattern);

            options.loadingMode = (DllLoadingMode)EditorGUILayout.EnumPopup(DLL_LOADING_MODE_GUI_CONTENT, options.loadingMode);

#if UNITY_STANDALONE_LINUX || UNITY_STANDALONE_OSX
            options.posixDlopenFlags = (PosixDlopenFlags)EditorGUILayout.EnumPopup(POSIX_DLOPEN_FLAGS_GUI_CONTENT, options.posixDlopenFlags);
#endif

            guiEnabledStack.Push(GUI.enabled);
            if (options.loadingMode != DllLoadingMode.Preload)
            {
                options.threadSafe = false;
                GUI.enabled        = false;
            }
            options.threadSafe = EditorGUILayout.Toggle(THREAD_SAFE_GUI_CONTENT, options.threadSafe);
            GUI.enabled        = guiEnabledStack.Pop();

            options.enableCrashLogs = EditorGUILayout.Toggle(CRASH_LOGS_GUI_CONTENT, options.enableCrashLogs);

            if (options.enableCrashLogs)
            {
                var prevIndent = EditorGUI.indentLevel;
                EditorGUI.indentLevel += 1;

                options.crashLogsDir = EditorGUILayout.TextField(CRASH_LOGS_DIR_GUI_CONTENT, options.crashLogsDir);

                options.crashLogsStackTrace = EditorGUILayout.Toggle(CRASH_LOGS_STACK_TRACE_GUI_CONTENT, options.crashLogsStackTrace);

                EditorGUI.indentLevel = prevIndent;
            }

            GUI.enabled = guiEnabledStack.Pop();
        }
コード例 #28
0
        public override void Execute(Pipeline pipeline)
        {
            var excludedExtensions = new[] { ".dll", ".cs", ".meta" };

            AssetDatabase.SaveAssets();

            var assetBundleDefs    = pipeline.Datums.OfType <AssetBundleDefinitions>().ToArray();
            var bundleArtifactPath = BundleArtifactPath.Resolve(pipeline, this);

            Directory.CreateDirectory(bundleArtifactPath);

            var builds      = new AssetBundleBuild[assetBundleDefs.Sum(abd => abd.assetBundles.Length)];
            var buildsIndex = 0;

            for (int defIndex = 0; defIndex < assetBundleDefs.Length; defIndex++)
            {
                var assetBundleDef   = assetBundleDefs[defIndex];
                var playerAssemblies = CompilationPipeline.GetAssemblies();
                var assemblyFiles    = playerAssemblies.Select(pa => pa.outputPath).ToArray();
                var sourceFiles      = playerAssemblies.SelectMany(pa => pa.sourceFiles).ToArray();

                var fileCount = 0;

                var logBuilder = new StringBuilder();
                logBuilder.AppendLine("Constructing AssetBundles");
                for (int i = 0; i < assetBundleDef.assetBundles.Length; i++)
                {
                    var def = assetBundleDef.assetBundles[i];

                    var explicitAssets = assetBundleDef.assetBundles.Where((ab, abi) => abi != i).SelectMany(ab => ab.assets).Select(asset => AssetDatabase.GetAssetPath(asset)).ToArray();
                    var build          = builds[buildsIndex];

                    var assets = new List <string>();

                    logBuilder.AppendLine($"Building bundle: {def.assetBundleName}");

                    var firstAsset = def.assets.FirstOrDefault(x => x is SceneAsset);

                    if (firstAsset != null)
                    {
                        assets.Add(AssetDatabase.GetAssetPath(firstAsset));
                    }
                    else
                    {
                        foreach (var asset in def.assets)
                        {
                            var assetPath = AssetDatabase.GetAssetPath(asset);

                            if (AssetDatabase.IsValidFolder(assetPath))
                            {
                                assets.AddRange(Directory.GetFiles(assetPath, "*", SearchOption.AllDirectories)
                                                .SelectMany(ap => AssetDatabase.GetDependencies(ap).Union(new[] { ap })));
                            }

                            else if (asset is UnityPackage up)
                            {
                                if (up.exportPackageOptions.HasFlag(ExportPackageOptions.Recurse))
                                {
                                    foreach (var upAsset in up.AssetFiles)
                                    {
                                        var path = AssetDatabase.GetAssetPath(upAsset);
                                        if (AssetDatabase.IsValidFolder(path))
                                        {
                                            assets.AddRange(Directory.GetFiles(path, "*", SearchOption.AllDirectories)
                                                            .SelectMany(ap => AssetDatabase.GetDependencies(ap).Union(new[] { ap })));
                                        }
                                        else
                                        {
                                            assets.Add(path);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                assets.AddRange(AssetDatabase.GetDependencies(assetPath)
                                                .Where(ap => AssetDatabase.GetMainAssetTypeAtPath(ap) != typeof(UnityPackage))
                                                .Union(new[] { assetPath }));
                            }
                        }
                    }

                    build.assetNames = assets
                                       .Select(ap => ap.Replace("\\", "/"))
                                       //.Where(dap => !explicitDownstreamAssets.Contains(dap))
                                       .Where(dap => !ArrayUtility.Contains(explicitAssets, dap) &&
                                              !ArrayUtility.Contains(excludedExtensions, Path.GetExtension(dap)) &&
                                              !ArrayUtility.Contains(sourceFiles, dap) &&
                                              !ArrayUtility.Contains(assemblyFiles, dap) &&
                                              !AssetDatabase.IsValidFolder(dap))
                                       .Distinct()
                                       .ToArray();
                    build.assetBundleName = def.assetBundleName;
                    builds[buildsIndex]   = build;
                    buildsIndex++;

                    fileCount += build.assetNames.Length;
                    foreach (var asset in build.assetNames)
                    {
                        logBuilder.AppendLine(asset);
                    }
                }
                logBuilder.AppendLine($"Constructed {builds.Length} AssetBundleBuilds with {fileCount} files.");

                Debug.Log(logBuilder.ToString());
            }

            if (!simulate)
            {
                var allBuilds = builds.ToArray();
                BuildPipeline.BuildAssetBundles(bundleArtifactPath, allBuilds, AssetBundleBuildOptions, buildTarget);
                for (pipeline.ManifestIndex = 0; pipeline.ManifestIndex < pipeline.Manifests.Length; pipeline.ManifestIndex++)
                {
                    var manifest = pipeline.Manifest;
                    foreach (var assetBundleDef in manifest.Data.OfType <AssetBundleDefinitions>())
                    {
                        var bundleNames = assetBundleDef.assetBundles.Select(ab => ab.assetBundleName).ToArray();
                        foreach (var outputPath in assetBundleDef.StagingPaths.Select(path => path.Resolve(pipeline, this)))
                        {
                            foreach (string dirPath in Directory.GetDirectories(bundleArtifactPath, "*", SearchOption.AllDirectories))
                            {
                                Directory.CreateDirectory(dirPath.Replace(bundleArtifactPath, outputPath));
                            }

                            foreach (string filePath in Directory.GetFiles(bundleArtifactPath, "*", SearchOption.AllDirectories))
                            {
                                bool found = false;
                                foreach (var bundleName in bundleNames)
                                {
                                    if (filePath.IndexOf(bundleName, System.StringComparison.OrdinalIgnoreCase) >= 0)
                                    {
                                        found = true;
                                        break;
                                    }
                                }
                                if (!found)
                                {
                                    continue;
                                }
                                string destFileName = filePath.Replace(bundleArtifactPath, outputPath);
                                Directory.CreateDirectory(Path.GetDirectoryName(destFileName));
                                FileUtil.ReplaceFile(filePath, destFileName);
                            }

                            var manifestSource      = Path.Combine(bundleArtifactPath, $"{Path.GetFileName(bundleArtifactPath)}.manifest");
                            var manifestDestination = Path.Combine(outputPath, $"{manifest.Identity.Name}.manifest");
                            FileUtil.ReplaceFile(manifestSource, manifestDestination);
                        }
                    }
                }
                pipeline.ManifestIndex = -1;
            }
        }
コード例 #29
0
        private static void OnCompilationFinished(string assemblyPath, CompilerMessage[] messages)
        {
            var sw = Stopwatch.StartNew();

            if (Array.FindIndex(messages, IsErrorMessage) != -1)
            {
                return;
            }

            var assemblyName = Path.GetFileNameWithoutExtension(assemblyPath);

            if (assemblyName == null || assemblyName == UniMobRuntimeAssemblyName)
            {
                return;
            }

            //if (assemblyName == UniMobEditorAssemblyName)
            //{
            //    // should we reload scripts when Weaver changed?
            //    // it allow package update but assemblies will reload twice
            //    // on project startup
            //    SessionState.SetBool(UniMobWeavedFlagName, false);
            //    return;
            //}

            if (assemblyPath.Contains("-Editor") || assemblyPath.Contains(".Editor"))
            {
                return;
            }

            var assemblies = CompilationPipeline.GetAssemblies();

            var uniMobRuntime = FindUniMobRuntime(assemblies);

            if (uniMobRuntime == null)
            {
                Debug.LogError("Failed to find UniMob runtime assembly");
                return;
            }

            if (!File.Exists(uniMobRuntime.outputPath))
            {
                return;
            }

            var dependencyPaths = new HashSet <string>
            {
                Path.GetDirectoryName(assemblyPath)
            };

            var shouldWeave = false;

            for (var asmIndex = 0; asmIndex < assemblies.Length; asmIndex++)
            {
                var assembly = assemblies[asmIndex];
                if (assembly.outputPath != assemblyPath)
                {
                    continue;
                }

                for (var i = 0; i < assembly.compiledAssemblyReferences.Length; i++)
                {
                    var referencePath = assembly.compiledAssemblyReferences[i];
                    dependencyPaths.Add(Path.GetDirectoryName(referencePath));
                }

                for (var i = 0; i < assembly.assemblyReferences.Length; i++)
                {
                    var reference = assembly.assemblyReferences[i];
                    if (reference.outputPath == uniMobRuntime.outputPath)
                    {
                        shouldWeave = true;
                    }
                }

                break;
            }

            if (!shouldWeave)
            {
                return;
            }

            Weave(assemblyPath, dependencyPaths);

#if UNIMOB_WEAVER_LOGGING_ENABLED
            Debug.Log($"Weaved {assemblyPath} in {sw.ElapsedMilliseconds}ms");
#endif
        }
コード例 #30
0
    public static void Build()
    {
        var getFilePath = Application.dataPath + "/" + HotFixCodePath;

        Debug.Log("getFilePath" + getFilePath);
        string[] scritpsFilePaths = Directory.GetFiles(getFilePath, "*.cs", SearchOption.AllDirectories).Where(
            x => !x.Contains("AssemblyInfo") && !x.Contains("TemporaryGeneratedFile")).ToArray();

        #region 根据csproj过滤工程

        //var csProjTxt= File.ReadAllText(Application.dataPath + "/" +HotFixCsproj);
        //XMLParser p =new XMLParser();
        //p.Parse(csProjTxt);
        //var projXml = p.ToXml();
        //projXml.GetChildNodeList("ItemGroup");
        #endregion



        AssemblyBuilder assemblyBuilder = new AssemblyBuilder("Assets/Resources/Data/HotfixCode/Hotfix_dll.bytes", scritpsFilePaths);
        assemblyBuilder.buildTarget = EditorUserBuildSettings.activeBuildTarget;
        List <string> assemblyNamesList = new List <string>();
        foreach (UnityEditor.Compilation.Assembly assembly in CompilationPipeline.GetAssemblies())
        {
            if ((assembly.flags & AssemblyFlags.EditorAssembly) == AssemblyFlags.None)
            {
                if (assembly.name.Contains("spine"))
                {
                    continue;
                }
                assemblyNamesList.Add("Temp/UnityVS_bin/Debug/" + assembly.name + ".dll");
            }
        }
        //EditorBuildRules
        assemblyBuilder.additionalReferences = assemblyNamesList.ToArray();

        assemblyBuilder.flags = AssemblyBuilderFlags.DevelopmentBuild;
        //assemblyBuilder.c
        assemblyBuilder.buildFinished += delegate(string assemblyPath, CompilerMessage[] compilerMessages)
        {
            var errorCount   = compilerMessages.Count(m => m.type == CompilerMessageType.Error);
            var warningCount = compilerMessages.Count(m => m.type == CompilerMessageType.Warning);

            Debug.LogFormat("Assembly build finished for {0}", assemblyPath);
            Debug.LogFormat("Warnings: {0} - Errors: {0}", errorCount, warningCount);
            if (errorCount > 0)
            {
                foreach (var _compilerMessage in compilerMessages)
                {
                    if (_compilerMessage.type == CompilerMessageType.Error)
                    {
                        Debug.LogErrorFormat("File {0} Msg {1} ", _compilerMessage.file, _compilerMessage.message);
                    }
                    else
                    {
                        Debug.LogFormat("File {0} Msg {1} ", _compilerMessage.file, _compilerMessage.message);
                    }
                }
            }
        };
        if (assemblyBuilder.Build())
        {
            Debug.Log("BuildSuccess");
        }
        else
        {
            Debug.LogErrorFormat("Failed to start build of assembly {0}!", assemblyBuilder.assemblyPath);
        }
    }