예제 #1
0
        public override void BuildTargetLib(TargetLib TargetLib, string TargetConfiguration)
        {
            DirectoryReference ConfigDirectory = GetProjectsDirectory(TargetLib, TargetConfiguration);

            string Makefile = FileReference.Combine(ConfigDirectory, "Makefile").FullName;

            if (!FileExists(Makefile))
            {
                throw new AutomationException("Unabled to build {0} - file not found.", Makefile);
            }

            DirectoryReference CommonToolsPath = new DirectoryReference(System.Environment.GetEnvironmentVariable("VS140COMNTOOLS"));

            ProcessStartInfo StartInfo = new ProcessStartInfo();

            StartInfo.FileName         = "cmd.exe";
            StartInfo.WorkingDirectory = ConfigDirectory.FullName;

            StartInfo.Arguments = string.Format("/C \"{0}\" amd64 && nmake {1}", FileReference.Combine(CommonToolsPath, "..", "..", "VC", "vcvarsall.bat").FullName, TargetLib.MakeTarget);

            LogInformation("Working in: {0}", StartInfo.WorkingDirectory);
            LogInformation("{0} {1}", StartInfo.FileName, StartInfo.Arguments);

            if (Utils.RunLocalProcessAndLogOutput(StartInfo) != 0)
            {
                throw new AutomationException("Unabled to build {0}. Build process failed.", Makefile);
            }
        }
예제 #2
0
        public virtual void SetupTargetLib(TargetLib TargetLib, string TargetConfiguration)
        {
            LogInformation("Building {0} for {1} ({2})...", TargetLib.Name, TargetBuildPlatform, TargetConfiguration);

            if (BuildHostPlatform.Current.Platform.IsInGroup(UnrealPlatformGroup.Unix))
            {
                Environment.SetEnvironmentVariable("CMAKE_ROOT", DirectoryReference.Combine(CMakeRootDirectory, "share").FullName);
                LogInformation("set {0}={1}", "CMAKE_ROOT", Environment.GetEnvironmentVariable("CMAKE_ROOT"));
            }

            DirectoryReference CMakeTargetDirectory = GetProjectsDirectory(TargetLib, TargetConfiguration);

            MakeFreshDirectoryIfRequired(CMakeTargetDirectory);

            LogInformation("Generating projects for lib " + TargetLib.Name + ", " + FriendlyName);

            ProcessStartInfo StartInfo = new ProcessStartInfo();

            StartInfo.FileName         = CMakeCommand;
            StartInfo.WorkingDirectory = CMakeTargetDirectory.FullName;
            StartInfo.Arguments        = GetCMakeArguments(TargetLib, TargetConfiguration);

            if (Utils.RunLocalProcessAndLogOutput(StartInfo) != 0)
            {
                throw new AutomationException("Unable to generate projects for {0}.", TargetLib.ToString() + ", " + FriendlyName);
            }
        }
예제 #3
0
        public override void BuildTargetLib(TargetLib TargetLib, string TargetConfiguration)
        {
            DirectoryReference ConfigDirectory = GetProjectsDirectory(TargetLib, TargetConfiguration);

            Environment.SetEnvironmentVariable("LIB_SUFFIX", TargetLib.BuildSuffix[TargetConfiguration]);

            string Makefile = FileReference.Combine(ConfigDirectory, "Makefile").FullName;

            if (!FileExists(Makefile))
            {
                throw new AutomationException("Unabled to build {0} - file not found.", Makefile);
            }

            ProcessStartInfo StartInfo = new ProcessStartInfo();

            StartInfo.FileName         = MakeCommand;
            StartInfo.WorkingDirectory = ConfigDirectory.FullName;

            // Bundled GNU make does not pass job number to subprocesses on Windows, work around that...
            // Redefining the MAKE variable will cause the -j flag to be passed to child make instances.
            StartInfo.Arguments = BuildHostPlatform.Current.Platform.IsInGroup(UnrealPlatformGroup.Windows)
                                ? string.Format("{1} {2} \"MAKE={0} {1}\"", MakeCommand, MakeOptions, TargetLib.MakeTarget)
                                : string.Format("{0} {1}", MakeOptions, TargetLib.MakeTarget);

            LogInformation("Working in: {0}", StartInfo.WorkingDirectory);
            LogInformation("{0} {1}", StartInfo.FileName, StartInfo.Arguments);

            if (Utils.RunLocalProcessAndLogOutput(StartInfo) != 0)
            {
                throw new AutomationException("Unabled to build {0}. Build process failed.", Makefile);
            }
        }
