bool FDesktopPlatformBase::GenerateProjectFiles(const FString& RootDir, const FString& ProjectFileName, FFeedbackContext* Warn) { #if PLATFORM_MAC FString Arguments = TEXT(" -xcodeprojectfile"); #elif PLATFORM_LINUX FString Arguments = TEXT(" -makefile -kdevelopfile -qmakefile -cmakefile -codelitefile "); #else FString Arguments = TEXT(" -projectfiles"); #endif // Build the arguments to pass to UBT. If it's a non-foreign project, just build full project files. if ( !ProjectFileName.IsEmpty() && GetCachedProjectDictionary(RootDir).IsForeignProject(ProjectFileName) ) { // Figure out whether it's a foreign project const FUProjectDictionary &ProjectDictionary = GetCachedProjectDictionary(RootDir); if(ProjectDictionary.IsForeignProject(ProjectFileName)) { Arguments += FString::Printf(TEXT(" -project=\"%s\""), *IFileManager::Get().ConvertToAbsolutePathForExternalAppForRead(*ProjectFileName)); // Always include game source Arguments += TEXT(" -game"); // Determine whether or not to include engine source if(IsSourceDistribution(RootDir) && !FRocketSupport::IsRocket()) { Arguments += TEXT(" -engine"); } else { Arguments += TEXT(" -rocket"); } } } Arguments += TEXT(" -progress"); // Compile UnrealBuildTool if it doesn't exist. This can happen if we're just copying source from somewhere. bool bRes = true; Warn->BeginSlowTask(LOCTEXT("GeneratingProjectFiles", "Generating project files..."), true, true); if(!FPaths::FileExists(GetUnrealBuildToolExecutableFilename(RootDir))) { Warn->StatusUpdate(0, 1, LOCTEXT("BuildingUBT", "Building UnrealBuildTool...")); bRes = BuildUnrealBuildTool(RootDir, *Warn); } if(bRes) { Warn->StatusUpdate(0, 1, LOCTEXT("GeneratingProjectFiles", "Generating project files...")); bRes = RunUnrealBuildTool(LOCTEXT("GeneratingProjectFiles", "Generating project files..."), RootDir, Arguments, Warn); } Warn->EndSlowTask(); return bRes; }
bool FDesktopPlatformBase::SetEngineIdentifierForProject(const FString &ProjectFileName, const FString &InIdentifier) { // Load the project file TSharedPtr<FJsonObject> ProjectFile = LoadProjectFile(ProjectFileName); if (!ProjectFile.IsValid()) { return false; } // Check if the project is a non-foreign project of the given engine installation. If so, blank the identifier // string to allow portability between source control databases. GetEngineIdentifierForProject will translate // the association back into a local identifier on other machines or syncs. FString Identifier = InIdentifier; if(Identifier.Len() > 0) { FString RootDir; if(GetEngineRootDirFromIdentifier(Identifier, RootDir)) { const FUProjectDictionary &Dictionary = GetCachedProjectDictionary(RootDir); if(!Dictionary.IsForeignProject(ProjectFileName)) { Identifier.Empty(); } } } // Set the association on the project and save it ProjectFile->SetStringField(TEXT("EngineAssociation"), Identifier); return SaveProjectFile(ProjectFileName, ProjectFile); }
bool FDesktopPlatformBase::InvalidateMakefiles(const FString& RootDir, const FString& ProjectFileName, FFeedbackContext* Warn) { // Composes the target, platform, and config (eg, "QAGame Win64 Development") FString Arguments = FString::Printf(TEXT("%s %s %s"), FApp::GetGameName(), FPlatformMisc::GetUBTPlatform(), FModuleManager::GetUBTConfiguration()); // -editorrecompile tells UBT to work out the editor target name from the game target name we provided (eg, converting "QAGame" to "QAGameEditor") Arguments += TEXT(" -editorrecompile"); // Build the arguments to pass to UBT. If it's a non-foreign project, just build full project files. if ( !ProjectFileName.IsEmpty() && GetCachedProjectDictionary(RootDir).IsForeignProject(ProjectFileName) ) { // Figure out whether it's a foreign project const FUProjectDictionary &ProjectDictionary = GetCachedProjectDictionary(RootDir); if(ProjectDictionary.IsForeignProject(ProjectFileName)) { Arguments += FString::Printf(TEXT(" \"%s\""), *IFileManager::Get().ConvertToAbsolutePathForExternalAppForRead(*ProjectFileName)); } } // -invalidatemakefilesonly tells UBT to invalidate its UBT makefiles without building Arguments += TEXT(" -invalidatemakefilesonly"); if (FRocketSupport::IsRocket()) { Arguments += TEXT(" -rocket"); } // Compile UnrealBuildTool if it doesn't exist. This can happen if we're just copying source from somewhere. bool bRes = true; Warn->BeginSlowTask(LOCTEXT("InvalidateMakefiles", "Invalidating makefiles..."), true, true); if(!FPaths::FileExists(GetUnrealBuildToolExecutableFilename(RootDir))) { Warn->StatusUpdate(0, 1, LOCTEXT("BuildingUBT", "Building UnrealBuildTool...")); bRes = BuildUnrealBuildTool(RootDir, *Warn); } if(bRes) { Warn->StatusUpdate(0, 1, LOCTEXT("InvalidateMakefiles", "Invalidating makefiles...")); bRes = RunUnrealBuildTool(LOCTEXT("InvalidateMakefiles", "Invalidating makefiles..."), RootDir, Arguments, Warn); } Warn->EndSlowTask(); return bRes; }
bool FDesktopPlatformBase::EnumerateProjectsKnownByEngine(const FString &Identifier, bool bIncludeNativeProjects, TArray<FString> &OutProjectFileNames) { // Get the engine root directory FString RootDir; if (!GetEngineRootDirFromIdentifier(Identifier, RootDir)) { return false; } FString GameAgnosticConfigDir = GetEngineSavedConfigDirectory(Identifier); if (GameAgnosticConfigDir.Len() == 0) { return false; } // Find all the created project directories. Start with the default project creation path. TArray<FString> SearchDirectories; SearchDirectories.AddUnique(GetDefaultProjectCreationPath()); // Load the config file FConfigFile GameAgnosticConfig; FConfigCacheIni::LoadExternalIniFile(GameAgnosticConfig, TEXT("EditorSettings"), NULL, *GameAgnosticConfigDir, false); // Find the editor game-agnostic settings FConfigSection* Section = GameAgnosticConfig.Find(TEXT("/Script/UnrealEd.EditorSettings")); if (Section == NULL) { FConfigCacheIni::LoadExternalIniFile(GameAgnosticConfig, TEXT("EditorGameAgnostic"), NULL, *GameAgnosticConfigDir, false); Section = GameAgnosticConfig.Find(TEXT("/Script/UnrealEd.EditorGameAgnosticSettings")); } if(Section != NULL) { // Add in every path that the user has ever created a project file. This is to catch new projects showing up in the user's project folders TArray<FString> AdditionalDirectories; Section->MultiFind(TEXT("CreatedProjectPaths"), AdditionalDirectories); for(int Idx = 0; Idx < AdditionalDirectories.Num(); Idx++) { FPaths::NormalizeDirectoryName(AdditionalDirectories[Idx]); SearchDirectories.AddUnique(AdditionalDirectories[Idx]); } // Also add in all the recently opened projects TArray<FString> RecentlyOpenedFiles; Section->MultiFind(TEXT("RecentlyOpenedProjectFiles"), RecentlyOpenedFiles); for(int Idx = 0; Idx < RecentlyOpenedFiles.Num(); Idx++) { FPaths::NormalizeFilename(RecentlyOpenedFiles[Idx]); OutProjectFileNames.AddUnique(RecentlyOpenedFiles[Idx]); } } // Find all the other projects that are in the search directories for(int Idx = 0; Idx < SearchDirectories.Num(); Idx++) { TArray<FString> ProjectFolders; IFileManager::Get().FindFiles(ProjectFolders, *(SearchDirectories[Idx] / TEXT("*")), false, true); for(int32 FolderIdx = 0; FolderIdx < ProjectFolders.Num(); FolderIdx++) { TArray<FString> ProjectFiles; IFileManager::Get().FindFiles(ProjectFiles, *(SearchDirectories[Idx] / ProjectFolders[FolderIdx] / TEXT("*.uproject")), true, false); for(int32 FileIdx = 0; FileIdx < ProjectFiles.Num(); FileIdx++) { OutProjectFileNames.AddUnique(SearchDirectories[Idx] / ProjectFolders[FolderIdx] / ProjectFiles[FileIdx]); } } } // Find all the native projects, and either add or remove them from the list depending on whether we want native projects const FUProjectDictionary &Dictionary = GetCachedProjectDictionary(RootDir); if(bIncludeNativeProjects) { TArray<FString> NativeProjectPaths = Dictionary.GetProjectPaths(); for(int Idx = 0; Idx < NativeProjectPaths.Num(); Idx++) { if(!NativeProjectPaths[Idx].Contains(TEXT("/Templates/"))) { OutProjectFileNames.AddUnique(NativeProjectPaths[Idx]); } } } else { TArray<FString> NativeProjectPaths = Dictionary.GetProjectPaths(); for(int Idx = 0; Idx < NativeProjectPaths.Num(); Idx++) { OutProjectFileNames.Remove(NativeProjectPaths[Idx]); } } return true; }