Skip to content

Commit

Permalink
fix(net5): Support parallel builds
Browse files Browse the repository at this point in the history
  • Loading branch information
jeromelaban committed Dec 1, 2020
1 parent 2df9b4e commit 1c3d982
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 39 deletions.
9 changes: 6 additions & 3 deletions .vsts-ci-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,14 @@ jobs:
versionSpec: 4.9.1
checkLatest: false

- bash: |
cd $(build.sourcesdirectory)/src/Uno.Wasm.Bootstrap
dotnet msbuild /r /p:Configuration=Release
displayName: Build bootstrap
- bash: |
cd $(build.sourcesdirectory)/src/Uno.Wasm.Sample
dotnet msbuild /r /p:Configuration=Release || true # expected failure (nuget restore does not provide the packager a proper TargetFramework support)
dotnet msbuild /r /p:Configuration=Release || true # expected failure (nuget restore does not provide the iltrim a proper TargetFramework support)
dotnet msbuild /r /p:Configuration=Release -m:1
dotnet msbuild /r /p:Configuration=Release
displayName: Build Mono Sample
- bash: |
Expand Down
9 changes: 6 additions & 3 deletions .vsts-ci-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,15 @@ jobs:
# OverWrite: false
# flattenFolders: false

- bash: |
cd $(build.sourcesdirectory)/src/Uno.Wasm.Bootstrap
dotnet msbuild /r /p:Configuration=Release
displayName: Build bootstrap
- bash: |
source ~/emsdk/emsdk_env.sh
cd $(build.sourcesdirectory)/src/Uno.Wasm.Sample
dotnet build || true # expected failure (nuget restore does not provide the packager a proper TargetFramework support)
dotnet build || true # expected failure (nuget restore does not provide the iltrim a proper TargetFramework support)
dotnet build -m:1
dotnet build
displayName: Build Mono Sample
Expand Down
4 changes: 2 additions & 2 deletions .vsts-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ jobs:
- script: |
cd $(build.sourcesdirectory)\src\Uno.Wasm.Bootstrap
dotnet msbuild /r /p:Configuration=Release -m:1 /p:InformationalVersion=$(GITVERSION.INFORMATIONALVERSION) /p:PackageVersion=$(GITVERSION.FullSemVer) /p:PackageOutputPath=$(build.sourcesdirectory)\build\nuget
dotnet msbuild /r /p:Configuration=Release /p:InformationalVersion=$(GITVERSION.INFORMATIONALVERSION) /p:PackageVersion=$(GITVERSION.FullSemVer) /p:PackageOutputPath=$(build.sourcesdirectory)\build\nuget
cd $(build.sourcesdirectory)\src\Uno.Wasm.Bootstrap.DevServer
dotnet msbuild /r /p:Configuration=Release -m:1 /p:InformationalVersion=$(GITVERSION.INFORMATIONALVERSION) /p:PackageVersion=$(GITVERSION.FullSemVer) /p:PackageOutputPath=$(build.sourcesdirectory)\build\nuget
dotnet msbuild /r /p:Configuration=Release /p:InformationalVersion=$(GITVERSION.INFORMATIONALVERSION) /p:PackageVersion=$(GITVERSION.FullSemVer) /p:PackageOutputPath=$(build.sourcesdirectory)\build\nuget
displayName: Build packages
- task: CopyFiles@2
Expand Down
6 changes: 5 additions & 1 deletion src/Uno.Wasm.Bootstrap/Uno.Wasm.Bootstrap.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -217,13 +217,17 @@
<Using Namespace="System.IO" />
<Code Type="Fragment" Language="cs">
<![CDATA[
Log.LogMessage("Updating : " + FilePath);
var output = File.ReadAllText(FilePath);
if(!output.Contains(SHAVersion))
{
Log.LogMessage("Updating : " + FilePath);
File.WriteAllText(FilePath, output.Replace("v0", SHAVersion));
}
else
{
Log.LogMessage("Skipping : " + FilePath);
}
]]>
</Code>
</Task>
Expand Down
146 changes: 116 additions & 30 deletions src/Uno.Wasm.Bootstrap/UnoInstallSDKTask.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Build.Framework;
using Uno.Wasm.Bootstrap.Extensions;