예제 #4
0
        public virtual IEnumerable <FileReference> EnumerateOutputFiles(TargetLib TargetLib, string TargetConfiguration)
        {
            string SearchPrefix = "*" + TargetLib.BuildSuffix[TargetConfiguration] + ".";

            DirectoryReference OutputLibraryDirectory = GetOutputLibraryDirectory(TargetLib, TargetConfiguration);

            // Scan static libraries directory
            IEnumerable <FileReference> Results = EnumerateOutputFiles(OutputLibraryDirectory, SearchPrefix + StaticLibraryExtension, TargetLib);

            if (DebugDatabaseExtension != null)
            {
                Results = Results.Concat(EnumerateOutputFiles(OutputLibraryDirectory, SearchPrefix + DebugDatabaseExtension, TargetLib));
            }

            // Scan dynamic libraries directory
            if (HasBinaries)
            {
                DirectoryReference OutputBinaryDirectory = GetOutputBinaryDirectory(TargetLib, TargetConfiguration);

                Results = Results.Concat(EnumerateOutputFiles(OutputBinaryDirectory, SearchPrefix + DynamicLibraryExtension, TargetLib));
                if (DebugDatabaseExtension != null)
                {
                    Results = Results.Concat(EnumerateOutputFiles(OutputBinaryDirectory, SearchPrefix + DebugDatabaseExtension, TargetLib));
                }
            }

            return(Results);
        }
예제 #5
0
 public virtual void CleanupTargetLib(TargetLib TargetLib, string TargetConfiguration)
 {
     if (string.IsNullOrEmpty(TargetConfiguration))
     {
         InternalUtils.SafeDeleteDirectory(DirectoryReference.Combine(GetTargetLibRootDirectory(TargetLib), "Build").FullName);
     }
     else
     {
         DirectoryReference CMakeTargetDirectory = GetProjectsDirectory(TargetLib, TargetConfiguration);
         InternalUtils.SafeDeleteDirectory(CMakeTargetDirectory.FullName);
     }
 }
예제 #6
0
        public override void BuildTargetLib(TargetLib TargetLib, string TargetConfiguration)
        {
            DirectoryReference Directory = GetProjectsDirectory(TargetLib, TargetConfiguration);

            string ProjectFile = FileReference.Combine(Directory, TargetLib.ToString() + ".xcodeproj").FullName;

            if (!DirectoryExists(ProjectFile))
            {
                throw new AutomationException("Unabled to build project {0}. Project file not found.", ProjectFile);
            }

            RunAndLog(CmdEnv, "/usr/bin/xcodebuild", string.Format("-project \"{0}\" -target=\"ALL_BUILD\" -configuration {1} -quiet", ProjectFile, TargetConfiguration));
        }
예제 #7
0
        private DirectoryReference GetTargetLibBaseBuildScriptDirectory(TargetLib TargetLib)
        {
            // Some libraries use BuildForUE4 instead of BuildForUE, check this here
            DirectoryReference BuildForUEDirectory = DirectoryReference.Combine(GetTargetLibBaseRootDirectory(TargetLib), "BuildForUE");

            if (!DirectoryReference.Exists(BuildForUEDirectory))
            {
                // If not available then check BuildForUE4
                BuildForUEDirectory = DirectoryReference.Combine(GetTargetLibBaseRootDirectory(TargetLib), "BuildForUE4");
            }

            return(BuildForUEDirectory);
        }
