/// <summary> /// Write a Module to a JSON writer. If array is empty, don't write anything /// </summary> /// <param name="BinaryOutputDir"></param> /// <param name="TargetOutputDir"></param> /// <param name="Writer">Writer for the array data</param> /// <param name="Module"></param> private static void ExportModule(UEBuildModule Module, DirectoryReference BinaryOutputDir, DirectoryReference TargetOutputDir, JsonWriter Writer) { Writer.WriteValue("Name", Module.Name); Writer.WriteValue("Directory", Module.ModuleDirectory.FullName); Writer.WriteValue("Rules", Module.RulesFile.FullName); Writer.WriteValue("PCHUsage", Module.Rules.PCHUsage.ToString()); if (Module.Rules.PrivatePCHHeaderFile != null) { Writer.WriteValue("PrivatePCH", FileReference.Combine(Module.ModuleDirectory, Module.Rules.PrivatePCHHeaderFile).FullName); } if (Module.Rules.SharedPCHHeaderFile != null) { Writer.WriteValue("SharedPCH", FileReference.Combine(Module.ModuleDirectory, Module.Rules.SharedPCHHeaderFile).FullName); } ExportJsonModuleArray(Writer, "PublicDependencyModules", Module.PublicDependencyModules); ExportJsonModuleArray(Writer, "PublicIncludePathModules", Module.PublicIncludePathModules); ExportJsonModuleArray(Writer, "PrivateDependencyModules", Module.PrivateDependencyModules); ExportJsonModuleArray(Writer, "PrivateIncludePathModules", Module.PrivateIncludePathModules); ExportJsonModuleArray(Writer, "DynamicallyLoadedModules", Module.DynamicallyLoadedModules); ExportJsonStringArray(Writer, "PublicSystemIncludePaths", Module.PublicSystemIncludePaths.Select(x => x.FullName)); ExportJsonStringArray(Writer, "PublicIncludePaths", Module.PublicIncludePaths.Select(x => x.FullName)); ExportJsonStringArray(Writer, "LegacyPublicIncludePaths", Module.LegacyPublicIncludePaths.Select(x => x.FullName)); ExportJsonStringArray(Writer, "PrivateIncludePaths", Module.PrivateIncludePaths.Select(x => x.FullName)); ExportJsonStringArray(Writer, "PublicLibraryPaths", Module.PublicSystemLibraryPaths.Select(x => x.FullName)); ExportJsonStringArray(Writer, "PublicAdditionalLibraries", Module.PublicSystemLibraries.Concat(Module.PublicAdditionalLibraries)); ExportJsonStringArray(Writer, "PublicFrameworks", Module.PublicFrameworks); ExportJsonStringArray(Writer, "PublicWeakFrameworks", Module.PublicWeakFrameworks); ExportJsonStringArray(Writer, "PublicDelayLoadDLLs", Module.PublicDelayLoadDLLs); ExportJsonStringArray(Writer, "PublicDefinitions", Module.PublicDefinitions); ExportJsonStringArray(Writer, "PrivateDefinitions", Module.Rules.PrivateDefinitions); ExportJsonStringArray(Writer, "ProjectDefinitions", /* TODO: Add method ShouldAddProjectDefinitions */ !Module.Rules.bTreatAsEngineModule ? Module.Rules.Target.ProjectDefinitions : new string[0]); ExportJsonStringArray(Writer, "ApiDefinitions", Module.GetEmptyApiMacros()); Writer.WriteValue("ShouldAddLegacyPublicIncludePaths", Module.Rules.bLegacyPublicIncludePaths); if (Module.Rules.CircularlyReferencedDependentModules.Any()) { Writer.WriteArrayStart("CircularlyReferencedModules"); foreach (string ModuleName in Module.Rules.CircularlyReferencedDependentModules) { Writer.WriteValue(ModuleName); } Writer.WriteArrayEnd(); } if (Module.Rules.RuntimeDependencies.Inner.Any()) { // We don't use info from RuntimeDependencies for code analyzes (at the moment) // So we're OK with skipping some values if they are not presented Writer.WriteArrayStart("RuntimeDependencies"); foreach (ModuleRules.RuntimeDependency RuntimeDependency in Module.Rules.RuntimeDependencies.Inner) { Writer.WriteObjectStart(); try { Writer.WriteValue("Path", Module.ExpandPathVariables(RuntimeDependency.Path, BinaryOutputDir, TargetOutputDir)); } catch (BuildException buildException) { Log.TraceVerbose("Value {0} for module {1} will not be stored. Reason: {2}", "Path", Module.Name, buildException); } if (RuntimeDependency.SourcePath != null) { try { Writer.WriteValue("SourcePath", Module.ExpandPathVariables(RuntimeDependency.SourcePath, BinaryOutputDir, TargetOutputDir)); } catch (BuildException buildException) { Log.TraceVerbose("Value {0} for module {1} will not be stored. Reason: {2}", "SourcePath", Module.Name, buildException); } } Writer.WriteValue("Type", RuntimeDependency.Type.ToString()); Writer.WriteObjectEnd(); } Writer.WriteArrayEnd(); } }
/// <summary> /// Write this module to a JsonWriter /// </summary> /// <param name="Writer">Writer to output to</param> void Write(JsonWriter Writer) { Writer.WriteObjectStart(); Writer.WriteValue("Name", Name); Writer.WriteValue("Type", Type.ToString()); Writer.WriteValue("LoadingPhase", LoadingPhase.ToString()); if (WhitelistPlatforms != null && WhitelistPlatforms.Length > 0) { Writer.WriteArrayStart("WhitelistPlatforms"); foreach (UnrealTargetPlatform WhitelistPlatform in WhitelistPlatforms) { Writer.WriteValue(WhitelistPlatform.ToString()); } Writer.WriteArrayEnd(); } if (BlacklistPlatforms != null && BlacklistPlatforms.Length > 0) { Writer.WriteArrayStart("BlacklistPlatforms"); foreach (UnrealTargetPlatform BlacklistPlatform in BlacklistPlatforms) { Writer.WriteValue(BlacklistPlatform.ToString()); } Writer.WriteArrayEnd(); } if (WhitelistTargets != null && WhitelistTargets.Length > 0) { Writer.WriteArrayStart("WhitelistTargets"); foreach (TargetType WhitelistTarget in WhitelistTargets) { Writer.WriteValue(WhitelistTarget.ToString()); } Writer.WriteArrayEnd(); } if (BlacklistTargets != null && BlacklistTargets.Length > 0) { Writer.WriteArrayStart("BlacklistTargets"); foreach (TargetType BlacklistTarget in BlacklistTargets) { Writer.WriteValue(BlacklistTarget.ToString()); } Writer.WriteArrayEnd(); } if (WhitelistTargetConfigurations != null && WhitelistTargetConfigurations.Length > 0) { Writer.WriteArrayStart("WhitelistTargetConfigurations"); foreach (UnrealTargetConfiguration WhitelistTargetConfiguration in WhitelistTargetConfigurations) { Writer.WriteValue(WhitelistTargetConfiguration.ToString()); } Writer.WriteArrayEnd(); } if (BlacklistTargetConfigurations != null && BlacklistTargetConfigurations.Length > 0) { Writer.WriteArrayStart("BlacklistTargetConfigurations"); foreach (UnrealTargetConfiguration BlacklistTargetConfiguration in BlacklistTargetConfigurations) { Writer.WriteValue(BlacklistTargetConfiguration.ToString()); } Writer.WriteArrayEnd(); } if (AdditionalDependencies != null && AdditionalDependencies.Length > 0) { Writer.WriteArrayStart("AdditionalDependencies"); foreach (string AdditionalDependency in AdditionalDependencies) { Writer.WriteValue(AdditionalDependency); } Writer.WriteArrayEnd(); } Writer.WriteObjectEnd(); }
/// <summary> /// Write the receipt to disk. /// </summary> /// <param name="FileName">Output filename</param> public void Write(string FileName) { using (JsonWriter Writer = new JsonWriter(FileName)) { Writer.WriteObjectStart(); Writer.WriteValue("TargetName", TargetName); Writer.WriteValue("Platform", Platform.ToString()); Writer.WriteValue("Configuration", Configuration.ToString()); Writer.WriteValue("BuildId", BuildId); Writer.WriteObjectStart("Version"); Version.WriteProperties(Writer); Writer.WriteObjectEnd(); Writer.WriteArrayStart("BuildProducts"); foreach (BuildProduct BuildProduct in BuildProducts) { Writer.WriteObjectStart(); Writer.WriteValue("Path", BuildProduct.Path); Writer.WriteValue("Type", BuildProduct.Type.ToString()); if (BuildProduct.IsPrecompiled) { Writer.WriteValue("IsPrecompiled", BuildProduct.IsPrecompiled); } Writer.WriteObjectEnd(); } Writer.WriteArrayEnd(); Writer.WriteArrayStart("RuntimeDependencies"); foreach (RuntimeDependency RuntimeDependency in RuntimeDependencies) { Writer.WriteObjectStart(); Writer.WriteValue("Path", RuntimeDependency.Path); Writer.WriteValue("Type", RuntimeDependency.Type.ToString()); Writer.WriteObjectEnd(); } Writer.WriteArrayEnd(); if (AdditionalProperties.Count > 0) { Writer.WriteArrayStart("AdditionalProperties"); foreach (ReceiptProperty AdditionalProperty in AdditionalProperties) { Writer.WriteObjectStart(); Writer.WriteValue("Name", AdditionalProperty.Name); Writer.WriteValue("Value", AdditionalProperty.Value); Writer.WriteObjectEnd(); } Writer.WriteArrayEnd(); } if (PrecompiledBuildDependencies.Count > 0) { Writer.WriteArrayStart("PrecompiledBuildDependencies"); foreach (string PrecompiledBuildDependency in PrecompiledBuildDependencies.OrderBy(x => x)) { Writer.WriteValue(PrecompiledBuildDependency); } Writer.WriteArrayEnd(); } if (PrecompiledRuntimeDependencies.Count > 0) { Writer.WriteArrayStart("PrecompiledRuntimeDependencies"); foreach (string PrecompiledRuntimeDependency in PrecompiledRuntimeDependencies.OrderBy(x => x)) { Writer.WriteValue(PrecompiledRuntimeDependency); } Writer.WriteArrayEnd(); } Writer.WriteObjectEnd(); } }
/// <summary> /// Write the receipt to disk. /// </summary> /// <param name="Location">Output filename</param> /// <param name="EngineDir">Engine directory for expanded paths</param> public void Write(FileReference Location, DirectoryReference EngineDir) { using (JsonWriter Writer = new JsonWriter(Location.FullName)) { Writer.WriteObjectStart(); Writer.WriteValue("TargetName", TargetName); Writer.WriteValue("Platform", Platform.ToString()); Writer.WriteValue("Configuration", Configuration.ToString()); Writer.WriteValue("TargetType", TargetType.ToString()); Writer.WriteValue("Architecture", Architecture); if (ProjectFile != null) { Writer.WriteValue("Project", ProjectFile.MakeRelativeTo(Location.Directory).Replace(Path.DirectorySeparatorChar, '/')); } if (Launch != null) { Writer.WriteValue("Launch", InsertPathVariables(Launch, EngineDir, ProjectDir)); } Writer.WriteObjectStart("Version"); Version.WriteProperties(Writer); Writer.WriteObjectEnd(); Writer.WriteArrayStart("BuildProducts"); foreach (BuildProduct BuildProduct in BuildProducts) { Writer.WriteObjectStart(); Writer.WriteValue("Path", InsertPathVariables(BuildProduct.Path, EngineDir, ProjectDir)); Writer.WriteValue("Type", BuildProduct.Type.ToString()); Writer.WriteObjectEnd(); } Writer.WriteArrayEnd(); Writer.WriteArrayStart("RuntimeDependencies"); foreach (RuntimeDependency RuntimeDependency in RuntimeDependencies) { Writer.WriteObjectStart(); Writer.WriteValue("Path", InsertPathVariables(RuntimeDependency.Path, EngineDir, ProjectDir)); Writer.WriteValue("Type", RuntimeDependency.Type.ToString()); Writer.WriteObjectEnd(); } Writer.WriteArrayEnd(); if (PluginNameToEnabledState.Count > 0) { Writer.WriteArrayStart("Plugins"); foreach (KeyValuePair <string, bool> PluginNameToEnabledStatePair in PluginNameToEnabledState.OrderBy(x => x.Key)) { Writer.WriteObjectStart(); Writer.WriteValue("Name", PluginNameToEnabledStatePair.Key); Writer.WriteValue("Enabled", PluginNameToEnabledStatePair.Value); Writer.WriteObjectEnd(); } Writer.WriteArrayEnd(); } if (AdditionalProperties.Count > 0) { Writer.WriteArrayStart("AdditionalProperties"); foreach (ReceiptProperty AdditionalProperty in AdditionalProperties) { Writer.WriteObjectStart(); Writer.WriteValue("Name", AdditionalProperty.Name); Writer.WriteValue("Value", AdditionalProperty.Value); Writer.WriteObjectEnd(); } Writer.WriteArrayEnd(); } Writer.WriteObjectEnd(); } }
/// <summary> /// Writes a manifest containing all the information needed to create a live coding patch /// </summary> /// <param name="ManifestFile">File to write to</param> /// <param name="Actions">List of actions that are part of the graph</param> public static void WriteLiveCodingManifest(FileReference ManifestFile, List <Action> Actions) { // Find all the output object files HashSet <FileItem> ObjectFiles = new HashSet <FileItem>(); foreach (Action Action in Actions) { if (Action.ActionType == ActionType.Compile) { ObjectFiles.UnionWith(Action.ProducedItems.Where(x => x.HasExtension(".obj"))); } } // Write the output manifest using (JsonWriter Writer = new JsonWriter(ManifestFile)) { Writer.WriteObjectStart(); Action LinkAction = Actions.FirstOrDefault(x => x.ActionType == ActionType.Link && x.ProducedItems.Any(y => y.HasExtension(".exe") || y.HasExtension(".dll"))); if (LinkAction != null) { Writer.WriteValue("LinkerPath", LinkAction.CommandPath.FullName); } Writer.WriteObjectStart("LinkerEnvironment"); foreach (System.Collections.DictionaryEntry Entry in Environment.GetEnvironmentVariables()) { Writer.WriteValue(Entry.Key.ToString(), Entry.Value.ToString()); } Writer.WriteObjectEnd(); Writer.WriteArrayStart("Modules"); foreach (Action Action in Actions) { if (Action.ActionType == ActionType.Link) { FileItem OutputFile = Action.ProducedItems.FirstOrDefault(x => x.HasExtension(".exe") || x.HasExtension(".dll")); if (OutputFile != null) { Writer.WriteObjectStart(); Writer.WriteValue("Output", OutputFile.Location.FullName); Writer.WriteArrayStart("Inputs"); foreach (FileItem InputFile in Action.PrerequisiteItems) { if (ObjectFiles.Contains(InputFile)) { Writer.WriteValue(InputFile.AbsolutePath); } } Writer.WriteArrayEnd(); Writer.WriteObjectEnd(); } } } Writer.WriteArrayEnd(); Writer.WriteObjectEnd(); } }
/// <summary> /// Execute the command /// </summary> /// <param name="Arguments">Command line arguments</param> /// <returns>Exit code</returns> public override int Execute(CommandLineArguments Arguments) { Arguments.ApplyTo(this); // Create the build configuration object, and read the settings BuildConfiguration BuildConfiguration = new BuildConfiguration(); XmlConfig.ApplyTo(BuildConfiguration); Arguments.ApplyTo(BuildConfiguration); // Parse the filter argument FileFilter FileFilter = null; if (FilterRules.Count > 0) { FileFilter = new FileFilter(FileFilterType.Exclude); foreach (string FilterRule in FilterRules) { FileFilter.AddRules(FilterRule.Split(';')); } } // Parse all the target descriptors List <TargetDescriptor> TargetDescriptors = TargetDescriptor.ParseCommandLine(Arguments, BuildConfiguration.bUsePrecompiled, BuildConfiguration.bSkipRulesCompile); // Generate the compile DB for each target using (ISourceFileWorkingSet WorkingSet = new EmptySourceFileWorkingSet()) { // Find the compile commands for each file in the target Dictionary <FileReference, string> FileToCommand = new Dictionary <FileReference, string>(); foreach (TargetDescriptor TargetDescriptor in TargetDescriptors) { // Disable PCHs and unity builds for the target TargetDescriptor.AdditionalArguments = TargetDescriptor.AdditionalArguments.Append(new string[] { "-NoPCH", "-DisableUnity" }); // Create a makefile for the target UEBuildTarget Target = UEBuildTarget.Create(TargetDescriptor, BuildConfiguration.bSkipRulesCompile, BuildConfiguration.bUsePrecompiled); // Find the location of the compiler VCEnvironment Environment = VCEnvironment.Create(WindowsCompiler.Clang, Target.Platform, Target.Rules.WindowsPlatform.Architecture, null, Target.Rules.WindowsPlatform.WindowsSdkVersion); FileReference ClangPath = FileReference.Combine(Environment.CompilerDir, "bin", "clang++.exe"); // Create all the binaries and modules CppCompileEnvironment GlobalCompileEnvironment = Target.CreateCompileEnvironmentForProjectFiles(); foreach (UEBuildBinary Binary in Target.Binaries) { CppCompileEnvironment BinaryCompileEnvironment = Binary.CreateBinaryCompileEnvironment(GlobalCompileEnvironment); foreach (UEBuildModuleCPP Module in Binary.Modules.OfType <UEBuildModuleCPP>()) { if (!Module.Rules.bUsePrecompiled) { UEBuildModuleCPP.InputFileCollection InputFileCollection = Module.FindInputFiles(Target.Platform, new Dictionary <DirectoryItem, FileItem[]>()); List <FileItem> InputFiles = new List <FileItem>(); InputFiles.AddRange(InputFileCollection.CPPFiles); InputFiles.AddRange(InputFileCollection.CCFiles); CppCompileEnvironment ModuleCompileEnvironment = Module.CreateModuleCompileEnvironment(Target.Rules, BinaryCompileEnvironment); StringBuilder CommandBuilder = new StringBuilder(); CommandBuilder.AppendFormat("\"{0}\"", ClangPath.FullName); foreach (FileItem ForceIncludeFile in ModuleCompileEnvironment.ForceIncludeFiles) { CommandBuilder.AppendFormat(" -include \"{0}\"", ForceIncludeFile.FullName); } foreach (string Definition in ModuleCompileEnvironment.Definitions) { CommandBuilder.AppendFormat(" -D\"{0}\"", Definition); } foreach (DirectoryReference IncludePath in ModuleCompileEnvironment.UserIncludePaths) { CommandBuilder.AppendFormat(" -I\"{0}\"", IncludePath); } foreach (DirectoryReference IncludePath in ModuleCompileEnvironment.SystemIncludePaths) { CommandBuilder.AppendFormat(" -I\"{0}\"", IncludePath); } foreach (FileItem InputFile in InputFiles) { if (FileFilter == null || FileFilter.Matches(InputFile.Location.MakeRelativeTo(UnrealBuildTool.RootDirectory))) { FileToCommand[InputFile.Location] = String.Format("{0} \"{1}\"", CommandBuilder, InputFile.FullName); } } } } } } // Write the compile database FileReference DatabaseFile = FileReference.Combine(UnrealBuildTool.RootDirectory, "compile_commands.json"); using (JsonWriter Writer = new JsonWriter(DatabaseFile)) { Writer.WriteArrayStart(); foreach (KeyValuePair <FileReference, string> FileCommandPair in FileToCommand.OrderBy(x => x.Key.FullName)) { Writer.WriteObjectStart(); Writer.WriteValue("file", FileCommandPair.Key.FullName); Writer.WriteValue("command", FileCommandPair.Value); Writer.WriteValue("directory", UnrealBuildTool.EngineSourceDirectory.ToString()); Writer.WriteObjectEnd(); } Writer.WriteArrayEnd(); } } return(0); }
/// <summary> /// Write the receipt to disk. /// </summary> /// <param name="Location">Output filename</param> /// <param name="EngineDir">Engine directory for expanded paths</param> /// <param name="ProjectDir">Project directory for expanded paths</param> public void Write(FileReference Location, DirectoryReference EngineDir, DirectoryReference ProjectDir) { using (JsonWriter Writer = new JsonWriter(Location.FullName)) { Writer.WriteObjectStart(); Writer.WriteValue("TargetName", TargetName); Writer.WriteValue("Platform", Platform.ToString()); Writer.WriteValue("Configuration", Configuration.ToString()); Writer.WriteObjectStart("Version"); Version.WriteProperties(Writer); Writer.WriteObjectEnd(); Writer.WriteArrayStart("BuildProducts"); foreach (BuildProduct BuildProduct in BuildProducts) { Writer.WriteObjectStart(); Writer.WriteValue("Path", InsertPathVariables(BuildProduct.Path, EngineDir, ProjectDir)); Writer.WriteValue("Type", BuildProduct.Type.ToString()); if (BuildProduct.IsPrecompiled) { Writer.WriteValue("IsPrecompiled", BuildProduct.IsPrecompiled); } Writer.WriteObjectEnd(); } Writer.WriteArrayEnd(); Writer.WriteArrayStart("RuntimeDependencies"); foreach (RuntimeDependency RuntimeDependency in RuntimeDependencies) { Writer.WriteObjectStart(); Writer.WriteValue("Path", InsertPathVariables(RuntimeDependency.Path, EngineDir, ProjectDir)); Writer.WriteValue("Type", RuntimeDependency.Type.ToString()); Writer.WriteObjectEnd(); } Writer.WriteArrayEnd(); if (AdditionalProperties.Count > 0) { Writer.WriteArrayStart("AdditionalProperties"); foreach (ReceiptProperty AdditionalProperty in AdditionalProperties) { Writer.WriteObjectStart(); Writer.WriteValue("Name", AdditionalProperty.Name); Writer.WriteValue("Value", AdditionalProperty.Value); Writer.WriteObjectEnd(); } Writer.WriteArrayEnd(); } if (PrecompiledBuildDependencies.Count > 0) { Writer.WriteArrayStart("PrecompiledBuildDependencies"); foreach (string PrecompiledBuildDependency in PrecompiledBuildDependencies.Select(x => InsertPathVariables(x, EngineDir, ProjectDir)).OrderBy(x => x)) { Writer.WriteValue(PrecompiledBuildDependency); } Writer.WriteArrayEnd(); } if (PrecompiledRuntimeDependencies.Count > 0) { Writer.WriteArrayStart("PrecompiledRuntimeDependencies"); foreach (string PrecompiledRuntimeDependency in PrecompiledRuntimeDependencies.Select(x => InsertPathVariables(x, EngineDir, ProjectDir)).OrderBy(x => x)) { Writer.WriteValue(PrecompiledRuntimeDependency); } Writer.WriteArrayEnd(); } Writer.WriteObjectEnd(); } }