Пример #1
0
        /// <summary>
        /// Format an include of the given file
        /// </summary>
        /// <param name="FromDirectory">The directory containing the file with the #include directive</param>
        /// <param name="IncludeFile">File to include</param>
        /// <param name="IncludePaths">Directories to base relative include paths from</param>
        /// <param name="SystemIncludePaths">Directories to base system include paths from</param>
        /// <returns>Formatted include path, with surrounding quotes</returns>
        public static bool TryFormatInclude(DirectoryReference FromDirectory, FileReference IncludeFile, IEnumerable <DirectoryReference> IncludePaths, IEnumerable <DirectoryReference> SystemIncludePaths, out string IncludeText)
        {
            // Generated headers are always included without a path
            if (IncludeFile.FullName.Contains(".generated.") || IncludeFile.FullName.EndsWith("Classes.h"))
            {
                IncludeText = String.Format("\"{0}\"", IncludeFile.GetFileName());
                return(true);
            }

            // Try to write an include relative to one of the system include paths
            foreach (DirectoryReference SystemIncludePath in SystemIncludePaths)
            {
                if (IncludeFile.IsUnderDirectory(SystemIncludePath))
                {
                    IncludeText = String.Format("<{0}>", IncludeFile.MakeRelativeTo(SystemIncludePath).Replace('\\', '/'));
                    return(true);
                }
            }

            // Try to write an include relative to one of the standard include paths
            foreach (DirectoryReference IncludePath in IncludePaths)
            {
                if (IncludeFile.IsUnderDirectory(IncludePath))
                {
                    IncludeText = String.Format("\"{0}\"", IncludeFile.MakeRelativeTo(IncludePath).Replace('\\', '/'));
                    return(true);
                }
            }

            // Try to write an include relative to the file
            if (IncludeFile.IsUnderDirectory(FromDirectory))
            {
                IncludeText = String.Format("\"{0}\"", IncludeFile.MakeRelativeTo(FromDirectory).Replace('\\', '/'));
                return(true);
            }

            // HACK: VsPerf.h is in the compiler environment, but the include path is added directly
            if (IncludeFile.FullName.EndsWith("\\PerfSDK\\VSPerf.h", StringComparison.InvariantCultureIgnoreCase))
            {
                IncludeText = "\"VSPerf.h\"";
                return(true);
            }

            // HACK: public Paper2D header in classes folder including private Paper2D header
            if (IncludeFile.FullName.IndexOf("\\Paper2D\\Private\\", StringComparison.InvariantCultureIgnoreCase) != -1)
            {
                IncludeText = "\"" + IncludeFile.GetFileName() + "\"";
                return(true);
            }
            if (IncludeFile.FullName.IndexOf("\\OnlineSubsystemUtils\\Private\\", StringComparison.InvariantCultureIgnoreCase) != -1)
            {
                IncludeText = "\"" + IncludeFile.GetFileName() + "\"";
                return(true);
            }

            // HACK: including private headers from public headers in the same module
            int PrivateIdx = IncludeFile.FullName.IndexOf("\\Private\\", StringComparison.InvariantCultureIgnoreCase);

            if (PrivateIdx != -1)
            {
                DirectoryReference BaseDir = new DirectoryReference(IncludeFile.FullName.Substring(0, PrivateIdx));
                if (FromDirectory.IsUnderDirectory(BaseDir))
                {
                    IncludeText = "\"" + IncludeFile.MakeRelativeTo(FromDirectory).Replace('\\', '/') + "\"";
                    return(true);
                }
            }

            // Otherwise we don't know where it came from
            IncludeText = null;
            return(false);
        }
Пример #2
0
//#nv begin #Blast Linux build
    void StageBootstrapExecutable(DeploymentContext SC, StageTarget Target, string ExeName, string TargetFile, string StagedRelativeTargetPath, string StagedArguments)     //@third party code - NVSTUDIOS Set LD_LIBRARY_PATH