예제 #8
0
        public virtual string GetCMakeArguments(TargetLib TargetLib, string TargetConfiguration)
        {
            string Args = "\"" + GetTargetLibPlatformCMakeDirectory(TargetLib).FullName + "\"";

            Args += " -G \"" + CMakeGeneratorName + "\"";

            if (SeparateProjectPerConfig)
            {
                Args += " -DCMAKE_BUILD_TYPE=\"" + TargetConfiguration + "\"";
            }

            FileReference ToolchainPath = GetToolchainPath(TargetLib, TargetConfiguration);

            if (ToolchainPath != null && FileReference.Exists(ToolchainPath))
            {
                Args += " -DCMAKE_TOOLCHAIN_FILE=\"" + ToolchainPath.FullName + "\"";
            }

            FileReference ProjectIncludePath = GetProjectIncludePath(TargetLib, TargetConfiguration);

            if (ProjectIncludePath != null && FileReference.Exists(ProjectIncludePath))
            {
                Args += " -DCMAKE_PROJECT_INCLUDE_FILE=\"" + ProjectIncludePath.FullName + "\"";
            }

            Args += " -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY=\"" + GetOutputLibraryDirectory(TargetLib, TargetConfiguration) + "\"";

            if (HasBinaries)
            {
                Args += " -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=\"" + GetOutputBinaryDirectory(TargetLib, TargetConfiguration) + "\"";
                Args += " -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=\"" + GetOutputBinaryDirectory(TargetLib, TargetConfiguration) + "\"";
            }

            if (UseResponseFiles)
            {
                // Enable response files for platforms that require them.
                // Response files are used for include paths etc, to fix max command line length issues.
                Args += " -DUSE_RESPONSE_FILES=1";
            }

            string AdditionalArgs = GetAdditionalCMakeArguments(TargetLib, TargetConfiguration);

            if (AdditionalArgs != null)
            {
                Args += AdditionalArgs.Replace("${TARGET_CONFIG}", TargetConfiguration ?? "");
            }

            return(Args);
        }
예제 #9
0
    private TargetLib GetTargetLib()
    {
        TargetLib TargetLib = new TargetLib();

        TargetLib.Name                     = ParseParamValue("TargetLib", "");
        TargetLib.Version                  = ParseParamValue("TargetLibVersion", "");
        TargetLib.SourcePath               = ParseParamValue("TargetLibSourcePath", "");
        TargetLib.LibOutputPath            = ParseParamValue("LibOutputPath", "");
        TargetLib.CMakeProjectIncludeFile  = ParseParamValue("CMakeProjectIncludeFile", "");
        TargetLib.CMakeAdditionalArguments = ParseParamValue("CMakeAdditionalArguments", "");
        TargetLib.MakeTarget               = ParseParamValue("MakeTarget", TargetLib.Name).ToLower();

        if (string.IsNullOrEmpty(TargetLib.Name) || string.IsNullOrEmpty(TargetLib.Version))
        {
            throw new AutomationException("Must specify both -TargetLib and -TargetLibVersion");
        }

        return(TargetLib);
    }
예제 #10
0
        protected FileReference GetToolchainPath(TargetLib TargetLib, string TargetConfiguration)
        {
            string ToolchainName = GetToolchainName(TargetLib, TargetConfiguration);

            if (ToolchainName == null)
            {
                return(null);
            }

            // First check for an overriden toolchain in the BuildForUE/Platform directory
            FileReference ToolChainPath = FileReference.Combine(GetTargetLibBuildScriptDirectory(TargetLib), IsPlatformExtension ? "" : Platform.ToString(), ToolchainName);

            if (!FileReference.Exists(ToolChainPath))
            {
                // If not available then use the top level toolchain path
                ToolChainPath = FileReference.Combine(PlatformEngineRoot, "Source", "ThirdParty", "CMake", "PlatformScripts", IsPlatformExtension ? "" : Platform.ToString(), ToolchainName);
            }

            return(ToolChainPath);
        }
