示例#1
0
        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");
        }
示例#2
0
        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);
                }
        }
示例#3
0
        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);
            }
        }
示例#4
0
        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);
                }
        }