// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved. using System; using System.Collections.Generic; using System.Text; using System.IO; namespace UnrealBuildTool { /// /// Represents a folder within the master project (e.g. Visual Studio solution) /// public class MakefileFolder : MasterProjectFolder { /// /// Constructor /// public MakefileFolder( ProjectFileGenerator InitOwnerProjectFileGenerator, string InitFolderName ) : base(InitOwnerProjectFileGenerator, InitFolderName) { } } public class MakefileProjectFile : ProjectFile { public MakefileProjectFile( string InitFilePath ) : base(InitFilePath) { } } /// /// Makefile project file generator implementation /// public class MakefileGenerator : ProjectFileGenerator { /// File extension for project files we'll be generating (e.g. ".vcxproj") override public string ProjectFileExtension { get { return ".mk"; } } protected override bool WriteMasterProjectFile( ProjectFile UBTProject ) { bool bSuccess = true; return bSuccess; } private bool WriteMakefile() { var FileName = "Makefile"; // MasterProjectName + ".mk"; var MakefileContent = new StringBuilder(); MakefileContent.Append( "# Makefile generated by MakefileGenerator.cs\n" + "# *DO NOT EDIT*\n\n" + "TARGETS =" ); foreach (string Target in DiscoverTargets()) { var Basename = Path.GetFileNameWithoutExtension(Target); Basename = Path.GetFileNameWithoutExtension(Basename); foreach (UnrealTargetConfiguration CurConfiguration in Enum.GetValues(typeof(UnrealTargetConfiguration))) { if (CurConfiguration != UnrealTargetConfiguration.Unknown && CurConfiguration != UnrealTargetConfiguration.Development) { if (UnrealBuildTool.IsValidConfiguration(CurConfiguration)) { var Confname = Enum.GetName(typeof(UnrealTargetConfiguration), CurConfiguration); MakefileContent.Append(String.Format(" \\\n {0}-Linux-{1}", Basename, Confname)); } } } MakefileContent.Append(" \\\n " + Basename); } MakefileContent.Append("\n\nBUILD = Engine/Build/BatchFiles/Linux/Build.sh\n\n" + "all: $(TARGETS)\n" ); foreach (string Target in DiscoverTargets()) { var Basename = Path.GetFileNameWithoutExtension(Target); Basename = Path.GetFileNameWithoutExtension(Basename); foreach (UnrealTargetConfiguration CurConfiguration in Enum.GetValues(typeof(UnrealTargetConfiguration))) { if (CurConfiguration != UnrealTargetConfiguration.Unknown && CurConfiguration != UnrealTargetConfiguration.Development) { if (UnrealBuildTool.IsValidConfiguration(CurConfiguration)) { var Confname = Enum.GetName(typeof(UnrealTargetConfiguration), CurConfiguration); MakefileContent.Append(String.Format("\n{0}-Linux-{1}:\n\t$(BUILD) {0} Linux {1} $(ARGS)\n", Basename, Confname)); } } } MakefileContent.Append(String.Format("\n{0}:\n\t$(BUILD) {0} Linux Development $(ARGS)\n", Basename)); } MakefileContent.Append("\n.PHONY: $(TARGETS)\n"); var FullFileName = Path.Combine(MasterProjectRelativePath, FileName); return WriteFileIfChanged(FullFileName, MakefileContent.ToString()); } private bool WriteCMakeLists() { var FileName = "CMakeLists.txt"; var CMakefileContent = new StringBuilder(); CMakefileContent.Append( "# Makefile generated by MakefileGenerator.cs\n" + "# *DO NOT EDIT*\n\n" + "cmake_minimum_required (VERSION 2.6)\n" + "project (UE4)\n\n" + "set(BUILD ${CMAKE_SOURCE_DIR}/Engine/Build/BatchFiles/Linux/Build.sh)\n\n" + "set(SOURCE_FILES" ); var AllModuleFiles = DiscoverModules(); foreach (string CurModuleFile in AllModuleFiles) { CMakefileContent.Append("\n\t"); var FoundFiles = SourceFileSearch.FindModuleSourceFiles(CurModuleFile, ExcludeNoRedistFiles: bExcludeNoRedistFiles); foreach (string CurSourceFile in FoundFiles) { string SourceFileRelativeToRoot = Utils.MakePathRelativeTo(CurSourceFile, Path.Combine(EngineRelativePath)); if (!SourceFileRelativeToRoot.StartsWith("..") && !Path.IsPathRooted(SourceFileRelativeToRoot)) { SourceFileRelativeToRoot = "Engine/" + SourceFileRelativeToRoot; } else { SourceFileRelativeToRoot = SourceFileRelativeToRoot.Substring(3); } CMakefileContent.Append(String.Format("\"{0}\" ", SourceFileRelativeToRoot)); } } CMakefileContent.Append("\n)\n\n"); foreach (string TargetFilePath in DiscoverTargets()) { var TargetName = Utils.GetFilenameWithoutAnyExtensions(TargetFilePath); // Remove both ".cs" and ". foreach (UnrealTargetConfiguration CurConfiguration in Enum.GetValues(typeof(UnrealTargetConfiguration))) { if (CurConfiguration != UnrealTargetConfiguration.Unknown && CurConfiguration != UnrealTargetConfiguration.Development) { if (UnrealBuildTool.IsValidConfiguration(CurConfiguration)) { var ConfName = Enum.GetName(typeof(UnrealTargetConfiguration), CurConfiguration); CMakefileContent.Append(String.Format("add_custom_target({0}-Linux-{1} ${{BUILD}} {0} Linux {1})\n", TargetName, ConfName)); } } } CMakefileContent.Append(String.Format("add_custom_target({0} ${{BUILD}} {0} Linux Development SOURCES ${{SOURCE_FILES}})\n\n", TargetName)); } var FullFileName = Path.Combine(MasterProjectRelativePath, FileName); return WriteFileIfChanged(FullFileName, CMakefileContent.ToString()); } /// ProjectFileGenerator interface //protected override bool WriteMasterProjectFile( ProjectFile UBTProject ) protected override bool WriteProjectFiles () { return WriteMakefile() && WriteCMakeLists(); } /// ProjectFileGenerator interface public override MasterProjectFolder AllocateMasterProjectFolder( ProjectFileGenerator InitOwnerProjectFileGenerator, string InitFolderName ) { return new MakefileFolder( InitOwnerProjectFileGenerator, InitFolderName ); } /// ProjectFileGenerator interface /// /// Allocates a generator-specific project file object /// /// Path to the project file /// The newly allocated project file object protected override ProjectFile AllocateProjectFile( string InitFilePath ) { return new MakefileProjectFile( InitFilePath ); } /// ProjectFileGenerator interface public override void CleanProjectFiles(string InMasterProjectRelativePath, string InMasterProjectName, string InIntermediateProjectFilesPath) { } } }