Esempio n. 1
0
        /// <summary>
        /// Construct an instance of the given target rules
        /// </summary>
        /// <param name="TypeName">Type name of the target rules</param>
        /// <param name="TargetInfo">Target configuration information to pass to the constructor</param>
        /// <param name="Arguments">Command line arguments for this target</param>
        /// <returns>Instance of the corresponding TargetRules</returns>
        protected TargetRules CreateTargetRulesInstance(string TypeName, TargetInfo TargetInfo, string[] Arguments)
        {
            // The build module must define a type named '<TargetName>Target' that derives from our 'TargetRules' type.
            Type RulesType = CompiledAssembly.GetType(TypeName);

            if (RulesType == null)
            {
                throw new BuildException("Expecting to find a type to be declared in a target rules named '{0}'.  This type must derive from the 'TargetRules' type defined by Unreal Build Tool.", TypeName);
            }

            // Create an instance of the module's rules object, and set some defaults before calling the constructor.
            TargetRules Rules = (TargetRules)FormatterServices.GetUninitializedObject(RulesType);

            Rules.bUseBackwardsCompatibleDefaults = bUseBackwardsCompatibleDefaults;

            // Find the constructor
            ConstructorInfo Constructor = RulesType.GetConstructor(new Type[] { typeof(TargetInfo) });

            if (Constructor == null)
            {
                throw new BuildException("No constructor found on {0} which takes an argument of type TargetInfo.", RulesType.Name);
            }

            // Invoke the regular constructor
            try
            {
                Constructor.Invoke(Rules, new object[] { TargetInfo });
            }
            catch (Exception Ex)
            {
                throw new BuildException(Ex, "Unable to instantiate instance of '{0}' object type from compiled assembly '{1}'.  Unreal Build Tool creates an instance of your module's 'Rules' object in order to find out about your module's requirements.  The CLR exception details may provide more information:  {2}", TypeName, Path.GetFileNameWithoutExtension(CompiledAssembly.Location), Ex.ToString());
            }

            // Set the default overriddes for the configured target type
            Rules.SetOverridesForTargetType();

            // Parse any additional command-line arguments. These override default settings specified in config files or the .target.cs files.
            if (Arguments != null)
            {
                foreach (object ConfigurableObject in Rules.GetConfigurableObjects())
                {
                    CommandLine.ParseArguments(Arguments, ConfigurableObject);
                }
            }

            // Set the final value for the link type in the target rules
            if (Rules.LinkType == TargetLinkType.Default)
            {
                throw new BuildException("TargetRules.LinkType should be inferred from TargetType");
            }

            // Set the default value for whether to use the shared build environment
            if (Rules.BuildEnvironment == TargetBuildEnvironment.Default)
            {
                if (Rules.Type == TargetType.Program && TargetInfo.ProjectFile != null && TargetNameToTargetFile[Rules.Name].IsUnderDirectory(TargetInfo.ProjectFile.Directory))
                {
                    Rules.BuildEnvironment = TargetBuildEnvironment.Unique;
                }
                else if (UnrealBuildTool.IsEngineInstalled() || Rules.LinkType != TargetLinkType.Monolithic)
                {
                    Rules.BuildEnvironment = TargetBuildEnvironment.Shared;
                }
                else
                {
                    Rules.BuildEnvironment = TargetBuildEnvironment.Unique;
                }
            }

            // Lean and mean means no Editor and other frills.
            if (Rules.bCompileLeanAndMeanUE)
            {
                Rules.bBuildEditor         = false;
                Rules.bBuildDeveloperTools = Rules.bBuildDeveloperTools ?? false;
                Rules.bCompileSimplygon    = false;
                Rules.bCompileSimplygonSSF = false;
                Rules.bCompileSpeedTree    = false;
            }

            // if the bBuildDeveloperTools switch hasn't been defined, default it to the bCompileAgainstEngine switch.
            if (!Rules.bBuildDeveloperTools.HasValue)
            {
                Rules.bBuildDeveloperTools = Rules.bCompileAgainstEngine;
            }

            // Automatically include CoreUObject
            if (Rules.bCompileAgainstEngine)
            {
                Rules.bCompileAgainstCoreUObject = true;
            }

            // Must have editor only data if building the editor.
            if (Rules.bBuildEditor)
            {
                Rules.bBuildWithEditorOnlyData = true;
            }

            // Apply the override to force debug info to be enabled
            if (Rules.bForceDebugInfo)
            {
                Rules.bDisableDebugInfo             = false;
                Rules.bOmitPCDebugInfoInDevelopment = false;
            }

            // Setup the malloc profiler
            if (Rules.bUseMallocProfiler)
            {
                Rules.bOmitFramePointers = false;
                Rules.GlobalDefinitions.Add("USE_MALLOC_PROFILER=1");
            }

            // Set a macro if we allow using generated inis
            if (!Rules.bAllowGeneratedIniWhenCooked)
            {
                Rules.GlobalDefinitions.Add("DISABLE_GENERATED_INI_WHEN_COOKED=1");
            }

            return(Rules);
        }