//nv end
    {
        // create a temp script file location
        DirectoryReference IntermediateDir  = DirectoryReference.Combine(SC.ProjectRoot, "Intermediate", "Staging");
        FileReference      IntermediateFile = FileReference.Combine(IntermediateDir, ExeName);

        DirectoryReference.CreateDirectory(IntermediateDir);

        // make sure slashes are good
        StagedRelativeTargetPath = StagedRelativeTargetPath.Replace("\\", "/");

        // make contents
        StringBuilder Script = new StringBuilder();
        string        EOL    = "\n";

        Script.Append("#!/bin/sh" + EOL);
        // allow running from symlinks
        Script.AppendFormat("UE4_TRUE_SCRIPT_NAME=$(echo \\\"$0\\\" | xargs readlink -f)" + EOL);
        Script.AppendFormat("UE4_PROJECT_ROOT=$(dirname \"$UE4_TRUE_SCRIPT_NAME\")" + EOL);
        Script.AppendFormat("chmod +x \"$UE4_PROJECT_ROOT/{0}\"" + EOL, StagedRelativeTargetPath);

//#nv begin #Blast Linux build
        //The Blast .so files are not loaded by dlopen so we we need to setup the search paths
        //Really UE should be doing this for all dependent libraries, but they usually statically link
        HashSet <string>   LDLibraryPaths   = new HashSet <string>();
        DirectoryReference TargetFileDir    = (new FileReference(TargetFile)).Directory;
        DirectoryReference SourceEngineDir  = SC.LocalRoot;
        DirectoryReference SourceProjectDir = SC.ProjectRoot;

        foreach (var RuntimeDependency in Target.Receipt.RuntimeDependencies)
        {
            foreach (FileReference File in CommandUtils.ResolveFilespec(CommandUtils.RootDirectory, RuntimeDependency.Path.FullName, new string[] { }))
            {
                if (FileReference.Exists(File) && File.GetExtension().Equals(".so", StringComparison.OrdinalIgnoreCase))
                {
                    string             FileRelativePath = null;
                    DirectoryReference SharedLibFolder  = File.Directory;
                    if (SharedLibFolder.IsUnderDirectory(SourceProjectDir))
                    {
                        FileRelativePath = Path.Combine(SharedLibFolder.MakeRelativeTo(SourceProjectDir), SC.RelativeProjectRootForStage.ToString());
                    }
                    else if (SharedLibFolder.IsUnderDirectory(SourceEngineDir))
                    {
                        FileRelativePath = SharedLibFolder.MakeRelativeTo(SourceEngineDir);
                    }

                    if (FileRelativePath != null)
                    {
                        FileRelativePath = Path.Combine("$UE4_PROJECT_ROOT", FileRelativePath);
                        FileRelativePath = FileRelativePath.Replace("\\", "/");
                        //Escape spaces
                        FileRelativePath = FileRelativePath.Replace(" ", @"\ ");
                        LDLibraryPaths.Add(FileRelativePath);
                    }
                }
            }
        }

        if (LDLibraryPaths.Count > 0)
        {
            Script.AppendFormat("export LD_LIBRARY_PATH={0}" + EOL, string.Join(":", LDLibraryPaths));
        }
//nv end
        Script.AppendFormat("\"$UE4_PROJECT_ROOT/{0}\" {1} $@ " + EOL, StagedRelativeTargetPath, StagedArguments);

        // write out the
        FileReference.WriteAllText(IntermediateFile, Script.ToString());

        if (Utils.IsRunningOnMono)
        {
            var Result = CommandUtils.Run("sh", string.Format("-c 'chmod +x \\\"{0}\\\"'", IntermediateFile));
            if (Result.ExitCode != 0)
            {
                throw new AutomationException(string.Format("Failed to chmod \"{0}\"", IntermediateFile));
            }
        }

        SC.StageFile(StagedFileType.NonUFS, IntermediateFile, new StagedFileReference(ExeName));
    }
