bool FCodeLiteSourceCodeAccessor::OpenSolution() { FString Filename = FPaths::GetBaseFilename(GetSolutionPath()) + ".workspace"; FString Directory = FPaths::GetPath(GetSolutionPath()); FString Solution = "\"" + Directory + "/" + Filename + "\""; FString CodeLitePath; if(!CanRunCodeLite(CodeLitePath)) { UE_LOG(LogCodeLiteAccessor, Warning, TEXT("FCodeLiteSourceCodeAccessor::OpenSolution: Cannot find CodeLite binary")); return false; } UE_LOG(LogCodeLiteAccessor, Warning, TEXT("FCodeLiteSourceCodeAccessor::OpenSolution: %s %s"), *CodeLitePath, *Solution); #ifdef USE_DBUS // // TODO Somehow codelite is not opening the workspace using GetWorkspace()->Open(...) // DBusMessage* message = nullptr; DBusMessageIter args; // Create new message. message = dbus_message_new_signal ("/org/codelite/command", "org.codelite.command", "OpenWorkSpace"); char* fileName = TCHAR_TO_ANSI(*Solution); // Add parameters to the message. dbus_message_iter_init_append(message, &args); if(!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &fileName)) { UE_LOG(LogCodeLiteAccessor, Warning, TEXT("Sdbus_message_iter_append_basic failed.")); return false; } // Send the message. dbus_connection_send(DBusConnection, message, nullptr); if(dbus_error_is_set(&DBusError)) { UE_LOG(LogCodeLiteAccessor, Warning, TEXT("dbus_connection_send failed: %s"), DBusError.message); return false; } // Free the message resources. dbus_message_unref(message); return true; #else FProcHandle Proc = FPlatformProcess::CreateProc(*CodeLitePath, *Solution, true, false, false, nullptr, 0, nullptr, nullptr); if(Proc.IsValid()) { FPlatformProcess::CloseProc(Proc); return true; } return false; #endif }
bool FDesktopPlatformBase::InvokeUnrealBuildToolSync(const FString& InCmdLineParams, FOutputDevice &Ar, bool bSkipBuildUBT, int32& OutReturnCode, FString& OutProcOutput) { void* PipeRead = nullptr; void* PipeWrite = nullptr; verify(FPlatformProcess::CreatePipe(PipeRead, PipeWrite)); bool bInvoked = false; FProcHandle ProcHandle = InvokeUnrealBuildToolAsync(InCmdLineParams, Ar, PipeRead, PipeWrite, bSkipBuildUBT); if (ProcHandle.IsValid()) { // rather than waiting, we must flush the read pipe or UBT will stall if it writes out a ton of text to the console. while (FPlatformProcess::IsProcRunning(ProcHandle)) { OutProcOutput += FPlatformProcess::ReadPipe(PipeRead); FPlatformProcess::Sleep(0.1f); } bInvoked = true; bool bGotReturnCode = FPlatformProcess::GetProcReturnCode(ProcHandle, &OutReturnCode); check(bGotReturnCode); } else { bInvoked = false; OutReturnCode = -1; OutProcOutput = TEXT(""); } FPlatformProcess::ClosePipe(PipeRead, PipeWrite); return bInvoked; }
bool FVSAccessorModule::RunVisualStudioAndOpenSolution() const { bool bSuccess = false; FString Path; if ( CanRunVisualStudio( Path ) ) { FString Params; if ( FModuleManager::Get().IsSolutionFilePresent() ) { Params += TEXT("\""); Params += FModuleManager::Get().GetSolutionFilepath(); Params += TEXT("\""); FProcHandle WorkerHandle = FPlatformProcess::CreateProc( *Path, *Params, true, false, false, NULL, 0, NULL, NULL ); if ( WorkerHandle.IsValid() ) { bSuccess = true; } WorkerHandle.Close(); } } return bSuccess; }
bool FLinuxTargetDevice::Launch( const FString& AppId, EBuildConfigurations::Type BuildConfiguration, EBuildTargets::Type BuildTarget, const FString& Params, uint32* OutProcessId ) { #if PLATFORM_LINUX // if running natively, support launching in place // build executable path FString PlatformName = TEXT("Linux"); FString ExecutablePath = FPaths::EngineIntermediateDir() / TEXT("Devices") / PlatformName / TEXT("Engine") / TEXT("Binaries") / PlatformName; if (BuildTarget == EBuildTargets::Game) { ExecutablePath /= TEXT("UE4Game"); } else if (BuildTarget == EBuildTargets::Server) { ExecutablePath /= TEXT("UE4Server"); } else if (BuildTarget == EBuildTargets::Editor) { ExecutablePath /= TEXT("UE4Editor"); } if (BuildConfiguration != EBuildConfigurations::Development) { ExecutablePath += FString::Printf(TEXT("-%s-%s"), *PlatformName, EBuildConfigurations::ToString(BuildConfiguration)); } // launch the game FProcHandle ProcessHandle = FPlatformProcess::CreateProc(*ExecutablePath, *Params, true, false, false, OutProcessId, 0, NULL, NULL); return ProcessHandle.Close(); #else // @todo: support launching on a remote machine STUBBED("FLinuxTargetDevice::Launch"); return false; #endif // PLATFORM_LINUX }
void FWindowsPlatformProcess::CloseProc(FProcHandle & ProcessHandle) { if (ProcessHandle.IsValid()) { ::CloseHandle(ProcessHandle.Get()); ProcessHandle.Reset(); } }
void FLinuxPlatformProcess::CloseProc(FProcHandle & ProcessHandle) { // dispose of both handle and process info FProcState * ProcInfo = ProcessHandle.GetProcessInfo(); ProcessHandle.Reset(); delete ProcInfo; }
bool FBuildPatchInstaller::RunPrereqInstaller() { FString PrereqPath = InstallDirectory / NewBuildManifest->GetPrereqPath(); PrereqPath = FPaths::ConvertRelativePathToFull(PrereqPath); FString PrereqCommandline = NewBuildManifest->GetPrereqArgs(); GLog->Logf(TEXT("BuildPatchServices: Running prerequisites installer %s %s"), *PrereqPath, *PrereqCommandline); BuildProgress.SetStateProgress(EBuildPatchProgress::PrerequisitesInstall, 0.0f); // @TODO: Tell our installer to run with no UI since we will have BuildPatchProgress // @TODO: Pass in params to the installer that tell it to fire up the portal/launcher after install if it has to perform a restart. FProcHandle ProcessHandle = FPlatformProcess::CreateProc(*PrereqPath, *PrereqCommandline, true, false, false, NULL, 0, *FPaths::GetPath(PrereqPath), NULL); bool bPrereqInstallSuccessful = true; if (!ProcessHandle.IsValid()) { GLog->Logf(TEXT("BuildPatchServices: ERROR: Failed to start the prerequisites install process.")); FBuildPatchAnalytics::RecordPrereqInstallnError(PrereqPath, PrereqCommandline, -1, TEXT("Failed to start installer")); // @TODO: Do we need to do anything special to fail? bPrereqInstallSuccessful = false; } int32 ReturnCode; if (bPrereqInstallSuccessful) { FPlatformProcess::WaitForProc(ProcessHandle); FPlatformProcess::GetProcReturnCode(ProcessHandle, &ReturnCode); ProcessHandle.Close(); if (ReturnCode != 0) { if (ReturnCode == 3010) { GLog->Logf(TEXT("BuildPatchServices: Prerequisites executable returned restart required code %d"), ReturnCode); // @TODO: Inform app that system restart is required } else { GLog->Logf(TEXT("BuildPatchServices: ERROR: Prerequisites executable failed with code %d"), ReturnCode); FBuildPatchAnalytics::RecordPrereqInstallnError(PrereqPath, PrereqCommandline, ReturnCode, TEXT("Failed to install")); bPrereqInstallSuccessful = false; } } } if (bPrereqInstallSuccessful) { BuildProgress.SetStateProgress(EBuildPatchProgress::PrerequisitesInstall, 1.0f); } else { FBuildPatchInstallError::SetFatalError(EBuildPatchInstallError::PrerequisiteError); } return bPrereqInstallSuccessful; }
bool FLinuxTargetDevice::Run( const FString& ExecutablePath, const FString& Params, uint32* OutProcessId ) { #if PLATFORM_LINUX // if running natively, support simplified, local deployment FProcHandle ProcessHandle = FPlatformProcess::CreateProc(*ExecutablePath, *Params, true, false, false, OutProcessId, 0, NULL, NULL); return ProcessHandle.Close(); #else // @todo: support remote run STUBBED("FLinuxTargetDevice::Run"); return false; #endif // PLATFORM_LINUX }
bool FVisualStudioSourceCodeAccessor::RunVisualStudioAndOpenSolutionAndFiles(const FString& ExecutablePath, const FString& SolutionPath, const TArray<FileOpenRequest>* const Requests) const { ISourceCodeAccessModule& SourceCodeAccessModule = FModuleManager::LoadModuleChecked<ISourceCodeAccessModule>(TEXT("SourceCodeAccess")); FString Params; // Only open the solution if it exists if (!SolutionPath.IsEmpty()) { if (FPaths::FileExists(SolutionPath)) { Params += TEXT("\""); Params += SolutionPath; Params += TEXT("\""); } else { SourceCodeAccessModule.OnOpenFileFailed().Broadcast(SolutionPath); return false; } } if (Requests) { int32 GoToLine = 0; for (const FileOpenRequest& Request : *Requests) { // Only open the file if it exists if (FPaths::FileExists(Request.FullPath)) { Params += TEXT(" \""); Params += Request.FullPath; Params += TEXT("\""); GoToLine = Request.LineNumber; } else { SourceCodeAccessModule.OnOpenFileFailed().Broadcast(Request.FullPath); return false; } } if (GoToLine > 0) { Params += FString::Printf(TEXT(" /command \"edit.goto %d\""), GoToLine); } } FProcHandle WorkerHandle = FPlatformProcess::CreateProc(*ExecutablePath, *Params, true, false, false, nullptr, 0, nullptr, nullptr); bool bSuccess = WorkerHandle.IsValid(); FPlatformProcess::CloseProc(WorkerHandle); return bSuccess; }
FProcHandle FParent::Launch(bool bDetached) { // Launch the worker process int32 PriorityModifier = -1; // below normal uint32 WorkerId = 0; FString WorkerName = FPlatformProcess::ExecutableName(false); FProcHandle WorkerHandle = FPlatformProcess::CreateProc(*WorkerName, TEXT("proc-child"), bDetached, false, false, &WorkerId, PriorityModifier, NULL, NULL); if (!WorkerHandle.IsValid()) { // If this doesn't error, the app will hang waiting for jobs that can never be completed UE_LOG(LogTestPAL, Fatal, TEXT("Couldn't launch %s! Make sure the file is in your binaries folder."), *WorkerName); } return WorkerHandle; }
INT32_MAIN_INT32_ARGC_TCHAR_ARGV() { // FPlatformProcess::OpenProcess only implemented for windows atm #if PLATFORM_WINDOWS if (ArgC == 4 && FCString::Strcmp(ArgV[1], TEXT("-xgemonitor")) == 0) { // Open handles to the two processes FProcHandle EngineProc = FPlatformProcess::OpenProcess(FCString::Atoi(ArgV[2])); FProcHandle BuildProc = FPlatformProcess::OpenProcess(FCString::Atoi(ArgV[3])); if (EngineProc.IsValid() && BuildProc.IsValid()) { // Whilst the build is still in progress while (FPlatformProcess::IsProcRunning(BuildProc)) { // Check that the engine is still alive. if (!FPlatformProcess::IsProcRunning(EngineProc)) { // The engine has shutdown before the build was stopped. // Kill off the build process FPlatformProcess::TerminateProc(BuildProc); break; } FPlatformProcess::Sleep(0.01f); } } return 0; } #endif if(ArgC < 6) { printf("ShaderCompileWorker is called by UE4, it requires specific command like arguments.\n"); return -1; } // Game exe can pass any number of parameters through with appGetSubprocessCommandline // so just make sure we have at least the minimum number of parameters. check(ArgC >= 6); TCHAR OutputFilePath[PLATFORM_MAX_FILEPATH_LENGTH]; FCString::Strncpy(OutputFilePath, ArgV[1], PLATFORM_MAX_FILEPATH_LENGTH); FCString::Strncat(OutputFilePath, ArgV[5], PLATFORM_MAX_FILEPATH_LENGTH); const int32 ReturnCode = GuardedMainWrapper(ArgC,ArgV,OutputFilePath); return ReturnCode; }
void FLinuxPlatformProcess::WaitForProc( FProcHandle & ProcessHandle ) { FProcState * ProcInfo = ProcessHandle.GetProcessInfo(); if (ProcInfo) { ProcInfo->Wait(); } }
bool FLinuxPlatformProcess::GetProcReturnCode( FProcHandle& ProcHandle, int32* ReturnCode ) { if (IsProcRunning(ProcHandle)) { return false; } return ProcHandle.GetReturnCode(ReturnCode); }
bool FCodeLiteSourceCodeAccessor::Launch(const TArray<FString>& InArgs) { if (Location.IsValid()) { FString ArgsString; for (const FString& Arg : InArgs) { ArgsString.Append(Arg); ArgsString.Append(TEXT(" ")); } uint32 ProcessID; FProcHandle hProcess = FPlatformProcess::CreateProc(*Location.URL, *ArgsString, true, false, false, &ProcessID, 0, nullptr, nullptr, nullptr); return hProcess.IsValid(); } return false; }
bool FWindowsPlatformProcess::IsProcRunning( FProcHandle & ProcessHandle ) { bool bApplicationRunning = true; uint32 WaitResult = ::WaitForSingleObject(ProcessHandle.Get(), 0); if (WaitResult != WAIT_TIMEOUT) { bApplicationRunning = false; } return bApplicationRunning; }
bool FLinuxPlatformProcess::GetProcReturnCode( FProcHandle& ProcHandle, int32* ReturnCode ) { if (IsProcRunning(ProcHandle)) { return false; } FProcState * ProcInfo = ProcHandle.GetProcessInfo(); return ProcInfo ? ProcInfo->GetReturnCode(ReturnCode) : false; }
void FLinuxPlatformProcess::TerminateProc( FProcHandle & ProcessHandle, bool KillTree ) { if (KillTree) { // TODO: enumerate the children STUBBED("FLinuxPlatformProcess::TerminateProc() : Killing a subtree is not implemented yet"); } int KillResult = kill(ProcessHandle.Get(), SIGTERM); // graceful check(KillResult != -1 || errno != EINVAL); }
bool FCodeLiteSourceCodeAccessor::OpenSolution() { FString Filename = FPaths::GetBaseFilename(GetSolutionPath()) + ".workspace"; FString Directory = FPaths::GetPath(GetSolutionPath()); FString Solution = "\"" + Directory + "/" + Filename + "\""; FString CodeLitePath; if(!CanRunCodeLite(CodeLitePath)) { UE_LOG(LogCodeLiteAccessor, Warning, TEXT("FCodeLiteSourceCodeAccessor::OpenSolution: Cannot find CodeLite binary")); return false; } UE_LOG(LogCodeLiteAccessor, Warning, TEXT("FCodeLiteSourceCodeAccessor::OpenSolution: %s %s"), *CodeLitePath, *Solution); FProcHandle Proc = FPlatformProcess::CreateProc(*CodeLitePath, *Solution, true, false, false, nullptr, 0, nullptr, nullptr); if(Proc.IsValid()) { FPlatformProcess::CloseProc(Proc); return true; } return false; }
void FWindowsPlatformProcess::TerminateProc( FProcHandle & ProcessHandle, bool KillTree ) { if (KillTree) { HANDLE SnapShot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (SnapShot != INVALID_HANDLE_VALUE) { ::DWORD ProcessId = ::GetProcessId(ProcessHandle.Get()); PROCESSENTRY32 Entry; Entry.dwSize = sizeof(PROCESSENTRY32); if (::Process32First(SnapShot, &Entry)) { do { if (Entry.th32ParentProcessID == ProcessId) { HANDLE ChildProcHandle = ::OpenProcess(PROCESS_ALL_ACCESS, 0, Entry.th32ProcessID); if (ChildProcHandle) { FProcHandle ChildHandle(ChildProcHandle); TerminateProc(ChildHandle, KillTree); // ::TerminateProcess(ChildProcHandle, 1); } } } while(::Process32Next(SnapShot, &Entry)); } } } TerminateProcess(ProcessHandle.Get(),0); }
bool FCodeLiteSourceCodeAccessor::OpenSourceFiles(const TArray<FString>& AbsoluteSourcePaths) { FString CodeLitePath; if(!CanRunCodeLite(CodeLitePath)) { UE_LOG(LogCodeLiteAccessor, Warning, TEXT("FCodeLiteSourceCodeAccessor::OpenSourceFiles: Cannot find CodeLite binary")); return false; } for(const auto& SourcePath : AbsoluteSourcePaths) { const FString Path = FString::Printf(TEXT("\"%s\""), *SourcePath); FProcHandle Proc = FPlatformProcess::CreateProc(*CodeLitePath, *Path, true, false, false, nullptr, 0, nullptr, nullptr); if(Proc.IsValid()) { UE_LOG(LogCodeLiteAccessor, Warning, TEXT("CodeLiteSourceCodeAccessor::OpenSourceFiles: %s"), *Path); FPlatformProcess::CloseProc(Proc); return true; } } return false; }
bool FWindowsPlatformProcess::GetProcReturnCode( FProcHandle & ProcHandle, int32* ReturnCode ) { return ::GetExitCodeProcess( ProcHandle.Get(), (::DWORD *)ReturnCode ) && *((uint32*)ReturnCode) != ProcessConstants::WIN_STILL_ACTIVE; }
bool FLinuxPlatformProcess::ExecProcess( const TCHAR* URL, const TCHAR* Params, int32* OutReturnCode, FString* OutStdOut, FString* OutStdErr ) { FString CmdLineParams = Params; FString ExecutableFileName = URL; int32 ReturnCode = -1; FString DefaultError; if (!OutStdErr) { OutStdErr = &DefaultError; } void* PipeRead = nullptr; void* PipeWrite = nullptr; verify(FPlatformProcess::CreatePipe(PipeRead, PipeWrite)); bool bInvoked = false; const bool bLaunchDetached = true; const bool bLaunchHidden = false; const bool bLaunchReallyHidden = bLaunchHidden; FProcHandle ProcHandle = FPlatformProcess::CreateProc(*ExecutableFileName, *CmdLineParams, bLaunchDetached, bLaunchHidden, bLaunchReallyHidden, NULL, 0, NULL, PipeWrite); if (ProcHandle.IsValid()) { while (FPlatformProcess::IsProcRunning(ProcHandle)) { FString NewLine = FPlatformProcess::ReadPipe(PipeRead); if (NewLine.Len() > 0) { if (OutStdOut != nullptr) { *OutStdOut += NewLine; } } FPlatformProcess::Sleep(0.5); } // read the remainder for(;;) { FString NewLine = FPlatformProcess::ReadPipe(PipeRead); if (NewLine.Len() <= 0) { break; } if (OutStdOut != nullptr) { *OutStdOut += NewLine; } } FPlatformProcess::Sleep(0.5); bInvoked = true; bool bGotReturnCode = FPlatformProcess::GetProcReturnCode(ProcHandle, &ReturnCode); check(bGotReturnCode); *OutReturnCode = ReturnCode; FPlatformProcess::CloseProc(ProcHandle); } else { bInvoked = false; *OutReturnCode = -1; *OutStdOut = ""; UE_LOG(LogHAL, Warning, TEXT("Failed to launch Tool. (%s)"), *ExecutableFileName); } FPlatformProcess::ClosePipe(PipeRead, PipeWrite); return bInvoked; }
static bool CompressSliceToASTC( const void* SourceData, int32 SizeX, int32 SizeY, FString CompressionParameters, TArray<uint8>& OutCompressedData ) { // Always Y-invert the image prior to compression for proper orientation post-compression uint8 LineBuffer[16384 * 4]; uint32 LineSize = SizeX * 4; for (int32 LineIndex = 0; LineIndex < (SizeY / 2); LineIndex++) { uint8* LineData0 = ((uint8*)SourceData) + (LineSize * LineIndex); uint8* LineData1 = ((uint8*)SourceData) + (LineSize * (SizeY - LineIndex - 1)); FMemory::Memcpy(LineBuffer, LineData0, LineSize); FMemory::Memcpy(LineData0, LineData1, LineSize); FMemory::Memcpy(LineData1, LineBuffer, LineSize); } // Compress and retrieve the PNG data to write out to disk IImageWrapperPtr ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::PNG); ImageWrapper->SetRaw(SourceData, SizeX * SizeY * 4, SizeX, SizeY, ERGBFormat::RGBA, 8); const TArray<uint8>& FileData = ImageWrapper->GetCompressed(); int32 FileDataSize = FileData.Num(); FGuid Guid; FPlatformMisc::CreateGuid(Guid); FString InputFilePath = FString::Printf(TEXT("Cache/%08x-%08x-%08x-%08x-RGBToASTCIn.png"), Guid.A, Guid.B, Guid.C, Guid.D); FString OutputFilePath = FString::Printf(TEXT("Cache/%08x-%08x-%08x-%08x-RGBToASTCOut.astc"), Guid.A, Guid.B, Guid.C, Guid.D); InputFilePath = FPaths::GameIntermediateDir() + InputFilePath; OutputFilePath = FPaths::GameIntermediateDir() + OutputFilePath; FArchive* PNGFile = NULL; while (!PNGFile) { PNGFile = IFileManager::Get().CreateFileWriter(*InputFilePath); // Occasionally returns NULL due to error code ERROR_SHARING_VIOLATION FPlatformProcess::Sleep(0.01f); // ... no choice but to wait for the file to become free to access } PNGFile->Serialize((void*)&FileData[0], FileDataSize); delete PNGFile; // Compress PNG file to ASTC (using the reference astcenc.exe from ARM) FString Params = FString::Printf(TEXT("-c %s %s %s"), *InputFilePath, *OutputFilePath, *CompressionParameters ); UE_LOG(LogTextureFormatASTC, Display, TEXT("Compressing to ASTC (%s)..."), *CompressionParameters); // Start Compressor #if PLATFORM_MAC FString CompressorPath(FPaths::EngineDir() + TEXT("Binaries/ThirdParty/ARM/Mac/astcenc")); #elif PLATFORM_LINUX FString CompressorPath(FPaths::EngineDir() + TEXT("Binaries/ThirdParty/ARM/Linux32/astcenc")); #elif PLATFORM_WINDOWS FString CompressorPath(FPaths::EngineDir() + TEXT("Binaries/ThirdParty/ARM/Win32/astcenc.exe")); #else #error Unsupported platform #endif FProcHandle Proc = FPlatformProcess::CreateProc(*CompressorPath, *Params, true, false, false, NULL, -1, NULL, NULL); // Failed to start the compressor process if (!Proc.IsValid()) { UE_LOG(LogTextureFormatASTC, Error, TEXT("Failed to start astcenc for compressing images (%s)"), *CompressorPath); return false; } // Wait for the process to complete int ReturnCode; while (!FPlatformProcess::GetProcReturnCode(Proc, &ReturnCode)) { FPlatformProcess::Sleep(0.01f); } // Did it work? bool bConversionWasSuccessful = (ReturnCode == 0); // Open compressed file and put the data in OutCompressedImage if (bConversionWasSuccessful) { // Get raw file data TArray<uint8> ASTCData; FFileHelper::LoadFileToArray(ASTCData, *OutputFilePath); // Process it FASTCHeader* Header = (FASTCHeader*)ASTCData.GetData(); // Fiddle with the texel count data to get the right value uint32 TexelCountX = (Header->TexelCountX[0] << 0) + (Header->TexelCountX[1] << 8) + (Header->TexelCountX[2] << 16); uint32 TexelCountY = (Header->TexelCountY[0] << 0) + (Header->TexelCountY[1] << 8) + (Header->TexelCountY[2] << 16); uint32 TexelCountZ = (Header->TexelCountZ[0] << 0) + (Header->TexelCountZ[1] << 8) + (Header->TexelCountZ[2] << 16); // UE_LOG(LogTextureFormatASTC, Display, TEXT(" Compressed Texture Header:")); // UE_LOG(LogTextureFormatASTC, Display, TEXT(" Magic: %x"), Header->Magic); // UE_LOG(LogTextureFormatASTC, Display, TEXT(" BlockSizeX: %u"), Header->BlockSizeX); // UE_LOG(LogTextureFormatASTC, Display, TEXT(" BlockSizeY: %u"), Header->BlockSizeY); // UE_LOG(LogTextureFormatASTC, Display, TEXT(" BlockSizeZ: %u"), Header->BlockSizeZ); // UE_LOG(LogTextureFormatASTC, Display, TEXT(" TexelCountX: %u"), TexelCountX); // UE_LOG(LogTextureFormatASTC, Display, TEXT(" TexelCountY: %u"), TexelCountY); // UE_LOG(LogTextureFormatASTC, Display, TEXT(" TexelCountZ: %u"), TexelCountZ); // Calculate size of this mip in blocks uint32 MipSizeX = (TexelCountX + Header->BlockSizeX - 1) / Header->BlockSizeX; uint32 MipSizeY = (TexelCountY + Header->BlockSizeY - 1) / Header->BlockSizeY; // A block is always 16 bytes uint32 MipSize = MipSizeX * MipSizeY * 16; // Copy the compressed data OutCompressedData.Empty(MipSize); OutCompressedData.AddUninitialized(MipSize); void* MipData = OutCompressedData.GetData(); // Calculate the offset to get to the mip data check(sizeof(FASTCHeader) == 16); check(ASTCData.Num() == (sizeof(FASTCHeader) + MipSize)); FMemory::Memcpy(MipData, ASTCData.GetData() + sizeof(FASTCHeader), MipSize); } else { UE_LOG(LogTextureFormatASTC, Error, TEXT("ASTC encoder failed with return code %d, mip size (%d, %d)"), ReturnCode, SizeX, SizeY); IFileManager::Get().Delete(*InputFilePath); IFileManager::Get().Delete(*OutputFilePath); return false; } // Delete intermediate files IFileManager::Get().Delete(*InputFilePath); IFileManager::Get().Delete(*OutputFilePath); return true; }
void FWindowsPlatformProcess::WaitForProc( FProcHandle & ProcessHandle ) { ::WaitForSingleObject(ProcessHandle.Get(), INFINITE); }
/** * Run a Git show command to dump the binary content of a revision into a file. */ bool RunDumpToFile(const FString& InPathToGitBinary, const FString& InRepositoryRoot, const FString& InParameter, const FString& InDumpFileName) { bool bResult = false; FString FullCommand; if(!InRepositoryRoot.IsEmpty()) { // Specify the working copy (the root) of the git repository (before the command itself) FullCommand = TEXT("--work-tree=\""); FullCommand += InRepositoryRoot; // and the ".git" subdirectory in it (before the command itself) FullCommand += TEXT("\" --git-dir=\""); FullCommand += InRepositoryRoot; FullCommand += TEXT(".git\" "); } // then the git command itself FullCommand += TEXT("show "); // Append to the command the parameter FullCommand += InParameter; const bool bLaunchDetached = false; const bool bLaunchHidden = true; const bool bLaunchReallyHidden = bLaunchHidden; // Setup output redirection pipes, so that we can harvest compiler output and display it ourselves #if PLATFORM_LINUX int pipefd[2]; pipe(pipefd); void* PipeRead = &pipefd[0]; void* PipeWrite = &pipefd[1]; #else void* PipeRead = NULL; void* PipeWrite = NULL; #endif verify(FPlatformProcess::CreatePipe(PipeRead, PipeWrite)); // @todo temp debug log //UE_LOG(LogSourceControl, Log, TEXT("RunDumpToFile: 'git %s'"), *FullCommand); FProcHandle ProcessHandle = FPlatformProcess::CreateProc(*InPathToGitBinary, *FullCommand, bLaunchDetached, bLaunchHidden, bLaunchReallyHidden, NULL, 0, NULL, PipeWrite); //UE_LOG(LogSourceControl, Log, TEXT("RunDumpToFile: ProcessHandle=%x"), ProcessHandle.Get()); if(ProcessHandle.IsValid()) { FPlatformProcess::Sleep(0.01); TArray<uint8> BinaryFileContent; while(FPlatformProcess::IsProcRunning(ProcessHandle)) { TArray<uint8> BinaryData; FPlatformProcess::ReadPipeToArray(PipeRead, BinaryData); if(BinaryData.Num() > 0) { BinaryFileContent.Append(MoveTemp(BinaryData)); } } TArray<uint8> BinaryData; FPlatformProcess::ReadPipeToArray(PipeRead, BinaryData); if(BinaryData.Num() > 0) { BinaryFileContent.Append(MoveTemp(BinaryData)); } // Save buffer into temp file if(FFileHelper::SaveArrayToFile(BinaryFileContent, *InDumpFileName)) { UE_LOG(LogSourceControl, Log, TEXT("Writed '%s' (%do)"), *InDumpFileName, BinaryFileContent.Num()); bResult = true; } else { UE_LOG(LogSourceControl, Error, TEXT("Could not write %s"), *InDumpFileName); } } else { UE_LOG(LogSourceControl, Error, TEXT("Failed to launch 'git show'")); } #if PLATFORM_LINUX close(*(int*)PipeRead); close(*(int*)PipeWrite); #else FPlatformProcess::ClosePipe(PipeRead, PipeWrite); #endif return bResult; }
bool FCodeLiteSourceCodeAccessor::OpenSourceFiles(const TArray<FString>& AbsoluteSourcePaths) { FString CodeLitePath; if(!CanRunCodeLite(CodeLitePath)) { UE_LOG(LogCodeLiteAccessor, Warning, TEXT("FCodeLiteSourceCodeAccessor::OpenSourceFiles: Cannot find CodeLite binary")); return false; } #ifdef USE_DBUS for(const auto& SourcePath : AbsoluteSourcePaths) { DBusMessage* message = nullptr; DBusMessageIter args; // Create new message. message = dbus_message_new_signal ("/org/codelite/command", "org.codelite.command", "OpenFile"); char* fileName = TCHAR_TO_ANSI(*SourcePath); // Add parameters to the message. dbus_message_iter_init_append(message, &args); if(!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &fileName)) { UE_LOG(LogCodeLiteAccessor, Warning, TEXT("Sdbus_message_iter_append_basic failed.")); return false; } // Send the message. dbus_connection_send(DBusConnection, message, nullptr); if(dbus_error_is_set(&DBusError)) { UE_LOG(LogCodeLiteAccessor, Warning, TEXT("dbus_connection_send failed: %s"), DBusError.message); return false; } // Free the message resources. dbus_message_unref(message); } dbus_connection_flush(DBusConnection); return true; #else for(const auto& SourcePath : AbsoluteSourcePaths) { const FString Path = FString::Printf(TEXT("\"%s\""), *SourcePath); FProcHandle Proc = FPlatformProcess::CreateProc(*CodeLitePath, *Path, true, false, false, nullptr, 0, nullptr, nullptr); if(Proc.IsValid()) { UE_LOG(LogCodeLiteAccessor, Warning, TEXT("CodeLiteSourceCodeAccessor::OpenSourceFiles: %s"), *Path); FPlatformProcess::CloseProc(Proc); return true; } } #endif return false; }
bool FFeedbackContextMarkup::PipeProcessOutput(const FText& Description, const FString& URL, const FString& Params, FFeedbackContext* Warn, int32* OutExitCode) { bool bRes; // Create a read and write pipe for the child process void* PipeRead = NULL; void* PipeWrite = NULL; verify(FPlatformProcess::CreatePipe(PipeRead, PipeWrite)); // Start the slow task Warn->BeginSlowTask(Description, true, true); // Create the process FProcHandle ProcessHandle = FPlatformProcess::CreateProc(*URL, *Params, false, true, true, NULL, 0, NULL, PipeWrite); if(ProcessHandle.IsValid()) { FString BufferedText; for(bool bProcessFinished = false; !bProcessFinished; ) { bProcessFinished = FPlatformProcess::GetProcReturnCode(ProcessHandle, OutExitCode); if(!bProcessFinished && Warn->ReceivedUserCancel()) { FPlatformProcess::TerminateProc(ProcessHandle); bProcessFinished = true; } BufferedText += FPlatformProcess::ReadPipe(PipeRead); int32 EndOfLineIdx; while(BufferedText.FindChar('\n', EndOfLineIdx)) { FString Line = BufferedText.Left(EndOfLineIdx); Line.RemoveFromEnd(TEXT("\r")); if(!ParseCommand(Line, Warn)) { Warn->Log(*Line); } BufferedText = BufferedText.Mid(EndOfLineIdx + 1); } FPlatformProcess::Sleep(0.1f); } ProcessHandle.Reset(); bRes = true; } else { Warn->Logf(ELogVerbosity::Error, TEXT("Couldn't create process '%s'"), *URL); bRes = false; } // Finish the slow task Warn->EndSlowTask(); // Close the pipes FPlatformProcess::ClosePipe(0, PipeRead); FPlatformProcess::ClosePipe(0, PipeWrite); return bRes; }
FProcHandle FDesktopPlatformBase::InvokeUnrealBuildToolAsync(const FString& InCmdLineParams, FOutputDevice &Ar, void*& OutReadPipe, void*& OutWritePipe, bool bSkipBuildUBT) { FString CmdLineParams = InCmdLineParams; #if PLATFORM_WINDOWS #if _MSC_VER >= 1900 CmdLineParams += TEXT(" -2015"); #elif _MSC_VER >= 1800 CmdLineParams += TEXT(" -2013"); #else CmdLineParams += TEXT(" -2012"); #endif #endif // PLATFORM_WINDOWS // UnrealBuildTool is currently always located in the Binaries/DotNET folder FString ExecutableFileName = GetUnrealBuildToolExecutableFilename(FPaths::RootDir()); // Rocket never builds UBT, UnrealBuildTool should already exist bool bSkipBuild = FApp::IsEngineInstalled() || bSkipBuildUBT; if (!bSkipBuild) { // When not using rocket, we should attempt to build UBT to make sure it is up to date // Only do this if we have not already successfully done it once during this session. static bool bSuccessfullyBuiltUBTOnce = false; if (!bSuccessfullyBuiltUBTOnce) { Ar.Log(TEXT("Building UnrealBuildTool...")); if (BuildUnrealBuildTool(FPaths::RootDir(), Ar)) { bSuccessfullyBuiltUBTOnce = true; } else { // Failed to build UBT Ar.Log(TEXT("Failed to build UnrealBuildTool.")); return FProcHandle(); } } } #if PLATFORM_LINUX CmdLineParams += (" -progress"); #endif // PLATFORM_LINUX Ar.Logf(TEXT("Launching UnrealBuildTool... [%s %s]"), *ExecutableFileName, *CmdLineParams); #if PLATFORM_MAC // On Mac we launch UBT with Mono FString ScriptPath = FPaths::ConvertRelativePathToFull(FPaths::EngineDir() / TEXT("Build/BatchFiles/Mac/RunMono.sh")); CmdLineParams = FString::Printf(TEXT("\"%s\" \"%s\" %s"), *ScriptPath, *ExecutableFileName, *CmdLineParams); ExecutableFileName = TEXT("/bin/sh"); #elif PLATFORM_LINUX // Real men run Linux (with Mono??) FString ScriptPath = FPaths::ConvertRelativePathToFull(FPaths::EngineDir() / TEXT("Build/BatchFiles/Linux/RunMono.sh")); CmdLineParams = FString::Printf(TEXT("\"%s\" \"%s\" %s"), *ScriptPath, *ExecutableFileName, *CmdLineParams); ExecutableFileName = TEXT("/bin/bash"); #endif // Run UnrealBuildTool const bool bLaunchDetached = false; const bool bLaunchHidden = true; const bool bLaunchReallyHidden = bLaunchHidden; FProcHandle ProcHandle = FPlatformProcess::CreateProc(*ExecutableFileName, *CmdLineParams, bLaunchDetached, bLaunchHidden, bLaunchReallyHidden, NULL, 0, NULL, OutWritePipe); if (!ProcHandle.IsValid()) { Ar.Logf(TEXT("Failed to launch Unreal Build Tool. (%s)"), *ExecutableFileName); } return ProcHandle; }
bool FDesktopPlatformBase::BuildUnrealBuildTool(const FString& RootDir, FOutputDevice& Ar) { Ar.Logf(TEXT("Building UnrealBuildTool in %s..."), *RootDir); // Check the project file exists FString CsProjLocation = GetUnrealBuildToolProjectFileName(RootDir); if(!FPaths::FileExists(CsProjLocation)) { Ar.Logf(TEXT("Project file not found at %s"), *CsProjLocation); return false; } FString CompilerExecutableFilename; FString CmdLineParams; if (PLATFORM_WINDOWS) { // To build UBT for windows, we must assemble a batch file that first registers the environment variable necessary to run msbuild then run it // This can not be done in a single invocation of CMD.exe because the environment variables do not transfer between subsequent commands when using the "&" syntax // devenv.exe can be used to build as well but it takes several seconds to start up so it is not desirable // First determine the appropriate vcvars batch file to launch FString VCVarsBat; #if PLATFORM_WINDOWS #if _MSC_VER >= 1900 FPlatformMisc::GetVSComnTools(14, VCVarsBat); #elif _MSC_VER >= 1800 FPlatformMisc::GetVSComnTools(12, VCVarsBat); #else FPlatformMisc::GetVSComnTools(11, VCVarsBat); #endif #endif // PLATFORM_WINDOWS VCVarsBat = FPaths::Combine(*VCVarsBat, L"../../VC/bin/x86_amd64/vcvarsx86_amd64.bat"); // Check to make sure we found one. if (VCVarsBat.IsEmpty() || !FPaths::FileExists(VCVarsBat)) { Ar.Logf(TEXT("Couldn't find %s; skipping."), *VCVarsBat); return false; } // Now make a batch file in the intermediate directory to invoke the vcvars batch then msbuild FString BuildBatchFile = RootDir / TEXT("Engine/Intermediate/Build/UnrealBuildTool/BuildUBT.bat"); BuildBatchFile.ReplaceInline(TEXT("/"), TEXT("\\")); FString BatchFileContents; BatchFileContents = FString::Printf(TEXT("call \"%s\"") LINE_TERMINATOR, *VCVarsBat); BatchFileContents += FString::Printf(TEXT("msbuild /nologo /verbosity:quiet \"%s\" /property:Configuration=Development /property:Platform=AnyCPU"), *CsProjLocation); FFileHelper::SaveStringToFile(BatchFileContents, *BuildBatchFile); TCHAR CmdExePath[MAX_PATH]; FPlatformMisc::GetEnvironmentVariable(TEXT("ComSpec"), CmdExePath, ARRAY_COUNT(CmdExePath)); CompilerExecutableFilename = CmdExePath; CmdLineParams = FString::Printf(TEXT("/c \"%s\""), *BuildBatchFile); } else if (PLATFORM_MAC) { FString ScriptPath = FPaths::ConvertRelativePathToFull(RootDir / TEXT("Engine/Build/BatchFiles/Mac/RunXBuild.sh")); CompilerExecutableFilename = TEXT("/bin/sh"); CmdLineParams = FString::Printf(TEXT("\"%s\" /property:Configuration=Development %s"), *ScriptPath, *CsProjLocation); } else if (PLATFORM_LINUX) { FString ScriptPath = FPaths::ConvertRelativePathToFull(RootDir / TEXT("Engine/Build/BatchFiles/Linux/RunXBuild.sh")); CompilerExecutableFilename = TEXT("/bin/bash"); CmdLineParams = FString::Printf(TEXT("\"%s\" /property:Configuration=Development /property:TargetFrameworkVersion=v4.0 %s"), *ScriptPath, *CsProjLocation); } else { Ar.Log(TEXT("Unknown platform, unable to build UnrealBuildTool.")); return false; } // Spawn the compiler Ar.Logf(TEXT("Running: %s %s"), *CompilerExecutableFilename, *CmdLineParams); const bool bLaunchDetached = false; const bool bLaunchHidden = true; const bool bLaunchReallyHidden = bLaunchHidden; FProcHandle ProcHandle = FPlatformProcess::CreateProc(*CompilerExecutableFilename, *CmdLineParams, bLaunchDetached, bLaunchHidden, bLaunchReallyHidden, NULL, 0, NULL, NULL); if (!ProcHandle.IsValid()) { Ar.Log(TEXT("Failed to start process.")); return false; } FPlatformProcess::WaitForProc(ProcHandle); FPlatformProcess::CloseProc(ProcHandle); // If the executable appeared where we expect it, then we were successful FString UnrealBuildToolExePath = GetUnrealBuildToolExecutableFilename(RootDir); if(!FPaths::FileExists(UnrealBuildToolExePath)) { Ar.Logf(TEXT("Missing %s after build"), *UnrealBuildToolExePath); return false; } return true; }
bool FKDevelopSourceCodeAccessor::OpenSolution() { if (IsIDERunning()) { // use qdbus to open the project within session? STUBBED("OpenSolution: KDevelop is running, use qdbus to open the project within session?"); return false; } FString Solution = GetSolutionPath(); FString IDEPath; if (!CanRunKDevelop(IDEPath)) { UE_LOG(LogKDevelopAccessor, Warning, TEXT("FKDevelopSourceCodeAccessor::OpenSourceFiles: cannot find kdevelop binary")); return false; } FProcHandle Proc = FPlatformProcess::CreateProc(*IDEPath, *Solution, true, false, false, nullptr, 0, nullptr, nullptr); if (Proc.IsValid()) { FPlatformProcess::CloseProc(Proc); return true; } return false; }