Esempio n. 2
0
        public LuminToolChain(FileReference InProjectFile, bool bInUseLdGold = true, IReadOnlyList <string> InAdditionalArches = null, IReadOnlyList <string> InAdditionalGPUArches = null, bool bAllowMissingNDK = true)
            : base(CppPlatform.Lumin, InProjectFile,
                   // @todo Lumin: ld gold?
                   true, null, null, true)

        {
            AdditionalGPUArches = new List <string>();
            if (InAdditionalGPUArches != null)
            {
                AdditionalGPUArches.AddRange(InAdditionalGPUArches);
            }


            // by default tools chains don't parse arguments, but we want to be able to check the -gpuarchitectures flag defined above. This is
            // only necessary when LuminToolChain is used during UAT
            CommandLine.ParseArguments(Environment.GetCommandLineArgs(), this);
            if (AdditionalGPUArches.Count == 0 && GPUArchitectureArg.Count > 0)
            {
                AdditionalGPUArches.AddRange(GPUArchitectureArg);
            }

            string MLSDKPath = Environment.GetEnvironmentVariable("MLSDK");

            // don't register if we don't have an MLSDK specified
            if (String.IsNullOrEmpty(MLSDKPath))
            {
                throw new BuildException("MLSDK is not specified; cannot use Lumin toolchain.");
            }

            MLSDKPath = MLSDKPath.Replace("\"", "");

            string MabuSpec = RunMabuAndReadOutput("-t device --print-spec");

            // parse clange version
            Regex SpecRegex = new Regex("\\s*(?:[a-z]+_lumin_clang-)(\\d)[.](\\d)\\s*");

            Match SpecMatch = SpecRegex.Match(MabuSpec);

            if (SpecMatch.Groups.Count != 3)
            {
                throw new BuildException("Could not parse clang version from mabu spec '{0}'", MabuSpec);
            }

            string ClangVersion = string.Format("{0}.{1}", SpecMatch.Groups[1].Value, SpecMatch.Groups[2].Value);

            SetClangVersion(int.Parse(SpecMatch.Groups[1].Value), int.Parse(SpecMatch.Groups[2].Value), 0);

            string MabuTools = RunMabuAndReadOutput("-t device --print-tools");

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

            using (StringReader Reader = new StringReader(MabuTools))
            {
                string Line = null;
                while (null != (Line = Reader.ReadLine()))
                {
                    string[] Split = Line.Split('=');
                    if (Split.Length != 2)
                    {
                        throw new BuildException("Unexpected output from mabu in --print-tools: '{0}'", Line);
                    }

                    ToolsDict.Add(Split[0].Trim(), Split[1].Trim());
                }
            }

            // set up the path to our toolchains
            // Clang path used to be in quotes, but some part of FileReference in AndroidToolChain was choking on the quotes.  Don't put your MLSDK in a directory with spaces for now, I guess.
            ClangPath   = ToolsDict["CXX"];
            ArPathArm64 = "\"" + ToolsDict["AR"] + "\"";
            // The strip command does not execute through the shell. Hence we don't quote it.
            StripPath = ToolsDict["STRIP"];
            // The objcopy command does not execute through the shell. Hence we don't quote it.
            ObjCopyPath = ToolsDict["OBJCOPY"];

            // force the compiler to be executed through a command prompt instance
            bExecuteCompilerThroughShell = true;

            // toolchain params
            ToolchainParamsArm64 = " --sysroot=\"" + Path.Combine(MLSDKPath, "lumin") + "\"";

            ToolchainLinkParamsArm   = ToolchainParamsArm;
            ToolchainLinkParamsArm64 = ToolchainParamsArm64;
            ToolchainLinkParamsx86   = ToolchainParamsx86;
            ToolchainLinkParamsx64   = ToolchainParamsx64;
        }