Пример #3
0
    public override void ExecuteBuild()
    {
        // Get the plugin filename
        string PluginParam = ParseParamValue("Plugin");

        if (PluginParam == null)
        {
            throw new AutomationException("Missing -Plugin=... argument");
        }

        // Check it exists
        FileReference PluginFile = new FileReference(PluginParam);

        if (!FileReference.Exists(PluginFile))
        {
            throw new AutomationException("Plugin '{0}' not found", PluginFile.FullName);
        }

        // Get the output directory
        string PackageParam = ParseParamValue("Package");

        if (PackageParam == null)
        {
            throw new AutomationException("Missing -Package=... argument");
        }

        // Option for verifying that all include directive s
        bool bStrictIncludes = ParseParam("StrictIncludes");

        // Whether to use VS2019 for compiling all targets. By default, we currently use 2017 for compiling static libraries for maximum compatibility.
        bool bVS2019 = ParseParam("VS2019");

        // Make sure the packaging directory is valid
        DirectoryReference PackageDir = new DirectoryReference(PackageParam);

        if (PluginFile.IsUnderDirectory(PackageDir))
        {
            throw new AutomationException("Packaged plugin output directory must be different to source");
        }
        if (PackageDir.IsUnderDirectory(DirectoryReference.Combine(CommandUtils.RootDirectory, "Engine")))
        {
            throw new AutomationException("Output directory for packaged plugin must be outside engine directory");
        }

        // Clear the output directory of existing stuff
        if (DirectoryReference.Exists(PackageDir))
        {
            CommandUtils.DeleteDirectoryContents(PackageDir.FullName);
        }
        else
        {
            DirectoryReference.CreateDirectory(PackageDir);
        }

        // Create a placeholder FilterPlugin.ini with instructions on how to use it
        FileReference SourceFilterFile = FileReference.Combine(PluginFile.Directory, "Config", "FilterPlugin.ini");

        if (!FileReference.Exists(SourceFilterFile))
        {
            List <string> Lines = new List <string>();
            Lines.Add("[FilterPlugin]");
            Lines.Add("; This section lists additional files which will be packaged along with your plugin. Paths should be listed relative to the root plugin directory, and");
            Lines.Add("; may include \"...\", \"*\", and \"?\" wildcards to match directories, files, and individual characters respectively.");
            Lines.Add(";");
            Lines.Add("; Examples:");
            Lines.Add(";    /README.txt");
            Lines.Add(";    /Extras/...");
            Lines.Add(";    /Binaries/ThirdParty/*.dll");
            DirectoryReference.CreateDirectory(SourceFilterFile.Directory);
            CommandUtils.WriteAllLines_NoExceptions(SourceFilterFile.FullName, Lines.ToArray());
        }

        // Create a host project for the plugin. For script generator plugins, we need to have UHT be able to load it, which can only happen if it's enabled in a project.
        FileReference HostProjectFile       = FileReference.Combine(PackageDir, "HostProject", "HostProject.uproject");
        FileReference HostProjectPluginFile = CreateHostProject(HostProjectFile, PluginFile);

        // Read the plugin
        CommandUtils.LogInformation("Reading plugin from {0}...", HostProjectPluginFile);
        PluginDescriptor Plugin = PluginDescriptor.FromFile(HostProjectPluginFile);

        // Get the arguments for the compile
        StringBuilder AdditionalArgs = new StringBuilder();

        if (bStrictIncludes)
        {
            CommandUtils.LogInformation("Building with precompiled headers and unity disabled");
            AdditionalArgs.Append(" -NoPCH -NoSharedPCH -DisableUnity");
        }

        // Compile the plugin for all the target platforms
        List <UnrealTargetPlatform> HostPlatforms = ParseParam("NoHostPlatform")? new List <UnrealTargetPlatform>() : new List <UnrealTargetPlatform> {
            BuildHostPlatform.Current.Platform
        };
        List <UnrealTargetPlatform> TargetPlatforms = GetTargetPlatforms(this, BuildHostPlatform.Current.Platform);

        FileReference[] BuildProducts = CompilePlugin(HostProjectFile, HostProjectPluginFile, Plugin, HostPlatforms, TargetPlatforms, AdditionalArgs.ToString(), bVS2019);

        // Package up the final plugin data
        PackagePlugin(HostProjectPluginFile, BuildProducts, PackageDir, ParseParam("unversioned"));

        // Remove the host project
        if (!ParseParam("NoDeleteHostProject"))
        {
            CommandUtils.DeleteDirectory(HostProjectFile.Directory.FullName);
        }
    }
	public override void ExecuteBuild()
	{
		// Get the plugin filename
		string PluginParam = ParseParamValue("Plugin");
		if(PluginParam == null)
		{
			throw new AutomationException("Missing -Plugin=... argument");
		}

		// Check it exists
		FileReference PluginFile = new FileReference(PluginParam);
		if (!PluginFile.Exists())
		{
			throw new AutomationException("Plugin '{0}' not found", PluginFile.FullName);
		}

		// Get the output directory
		string PackageParam = ParseParamValue("Package");
		if (PackageParam == null)
		{
			throw new AutomationException("Missing -Package=... argument");
		}

		// Make sure the packaging directory is valid
		DirectoryReference PackageDir = new DirectoryReference(PackageParam);
		if (PluginFile.IsUnderDirectory(PackageDir))
		{
			throw new AutomationException("Packaged plugin output directory must be different to source");
		}
		if (PackageDir.IsUnderDirectory(DirectoryReference.Combine(CommandUtils.RootDirectory, "Engine")))
		{
			throw new AutomationException("Output directory for packaged plugin must be outside engine directory");
		}

		// Clear the output directory of existing stuff
		if (PackageDir.Exists())
		{
			CommandUtils.DeleteDirectoryContents(PackageDir.FullName);
		}
		else
		{
			PackageDir.CreateDirectory();
		}

		// Create a placeholder FilterPlugin.ini with instructions on how to use it
		FileReference SourceFilterFile = FileReference.Combine(PluginFile.Directory, "Config", "FilterPlugin.ini");
		if (!SourceFilterFile.Exists())
		{
			List<string> Lines = new List<string>();
			Lines.Add("[FilterPlugin]");
			Lines.Add("; This section lists additional files which will be packaged along with your plugin. Paths should be listed relative to the root plugin directory, and");
			Lines.Add("; may include \"...\", \"*\", and \"?\" wildcards to match directories, files, and individual characters respectively.");
			Lines.Add(";");
			Lines.Add("; Examples:");
			Lines.Add(";    /README.txt");
			Lines.Add(";    /Extras/...");
			Lines.Add(";    /Binaries/ThirdParty/*.dll");
			SourceFilterFile.Directory.CreateDirectory();
			CommandUtils.WriteAllLines_NoExceptions(SourceFilterFile.FullName, Lines.ToArray());
		}

		// Create a host project for the plugin. For script generator plugins, we need to have UHT be able to load it, which can only happen if it's enabled in a project.
		FileReference HostProjectFile = FileReference.Combine(PackageDir, "HostProject", "HostProject.uproject");
		FileReference HostProjectPluginFile = CreateHostProject(HostProjectFile, PluginFile);

		// Read the plugin
		CommandUtils.Log("Reading plugin from {0}...", HostProjectPluginFile);
		PluginDescriptor Plugin = PluginDescriptor.FromFile(HostProjectPluginFile, false);

		// Compile the plugin for all the target platforms
		List<UnrealTargetPlatform> HostPlatforms = ParseParam("NoHostPlatform")? new List<UnrealTargetPlatform>() : new List<UnrealTargetPlatform> { BuildHostPlatform.Current.Platform };
		List<UnrealTargetPlatform> TargetPlatforms = GetTargetPlatforms(this, BuildHostPlatform.Current.Platform).Where(x => IsCodeTargetPlatform(BuildHostPlatform.Current.Platform, x)).ToList();
		FileReference[] BuildProducts = CompilePlugin(HostProjectFile, HostProjectPluginFile, Plugin, HostPlatforms, TargetPlatforms, "");

		// Package up the final plugin data
		PackagePlugin(HostProjectPluginFile, BuildProducts, PackageDir);

		// Remove the host project
		if(!ParseParam("NoDeleteHostProject"))
		{
			CommandUtils.DeleteDirectory(HostProjectFile.Directory.FullName);
		}
	}