/// <summary> /// Generate the required build operations for the requested build /// </summary> public BuildResult Execute( IBuildState buildState, BuildArguments arguments) { var result = new BuildResult(); // Ensure the output directories exists as the first step var referenceDirectory = arguments.BinaryDirectory + new Path("ref/"); result.BuildOperations.Add( SharedOperations.CreateCreateDirectoryOperation( arguments.TargetRootDirectory, arguments.ObjectDirectory)); result.BuildOperations.Add( SharedOperations.CreateCreateDirectoryOperation( arguments.TargetRootDirectory, arguments.BinaryDirectory)); result.BuildOperations.Add( SharedOperations.CreateCreateDirectoryOperation( arguments.TargetRootDirectory, referenceDirectory)); // Perform the core compilation of the source files CoreCompile(buildState, arguments, referenceDirectory, result); // Copy previous runtime dependencies after linking has completed CopyRuntimeDependencies(arguments, result); GenerateBuildRuntimeConfigurationFiles(arguments, result); return(result); }
/// <summary> /// Generate the required build operations for the requested build /// </summary> public BuildResult Execute( IBuildState buildState, BuildArguments arguments) { var result = new BuildResult(); // All dependencies must include the entire interface dependency closure result.ModuleDependencies = new List <Path>(arguments.ModuleDependencies); // Ensure the output directories exists as the first step result.BuildOperations.Add( SharedOperations.CreateCreateDirectoryOperation( arguments.TargetRootDirectory, arguments.ObjectDirectory)); result.BuildOperations.Add( SharedOperations.CreateCreateDirectoryOperation( arguments.TargetRootDirectory, arguments.BinaryDirectory)); // Perform the core compilation of the source files CoreCompile(buildState, arguments, result); // Link the final target after all of the compile graph is done CoreLink(buildState, arguments, result); // Copy previous runtime dependencies after linking has completed CopyRuntimeDependencies(arguments, result); return(result); }
public static void CreateOperation(this IBuildState buildState, BuildOperation operation) { buildState.CreateOperation( operation.Title, operation.Executable.ToString(), operation.Arguments, operation.WorkingDirectory.ToString(), operation.DeclaredInput.Select(value => value.ToString()).ToArray(), operation.DeclaredOutput.Select(value => value.ToString()).ToArray()); }
public BuildTask(IBuildState buildState, IValueFactory factory) : this(buildState, factory, new Dictionary <string, Func <IValueTable, ICompiler> >()) { // Register default compilers // TODO: Fix up compiler names for different languages this.compilerFactory.Add("MSVC", (IValueTable activeState) => { var clToolPath = new Path(activeState["Roslyn.CscToolPath"].AsString()); return(new Compiler.Roslyn.Compiler(clToolPath)); }); }
public TestBuildTask(IBuildState buildState, IValueFactory factory) : this(buildState, factory, new Dictionary <string, Func <IValueTable, ICompiler> >()) { // Register default compilers this.compilerFactory.Add("MSVC", (IValueTable activeState) => { var clToolPath = new Path(activeState["MSVC.ClToolPath"].AsString()); var linkToolPath = new Path(activeState["MSVC.LinkToolPath"].AsString()); var libToolPath = new Path(activeState["MSVC.LibToolPath"].AsString()); return(new Compiler.MSVC.Compiler(clToolPath, linkToolPath, libToolPath)); }); }
public BuildTask(IBuildState buildState, IValueFactory factory, Dictionary <string, Func <IValueTable, ICompiler> > compilerFactory) { this.buildState = buildState; this.factory = factory; this.compilerFactory = compilerFactory; // TODO: Not ideal to be registering this on the fly... if (!LifetimeManager.Has <IProcessManager>()) { LifetimeManager.RegisterSingleton <IProcessManager, RuntimeProcessManager>(); } }
private static void LoadTestDependencyBuildInput( IBuildState buildState, IValueTable activeState, BuildArguments arguments) { if (activeState.TryGetValue("Dependencies", out var dependenciesValue)) { var dependenciesTable = dependenciesValue.AsTable(); if (dependenciesTable.TryGetValue("Test", out var testValue)) { var testDependenciesTable = testValue.AsTable(); foreach (var dependencyName in testDependenciesTable) { // Combine the core dependency build inputs for the core build task buildState.LogTrace(TraceLevel.Information, "Combine Test Dependency: " + dependencyName.Key); var dependencyTable = dependencyName.Value.AsTable(); if (dependencyTable.TryGetValue("Build", out var buildValue)) { var dependencyBuildTable = buildValue.AsTable(); if (dependencyBuildTable.TryGetValue("ModuleDependencies", out var moduleDependenciesValue)) { arguments.ModuleDependencies = CombineUnique( arguments.ModuleDependencies, moduleDependenciesValue.AsList().Select(value => new Path(value.AsString()))); } if (dependencyBuildTable.TryGetValue("RuntimeDependencies", out var runtimeDependenciesValue)) { arguments.RuntimeDependencies = CombineUnique( arguments.RuntimeDependencies, runtimeDependenciesValue.AsList().Select(value => new Path(value.AsString()))); } if (dependencyBuildTable.TryGetValue("LinkDependencies", out var linkDependenciesValue)) { arguments.LinkDependencies = CombineUnique( arguments.LinkDependencies, linkDependenciesValue.AsList().Select(value => new Path(value.AsString()))); } } } } } }
void LoadTestBuildProperties( IBuildState buildState, IValueTable testTable, BuildArguments arguments) { if (testTable.TryGetValue("Source", out var sourceValue)) { arguments.SourceFiles = sourceValue.AsList().Select(value => new Path(value.AsString())).ToList(); } else { throw new InvalidOperationException("No Test Source Files"); } arguments.TargetName = "TestHarness"; arguments.TargetType = BuildTargetType.Executable; }
public ResolveToolsTask(IBuildState buildState, IValueFactory factory) { this.buildState = buildState; this.factory = factory; }
public TaskMonitor(IBuildProgress buildProgress, IBuildState buildState) { _buildProgress = buildProgress; _buildState = buildState; }
/// <summary> /// Compile the module and source files /// </summary> private void CoreCompile( IBuildState buildState, BuildArguments arguments, BuildResult result) { // Ensure there are actually files to build if (arguments.ModuleInterfacePartitionSourceFiles.Count != 0 || !arguments.ModuleInterfaceSourceFile.IsEmpty || arguments.SourceFiles.Count != 0) { // Setup the shared properties var compileArguments = new SharedCompileArguments() { Standard = arguments.LanguageStandard, Optimize = Convert(arguments.OptimizationLevel), SourceRootDirectory = arguments.SourceRootDirectory, TargetRootDirectory = arguments.TargetRootDirectory, ObjectDirectory = arguments.ObjectDirectory, IncludeDirectories = arguments.IncludeDirectories, IncludeModules = arguments.ModuleDependencies, PreprocessorDefinitions = arguments.PreprocessorDefinitions, GenerateSourceDebugInfo = arguments.GenerateSourceDebugInfo, EnableWarningsAsErrors = arguments.EnableWarningsAsErrors, DisabledWarnings = arguments.DisabledWarnings, EnabledWarnings = arguments.EnabledWarnings, CustomProperties = arguments.CustomProperties, }; // Compile the resource file if present if (!arguments.ResourceFile.IsEmpty) { buildState.LogTrace(TraceLevel.Information, "Generate Resource File Compile: " + arguments.ResourceFile.ToString()); var compiledResourceFile = arguments.ObjectDirectory + new Path(arguments.ResourceFile.GetFileName()); compiledResourceFile.SetFileExtension(_compiler.ResourceFileExtension); var compileResourceFileArguments = new ResourceCompileArguments() { SourceFile = arguments.ResourceFile, TargetFile = compiledResourceFile, }; // Add the resource file arguments to the shared build definition compileArguments.ResourceFile = compileResourceFileArguments; } // Build up the entire Interface Dependency Closure for each file var partitionInterfaceDependencyLookup = new Dictionary <Path, IReadOnlyList <Path> >(); foreach (var file in arguments.ModuleInterfacePartitionSourceFiles) { partitionInterfaceDependencyLookup.Add(file.File, file.Imports); } // Compile the individual module interface partition translation units var compileInterfacePartitionUnits = new List <InterfaceUnitCompileArguments>(); var allPartitionInterfaces = new List <Path>(); foreach (var file in arguments.ModuleInterfacePartitionSourceFiles) { buildState.LogTrace(TraceLevel.Information, "Generate Module Interface Partition Compile Operation: " + file.File.ToString()); var objectModuleInterfaceFile = arguments.ObjectDirectory + new Path(file.File.GetFileName()); objectModuleInterfaceFile.SetFileExtension(_compiler.ModuleFileExtension); var interfaceDependencyClosure = new HashSet <Path>(); BuildClosure(interfaceDependencyClosure, file.File, partitionInterfaceDependencyLookup); if (interfaceDependencyClosure.Contains(file.File)) { throw new InvalidOperationException($"Circular partition references in: {file.File}"); } var partitionImports = new List <Path>(); foreach (var import in interfaceDependencyClosure) { var importInterface = arguments.ObjectDirectory + new Path(import.GetFileName()); importInterface.SetFileExtension(_compiler.ModuleFileExtension); partitionImports.Add(arguments.TargetRootDirectory + importInterface); } var compileFileArguments = new InterfaceUnitCompileArguments() { SourceFile = file.File, TargetFile = arguments.ObjectDirectory + new Path(file.File.GetFileName()), IncludeModules = partitionImports, ModuleInterfaceTarget = objectModuleInterfaceFile, }; compileFileArguments.TargetFile.SetFileExtension(_compiler.ObjectFileExtension); compileInterfacePartitionUnits.Add(compileFileArguments); allPartitionInterfaces.Add(arguments.TargetRootDirectory + objectModuleInterfaceFile); } // Add all partition unit interface files as module dependencies since MSVC does not // combine the interfaces into the final interface unit foreach (var module in allPartitionInterfaces) { result.ModuleDependencies.Add(module); } compileArguments.InterfacePartitionUnits = compileInterfacePartitionUnits; // Compile the module interface unit if present if (!arguments.ModuleInterfaceSourceFile.IsEmpty) { buildState.LogTrace(TraceLevel.Information, "Generate Module Interface Unit Compile: " + arguments.ModuleInterfaceSourceFile.ToString()); var objectModuleInterfaceFile = arguments.ObjectDirectory + new Path(arguments.ModuleInterfaceSourceFile.GetFileName()); objectModuleInterfaceFile.SetFileExtension(_compiler.ModuleFileExtension); var binaryOutputModuleInterfaceFile = arguments.BinaryDirectory + new Path(arguments.TargetName + "." + _compiler.ModuleFileExtension); var compileModuleFileArguments = new InterfaceUnitCompileArguments() { SourceFile = arguments.ModuleInterfaceSourceFile, TargetFile = arguments.ObjectDirectory + new Path(arguments.ModuleInterfaceSourceFile.GetFileName()), IncludeModules = allPartitionInterfaces, ModuleInterfaceTarget = objectModuleInterfaceFile, }; compileModuleFileArguments.TargetFile.SetFileExtension(_compiler.ObjectFileExtension); // Add the interface unit arguments to the shared build definition compileArguments.InterfaceUnit = compileModuleFileArguments; // Copy the binary module interface to the binary directory after compiling var copyInterfaceOperation = SharedOperations.CreateCopyFileOperation( arguments.TargetRootDirectory, objectModuleInterfaceFile, binaryOutputModuleInterfaceFile); result.BuildOperations.Add(copyInterfaceOperation); // Add output module interface to the parent set of modules // This will allow the module implementation units access as well as downstream // dependencies to the public interface. result.ModuleDependencies.Add( binaryOutputModuleInterfaceFile.HasRoot ? binaryOutputModuleInterfaceFile : arguments.TargetRootDirectory + binaryOutputModuleInterfaceFile); } // Compile the individual translation units var compileImplementationUnits = new List <TranslationUnitCompileArguments>(compileArguments.ImplementationUnits); foreach (var file in arguments.SourceFiles) { buildState.LogTrace(TraceLevel.Information, "Generate Compile Operation: " + file.ToString()); var compileFileArguments = new TranslationUnitCompileArguments(); compileFileArguments.SourceFile = file; compileFileArguments.TargetFile = arguments.ObjectDirectory + new Path(file.GetFileName()); compileFileArguments.TargetFile.SetFileExtension(_compiler.ObjectFileExtension); compileImplementationUnits.Add(compileFileArguments); } compileArguments.ImplementationUnits = compileImplementationUnits; // Compile all source files as a single call var compileOperations = _compiler.CreateCompileOperations(compileArguments); foreach (var operation in compileOperations) { result.BuildOperations.Add(operation); } } }
/// <summary> /// Link the library /// </summary> private void CoreLink( IBuildState buildState, BuildArguments arguments, BuildResult result) { buildState.LogTrace(TraceLevel.Information, "CoreLink"); Path targetFile; var implementationFile = new Path(); switch (arguments.TargetType) { case BuildTargetType.StaticLibrary: targetFile = arguments.BinaryDirectory + new Path(arguments.TargetName + "." + _compiler.StaticLibraryFileExtension); break; case BuildTargetType.DynamicLibrary: targetFile = arguments.BinaryDirectory + new Path(arguments.TargetName + "." + _compiler.DynamicLibraryFileExtension); implementationFile = arguments.BinaryDirectory + new Path(arguments.TargetName + "." + _compiler.StaticLibraryFileExtension); break; case BuildTargetType.Executable: case BuildTargetType.WindowsApplication: targetFile = arguments.BinaryDirectory + new Path(arguments.TargetName + ".exe"); break; default: throw new InvalidOperationException("Unknown build target type."); } buildState.LogTrace(TraceLevel.Information, "Linking target"); var linkArguments = new LinkArguments() { TargetFile = targetFile, TargetArchitecture = arguments.TargetArchitecture, ImplementationFile = implementationFile, TargetRootDirectory = arguments.TargetRootDirectory, LibraryPaths = arguments.LibraryPaths, GenerateSourceDebugInfo = arguments.GenerateSourceDebugInfo, }; // Only resolve link libraries if not a library ourself if (arguments.TargetType != BuildTargetType.StaticLibrary) { linkArguments.ExternalLibraryFiles = arguments.PlatformLinkDependencies; linkArguments.LibraryFiles = arguments.LinkDependencies; } // Translate the target type into the link target // and determine what dependencies to inject into downstream builds switch (arguments.TargetType) { case BuildTargetType.StaticLibrary: { linkArguments.TargetType = LinkTarget.StaticLibrary; // Add the library as a link dependency and all recursive libraries result.LinkDependencies = new List <Path>(arguments.LinkDependencies); var absoluteTargetFile = linkArguments.TargetFile.HasRoot ? linkArguments.TargetFile : linkArguments.TargetRootDirectory + linkArguments.TargetFile; result.LinkDependencies.Add(absoluteTargetFile); break; } case BuildTargetType.DynamicLibrary: { linkArguments.TargetType = LinkTarget.DynamicLibrary; // Add the DLL as a runtime dependency var absoluteTargetFile = linkArguments.TargetFile.HasRoot ? linkArguments.TargetFile : linkArguments.TargetRootDirectory + linkArguments.TargetFile; result.RuntimeDependencies.Add(absoluteTargetFile); // Clear out all previous link dependencies and replace with the // single implementation library for the DLL var absoluteImplementationFile = linkArguments.ImplementationFile.HasRoot ? linkArguments.ImplementationFile : linkArguments.TargetRootDirectory + linkArguments.ImplementationFile; result.LinkDependencies.Add(absoluteImplementationFile); // Set the targe file result.TargetFile = absoluteTargetFile; break; } case BuildTargetType.Executable: { linkArguments.TargetType = LinkTarget.Executable; // Add the Executable as a runtime dependency var absoluteTargetFile = linkArguments.TargetFile.HasRoot ? linkArguments.TargetFile : linkArguments.TargetRootDirectory + linkArguments.TargetFile; result.RuntimeDependencies.Add(absoluteTargetFile); // All link dependencies stop here. // Set the targe file result.TargetFile = absoluteTargetFile; break; } case BuildTargetType.WindowsApplication: { linkArguments.TargetType = LinkTarget.WindowsApplication; // Add the Executable as a runtime dependency var absoluteTargetFile = linkArguments.TargetFile.HasRoot ? linkArguments.TargetFile : linkArguments.TargetRootDirectory + linkArguments.TargetFile; result.RuntimeDependencies.Add(absoluteTargetFile); // All link dependencies stop here. // Set the targe file result.TargetFile = absoluteTargetFile; break; } default: { throw new InvalidOperationException("Unknown build target type."); } } // Build up the set of object files var objectFiles = new List <Path>(); // Add the resource file if present if (!arguments.ResourceFile.IsEmpty) { var compiledResourceFile = arguments.ObjectDirectory + new Path(arguments.ResourceFile.GetFileName()); compiledResourceFile.SetFileExtension(_compiler.ResourceFileExtension); objectFiles.Add(compiledResourceFile); } // Add the partition object files foreach (var sourceFile in arguments.ModuleInterfacePartitionSourceFiles) { var objectFile = arguments.ObjectDirectory + new Path(sourceFile.File.GetFileName()); objectFile.SetFileExtension(_compiler.ObjectFileExtension); objectFiles.Add(objectFile); } // Add the module interface object file if present if (!arguments.ModuleInterfaceSourceFile.IsEmpty) { var objectFile = arguments.ObjectDirectory + new Path(arguments.ModuleInterfaceSourceFile.GetFileName()); objectFile.SetFileExtension(_compiler.ObjectFileExtension); objectFiles.Add(objectFile); } // Add the implementation unit object files foreach (var sourceFile in arguments.SourceFiles) { var objectFile = arguments.ObjectDirectory + new Path(sourceFile.GetFileName()); objectFile.SetFileExtension(_compiler.ObjectFileExtension); objectFiles.Add(objectFile); } linkArguments.ObjectFiles = objectFiles; // Perform the link buildState.LogTrace(TraceLevel.Information, "Generate Link Operation: " + linkArguments.TargetFile.ToString()); var linkOperation = _compiler.CreateLinkOperation(linkArguments); result.BuildOperations.Add(linkOperation); // Pass along the link arguments for internal access result.InternalLinkDependencies = new List <Path>(arguments.LinkDependencies); foreach (var file in linkArguments.ObjectFiles) { result.InternalLinkDependencies.Add(file); } }
public TaskHeaderWriter(IOutput output, IBuildState buildState) { _output = output; _buildState = buildState; }
public BuildStateSnapshot(IBuildState toCopy) { Task = toCopy.Task; TaskRegistration = toCopy.TaskRegistration; TaskException = toCopy.TaskException; TaskWasSkipped = toCopy.TaskWasSkipped; }
public CustomBuildTask(IBuildState buildState, IValueFactory factory) { this.buildState = buildState; this.factory = factory; }
public ResolveDependenciesTask(IBuildState buildState, IValueFactory factory) { this.buildState = buildState; this.factory = factory; }
/// <summary> /// Compile the module and source files /// </summary> private void CoreCompile( IBuildState buildState, BuildArguments arguments, Path referenceDirectory, BuildResult result) { // Ensure there are actually files to build if (arguments.SourceFiles.Count != 0) { Path targetFile; Path referenceTargetFile; LinkTarget targetType; switch (arguments.TargetType) { case BuildTargetType.Library: targetType = LinkTarget.Library; targetFile = arguments.BinaryDirectory + new Path(arguments.TargetName + "." + _compiler.DynamicLibraryFileExtension); referenceTargetFile = referenceDirectory + new Path(arguments.TargetName + "." + _compiler.DynamicLibraryFileExtension); // Add the DLL as a runtime dependency result.RuntimeDependencies.Add(arguments.TargetRootDirectory + targetFile); // Link against the reference target result.LinkDependencies.Add(arguments.TargetRootDirectory + referenceTargetFile); break; case BuildTargetType.Executable: targetType = LinkTarget.Executable; targetFile = arguments.BinaryDirectory + new Path(arguments.TargetName + "." + _compiler.DynamicLibraryFileExtension); referenceTargetFile = referenceDirectory + new Path(arguments.TargetName + "." + _compiler.DynamicLibraryFileExtension); // Add the Executable as a runtime dependency result.RuntimeDependencies.Add(arguments.TargetRootDirectory + targetFile); // All link dependencies stop here. break; case BuildTargetType.Module: targetType = LinkTarget.Module; targetFile = arguments.BinaryDirectory + new Path(arguments.TargetName + "." + _compiler.ModuleFileExtension); referenceTargetFile = referenceDirectory + new Path(arguments.TargetName + "." + _compiler.ModuleFileExtension); // Add the DLL as a runtime dependency result.RuntimeDependencies.Add(arguments.TargetRootDirectory + targetFile); // Link against the reference target result.LinkDependencies.Add(arguments.TargetRootDirectory + referenceTargetFile); break; default: throw new InvalidOperationException("Unknown build target type."); } // Convert the nullable state NullableState nullableState; switch (arguments.NullableState) { case BuildNullableState.Disabled: nullableState = NullableState.Disabled; break; case BuildNullableState.Enabled: nullableState = NullableState.Enabled; break; case BuildNullableState.Warnings: nullableState = NullableState.Warnings; break; case BuildNullableState.Annotations: nullableState = NullableState.Annotations; break; default: throw new InvalidOperationException("Unknown Nullable State"); } // Setup the shared properties var compileArguments = new CompileArguments() { Target = targetFile, ReferenceTarget = referenceTargetFile, TargetType = targetType, SourceRootDirectory = arguments.SourceRootDirectory, TargetRootDirectory = arguments.TargetRootDirectory, ObjectDirectory = arguments.ObjectDirectory, SourceFiles = arguments.SourceFiles, PreprocessorDefinitions = arguments.PreprocessorDefinitions, GenerateSourceDebugInfo = arguments.GenerateSourceDebugInfo, EnableWarningsAsErrors = arguments.EnableWarningsAsErrors, DisabledWarnings = arguments.DisabledWarnings, EnabledWarnings = arguments.EnabledWarnings, NullableState = nullableState, CustomProperties = arguments.CustomProperties, ReferenceLibraries = arguments.LinkDependencies, }; // Compile all source files as a single call var compileOperations = _compiler.CreateCompileOperations(compileArguments); foreach (var operation in compileOperations) { result.BuildOperations.Add(operation); } result.TargetFile = arguments.TargetRootDirectory + targetFile; } }
public RecipeBuildTask(IBuildState buildState, IValueFactory factory) { this.buildState = buildState; this.factory = factory; }