Esempio n. 3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="ProjectFile"></param>
        /// <param name="Executable"></param>
        /// <param name="StageDirectory"></param>
        /// <param name="PlatformType"></param>
        public static void GenerateAssetCatalog(FileReference ProjectFile, string Executable, string StageDirectory, UnrealTargetPlatform PlatformType)
        {
            // Initialize the toolchain.
            IOSProjectSettings ProjectSettings = ((IOSPlatform)UEBuildPlatform.GetBuildPlatform(PlatformType)).ReadProjectSettings(null);
            IOSToolChain       ToolChain       = new IOSToolChain(ProjectFile, ProjectSettings);

            // Determine whether the user has modified icons that require a remote Mac to build.
            CppPlatform Platform         = PlatformType == UnrealTargetPlatform.IOS ? CppPlatform.IOS : CppPlatform.TVOS;
            bool        bUserImagesExist = false;

            ToolChain.GenerateAssetCatalog(Platform, ref bUserImagesExist);

            // Don't attempt to do anything remotely if the user is using the default UE4 images.
            if (!bUserImagesExist)
            {
                return;
            }

            // Also don't attempt to use a remote Mac if packaging for TVOS on PC.
            if (Platform == CppPlatform.TVOS && BuildHostPlatform.Current.Platform != UnrealTargetPlatform.Mac)
            {
                return;
            }

            // Save off the current bUseRPCUtil setting to restore at the end of this function.
            // At this time, iPhonePackager needs to be called with bUseRPCUtil == true.
            bool bSaveUseRPCUtil = RemoteToolChain.bUseRPCUtil;

            // Initialize the remote calling environment, taking into account the user's SSH setting.
            ToolChain.SetUpGlobalEnvironment(false);

            // Build the asset catalog ActionGraph.
            ActionGraph     ActionGraph = new ActionGraph();
            List <FileItem> OutputFiles = new List <FileItem>();

            ToolChain.CompileAssetCatalog(FileItem.GetItemByPath(Executable), Platform, ActionGraph, OutputFiles);

            ActionGraph.FinalizeActionGraph();

            // I'm not sure how to derive the UE4Game and Development arguments programmatically.
            string[] Arguments = new string[] { "UE4Game", (PlatformType == UnrealTargetPlatform.IOS ? "IOS" : "TVOS"), "Development", "-UniqueBuildEnvironment" };

            // Perform all of the setup necessary to actually execute the ActionGraph instance.
            ReadOnlyBuildVersion Version        = new ReadOnlyBuildVersion(BuildVersion.ReadDefault());
            List <string[]>      TargetSettings = new List <string[]>();

            TargetSettings.Add(Arguments);
            var Targets = new List <UEBuildTarget>();
            Dictionary <UEBuildTarget, CPPHeaders> TargetToHeaders = new Dictionary <UEBuildTarget, CPPHeaders>();
            List <TargetDescriptor> TargetDescs = new List <TargetDescriptor>();

            foreach (string[] TargetSetting in TargetSettings)
            {
                TargetDescs.AddRange(TargetDescriptor.ParseCommandLine(TargetSetting, ref ProjectFile));
            }
            foreach (TargetDescriptor TargetDesc in TargetDescs)
            {
                UEBuildTarget Target = UEBuildTarget.CreateTarget(TargetDesc, Arguments, false, Version);
                if (Target == null)
                {
                    continue;
                }
                Targets.Add(Target);
                TargetToHeaders.Add(Target, null);
            }

            bool bIsRemoteCompile = BuildHostPlatform.Current.Platform != UnrealTargetPlatform.Mac;

            // Create the build configuration object, and read the settings
            BuildConfiguration BuildConfiguration = new BuildConfiguration();

            XmlConfig.ApplyTo(BuildConfiguration);
            CommandLine.ParseArguments(Arguments, BuildConfiguration);
            BuildConfiguration.bUseUBTMakefiles = false;

            Action[] PrerequisiteActions;
            {
                HashSet <Action> PrerequisiteActionsSet = new HashSet <Action>();
                foreach (FileItem OutputFile in OutputFiles)
                {
                    ActionGraph.GatherPrerequisiteActions(OutputFile, ref PrerequisiteActionsSet);
                }
                PrerequisiteActions = PrerequisiteActionsSet.ToArray();
            }

            // Copy any asset catalog files to the remote Mac, if necessary.
            foreach (UEBuildTarget Target in Targets)
            {
                UEBuildPlatform.GetBuildPlatform(Target.Platform).PreBuildSync();
            }

            // Begin execution of the ActionGraph.
            Dictionary <UEBuildTarget, List <FileItem> > TargetToOutdatedPrerequisitesMap;
            List <Action> ActionsToExecute = ActionGraph.GetActionsToExecute(BuildConfiguration, PrerequisiteActions, Targets, TargetToHeaders, true, true, out TargetToOutdatedPrerequisitesMap);
            string        ExecutorName     = "Unknown";
            bool          bSuccess         = ActionGraph.ExecuteActions(BuildConfiguration, ActionsToExecute, bIsRemoteCompile, out ExecutorName, "", EHotReload.Disabled);

            if (bSuccess)
            {
                if (bIsRemoteCompile)
                {
                    // Copy the remotely built AssetCatalog directory locally.
                    foreach (FileItem OutputFile in OutputFiles)
                    {
                        string   RemoteDirectory = System.IO.Path.GetDirectoryName(OutputFile.AbsolutePath).Replace("\\", "/");
                        FileItem LocalExecutable = ToolChain.RemoteToLocalFileItem(FileItem.GetItemByPath(Executable));
                        string   LocalDirectory  = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(LocalExecutable.AbsolutePath), "AssetCatalog");
                        LocalDirectory = StageDirectory;
                        RPCUtilHelper.CopyDirectory(RemoteDirectory, LocalDirectory, RPCUtilHelper.ECopyOptions.DoNotReplace);
                    }
                }
                else
                {
                    // Copy the built AssetCatalog directory to the StageDirectory.
                    foreach (FileItem OutputFile in OutputFiles)
                    {
                        string SourceDirectory = System.IO.Path.GetDirectoryName(OutputFile.AbsolutePath).Replace("\\", "/");
                        System.IO.DirectoryInfo SourceDirectoryInfo = new System.IO.DirectoryInfo(SourceDirectory);
                        if (!System.IO.Directory.Exists(StageDirectory))
                        {
                            System.IO.Directory.CreateDirectory(StageDirectory);
                        }
                        System.IO.FileInfo[] SourceFiles = SourceDirectoryInfo.GetFiles();
                        foreach (System.IO.FileInfo SourceFile in SourceFiles)
                        {
                            string DestinationPath = System.IO.Path.Combine(StageDirectory, SourceFile.Name);
                            SourceFile.CopyTo(DestinationPath, true);
                        }
                    }
                }
            }

            // Restore the former bUseRPCUtil setting.
            RemoteToolChain.bUseRPCUtil = bSaveUseRPCUtil;
        }