예제 #11
0
        protected DirectoryReference GetTargetLibPlatformCMakeDirectory(TargetLib TargetLib)
        {
            // Possible "standard" locations for the CMakesLists.txt are BuildForUE/Platform, BuildForUE or the source root

            // First check for an overriden CMakeLists.txt in the BuildForUE/Platform directory
            DirectoryReference CMakeDirectory = GetTargetLibBuildScriptDirectory(TargetLib);

            if (!FileReference.Exists(FileReference.Combine(CMakeDirectory, IsPlatformExtension ? "" : Platform.ToString(), "CMakeLists.txt")))
            {
                // If not available then check BuildForUE
                CMakeDirectory = GetTargetLibBaseBuildScriptDirectory(TargetLib);
                if (!FileReference.Exists(FileReference.Combine(CMakeDirectory, "CMakeLists.txt")))
                {
                    // If not available then check the lib source root
                    CMakeDirectory = TargetLib.GetLibSourceDirectory();
                }
            }

            return(CMakeDirectory);
        }
예제 #12
0
 protected DirectoryReference GetProjectsDirectory(TargetLib TargetLib, string TargetConfiguration) =>
 DirectoryReference.Combine(GetTargetLibRootDirectory(TargetLib), "Build",
                            IsPlatformExtension ? "" : TargetBuildPlatform,
                            PlatformBuildSubdirectory ?? "",
                            SeparateProjectPerConfig ? TargetLib.BuildMap[TargetConfiguration] : "");
예제 #13
0
 protected FileReference GetProjectIncludePath(TargetLib TargetLib, string TargetConfiguration)
 {
     return(FileReference.Combine(GetTargetLibBuildScriptDirectory(TargetLib), IsPlatformExtension ? "" : Platform.ToString(), TargetLib.CMakeProjectIncludeFile));
 }
예제 #14
0
 protected DirectoryReference GetOutputLibraryDirectory(TargetLib TargetLib, string TargetConfiguration)
 {
     return(DirectoryReference.Combine(GetTargetLibRootDirectory(TargetLib), TargetLib.LibOutputPath, IsPlatformExtension ? "" : Platform.ToString(), PlatformBuildSubdirectory ?? "", TargetConfiguration));
 }
예제 #15
0
 public abstract void BuildTargetLib(TargetLib TargetLib, string TargetConfiguration);
예제 #16
0
 protected DirectoryReference GetOutputBinaryDirectory(TargetLib TargetLib, string TargetConfiguration)
 {
     return(DirectoryReference.Combine(PlatformEngineRoot, IsPlatformExtension ? "" : Platform.ToString(), PlatformBuildSubdirectory ?? "", TargetConfiguration));
 }
예제 #17
0
 public abstract bool SupportsTargetLib(TargetLib Library);