namespace Uno.Wasm.Bootstrap
{
public class UnoInstallSDKTask_v0 : Microsoft.Build.Utilities.Task
public class UnoInstallSDKTask_v0 : Microsoft.Build.Utilities.Task, ICancelableTask
{
private static readonly TimeSpan _SDKFolderLockTimeout = TimeSpan.FromMinutes(2);
private static readonly TimeSpan _SDKLockRetryDelay = TimeSpan.FromSeconds(10);

public string? MonoWasmSDKUri { get; set; }

public string? MonoWasmAOTSDKUri { get; set; }
Expand Down Expand Up @@ -65,22 +72,28 @@ public class UnoInstallSDKTask_v0 : Microsoft.Build.Utilities.Task
[Output]
public string? PackagerProjectFile { get; private set; }

private CancellationTokenSource _cts = new CancellationTokenSource();

public override bool Execute()
=> ExecuteAsync(_cts.Token).Result;

private async Task<bool> ExecuteAsync(CancellationToken ct)
{
if (IsNetCore)
{
InstallNetCoreWasmSdk();
await InstallNetCoreWasmSdk(ct);
}
else
{
InstallMonoSdk();
await InstallMonoSdk(ct);
}

return true;
}

private Version ActualTargetFrameworkVersion => Version.TryParse(TargetFrameworkVersion.Substring(1), out var v) ? v : new Version("0.0");

private void InstallNetCoreWasmSdk()
private async Task InstallNetCoreWasmSdk(CancellationToken ct)
{
var sdkUri = string.IsNullOrWhiteSpace(NetCoreWasmSDKUri) ? Constants.DefaultDotnetRuntimeSdkUrl : NetCoreWasmSDKUri!;

Expand All @@ -90,38 +103,80 @@ private void InstallNetCoreWasmSdk()
SdkPath = Path.Combine(GetMonoTempPath(), sdkName);
Log.LogMessage("NetCore-Wasm SDK Path: " + SdkPath);

var writeChecksum = false;
SetupPackagerOutput();

ValidateSDKCheckSum("NetCore-Wasm", SdkPath);
var writeChecksum = false;

if (!Directory.Exists(SdkPath))
try
{
var zipPath = SdkPath + ".zip";
Log.LogMessage($"Using NetCore-Wasm SDK {sdkUri}");
LockSDKPath(SdkPath);

zipPath = RetreiveSDKFile(sdkName, sdkUri, zipPath);
await ValidateSDKCheckSum(ct, "NetCore-Wasm", SdkPath);

ZipFile.ExtractToDirectory(zipPath, SdkPath);
Log.LogMessage($"Extracted {sdkName} to {SdkPath}");
if (!Directory.Exists(SdkPath))
{
var zipPath = SdkPath + ".zip";
Log.LogMessage($"Using NetCore-Wasm SDK {sdkUri}");

MarkSDKExecutable();
zipPath = await RetreiveSDKFile(ct, sdkName, sdkUri, zipPath);

ZipFile.ExtractToDirectory(zipPath, SdkPath);
Log.LogMessage($"Extracted {sdkName} to {SdkPath}");

MarkSDKExecutable();

writeChecksum = true;
WritePackager();
WriteWasmTuner();
WriteCilStrip();

writeChecksum = true;
}

if (writeChecksum)
{
WriteChecksum(SdkPath);
Log.LogMessage($"Wrote checksum to {SdkPath}");
}
}
finally
{
UnlockSDKPath(SdkPath);
}
}

WritePackager();
WriteWasmTuner();
WriteCilStrip();
private void SetupPackagerOutput()
{
var packagerName = IsNetCore ? "packager.dll" : "packager2.exe";
PackagerBinPath = Path.Combine(SdkPath, packagerName);
}

if (writeChecksum)
private void UnlockSDKPath(string sdkPath)
{
try
{
File.Delete(Path.Combine(sdkPath, ".lock"));
}
catch (Exception ex)
{
WriteChecksum(SdkPath);
Log.LogMessage($"Wrote checksum to {SdkPath}");
Log.LogMessage($"Failed to delete SDK lock file ({ex.Message})");
}
finally
{
Log.LogMessage(MessageImportance.Low, "Released SDK Folder lock");
}
}

private void ValidateSDKCheckSum(string sdkName, string sdkPath)
private static void LockSDKPath(string sdkPath)
{
var lockFilePath = Path.Combine(sdkPath, ".lock");
Directory.CreateDirectory(sdkPath);
File.WriteAllText(path: lockFilePath, Process.GetCurrentProcess().Id.ToString(CultureInfo.InvariantCulture));
}

private async Task ValidateSDKCheckSum(CancellationToken ct, string sdkName, string sdkPath)
{
await WaitForLockFile(sdkPath, ct);

if (!DisableSDKCheckSumValidation && Directory.Exists(sdkPath) && !VerifyChecksum(sdkPath))
{
// SDK folder was tampered with (e.g. StorageSense, User, etc.)
Expand All @@ -135,10 +190,35 @@ private void ValidateSDKCheckSum(string sdkName, string sdkPath)
}
}

private async Task WaitForLockFile(string sdkPath, CancellationToken ct)
{
var lockFilePath = Path.Combine(sdkPath, ".lock");
var sw = Stopwatch.StartNew();

while (sw.Elapsed < _SDKFolderLockTimeout)
{
if (File.Exists(lockFilePath))
{
if (int.TryParse(File.ReadAllText(lockFilePath), NumberStyles.Integer, CultureInfo.CurrentCulture, out var pid) && Process.GetCurrentProcess().Id == pid)
{
break;
}
else
{
Log.LogMessage(MessageImportance.Low, "SDK Folder is locked, waiting...");

await Task.Delay(_SDKLockRetryDelay, ct);
}
}
}

Log.LogMessage(MessageImportance.Low, "Got SDK Folder lock");
}

private bool IsNetCore =>
TargetFrameworkIdentifier == ".NETCoreApp" && ActualTargetFrameworkVersion >= new Version("5.0");

private void InstallMonoSdk()
private async Task InstallMonoSdk(CancellationToken ct)
{
var runtimeExecutionMode = ParseRuntimeExecutionMode();

Expand All @@ -162,16 +242,18 @@ private void InstallMonoSdk()
SdkPath = Path.Combine(GetMonoTempPath(), sdkName);
Log.LogMessage("SDK Path: " + SdkPath);

SetupPackagerOutput();

var writeChecksum = false;

ValidateSDKCheckSum("mono-wasm", SdkPath);
await ValidateSDKCheckSum(ct, "mono-wasm", SdkPath);

if (!Directory.Exists(SdkPath))
{
var zipPath = SdkPath + ".zip";
Log.LogMessage($"Using mono-wasm SDK {sdkUri}");

zipPath = RetreiveSDKFile(sdkName, sdkUri, zipPath);
zipPath = await RetreiveSDKFile(ct, sdkName, sdkUri, zipPath);

ZipFile.ExtractToDirectory(zipPath, SdkPath);
Log.LogMessage($"Extracted {sdkName} to {SdkPath}");
Expand All @@ -191,7 +273,7 @@ private void InstallMonoSdk()
{
var aotZipPath = SdkPath + ".aot.zip";
Log.LogMessage(Microsoft.Build.Framework.MessageImportance.High, $"Downloading {aotUri} to {aotZipPath}");
aotZipPath = RetreiveSDKFile(sdkName, aotUri, aotZipPath);
aotZipPath = await RetreiveSDKFile(ct, sdkName, aotUri, aotZipPath);

foreach (var entry in ZipFile.OpenRead(aotZipPath).Entries)
{
Expand Down Expand Up @@ -232,9 +314,6 @@ private void WritePackager()
{
if (!string.IsNullOrEmpty(PackagerOverrideFolderPath))
{
var packagerName = IsNetCore ? "packager.dll" : "packager2.exe";
PackagerBinPath = Path.Combine(SdkPath, packagerName);

foreach (var file in Directory.EnumerateFiles(PackagerOverrideFolderPath))
{
var destFileName = Path.Combine(SdkPath, Path.GetFileName(file));
Expand Down Expand Up @@ -280,7 +359,7 @@ private void WriteCilStrip()
private bool HasBitcodeAssets()
=> Assets.Any(asset => BitCodeExtensions.Any(ext => asset.ItemSpec.EndsWith(ext, StringComparison.OrdinalIgnoreCase)));

private string RetreiveSDKFile(string sdkName, string sdkUri, string zipPath)
private async Task<string> RetreiveSDKFile(CancellationToken ct, string sdkName, string sdkUri, string zipPath)
{
var tries = 3;

Expand All @@ -298,7 +377,11 @@ private string RetreiveSDKFile(string sdkName, string sdkUri, string zipPath)
client.Proxy = wp;

Log.LogMessage(Microsoft.Build.Framework.MessageImportance.High, $"Downloading {sdkName} to {zipPath}");
client.DownloadFile(sdkUri, zipPath);

using (ct.Register(() => client.CancelAsync()))
{
await client.DownloadFileTaskAsync(sdkUri, zipPath);
}

return zipPath;
}
Expand All @@ -322,6 +405,7 @@ private int ComputeChecksum(string path)
{
var exclusions = new[]
{
Path.Combine(path, ".lock"),
Path.Combine(path, ChecksumFilename),
Path.Combine(path, Path.Combine("wasm-bcl", "wasm_tools", "monolinker.exe.config"))
};
Expand Down Expand Up @@ -382,5 +466,7 @@ private RuntimeExecutionMode ParseRuntimeExecutionMode()

return runtimeExecutionMode;
}

public void Cancel() => throw new NotImplementedException();
}
}

0 comments on commit 1c3d982

Please sign in to comment.