Files
LuaCsForBarotraumaEP/Libraries/MonoGame.Framework/Src/Tools/MonoGame.Packaging.Flatpak/BuildFlatpakTask.cs
T
2019-06-25 16:00:44 +03:00

192 lines
7.9 KiB
C#

// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Diagnostics;
using System.IO;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
namespace MonoGame.Packaging
{
public class BuildFlatpakTask : Task
{
[Required]
public string IntermediateDir { get; set; }
[Required]
public string OutputPath { get; set; }
[Required]
public string ProjectDir { get; set; }
[Required]
public string PublishDir { get; set; }
[Required]
public string AssemblyName { get; set; }
[Required]
public string Title { get; set; }
[Required]
public string Id { get; set; }
[Required]
public string IconPath { get; set; }
public override bool Execute()
{
try
{
Log.LogMessage(MessageImportance.Normal, "BuildFlatpakTask: Starting...");
// Ensure that flatpak command is installed
if (!IsFlatpakInstalled())
{
Log.LogMessage(MessageImportance.High, "Flatpak command not found :(");
return false;
}
// Ensure that flatpak runtimes are installed
if (!AreFlatpakRuntimesInstalled())
{
Log.LogMessage(MessageImportance.High, "Error, the requred flatpak runtime components were not found:");
Log.LogMessage(MessageImportance.High, " - org.freedesktop.Platform/x86_64/1.6");
Log.LogMessage(MessageImportance.High, " - org.freedesktop.Sdk/x86_64/1.6");
return false;
}
// Setup intermediate directory
var objpath = Path.Combine(ProjectDir, IntermediateDir, "Flatpak");
if (Directory.Exists(objpath))
Directory.Delete(objpath, true);
Directory.CreateDirectory(objpath);
// Generate metadata
Log.LogMessage(MessageImportance.Normal, "BuildFlatpakTask: Generating metadata");
var metadatalines = new[] {
"[Application]",
"name=" + Id,
"runtime=org.freedesktop.Platform/x86_64/1.6",
"command=/app/opt/" + AssemblyName + "/" + AssemblyName,
"",
"[Context]",
"shared=ipc;network;",
"sockets=x11;wayland;pulseaudio;",
"devices=all;"
};
File.WriteAllLines(Path.Combine(objpath, "metadata"), metadatalines);
// Copy over icon
Log.LogMessage(MessageImportance.Normal, "BuildFlatpakTask: Copying over icon");
var icondir = Path.Combine(objpath, "export/share/icons");
Directory.CreateDirectory(icondir);
File.Copy(Path.Combine(ProjectDir, IconPath), Path.Combine(icondir, Id + ".png"));
// Generate .desktop launcher file
Log.LogMessage(MessageImportance.Normal, "BuildFlatpakTask: Generating launcher file");
var desktopdir = Path.Combine(objpath, "export/share/applications");
Directory.CreateDirectory(desktopdir);
var desktoplines = new[] {
"[Desktop Entry]",
"Name=" + Title,
"Exec=/app/opt/" + AssemblyName + "/" + AssemblyName,
"Type=Application",
"Icon=" + Id,
"Categories=Game;"
};
File.WriteAllLines(Path.Combine(desktopdir, Id + ".desktop"), desktoplines);
// Copy over game
Log.LogMessage(MessageImportance.Normal, "BuildFlatpakTask: Copying over game data");
var sourcegamedir = Path.Combine(ProjectDir, PublishDir);
var gamedir = Path.Combine(objpath, "files/opt/" + AssemblyName + "/");
Directory.CreateDirectory(gamedir);
foreach (var dirpath in Directory.GetDirectories(sourcegamedir, "*", SearchOption.AllDirectories))
Directory.CreateDirectory(dirpath.Replace(sourcegamedir, gamedir));
foreach (var filepath in Directory.GetFiles(sourcegamedir, "*.*", SearchOption.AllDirectories))
File.Copy(filepath, filepath.Replace(sourcegamedir, gamedir));
// Copy over suplementary libraries
var libdir = Path.Combine(Path.GetDirectoryName((new Uri(typeof(BuildFlatpakTask).Assembly.CodeBase)).LocalPath), "../../extra");
Directory.CreateDirectory(Path.Combine(objpath, "files/lib"));
File.Copy(Path.Combine(libdir, "libunwind-x86_64.so.8"), Path.Combine(objpath, "files/lib/libunwind-x86_64.so.8"));
File.Copy(Path.Combine(libdir, "libunwind.so.8"), Path.Combine(objpath, "files/lib/libunwind.so.8"));
File.Copy(Path.Combine(libdir, "libSDL2-2.0.so.0.8.0"), Path.Combine(objpath, "files/opt/" + AssemblyName + "/libSDL2-2.so"), true);
// Generate flatpak
Log.LogMessage(MessageImportance.Normal, "BuildFlatpakTask: Generating flatpak");
var repodir = Path.Combine(ProjectDir, IntermediateDir, "FlatpakRepo");
if (Directory.Exists(repodir))
Directory.Delete(repodir, true);
Directory.CreateDirectory(repodir);
var flatpak = Path.Combine(ProjectDir, OutputPath, AssemblyName + ".flatpak");
CallFlatpak("build-export " + repodir + " " + objpath);
CallFlatpak("build-bundle " + repodir + " " + flatpak + " " + Id);
Log.LogMessage(MessageImportance.High, "BuildFlatpakTask: Flatpak generated at: " + flatpak);
}
catch (Exception e)
{
Log.LogMessage(MessageImportance.High, "An error occured while trying to package the project into a flatpak.");
Log.LogMessage(MessageImportance.High, "Error Info: " + e.ToString());
return false;
}
return true;
}
private bool IsFlatpakInstalled()
{
var proc = new Process();
proc.StartInfo.FileName = "which";
proc.StartInfo.Arguments = "flatpak";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.Start();
proc.StandardOutput.ReadToEnd();
return proc.ExitCode == 0;
}
private bool AreFlatpakRuntimesInstalled()
{
var rt = false;
var rtsdk = false;
var proc = new Process();
proc.StartInfo.FileName = "flatpak";
proc.StartInfo.Arguments = "list";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.Start();
while (!proc.StandardOutput.EndOfStream)
{
var line = proc.StandardOutput.ReadLine();
if (line.Contains("org.freedesktop.Platform/x86_64/1.6"))
rt = true;
else if (line.Contains("org.freedesktop.Sdk/x86_64/1.6"))
rtsdk = true;
}
return rt && rtsdk;
}
private void CallFlatpak(string args)
{
var proc = new Process();
proc.StartInfo.FileName = "flatpak";
proc.StartInfo.Arguments = args;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.Start();
while (!proc.StandardOutput.EndOfStream)
Log.LogMessage(MessageImportance.Normal, proc.StandardOutput.ReadLine());
}
}
}