private bool TryParseInclude(Include include, ModuleDecl module, BuiltIns builtIns, ErrorReporter errorReporter, Errors errors) { try { var dafnyFile = new DafnyFile(include.includedFilename); int errorCount = Parser.Parse( useStdin: false, dafnyFile.SourceFileName, include, module, builtIns, errors, verifyThisFile: false, compileThisFile: false ); if (errorCount != 0) { errorReporter.Error(MessageSource.Parser, include.tok, $"{errorCount} parse error(s) detected in {include.includedFilename}"); return(false); } } catch (IllegalDafnyFile e) { errorReporter.Error(MessageSource.Parser, include.tok, $"Include of file {include.includedFilename} failed."); _logger.LogDebug(e, "encountered include of illegal dafny file {}", include.includedFilename); return(false); } catch (IOException e) { errorReporter.Error(MessageSource.Parser, include.tok, $"Unable to open the include {include.includedFilename}."); _logger.LogDebug(e, "could not open file {}", include.includedFilename); return(false); } return(true); }
public void SemErr(IToken tok, string msg) // semantic errors { Contract.Requires(tok != null); Contract.Requires(msg != null); ErrorCount++; Reporting.Error(MessageSource.Parser, tok, msg); }
private void CodeSign(string BaseDirectory, string GameName, string RawProjectPath, UnrealTargetConfiguration TargetConfig, string LocalRoot, string ProjectName, string ProjectDirectory, bool IsCode, bool Distribution = false) { // check for the proper xcodeproject bool bWasGenerated = false; string XcodeProj = EnsureXcodeProjectExists(RawProjectPath, LocalRoot, ProjectName, ProjectDirectory, IsCode, out bWasGenerated); string Arguments = "UBT_NO_POST_DEPLOY=true"; Arguments += " /usr/bin/xcrun xcodebuild build -project \"" + XcodeProj + "\""; Arguments += " -scheme '"; Arguments += GameName; Arguments += " - iOS'"; Arguments += " -configuration " + TargetConfig.ToString(); Arguments += " CODE_SIGN_IDENTITY=" + (Distribution ? "\"iPhone Distribution\"" : "\"iPhone Developer\""); ProcessResult Result = Run("/usr/bin/env", Arguments, null, ERunOptions.Default); if (bWasGenerated) { InternalUtils.SafeDeleteDirectory(XcodeProj, true); } if (Result.ExitCode != 0) { ErrorReporter.Error("CodeSign Failed", (int)ErrorCodes.Error_FailedToCodeSign); throw new AutomationException("CodeSign Failed"); } }
private static string GetFinalObbName(string ApkName) { // calculate the name for the .obb file string PackageName = GetPackageInfo(ApkName, false); if (PackageName == null) { ErrorReporter.Error("Failed to get package name from " + ApkName, (int)ErrorCodes.Error_FailureGettingPackageInfo); throw new AutomationException("Failed to get package name from " + ApkName); } string PackageVersion = GetPackageInfo(ApkName, true); if (PackageVersion == null || PackageVersion.Length == 0) { ErrorReporter.Error("Failed to get package version from " + ApkName, (int)ErrorCodes.Error_FailureGettingPackageInfo); throw new AutomationException("Failed to get package version from " + ApkName); } if (PackageVersion.Length > 0) { int IntVersion = int.Parse(PackageVersion); PackageVersion = IntVersion.ToString("0"); } string ObbName = string.Format("main.{0}.{1}.obb", PackageVersion, PackageName); // plop the .obb right next to the executable ObbName = Path.Combine(Path.GetDirectoryName(ApkName), ObbName); return(ObbName); }
public ProofState(Program program, ErrorReporter reporter, Program unresolvedProgram = null) { Contract.Requires(program != null); // get a new program instance Datatypes = new Dictionary <string, DatatypeDecl>(); _topLevelClasses = new List <TopLevelClassDeclaration>(); Reporter = reporter; //get some token such that _filename != null var tld = (ClassDecl)program.DefaultModuleDef.TopLevelDecls.FirstOrDefault(x => x is ClassDecl); var member = tld?.Members.FirstOrDefault(); var tok = member?.tok; if (unresolvedProgram == null) { var err = Parser.ParseCheck(new List <string>() { tok?.filename ?? program.FullName }, program.Name, out _original); if (err != null) { reporter.Error(MessageSource.Tacny, program.DefaultModuleDef.tok, $"Error parsing a fresh Tacny program: {err}"); } } else { _original = unresolvedProgram; } ResultCache = new List <TacticCache>(); // fill state FillStaticState(program); }
public override object VisitFunctionDefinition([NotNull] functionalParser.FunctionDefinitionContext context) { var predicate = ((string, string[], Ty))Visit(context.predicate()); FunctionType functionPredicate; if (predicate.Item3.Type.Is <FunctionType>()) { functionPredicate = predicate.Item3.Type.As <FunctionType>(); } else { // If the predicate is not a function type make it into one (e.g. main :: Int) functionPredicate = new FunctionType(new Ty[] { predicate.Item3 }); } var overloads = context.stmt().Select( (obj) => ((string, Pattern[], Node, WhereClauseNode))Visit(obj)).ToArray(); // check if all functions are of the same name if (overloads.Any((obj) => obj.Item1 != predicate.Item1)) { ErrorReporter.Error("The function block `{0}` contains different functions", predicate.Item1); } return(new FunctionNode( predicate.Item1, overloads.Select((obj) => (obj.Item2, obj.Item3, obj.Item4)).ToArray(), functionPredicate, predicate.Item2, FileAndLine(context) )); }
public AstType Get(string name) { if (table.TryGetValue(name, out AstType type)) { return(type); } // TODO line count print ErrorReporter.Error("Type `{0}` does not exist", name); return(null); }
private static string GetAaptPath() { // there is a numbered directory in here, hunt it down string[] Subdirs = Directory.GetDirectories(Environment.ExpandEnvironmentVariables("%ANDROID_HOME%/build-tools/")); if (Subdirs.Length == 0) { ErrorReporter.Error("Failed to find %ANDROID_HOME%/build-tools subdirectory", (int)ErrorCodes.Error_AndroidBuildToolsPathNotFound); throw new AutomationException("Failed to find %ANDROID_HOME%/build-tools subdirectory"); } // we expect there to be one, so use the first one return(Path.Combine(Subdirs[0], "aapt.exe")); }
public static functionalParser Parse(string filePath) { if (!File.Exists(filePath)) { ErrorReporter.Error("File {0} does not exist", filePath); } AntlrInputStream inputStream = new AntlrInputStream(File.Open(filePath, FileMode.Open, FileAccess.Read)); functionalLexer lexer = new functionalLexer(inputStream); CommonTokenStream commonTokenStream = new CommonTokenStream(lexer); return(new functionalParser(commonTokenStream)); }
private void CaptureViolatedPostconditions(ErrorInformation errorInfo) { _errorReporter.Error(VerifierMessageSource, errorInfo.Tok, errorInfo.Msg); foreach (var auxiliaryErrorInfo in errorInfo.Aux) { // The execution trace is an additional auxiliary which identifies itself with // line=0 and character=0. These positions cause errors when exposing them, Furthermore, // the execution trace message appears to not have any interesting information. if (auxiliaryErrorInfo.Tok.line > 0) { _errorReporter.Info(VerifierMessageSource, auxiliaryErrorInfo.Tok, auxiliaryErrorInfo.Msg); } } }
public override void GetFilesToArchive(ProjectParams Params, DeploymentContext SC) { if (SC.StageTargetConfigurations.Count != 1) { string ErrorString = String.Format("Android is currently only able to package one target configuration at a time, but StageTargetConfigurations contained {0} configurations", SC.StageTargetConfigurations.Count); ErrorReporter.Error(ErrorString, (int)ErrorCodes.Error_OnlyOneTargetConfigurationSupported); throw new AutomationException(ErrorString); } string[] Architectures = UnrealBuildTool.AndroidToolChain.GetAllArchitectures(); string[] GPUArchitectures = UnrealBuildTool.AndroidToolChain.GetAllGPUArchitectures(); bool bMakeSeparateApks = UnrealBuildTool.Android.UEDeployAndroid.ShouldMakeSeparateApks(); bool bPackageDataInsideApk = UnrealBuildTool.Android.UEDeployAndroid.PackageDataInsideApk(false); bool bAddedOBB = false; foreach (string Architecture in Architectures) { foreach (string GPUArchitecture in GPUArchitectures) { string ApkName = GetFinalApkName(Params, SC.StageExecutables[0], true, bMakeSeparateApks ? Architecture : "", bMakeSeparateApks ? GPUArchitecture : ""); string ObbName = GetFinalObbName(ApkName); string BatchName = GetFinalBatchName(ApkName, Params, bMakeSeparateApks ? Architecture : "", bMakeSeparateApks ? GPUArchitecture : ""); // verify the files exist if (!FileExists(ApkName)) { string ErrorString = String.Format("ARCHIVE FAILED - {0} was not found", ApkName); ErrorReporter.Error(ErrorString, (int)ErrorCodes.Error_AppNotFound); throw new AutomationException(ErrorString); } if (!bPackageDataInsideApk && !FileExists(ObbName)) { string ErrorString = String.Format("ARCHIVE FAILED - {0} was not found", ObbName); ErrorReporter.Error(ErrorString, (int)ErrorCodes.Error_ObbNotFound); throw new AutomationException(ErrorString); } SC.ArchiveFiles(Path.GetDirectoryName(ApkName), Path.GetFileName(ApkName)); if (!bPackageDataInsideApk && !bAddedOBB) { bAddedOBB = true; SC.ArchiveFiles(Path.GetDirectoryName(ObbName), Path.GetFileName(ObbName)); } SC.ArchiveFiles(Path.GetDirectoryName(BatchName), Path.GetFileName(BatchName)); } } }
public virtual void Error(string message, string sourceURI, int line, string lineText, int lineOffset) { if (forEval) { throw ScriptRuntime.ConstructError("SyntaxError", message, sourceURI, line, lineText, lineOffset); } if (chainedReporter != null) { chainedReporter.Error(message, sourceURI, line, lineText, lineOffset); } else { throw RuntimeError(message, sourceURI, line, lineText, lineOffset); } }
public static Assembly CompileAssembly(string fullSource, ErrorReporter errorReporter, params string[] referencedAssemblies) { CompilerResults cr = DoCompile(fullSource, referencedAssemblies); foreach (CompilerError item in cr.Errors) { if (item.IsWarning) { errorReporter.Warning(item.ToString()); } else { errorReporter.Error(item.ToString()); } } return cr.CompiledAssembly; }
public override void PostRunClient(ProcessResult Result, ProjectParams Params) { if (UnrealBuildTool.BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac) { Console.WriteLine("Deleting " + Params.BaseStageDirectory + "/IOS/launch.trace"); if (Directory.Exists(Params.BaseStageDirectory + "/IOS/launch.trace")) { Directory.Delete(Params.BaseStageDirectory + "/IOS/launch.trace", true); } switch (Result.ExitCode) { case 253: ErrorReporter.Error("Launch Failure", (int)ErrorCodes.Error_DeviceNotSetupForDevelopment); break; case 255: ErrorReporter.Error("Launch Failure", (int)ErrorCodes.Error_DeviceOSNewerThanSDK); break; } } }
public ProofState(Program program, ErrorReporter reporter) { Contract.Requires(program != null); // get a new program instance Datatypes = new Dictionary <string, DatatypeDecl>(); _topLevelClasses = new List <TopLevelClassDeclaration>(); Reporter = reporter; //note the differences between this ParseCheck and the one at the top level. This function only parses but the other one resolves. var err = Parser.ParseOnly(new List <string>() { program.FullName }, program.Name, out _original); if (err != null) { reporter.Error(MessageSource.Tacny, program.DefaultModuleDef.tok, $"Error parsing a fresh Tacny program: {err}"); } // fill state FillStaticState(program); }
public override void Package(ProjectParams Params, DeploymentContext SC, int WorkingCL) { Log("Package {0}", Params.RawProjectPath); //@TODO: We should be able to use this code on both platforms, when the following issues are sorted: // - Raw executable is unsigned & unstripped (need to investigate adding stripping to IPP) // - IPP needs to be able to codesign a raw directory // - IPP needs to be able to take a .app directory instead of a Payload directory when doing RepackageFromStage (which would probably be renamed) // - Some discrepancy in the loading screen pngs that are getting packaged, which needs to be investigated // - Code here probably needs to be updated to write 0 byte files as 1 byte (difference with IPP, was required at one point when using Ionic.Zip to prevent issues on device, maybe not needed anymore?) if (UnrealBuildTool.BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac) { // copy in all of the artwork and plist var DeployHandler = UEBuildDeploy.GetBuildDeploy(UnrealTargetPlatform.IOS); DeployHandler.PrepForUATPackageOrDeploy(Params.ShortProjectName, Path.GetDirectoryName(Params.RawProjectPath), CombinePaths(Path.GetDirectoryName(Params.ProjectGameExeFilename), SC.StageExecutables[0]), CombinePaths(SC.LocalRoot, "Engine"), Params.Distribution, ""); // figure out where to pop in the staged files string AppDirectory = string.Format("{0}/Payload/{1}.app", Path.GetDirectoryName(Params.ProjectGameExeFilename), Path.GetFileNameWithoutExtension(Params.ProjectGameExeFilename)); // delete the old cookeddata InternalUtils.SafeDeleteDirectory(AppDirectory + "/cookeddata", true); InternalUtils.SafeDeleteFile(AppDirectory + "/ue4commandline.txt", true); // copy the Staged files to the AppDirectory string[] StagedFiles = Directory.GetFiles(SC.StageDirectory, "*", SearchOption.AllDirectories); foreach (string Filename in StagedFiles) { string DestFilename = Filename.Replace(SC.StageDirectory, AppDirectory); Directory.CreateDirectory(Path.GetDirectoryName(DestFilename)); InternalUtils.SafeCopyFile(Filename, DestFilename, true); } } if (UnrealBuildTool.BuildHostPlatform.Current.Platform != UnrealTargetPlatform.Mac) { if (SC.StageTargetConfigurations.Count != 1) { throw new AutomationException("iOS is currently only able to package one target configuration at a time, but StageTargetConfigurations contained {0} configurations", SC.StageTargetConfigurations.Count); } var TargetConfiguration = SC.StageTargetConfigurations[0]; var ProjectStub = Path.GetFullPath(Params.ProjectGameExeFilename) + "/" + Params.ShortProjectName + Path.GetExtension(Params.ProjectGameExeFilename); var ProjectIPA = MakeIPAFileName(TargetConfiguration, Params); // package a .ipa from the now staged directory var IPPExe = CombinePaths(CmdEnv.LocalRoot, "Engine/Binaries/DotNET/IOS/IPhonePackager.exe"); Log("ProjectName={0}", Params.ShortProjectName); Log("ProjectStub={0}", ProjectStub); Log("ProjectIPA={0}", ProjectIPA); Log("IPPExe={0}", IPPExe); bool cookonthefly = Params.CookOnTheFly || Params.SkipCookOnTheFly; // delete the .ipa to make sure it was made DeleteFile(ProjectIPA); if (RemoteToolChain.bUseRPCUtil) { string IPPArguments = "RepackageFromStage \"" + (Params.IsCodeBasedProject ? Params.RawProjectPath : "Engine") + "\""; IPPArguments += " -config " + TargetConfiguration.ToString(); if (TargetConfiguration == UnrealTargetConfiguration.Shipping) { IPPArguments += " -compress=best"; } // Determine if we should sign bool bNeedToSign = GetCodeSignDesirability(Params); if (!String.IsNullOrEmpty(Params.BundleName)) { // Have to sign when a bundle name is specified bNeedToSign = true; IPPArguments += " -bundlename " + Params.BundleName; } if (bNeedToSign) { IPPArguments += " -sign"; if (Params.Distribution) { IPPArguments += " -distribution"; } } IPPArguments += (cookonthefly ? " -cookonthefly" : ""); IPPArguments += " -stagedir \"" + CombinePaths(Params.BaseStageDirectory, "IOS") + "\""; IPPArguments += " -project \"" + Params.RawProjectPath + "\""; RunAndLog(CmdEnv, IPPExe, IPPArguments); } else { List <string> IPPArguments = new List <string>(); IPPArguments.Add("RepackageFromStage"); IPPArguments.Add(Params.IsCodeBasedProject ? Params.RawProjectPath : "Engine"); IPPArguments.Add("-config"); IPPArguments.Add(TargetConfiguration.ToString()); if (TargetConfiguration == UnrealTargetConfiguration.Shipping) { IPPArguments.Add("-compress=best"); } // Determine if we should sign bool bNeedToSign = GetCodeSignDesirability(Params); if (!String.IsNullOrEmpty(Params.BundleName)) { // Have to sign when a bundle name is specified bNeedToSign = true; IPPArguments.Add("-bundlename"); IPPArguments.Add(Params.BundleName); } if (bNeedToSign) { IPPArguments.Add("-sign"); } if (cookonthefly) { IPPArguments.Add(" -cookonthefly"); } IPPArguments.Add(" -stagedir"); IPPArguments.Add(CombinePaths(Params.BaseStageDirectory, "IOS")); IPPArguments.Add(" -project"); IPPArguments.Add(Params.RawProjectPath); if (RunIPP(IPPArguments.ToArray()) != 0) { throw new AutomationException("IPP Failed"); } } // verify the .ipa exists if (!FileExists(ProjectIPA)) { ErrorReporter.Error(String.Format("PACKAGE FAILED - {0} was not created", ProjectIPA), (int)ErrorCodes.Error_FailedToCreateIPA); throw new AutomationException("PACKAGE FAILED - {0} was not created", ProjectIPA); } if (WorkingCL > 0) { // Open files for add or edit var ExtraFilesToCheckin = new List <string> { ProjectIPA }; // check in the .ipa along with everything else UE4Build.AddBuildProductsToChangelist(WorkingCL, ExtraFilesToCheckin); } //@TODO: This automatically deploys after packaging, useful for testing on PC when iterating on IPP //Deploy(Params, SC); } else { // code sign the app CodeSign(Path.GetDirectoryName(Params.ProjectGameExeFilename), Params.IsCodeBasedProject ? Params.ShortProjectName : Path.GetFileNameWithoutExtension(Params.ProjectGameExeFilename), Params.RawProjectPath, SC.StageTargetConfigurations[0], SC.LocalRoot, Params.ShortProjectName, Path.GetDirectoryName(Params.RawProjectPath), SC.IsCodeBasedProject, Params.Distribution); // now generate the ipa PackageIPA(Path.GetDirectoryName(Params.ProjectGameExeFilename), Params.IsCodeBasedProject ? Params.ShortProjectName : Path.GetFileNameWithoutExtension(Params.ProjectGameExeFilename), Params.ShortProjectName, Path.GetDirectoryName(Params.RawProjectPath), SC.StageTargetConfigurations[0], Params.Distribution); } PrintRunTime(); }
public static void ReportException(ErrorReporter er, RhinoException ex) { if (er is Rhino.Tools.ToolErrorReporter) { ((Rhino.Tools.ToolErrorReporter)er).ReportException(ex); } else { string msg = GetExceptionMessage(ex); er.Error(msg, ex.SourceName(), ex.LineNumber(), ex.LineSource(), ex.ColumnNumber()); } }
public override ProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params) { string DeviceArchitecture = GetBestDeviceArchitecture(Params); string GPUArchitecture = GetBestGPUArchitecture(Params);; string ApkName = ClientApp + DeviceArchitecture + ".apk"; if (!File.Exists(ApkName)) { ApkName = GetFinalApkName(Params, Path.GetFileNameWithoutExtension(ClientApp), true, DeviceArchitecture, GPUArchitecture); } Console.WriteLine("Apk='{0}', ClientApp='{1}', ExeName='{2}'", ApkName, ClientApp, Params.ProjectGameExeFilename); // run aapt to get the name of the intent string PackageName = GetPackageInfo(ApkName, false); if (PackageName == null) { ErrorReporter.Error("Failed to get package name from " + ClientApp, (int)ErrorCodes.Error_FailureGettingPackageInfo); throw new AutomationException("Failed to get package name from " + ClientApp); } if (Params.Prebuilt) { // clear the log RunAdbCommand(Params, "logcat -c"); } // start the app on device! string CommandLine = "shell am start -n " + PackageName + "/com.epicgames.ue4.GameActivity"; ProcessResult ClientProcess = RunAdbCommand(Params, CommandLine, null, ClientRunFlags); if (Params.Prebuilt) { // save the output to the staging directory string LogPath = Path.Combine(Params.BaseStageDirectory, "Android\\logs"); string LogFilename = Path.Combine(LogPath, "devicelog" + Params.Device + ".log"); string ServerLogFilename = Path.Combine(CmdEnv.LogFolder, "devicelog" + Params.Device + ".log"); Directory.CreateDirectory(LogPath); // check if the game is still running // time out if it takes to long DateTime StartTime = DateTime.Now; int TimeOutSeconds = Params.RunTimeoutSeconds; while (true) { ProcessResult ProcessesResult = RunAdbCommand(Params, "shell ps", null, ERunOptions.SpewIsVerbose); string RunningProcessList = ProcessesResult.Output; if (!RunningProcessList.Contains(PackageName)) { break; } Thread.Sleep(10); TimeSpan DeltaRunTime = DateTime.Now - StartTime; if ((DeltaRunTime.TotalSeconds > TimeOutSeconds) && (TimeOutSeconds != 0)) { Log("Device: " + Params.Device + " timed out while waiting for run to finish"); break; } } // this is just to get the ue4 log to go to the output RunAdbCommand(Params, "logcat -d -s UE4 -s Debug"); // get the log we actually want to save ProcessResult LogFileProcess = RunAdbCommand(Params, "logcat -d", null, ERunOptions.AppMustExist); File.WriteAllText(LogFilename, LogFileProcess.Output); File.WriteAllText(ServerLogFilename, LogFileProcess.Output); } return(ClientProcess); }
private string GetBestDeviceArchitecture(ProjectParams Params) { bool bMakeSeparateApks = UnrealBuildTool.Android.UEDeployAndroid.ShouldMakeSeparateApks(); // if we are joining all .so's into a single .apk, there's no need to find the best one - there is no other one if (!bMakeSeparateApks) { return(""); } string[] AppArchitectures = AndroidToolChain.GetAllArchitectures(); // ask the device ProcessResult ABIResult = RunAdbCommand(Params, " shell getprop ro.product.cpu.abi", null, ERunOptions.AppMustExist); // the output is just the architecture string DeviceArch = UnrealBuildTool.Android.UEDeployAndroid.GetUE4Arch(ABIResult.Output.Trim()); // if the architecture wasn't built, look for a backup if (Array.IndexOf(AppArchitectures, DeviceArch) == -1) { // go from 64 to 32-bit if (DeviceArch == "-arm64") { DeviceArch = "-armv7"; } // go from 64 to 32-bit else if (DeviceArch == "-x86_64") { if (Array.IndexOf(AppArchitectures, "-x86") == -1) { DeviceArch = "-x86"; } // if it didn't have 32-bit x86, look for 64-bit arm for emulation // @todo android 64-bit: x86_64 most likely can't emulate arm64 at this ponit // else if (Array.IndexOf(AppArchitectures, "-arm64") == -1) // { // DeviceArch = "-arm64"; // } // finally try for 32-bit arm emulation (Houdini) else { DeviceArch = "-armv7"; } } // use armv7 (with Houdini emulation) else if (DeviceArch == "-x86") { DeviceArch = "-armv7"; } } // if after the fallbacks, we still don't have it, we can't continue if (Array.IndexOf(AppArchitectures, DeviceArch) == -1) { string ErrorString = String.Format("Unable to run because you don't have an apk that is usable on {0}", Params.Device); ErrorReporter.Error(ErrorString, (int)ErrorCodes.Error_NoApkSuitableForArchitecture); throw new AutomationException(ErrorString); } return(DeviceArch); }
public override void Package(ProjectParams Params, DeploymentContext SC, int WorkingCL) { string[] Architectures = UnrealBuildTool.AndroidToolChain.GetAllArchitectures(); string[] GPUArchitectures = UnrealBuildTool.AndroidToolChain.GetAllGPUArchitectures(); bool bMakeSeparateApks = UnrealBuildTool.Android.UEDeployAndroid.ShouldMakeSeparateApks(); foreach (string Architecture in Architectures) { foreach (string GPUArchitecture in GPUArchitectures) { string ApkName = GetFinalApkName(Params, SC.StageExecutables[0], true, bMakeSeparateApks ? Architecture : "", bMakeSeparateApks ? GPUArchitecture : ""); string BatchName = GetFinalBatchName(ApkName, Params, bMakeSeparateApks ? Architecture : "", bMakeSeparateApks ? GPUArchitecture : ""); // packaging just takes a pak file and makes it the .obb UEBuildConfiguration.bOBBinAPK = Params.OBBinAPK; // Make sure this setting is sync'd pre-build var Deploy = UEBuildDeploy.GetBuildDeploy(UnrealTargetPlatform.Android); if (!Params.Prebuilt) { string CookFlavor = SC.FinalCookPlatform.IndexOf("_") > 0 ? SC.FinalCookPlatform.Substring(SC.FinalCookPlatform.IndexOf("_")) : ""; string SOName = GetSONameWithoutArchitecture(Params, SC.StageExecutables[0]); Deploy.PrepForUATPackageOrDeploy(Params.ShortProjectName, SC.ProjectRoot, SOName, SC.LocalRoot + "/Engine", Params.Distribution, CookFlavor); } // first, look for a .pak file in the staged directory string[] PakFiles = Directory.GetFiles(SC.StageDirectory, "*.pak", SearchOption.AllDirectories); bool bHasPakFile = PakFiles.Length >= 1; // for now, we only support 1 pak/obb file if (PakFiles.Length > 1) { string ErrorString = String.Format("Can't package for Android with 0 or more than 1 pak file (found {0} pak files in {1})", PakFiles.Length, SC.StageDirectory); ErrorReporter.Error(ErrorString, (int)ErrorCodes.Error_OnlyOneObbFileSupported); throw new AutomationException(ErrorString); } string LocalObbName = GetFinalObbName(ApkName); string DeviceObbName = GetDeviceObbName(ApkName); // Always delete the target OBB file if it exists if (File.Exists(LocalObbName)) { File.Delete(LocalObbName); } if (!Params.OBBinAPK && bHasPakFile) { Log("Creating {0} from {1}", LocalObbName, PakFiles[0]); File.Copy(PakFiles[0], LocalObbName); } Log("Writing bat for install with {0}", Params.OBBinAPK ? "OBB in APK" : "OBB separate"); string PackageName = GetPackageInfo(ApkName, false); // make a batch file that can be used to install the .apk and .obb files string[] BatchLines = new string[] { "setlocal", "set ADB=%ANDROID_HOME%\\platform-tools\\adb.exe", "set DEVICE=", "if not \"%1\"==\"\" set DEVICE=-s %1", "for /f \"delims=\" %%A in ('adb " + GetStorageQueryCommand() + "') do @set STORAGE=%%A", "%ADB% %DEVICE% uninstall " + PackageName, "%ADB% %DEVICE% install " + Path.GetFileName(ApkName), "@if \"%ERRORLEVEL%\" NEQ \"0\" goto Error", "%ADB% %DEVICE% shell rm -r %STORAGE%/" + Params.ShortProjectName, "%ADB% %DEVICE% shell rm -r %STORAGE%/UE4Game/UE4CommandLine.txt", // we need to delete the commandline in UE4Game or it will mess up loading "%ADB% %DEVICE% shell rm -r %STORAGE%/obb/" + PackageName, Params.OBBinAPK || !bHasPakFile ? "" : "%ADB% %DEVICE% push " + Path.GetFileName(LocalObbName) + " %STORAGE%/" + DeviceObbName, Params.OBBinAPK || !bHasPakFile ? "" : "if \"%ERRORLEVEL%\" NEQ \"0\" goto Error", "goto:eof", ":Error", "@echo.", "@echo There was an error installing the game or the obb file. Look above for more info.", "@echo.", "@echo Things to try:", "@echo Check that the device (and only the device) is listed with \"%ADB$ devices\" from a command prompt.", "@echo Make sure all Developer options look normal on the device", "@echo Check that the device has an SD card.", "@pause" }; File.WriteAllLines(BatchName, BatchLines); } } PrintRunTime(); }
public override void Deploy(ProjectParams Params, DeploymentContext SC) { string DeviceArchitecture = GetBestDeviceArchitecture(Params); string GPUArchitecture = GetBestGPUArchitecture(Params); string ApkName = GetFinalApkName(Params, SC.StageExecutables[0], true, DeviceArchitecture, GPUArchitecture); // make sure APK is up to date (this is fast if so) var Deploy = UEBuildDeploy.GetBuildDeploy(UnrealTargetPlatform.Android); if (!Params.Prebuilt) { string CookFlavor = SC.FinalCookPlatform.IndexOf("_") > 0 ? SC.FinalCookPlatform.Substring(SC.FinalCookPlatform.IndexOf("_")) : ""; string SOName = GetSONameWithoutArchitecture(Params, SC.StageExecutables[0]); Deploy.PrepForUATPackageOrDeploy(Params.ShortProjectName, SC.ProjectRoot, SOName, SC.LocalRoot + "/Engine", Params.Distribution, CookFlavor, true); } // now we can use the apk to get more info string PackageName = GetPackageInfo(ApkName, false); // try uninstalling an old app with the same identifier. int SuccessCode = 0; string UninstallCommandline = "uninstall " + PackageName; RunAndLogAdbCommand(Params, UninstallCommandline, out SuccessCode); // install the apk string InstallCommandline = "install \"" + ApkName + "\""; string InstallOutput = RunAndLogAdbCommand(Params, InstallCommandline, out SuccessCode); int FailureIndex = InstallOutput.IndexOf("Failure"); // adb install doesn't always return an error code on failure, and instead prints "Failure", followed by an error code. if (SuccessCode != 0 || FailureIndex != -1) { string ErrorMessage = String.Format("Installation of apk '{0}' failed", ApkName); if (FailureIndex != -1) { string FailureString = InstallOutput.Substring(FailureIndex + 7).Trim(); if (FailureString != "") { ErrorMessage += ": " + FailureString; } } ErrorReporter.Error(ErrorMessage, (int)ErrorCodes.Error_AppInstallFailed); throw new AutomationException(ErrorMessage); } // update the ue4commandline.txt // update and deploy ue4commandline.txt // always delete the existing commandline text file, so it doesn't reuse an old one string IntermediateCmdLineFile = CombinePaths(SC.StageDirectory, "UE4CommandLine.txt"); Project.WriteStageCommandline(IntermediateCmdLineFile, Params, SC); // Setup the OBB name and add the storage path (queried from the device) to it string DeviceStorageQueryCommand = GetStorageQueryCommand(); ProcessResult Result = RunAdbCommand(Params, DeviceStorageQueryCommand, null, ERunOptions.AppMustExist); String StorageLocation = Result.Output.Trim(); string DeviceObbName = StorageLocation + "/" + GetDeviceObbName(ApkName); // copy files to device if we were staging if (SC.Stage) { // cache some strings string BaseCommandline = "push"; string RemoteDir = StorageLocation + "/UE4Game/" + Params.ShortProjectName; string UE4GameRemoteDir = StorageLocation + "/UE4Game/" + Params.ShortProjectName; // make sure device is at a clean state RunAdbCommand(Params, "shell rm -r " + RemoteDir); RunAdbCommand(Params, "shell rm -r " + UE4GameRemoteDir); // Copy UFS files.. string[] Files = Directory.GetFiles(SC.StageDirectory, "*", SearchOption.AllDirectories); System.Array.Sort(Files); // Find all the files we exclude from copying. And include // the directories we need to individually copy. HashSet <string> ExcludedFiles = new HashSet <string>(); SortedSet <string> IndividualCopyDirectories = new SortedSet <string>((IComparer <string>) new LongestFirst()); foreach (string Filename in Files) { bool Exclude = false; // Don't push the apk, we install it Exclude |= Path.GetExtension(Filename).Equals(".apk", StringComparison.InvariantCultureIgnoreCase); // For excluded files we add the parent dirs to our // tracking of stuff to individually copy. if (Exclude) { ExcludedFiles.Add(Filename); // We include all directories up to the stage root in having // to individually copy the files. for (string FileDirectory = Path.GetDirectoryName(Filename); !FileDirectory.Equals(SC.StageDirectory); FileDirectory = Path.GetDirectoryName(FileDirectory)) { if (!IndividualCopyDirectories.Contains(FileDirectory)) { IndividualCopyDirectories.Add(FileDirectory); } } if (!IndividualCopyDirectories.Contains(SC.StageDirectory)) { IndividualCopyDirectories.Add(SC.StageDirectory); } } } // The directories are sorted above in "deepest" first. We can // therefore start copying those individual dirs which will // recreate the tree. As the subtrees will get copied at each // possible individual level. HashSet <string> EntriesToDeploy = new HashSet <string>(); foreach (string DirectoryName in IndividualCopyDirectories) { string[] Entries = Directory.GetFileSystemEntries(DirectoryName, "*", SearchOption.TopDirectoryOnly); foreach (string Entry in Entries) { // We avoid excluded files and the individual copy dirs // (the individual copy dirs will get handled as we iterate). if (ExcludedFiles.Contains(Entry) || IndividualCopyDirectories.Contains(Entry)) { continue; } else { EntriesToDeploy.Add(Entry); } } } if (EntriesToDeploy.Count == 0) { EntriesToDeploy.Add(SC.StageDirectory); } // We now have a minimal set of file & dir entries we need // to deploy. Files we deploy will get individually copied // and dirs will get the tree copies by default (that's // what ADB does). HashSet <ProcessResult> DeployCommands = new HashSet <ProcessResult>(); foreach (string Entry in EntriesToDeploy) { string FinalRemoteDir = RemoteDir; string RemotePath = Entry.Replace(SC.StageDirectory, FinalRemoteDir).Replace("\\", "/"); string Commandline = string.Format("{0} \"{1}\" \"{2}\"", BaseCommandline, Entry, RemotePath); // We run deploy commands in parallel to maximize the connection // throughput. DeployCommands.Add( RunAdbCommand(Params, Commandline, null, ERunOptions.Default | ERunOptions.NoWaitForExit)); // But we limit the parallel commands to avoid overwhelming // memory resources. if (DeployCommands.Count == DeployMaxParallelCommands) { while (DeployCommands.Count > DeployMaxParallelCommands / 2) { Thread.Sleep(10); DeployCommands.RemoveWhere( delegate(ProcessResult r) { return(r.HasExited); }); } } } foreach (ProcessResult deploy_result in DeployCommands) { deploy_result.WaitForExit(); } // delete the .obb file, since it will cause nothing we just deployed to be used RunAdbCommand(Params, "shell rm " + DeviceObbName); } else if (SC.Archive) { // deploy the obb if there is one string ObbPath = Path.Combine(SC.StageDirectory, GetFinalObbName(ApkName)); if (File.Exists(ObbPath)) { // cache some strings string BaseCommandline = "push"; string Commandline = string.Format("{0} \"{1}\" \"{2}\"", BaseCommandline, ObbPath, DeviceObbName); RunAdbCommand(Params, Commandline); } } else { // cache some strings string BaseCommandline = "push"; string RemoteDir = StorageLocation + "/UE4Game/" + Params.ShortProjectName; string FinalRemoteDir = RemoteDir; /* * // handle the special case of the UE4Commandline.txt when using content only game (UE4Game) * if (!Params.IsCodeBasedProject) * { * FinalRemoteDir = "/mnt/sdcard/UE4Game"; * } */ string RemoteFilename = IntermediateCmdLineFile.Replace(SC.StageDirectory, FinalRemoteDir).Replace("\\", "/"); string Commandline = string.Format("{0} \"{1}\" \"{2}\"", BaseCommandline, IntermediateCmdLineFile, RemoteFilename); RunAdbCommand(Params, Commandline); } }