public void Execute() { var activeState = this.buildState.ActiveState; var sharedState = this.buildState.SharedState; var buildTable = activeState["Build"].AsTable(); var parametersTable = activeState["Parameters"].AsTable(); var arguments = new BuildArguments(); arguments.TargetArchitecture = parametersTable["Architecture"].AsString(); arguments.TargetName = buildTable["TargetName"].AsString(); arguments.TargetType = (BuildTargetType)buildTable["TargetType"].AsInteger(); arguments.SourceRootDirectory = new Path(buildTable["SourceRootDirectory"].AsString()); arguments.TargetRootDirectory = new Path(buildTable["TargetRootDirectory"].AsString()); arguments.ObjectDirectory = new Path(buildTable["ObjectDirectory"].AsString()); arguments.BinaryDirectory = new Path(buildTable["BinaryDirectory"].AsString()); if (buildTable.TryGetValue("Source", out var sourceValue)) { arguments.SourceFiles = sourceValue.AsList().Select(value => new Path(value.AsString())).ToList(); } if (buildTable.TryGetValue("LibraryPaths", out var libraryPathsValue)) { arguments.LibraryPaths = libraryPathsValue.AsList().Select(value => new Path(value.AsString())).ToList(); } if (buildTable.TryGetValue("PreprocessorDefinitions", out var preprocessorDefinitionsValue)) { arguments.PreprocessorDefinitions = preprocessorDefinitionsValue.AsList().Select(value => value.AsString()).ToList(); } if (buildTable.TryGetValue("OptimizationLevel", out var optimizationLevelValue)) { arguments.OptimizationLevel = (BuildOptimizationLevel) optimizationLevelValue.AsInteger(); } else { arguments.OptimizationLevel = BuildOptimizationLevel.None; } if (buildTable.TryGetValue("GenerateSourceDebugInfo", out var generateSourceDebugInfoValue)) { arguments.GenerateSourceDebugInfo = generateSourceDebugInfoValue.AsBoolean(); } else { arguments.GenerateSourceDebugInfo = false; } if (buildTable.TryGetValue("NullableState", out var nullableValue)) { arguments.NullableState = (BuildNullableState)nullableValue.AsInteger(); } else { arguments.NullableState = BuildNullableState.Enabled; } // Load the runtime dependencies if (buildTable.TryGetValue("RuntimeDependencies", out var runtimeDependenciesValue)) { arguments.RuntimeDependencies = MakeUnique( runtimeDependenciesValue.AsList().Select(value => new Path(value.AsString()))); } // Load the link dependencies if (buildTable.TryGetValue("LinkDependencies", out var linkDependenciesValue)) { arguments.LinkDependencies = MakeUnique( linkDependenciesValue.AsList().Select(value => new Path(value.AsString()))); } // Load the list of disabled warnings if (buildTable.TryGetValue("EnableWarningsAsErrors", out var enableWarningsAsErrorsValue)) { arguments.EnableWarningsAsErrors = enableWarningsAsErrorsValue.AsBoolean(); } else { arguments.GenerateSourceDebugInfo = false; } // Load the list of disabled warnings if (buildTable.TryGetValue("DisabledWarnings", out var disabledWarningsValue)) { arguments.DisabledWarnings = disabledWarningsValue.AsList().Select(value => value.AsString()).ToList(); } // Check for any custom compiler flags if (buildTable.TryGetValue("CustomCompilerProperties", out var customCompilerPropertiesValue)) { arguments.CustomProperties = customCompilerPropertiesValue.AsList().Select(value => value.AsString()).ToList(); } // Initialize the compiler to use var compilerName = parametersTable["Compiler"].AsString(); if (!this.compilerFactory.TryGetValue(compilerName, out var compileFactory)) { this.buildState.LogTrace(TraceLevel.Error, "Unknown compiler: " + compilerName); throw new InvalidOperationException(); } var compiler = compileFactory(activeState); var buildEngine = new BuildEngine(compiler); var buildResult = buildEngine.Execute(this.buildState, arguments); // Pass along internal state for other stages to gain access buildTable.EnsureValueList(this.factory, "InternalLinkDependencies").SetAll(this.factory, buildResult.InternalLinkDependencies); // Always pass along required input to shared build tasks var sharedBuildTable = sharedState.EnsureValueTable(this.factory, "Build"); sharedBuildTable.EnsureValueList(this.factory, "RuntimeDependencies").SetAll(this.factory, buildResult.RuntimeDependencies); sharedBuildTable.EnsureValueList(this.factory, "LinkDependencies").SetAll(this.factory, buildResult.LinkDependencies); if (!buildResult.TargetFile.IsEmpty) { sharedBuildTable["TargetFile"] = this.factory.Create(buildResult.TargetFile.ToString()); sharedBuildTable["RunExecutable"] = this.factory.Create("C:/Program Files/dotnet/dotnet.exe"); sharedBuildTable["RunArguments"] = this.factory.Create(buildResult.TargetFile.ToString()); } // Register the build operations foreach (var operation in buildResult.BuildOperations) { this.buildState.CreateOperation(operation); } this.buildState.LogTrace(TraceLevel.Information, "Build Generate Done"); }
public void Build_Library_MultipleFiles() { // Register the test process manager var processManager = new MockProcessManager(); // Register the test listener var testListener = new TestTraceListener(); using (var scopedTraceListener = new ScopedTraceListenerRegister(testListener)) using (var scopedProcesManager = new ScopedSingleton <IProcessManager>(processManager)) { // Register the mock compiler var compiler = new Mock.Compiler(); // Setup the build arguments var arguments = new BuildArguments(); arguments.TargetName = "Library"; arguments.TargetType = BuildTargetType.Library; arguments.SourceRootDirectory = new Path("C:/source/"); arguments.TargetRootDirectory = new Path("C:/target/"); arguments.ObjectDirectory = new Path("obj/"); arguments.BinaryDirectory = new Path("bin/"); arguments.SourceFiles = new List <Path>() { new Path("TestFile1.cs"), new Path("TestFile2.cs"), new Path("TestFile3.cs"), }; arguments.OptimizationLevel = BuildOptimizationLevel.Size; arguments.LinkDependencies = new List <Path>() { new Path("../Other/bin/OtherModule1.mock.a"), new Path("../OtherModule2.mock.a"), }; arguments.NullableState = BuildNullableState.Disabled; var uut = new BuildEngine(compiler); var fileSystemState = new FileSystemState(); var readAccessList = new List <Path>(); var writeAccessList = new List <Path>(); var buildState = new BuildState(new ValueTable(), fileSystemState, readAccessList, writeAccessList); var result = uut.Execute(buildState, arguments); // Verify expected process manager requests Assert.Equal( new List <string>() { "GetCurrentProcessFileName", "GetCurrentProcessFileName", "GetCurrentProcessFileName", }, processManager.GetRequests()); // Verify expected logs Assert.Equal( new List <string>() { }, testListener.GetMessages()); // Setup the shared arguments var expectedCompileArguments = new CompileArguments() { Target = new Path("./bin/Library.mock.dll"), ReferenceTarget = new Path("./bin/ref/Library.mock.dll"), SourceRootDirectory = new Path("C:/source/"), TargetRootDirectory = new Path("C:/target/"), ObjectDirectory = new Path("obj/"), SourceFiles = new List <Path>() { new Path("TestFile1.cs"), new Path("TestFile2.cs"), new Path("TestFile3.cs"), }, ReferenceLibraries = new List <Path>() { new Path("../Other/bin/OtherModule1.mock.a"), new Path("../OtherModule2.mock.a"), }, NullableState = NullableState.Disabled, }; // Verify expected compiler calls Assert.Equal( new List <CompileArguments>() { expectedCompileArguments, }, compiler.GetCompileRequests()); // Verify build state var expectedBuildOperations = new List <BuildOperation>() { new BuildOperation( "MakeDir [./obj/]", new Path("C:/target/"), new Path("C:/mkdir.exe"), "\"./obj/\"", new List <Path>(), new List <Path>() { new Path("./obj/"), }), new BuildOperation( "MakeDir [./bin/]", new Path("C:/target/"), new Path("C:/mkdir.exe"), "\"./bin/\"", new List <Path>(), new List <Path>() { new Path("./bin/"), }), new BuildOperation( "MakeDir [./bin/ref/]", new Path("C:/target/"), new Path("C:/mkdir.exe"), "\"./bin/ref/\"", new List <Path>(), new List <Path>() { new Path("./bin/ref/"), }), new BuildOperation( "MockCompile: 1", new Path("MockWorkingDirectory"), new Path("MockCompiler.exe"), "Arguments", new List <Path>() { new Path("InputFile.in"), }, new List <Path>() { new Path("OutputFile.out"), }), }; Assert.Equal( expectedBuildOperations, result.BuildOperations); Assert.Equal( new List <Path>() { new Path("C:/target/bin/ref/Library.mock.dll"), }, result.LinkDependencies); Assert.Equal( new List <Path>() { new Path("C:/target/bin/Library.mock.dll"), }, result.RuntimeDependencies); Assert.Equal( new Path("C:/target/bin/Library.mock.dll"), result.TargetFile); } }
public void Execute() { var activeState = this.buildState.ActiveState; var sharedState = this.buildState.SharedState; var recipeTable = activeState["Recipe"].AsTable(); var activeBuildTable = activeState["Build"].AsTable(); var parametersTable = activeState["Parameters"].AsTable(); if (!recipeTable.ContainsKey("Tests")) { throw new InvalidOperationException("No Tests Specified"); } var arguments = new BuildArguments(); arguments.TargetArchitecture = parametersTable["Architecture"].AsString(); // Load up the common build properties from the original Build table in the active state LoadBuildProperties(activeBuildTable, arguments); // Load the test properties var testTable = recipeTable["Tests"].AsTable(); LoadTestBuildProperties(buildState, testTable, arguments); // Load up the input build parameters from the shared build state as if // this is a dependency build var sharedBuildTable = sharedState["Build"].AsTable(); LoadDependencyBuildInput(sharedBuildTable, arguments); // Load up the test dependencies build input to add extra test runtime libraries LoadTestDependencyBuildInput(buildState, activeState, arguments); // Update to place the output in a sub folder arguments.ObjectDirectory = arguments.ObjectDirectory + new Path("Test/"); arguments.BinaryDirectory = arguments.BinaryDirectory + new Path("Test/"); // Initialize the compiler to use var compilerName = parametersTable["Compiler"].AsString(); if (!this.compilerFactory.TryGetValue(compilerName, out var compileFactory)) { this.buildState.LogTrace(TraceLevel.Error, "Unknown compiler: " + compilerName); throw new InvalidOperationException(); } var compiler = compileFactory(activeState); var buildEngine = new BuildEngine(compiler); var buildResult = buildEngine.Execute(buildState, arguments); // Create the operation to run tests during build var title = "Run Tests"; var program = new Path("C:/Program Files/dotnet/dotnet.exe"); var runtimeConfigFile = arguments.BinaryDirectory + new Path($"{arguments.TargetName}.runtimeconfig.json"); var workingDirectory = arguments.TargetRootDirectory; var runArguments = buildResult.TargetFile.ToString(); // Ensure that the executable and all runtime dependencies are in place before running tests var inputFiles = new List <Path>(buildResult.RuntimeDependencies); inputFiles.Add(program); inputFiles.Add(runtimeConfigFile); // The test should have no output var outputFiles = new List <Path>(); var runTestsOperation = new BuildOperation( title, workingDirectory, program, runArguments, inputFiles, outputFiles); // Run the test harness buildResult.BuildOperations.Add(runTestsOperation); // Register the build operations foreach (var operation in buildResult.BuildOperations) { buildState.CreateOperation(operation); } }
public void Build_Executable() { // Register the test process manager var processManager = new MockProcessManager(); // Register the test listener var testListener = new TestTraceListener(); using (var scopedTraceListener = new ScopedTraceListenerRegister(testListener)) using (var scopedProcesManager = new ScopedSingleton <IProcessManager>(processManager)) { // Register the mock compiler var compiler = new Mock.Compiler(); // Setup the build arguments var arguments = new BuildArguments(); arguments.TargetName = "Program"; arguments.TargetType = BuildTargetType.Executable; arguments.SourceRootDirectory = new Path("C:/source/"); arguments.TargetRootDirectory = new Path("C:/target/"); arguments.ObjectDirectory = new Path("obj/"); arguments.BinaryDirectory = new Path("bin/"); arguments.SourceFiles = new List <Path>() { new Path("TestFile.cs"), }; arguments.OptimizationLevel = BuildOptimizationLevel.None; arguments.LinkDependencies = new List <Path>() { new Path("../Other/bin/OtherModule1.mock.a"), new Path("../OtherModule2.mock.a"), }; var uut = new BuildEngine(compiler); var fileSystemState = new FileSystemState(); var readAccessList = new List <Path>(); var writeAccessList = new List <Path>(); var buildState = new BuildState(new ValueTable(), fileSystemState, readAccessList, writeAccessList); var result = uut.Execute(buildState, arguments); // Verify expected process manager requests Assert.Equal( new List <string>() { "GetCurrentProcessFileName", "GetCurrentProcessFileName", "GetCurrentProcessFileName", }, processManager.GetRequests()); // Verify expected logs Assert.Equal( new List <string>() { }, testListener.GetMessages()); var expectedCompileArguments = new CompileArguments() { Target = new Path("./bin/Program.mock.dll"), ReferenceTarget = new Path("./bin/ref/Program.mock.dll"), TargetType = LinkTarget.Executable, ObjectDirectory = new Path("obj/"), SourceRootDirectory = new Path("C:/source/"), TargetRootDirectory = new Path("C:/target/"), SourceFiles = new List <Path>() { new Path("TestFile.cs"), }, ReferenceLibraries = new List <Path>() { new Path("../Other/bin/OtherModule1.mock.a"), new Path("../OtherModule2.mock.a"), }, NullableState = NullableState.Enabled, }; // Verify expected compiler calls var val = compiler.GetCompileRequests()[0]; var areEqual = val == expectedCompileArguments; var areEqual2 = val.ObjectDirectory == expectedCompileArguments.ObjectDirectory; Assert.Equal( new List <CompileArguments>() { expectedCompileArguments, }, compiler.GetCompileRequests()); var expectedBuildOperations = new List <BuildOperation>() { new BuildOperation( "MakeDir [./obj/]", new Path("C:/target/"), new Path("C:/mkdir.exe"), "\"./obj/\"", new List <Path>(), new List <Path>() { new Path("./obj/"), }), new BuildOperation( "MakeDir [./bin/]", new Path("C:/target/"), new Path("C:/mkdir.exe"), "\"./bin/\"", new List <Path>(), new List <Path>() { new Path("./bin/"), }), new BuildOperation( "MakeDir [./bin/ref/]", new Path("C:/target/"), new Path("C:/mkdir.exe"), "\"./bin/ref/\"", new List <Path>(), new List <Path>() { new Path("./bin/ref/"), }), new BuildOperation( "MockCompile: 1", new Path("MockWorkingDirectory"), new Path("MockCompiler.exe"), "Arguments", new List <Path>() { new Path("./InputFile.in"), }, new List <Path>() { new Path("./OutputFile.out"), }), new BuildOperation( "WriteFile [./bin/Program.runtimeconfig.json]", new Path("C:/target/"), new Path("./writefile.exe"), @"""./bin/Program.runtimeconfig.json"" ""{ ""runtimeOptions"": { ""tfm"": ""net5.0"", ""framework"": { ""name"": ""Microsoft.NETCore.App"", ""version"": ""5.0.0"" } } }""", new List <Path>(), new List <Path>() { new Path("./bin/Program.runtimeconfig.json"), }), }; Assert.Equal( expectedBuildOperations, result.BuildOperations); Assert.Equal( new List <Path>(), result.LinkDependencies); Assert.Equal( new List <Path>() { new Path("C:/target/bin/Program.mock.dll"), }, result.RuntimeDependencies); } }