예제 #18
0
    public override void ExecuteBuild()
    {
        bool bAutoCreateChangelist = true;

        if (ParseParam("SkipCreateChangelist"))
        {
            bAutoCreateChangelist = false;
        }

        bool bAutoSubmit = bAutoCreateChangelist;

        if (ParseParam("SkipSubmit"))
        {
            bAutoSubmit = false;
        }

        // if we don't pass anything, we'll just merge by default
        string RobomergeCommand = ParseParamValue("Robomerge", "").ToLower();

        if (!string.IsNullOrEmpty(RobomergeCommand))
        {
            // for merge default action, add flag to make sure buildmachine commit isn't skipped
            if (RobomergeCommand == "merge")
            {
                RobomergeCommand = "#robomerge[all] #DisregardExcludedAuthors";
            }
            // otherwise add hashtags
            else if (RobomergeCommand == "ignore")
            {
                RobomergeCommand = "#robomerge #ignore";
            }
            else if (RobomergeCommand == "null")
            {
                RobomergeCommand = "#robomerge #null";
            }
            // otherwise the submit will likely fail.
            else
            {
                throw new AutomationException("Invalid Robomerge param passed in {0}.  Must be \"merge\", \"null\", or \"ignore\"", RobomergeCommand);
            }
        }

        SetupBuildEnvironment();

        TargetPlatform Platform = GetTargetPlatform();

        TargetLib TargetLib = GetTargetLib();

        List <string> TargetConfigurations = GetTargetConfigurations();

        if (Platform.SeparateProjectPerConfig)
        {
            foreach (string TargetConfiguration in TargetConfigurations)
            {
                Platform.SetupTargetLib(TargetLib, TargetConfiguration);
            }
        }
        else
        {
            Platform.SetupTargetLib(TargetLib, null);
        }

        HashSet <FileReference> FilesToReconcile = new HashSet <FileReference>();

        foreach (string TargetConfiguration in TargetConfigurations)
        {
            foreach (FileReference FileToDelete in Platform.EnumerateOutputFiles(TargetLib, TargetConfiguration).Distinct())
            {
                FilesToReconcile.Add(FileToDelete);

                // Also clean the output files
                InternalUtils.SafeDeleteFile(FileToDelete.FullName);
            }
        }

        foreach (string TargetConfiguration in TargetConfigurations)
        {
            Platform.BuildTargetLib(TargetLib, TargetConfiguration);
        }

        Platform.CleanupTargetLib(TargetLib, null);

        const int InvalidChangeList = -1;
        int       P4ChangeList      = InvalidChangeList;

        if (bAutoCreateChangelist)
        {
            string LibDeploymentDesc = TargetLib.Name + " " + Platform.FriendlyName;

            var Builder = new StringBuilder();
            Builder.AppendFormat("BuildCMakeLib.Automation: Deploying {0} libs.{1}", LibDeploymentDesc, Environment.NewLine);
            Builder.AppendLine("#rb none");
            Builder.AppendLine("#lockdown Nick.Penwarden");
            Builder.AppendLine("#tests none");
            Builder.AppendLine("#jira none");
            Builder.AppendLine("#okforgithub ignore");
            if (!string.IsNullOrEmpty(RobomergeCommand))
            {
                Builder.AppendLine(RobomergeCommand);
            }

            P4ChangeList = P4.CreateChange(P4Env.Client, Builder.ToString());
        }

        if (P4ChangeList != InvalidChangeList)
        {
            foreach (FileReference FileToReconcile in FilesToReconcile)
            {
                P4.Reconcile(P4ChangeList, FileToReconcile.FullName);
            }

            if (bAutoSubmit)
            {
                if (!P4.TryDeleteEmptyChange(P4ChangeList))
                {
                    LogInformation("Submitting changelist " + P4ChangeList.ToString());
                    int SubmittedChangeList = InvalidChangeList;
                    P4.Submit(P4ChangeList, out SubmittedChangeList);
                }
                else
                {
                    LogInformation("Nothing to submit!");
                }
            }
        }
    }
예제 #19
0
 public virtual string GetAdditionalCMakeArguments(TargetLib TargetLib, string TargetConfiguration) => " " + TargetLib.CMakeAdditionalArguments;
예제 #20
0
 public virtual string GetToolchainName(TargetLib TargetLib, string TargetConfiguration) => FriendlyName + ".cmake";
예제 #21
0
 private DirectoryReference GetTargetLibRootDirectory(TargetLib TargetLib)
 {
     return(DirectoryReference.Combine(PlatformEngineRoot, "Source", "ThirdParty", TargetLib.Name, TargetLib.Version));
 }
예제 #22
0
        public virtual IEnumerable <FileReference> EnumerateOutputFiles(DirectoryReference BaseDir, string SearchPrefix, TargetLib TargetLib)
        {
            if (!DirectoryReference.Exists(BaseDir))
            {
                yield break;
            }

            foreach (FileReference File in DirectoryReference.EnumerateFiles(BaseDir, SearchPrefix))
            {
                var FileNameUpper = File.GetFileName().ToUpper();
                if (FileNameUpper.Contains(TargetLib.Name.ToUpper()))
                {
                    yield return(File);
                }
            }
        }