323 lines
13 KiB
C#
323 lines
13 KiB
C#
using DependencyListGenerator;
|
|
using Nuke.Common;
|
|
using Nuke.Common.IO;
|
|
using Nuke.Common.ProjectModel;
|
|
using Nuke.Common.Tooling;
|
|
using Nuke.Common.Tools.Docker;
|
|
using Nuke.Common.Tools.DotNet;
|
|
using Nuke.Common.Tools.MSBuild;
|
|
using Serilog;
|
|
using static Nuke.Common.EnvironmentInfo;
|
|
using static Nuke.Common.Tools.Docker.DockerTasks;
|
|
using static Nuke.Common.Tools.DotNet.DotNetTasks;
|
|
using static Nuke.Common.Tools.MSBuild.MSBuildTasks;
|
|
|
|
partial class Build
|
|
{
|
|
Target CompileNativeSrcWindows => _ => _
|
|
.Unlisted()
|
|
.After(CompileManagedSrc)
|
|
.After(GenerateNetFxAssemblyRedirectionSource)
|
|
.OnlyWhenStatic(() => IsWin)
|
|
.Executes(() =>
|
|
{
|
|
// If we're building for x64, build for x86 too
|
|
var platforms =
|
|
Equals(Platform, MSBuildTargetPlatform.x64)
|
|
? new[] { MSBuildTargetPlatform.x64, MSBuildTargetPlatform.x86 }
|
|
: new[] { MSBuildTargetPlatform.x86 };
|
|
|
|
foreach (var project in Solution.GetNativeSrcProjects())
|
|
{
|
|
PerformLegacyRestoreIfNeeded(project);
|
|
|
|
var (major, minor, patch) = VersionHelper.GetVersionParts();
|
|
|
|
// Can't use dotnet msbuild, as needs to use the VS version of MSBuild
|
|
MSBuild(s => s
|
|
.SetTargetPath(project)
|
|
.SetConfiguration(BuildConfiguration)
|
|
.SetRestore(!NoRestore)
|
|
.SetMaxCpuCount(null)
|
|
.SetProperty("OTEL_AUTO_VERSION_MAJOR", major)
|
|
.SetProperty("OTEL_AUTO_VERSION_MINOR", minor)
|
|
.SetProperty("OTEL_AUTO_VERSION_PATCH", patch)
|
|
.CombineWith(platforms, (m, platform) => m
|
|
.SetTargetPlatform(platform)));
|
|
}
|
|
});
|
|
|
|
Target CompileNativeDependenciesForManagedTestsWindows => _ => _
|
|
.Unlisted()
|
|
.After(CompileManagedSrc)
|
|
.After(GenerateNetFxAssemblyRedirectionSource)
|
|
.OnlyWhenStatic(() => IsWin)
|
|
.Executes(() =>
|
|
{
|
|
var continuousProfilerNativeDepProject = Solution.GetContinuousProfilerNativeDep();
|
|
PerformLegacyRestoreIfNeeded(continuousProfilerNativeDepProject);
|
|
// Can't use dotnet msbuild, as needs to use the VS version of MSBuild
|
|
MSBuild(s => s
|
|
.SetProjectFile(continuousProfilerNativeDepProject)
|
|
.SetConfiguration(BuildConfiguration)
|
|
.SetRestore(!NoRestore)
|
|
.SetTargetPlatform(Platform)
|
|
.SetRestore(false));
|
|
});
|
|
|
|
Target CompileNativeTestsWindows => _ => _
|
|
.Unlisted()
|
|
.After(CompileNativeSrc)
|
|
.OnlyWhenStatic(() => IsWin)
|
|
.Executes(() =>
|
|
{
|
|
// If we're building for x64, build for x86 too
|
|
var platforms =
|
|
Equals(Platform, MSBuildTargetPlatform.x64)
|
|
? new[] { MSBuildTargetPlatform.x64, MSBuildTargetPlatform.x86 }
|
|
: new[] { MSBuildTargetPlatform.x86 };
|
|
|
|
var nativeTestProject = Solution.GetNativeTestProject();
|
|
PerformLegacyRestoreIfNeeded(nativeTestProject);
|
|
|
|
// Can't use dotnet msbuild, as needs to use the VS version of MSBuild
|
|
MSBuild(s => s
|
|
.SetTargetPath(nativeTestProject)
|
|
.SetConfiguration(BuildConfiguration)
|
|
.SetRestore(!NoRestore)
|
|
.SetMaxCpuCount(null)
|
|
.CombineWith(platforms, (m, platform) => m
|
|
.SetTargetPlatform(platform)));
|
|
});
|
|
|
|
Target PublishNativeProfilerWindows => _ => _
|
|
.Unlisted()
|
|
.OnlyWhenStatic(() => IsWin)
|
|
.After(CompileNativeSrc, PublishManagedProfiler)
|
|
.Executes(() =>
|
|
{
|
|
foreach (var architecture in ArchitecturesForPlatform)
|
|
{
|
|
var source = NativeProfilerProject.Directory / "bin" / BuildConfiguration / architecture.ToString() /
|
|
$"{NativeProfilerProject.Name}.dll";
|
|
var dest = TracerHomeDirectory / $"win-{architecture}";
|
|
|
|
Log.Information($"Copying '{source}' to '{dest}'");
|
|
|
|
source.CopyToDirectory(dest, ExistsPolicy.FileOverwrite);
|
|
}
|
|
});
|
|
|
|
Target RunNativeTestsWindows => _ => _
|
|
.Unlisted()
|
|
.After(CompileNativeSrcWindows)
|
|
.After(CompileNativeTestsWindows)
|
|
.After(PublishManagedProfiler)
|
|
.OnlyWhenStatic(() => IsWin)
|
|
.Executes(() =>
|
|
{
|
|
var project = Solution.GetProjectByName(Projects.Tests.AutoInstrumentationNativeTests);
|
|
var workingDirectory = project.Directory / "bin" / BuildConfiguration.ToString() / Platform.ToString();
|
|
var exePath = workingDirectory / $"{project.Name}.exe";
|
|
var envVars = new Dictionary<string, string>(){
|
|
{ "OTEL_DOTNET_AUTO_LOG_DIRECTORY", ProfilerTestLogs }
|
|
};
|
|
var testExe = ToolResolver.GetTool(exePath);
|
|
|
|
testExe($"--gtest_output=xml", workingDirectory: workingDirectory, environmentVariables: envVars);
|
|
});
|
|
|
|
Target PublishIisTestApplications => _ => _
|
|
.Unlisted()
|
|
.After(CompileManagedTests)
|
|
.After(BuildInstallationScripts)
|
|
.OnlyWhenStatic(() => IsWin && (Containers == ContainersWindows || Containers == ContainersWindowsOnly))
|
|
.Executes(() =>
|
|
{
|
|
var aspNetProject = Solution.GetProjectByName(Projects.Tests.Applications.AspNet);
|
|
BuildDockerImage(aspNetProject, "integrated-nogac", "classic-nogac", "integrated", "classic");
|
|
|
|
var wcfProject = Solution.GetProjectByName(Projects.Tests.Applications.WcfIis);
|
|
BuildDockerImage(wcfProject);
|
|
|
|
var owinProject = Solution.GetProjectByName(Projects.Tests.Applications.OwinIis);
|
|
BuildDockerImage(owinProject);
|
|
});
|
|
|
|
void BuildDockerImage(Project project, params string[] targets)
|
|
{
|
|
const string moduleName = "OpenTelemetry.DotNet.Auto.psm1";
|
|
var sourceModulePath = InstallationScriptsDirectory / moduleName;
|
|
var localBinDirectory = project.Directory / "bin";
|
|
var localTracerZip = localBinDirectory / "tracer.zip";
|
|
|
|
try
|
|
{
|
|
sourceModulePath.CopyToDirectory(localBinDirectory);
|
|
TracerHomeDirectory.ZipTo(localTracerZip);
|
|
|
|
PerformLegacyRestoreIfNeeded(project);
|
|
|
|
MSBuild(x => x
|
|
.SetConfiguration(BuildConfiguration)
|
|
.SetTargetPlatform(Platform)
|
|
.SetProperty("DeployOnBuild", true)
|
|
.SetMaxCpuCount(null)
|
|
.SetProperty("PublishProfile",
|
|
project.Directory / "Properties" / "PublishProfiles" / $"FolderProfile.{BuildConfiguration}.pubxml")
|
|
.SetTargetPath(project));
|
|
|
|
if (targets.Length > 0)
|
|
{
|
|
foreach (var target in targets)
|
|
{
|
|
DockerBuild(x => x
|
|
.SetPath(".")
|
|
.SetBuildArg($"configuration={BuildConfiguration}")
|
|
.EnableRm()
|
|
.SetProcessWorkingDirectory(project.Directory)
|
|
.SetTag($"{Path.GetFileNameWithoutExtension(project).Replace(".", "-")}-{target}".ToLowerInvariant())
|
|
.SetTarget(target)
|
|
);
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DockerBuild(x => x
|
|
.SetPath(".")
|
|
.SetBuildArg($"configuration={BuildConfiguration}")
|
|
.EnableRm()
|
|
.SetProcessWorkingDirectory(project.Directory)
|
|
.SetTag(Path.GetFileNameWithoutExtension(project).Replace(".", "-").ToLowerInvariant())
|
|
);
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
localTracerZip.DeleteFile();
|
|
var localModulePath = localBinDirectory / moduleName;
|
|
localModulePath.DeleteFile();
|
|
}
|
|
}
|
|
|
|
Target GenerateNetFxTransientDependencies => _ => _
|
|
.Unlisted()
|
|
.After(Restore)
|
|
.OnlyWhenStatic(() => IsWin)
|
|
.Executes(() =>
|
|
{
|
|
// The target project needs to have its NuGet packages restored prior to running the tool.
|
|
var targetProject = Solution.GetProjectByName(Projects.AutoInstrumentation);
|
|
DotNetRestore(s => s.SetProjectFile(targetProject));
|
|
|
|
var project = targetProject.GetMSBuildProject();
|
|
var packages = Solution.Directory / "src" / "Directory.Packages.props";
|
|
|
|
const string label = $"Transient dependencies auto-generated by {nameof(GenerateNetFxTransientDependencies)}";
|
|
|
|
var packagesGroup = project.Xml.ItemGroups.FirstOrDefault(x => x.Label == label);
|
|
if (packagesGroup == null)
|
|
{
|
|
packagesGroup = project.Xml.AddItemGroup();
|
|
packagesGroup.Label = label;
|
|
packagesGroup.Condition = " '$(TargetFramework)' == 'net462' AND $(_IsPacking) != true ";
|
|
}
|
|
|
|
var packagesProject = ProjectModelTasks.ParseProject(packages);
|
|
var versionGroup = packagesProject.Xml.ItemGroups.FirstOrDefault(x => x.Label == label);
|
|
if (versionGroup == null)
|
|
{
|
|
versionGroup = packagesProject.Xml.AddItemGroup();
|
|
versionGroup.Label = label;
|
|
}
|
|
|
|
var deps = Generator.EnumerateDependencies(project.FullPath);
|
|
foreach (var item in deps)
|
|
{
|
|
if (!packagesGroup.Items.Any(x => x.Include == item.Name))
|
|
{
|
|
packagesGroup.AddItem("PackageReference", item.Name);
|
|
}
|
|
|
|
if (!versionGroup.Items.Any(x => x.Include == item.Name))
|
|
{
|
|
var reference = versionGroup.AddItem("PackageVersion", item.Name);
|
|
reference.AddMetadata("Version", item.Version, expressAsAttribute: true);
|
|
}
|
|
}
|
|
|
|
project.Save();
|
|
packagesProject.Save();
|
|
});
|
|
|
|
Target GenerateNetFxAssemblyRedirectionSource => _ => _
|
|
.Unlisted()
|
|
.After(PublishManagedProfiler)
|
|
.OnlyWhenStatic(() => IsWin)
|
|
.Executes(() =>
|
|
{
|
|
var netFxAssembliesFolder = TracerHomeDirectory / MapToFolderOutput(TargetFramework.NET462);
|
|
var generatedSourceFile = SourceDirectory / Projects.AutoInstrumentationNative / "netfx_assembly_redirection.h";
|
|
|
|
AssemblyRedirectionSourceGenerator.Generate(netFxAssembliesFolder, generatedSourceFile);
|
|
});
|
|
|
|
Target InstallNetFxAssembliesGAC => _ => _
|
|
.Unlisted()
|
|
.After(BuildTracer)
|
|
.After(RunManagedUnitTests)
|
|
.OnlyWhenStatic(() => IsWin && (TestTargetFramework == TargetFramework.NET462 || TestTargetFramework == TargetFramework.NOT_SPECIFIED))
|
|
.Executes(() => RunNetFxGacOperation("-i"));
|
|
|
|
/// <remarks>
|
|
/// Warning: This target could cause potential harm to your system by removing a required library from GAC.
|
|
/// </remarks>
|
|
Target UninstallNetFxAssembliesGAC => _ => _
|
|
.Description("Removes .NET Framework output libraries from the GAC.")
|
|
.After(BuildTracer)
|
|
.OnlyWhenStatic(() => IsWin)
|
|
.Executes(() => RunNetFxGacOperation("-u"));
|
|
|
|
private void RunNetFxGacOperation(string operation)
|
|
{
|
|
// To update the GAC, we need to run the tool as Administrator.
|
|
// Throw if not running as a Windows Administrator.
|
|
if (!IsWindowsAdministrator())
|
|
{
|
|
throw new InvalidOperationException("This target must be run on Windows as Administrator.");
|
|
}
|
|
|
|
var netFxAssembliesFolder = TracerHomeDirectory / MapToFolderOutput(TargetFramework.NET462);
|
|
var installTool = Solution.GetProjectByName(Projects.Tools.GacInstallTool);
|
|
|
|
DotNetRun(s => s
|
|
.SetProjectFile(installTool)
|
|
.SetConfiguration(BuildConfiguration)
|
|
.SetApplicationArguments(operation, netFxAssembliesFolder));
|
|
|
|
static bool IsWindowsAdministrator()
|
|
{
|
|
if (!IsWin)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
#pragma warning disable CA1416 // Validate platform compatibility
|
|
using var identity = System.Security.Principal.WindowsIdentity.GetCurrent();
|
|
var principal = new System.Security.Principal.WindowsPrincipal(identity);
|
|
|
|
return principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator);
|
|
#pragma warning restore CA1416 // Validate platform compatibility
|
|
}
|
|
}
|
|
|
|
private void PerformLegacyRestoreIfNeeded(Project project)
|
|
{
|
|
if (!NoRestore && project.Directory.ContainsFile("packages.config"))
|
|
{
|
|
RestoreLegacyNuGetPackagesConfig(new[] { project });
|
|
}
|
|
}
|
|
}
|