// publicly accessible routines /// <summary> /// Builds the compilation for the Q# code or Q# snippet and referenced assemblies defined by the given options. /// Returns a suitable error code if one of the compilation or generation steps fails. /// Throws an ArgumentNullException if any of the given arguments is null. /// </summary> public static int Run(BuildOptions options, ConsoleLogger logger) { if (options == null) { throw new ArgumentNullException(nameof(options)); } if (logger == null) { throw new ArgumentNullException(nameof(logger)); } var usesPlugins = options.Plugins != null && options.Plugins.Any(); var loadOptions = new CompilationLoader.Configuration { ProjectName = options.ProjectName, GenerateFunctorSupport = true, SkipSyntaxTreeTrimming = options.TrimLevel == 0, AttemptFullPreEvaluation = options.TrimLevel > 1, DocumentationOutputFolder = options.DocFolder, BuildOutputFolder = options.OutputFolder ?? (usesPlugins ? "." : null), DllOutputPath = " ", // generating the dll in the same location as the .bson file RewriteSteps = options.Plugins?.Select(step => (step, (string)null)) ?? ImmutableArray <(string, string)> .Empty, EnableAdditionalChecks = false // todo: enable debug mode? }; var loaded = new CompilationLoader(options.LoadSourcesOrSnippet(logger), options.References, loadOptions, logger); return(ReturnCode.Status(loaded)); } }
// publicly accessible routines /// <summary> /// Builds the compilation for the Q# code or Q# snippet and referenced assemblies defined by the given options. /// Invokes all specified targets (dotnet core apps) with suitable TargetOptions, /// that in particular specify the path to the compiled binary as input and the same output folder, verbosity, and suppressed warnings as the given options. /// The output folder is set to the current directory if one or more targets have been specified but the output folder was left unspecified. /// Returns a suitable error code if one of the compilation or generation steps fails. /// </summary> /// <exception cref="System.ArgumentNullException">If any of the given arguments is null.</exception> /// </summary> public static int Run(BuildOptions options, ConsoleLogger logger) { if (options == null) { throw new ArgumentNullException(nameof(options)); } if (logger == null) { throw new ArgumentNullException(nameof(logger)); } CompilationLoader.BuildTarget DefineTarget(string exeName) => (binary, onException) => { var targetOpts = new TargetOptions { Input = new[] { binary }, OutputFolder = Path.GetFullPath(options.OutputFolder ?? "."), // GetFullPath is needed for the output folder to be relative to the current folder! Verbose = options.Verbose, NoWarn = options.NoWarn, }; var pathToExe = Path.GetFullPath(exeName); var commandLineArgs = $"{pathToExe} {Parser.Default.FormatCommandLine(targetOpts)}"; var success = ProcessRunner.Run("dotnet", commandLineArgs, out var output, out var error, out var exitCode, out var ex, timeout: 30000); if (ex != null) { onException?.Invoke(ex); } if (exitCode != 0) { logger.Log(WarningCode.TargetExitedAbnormally, new[] { exeName, exitCode.ToString() }, pathToExe); } var(outStr, errStr) = (output.ToString(), error.ToString()); if (!String.IsNullOrWhiteSpace(outStr)) { logger.Log(InformationCode.BuildTargetOutput, Enumerable.Empty <string>(), pathToExe, messageParam: outStr); } if (!String.IsNullOrWhiteSpace(errStr)) { logger.Log(InformationCode.BuildTargetError, Enumerable.Empty <string>(), pathToExe, messageParam: errStr); } return(success); }; var specifiesTargets = options.Targets != null && options.Targets.Any(); var loadOptions = new CompilationLoader.Configuration { ProjectFile = options.ProjectName == null ? null : new Uri(Path.GetFullPath(options.ProjectName)), GenerateFunctorSupport = true, SkipSyntaxTreeTrimming = false, DocumentationOutputFolder = options.DocFolder, BuildOutputFolder = options.OutputFolder ?? (specifiesTargets ? "." : null), Targets = options.Targets.ToImmutableDictionary(id => id, DefineTarget) }; var loaded = new CompilationLoader(options.LoadSourcesOrSnippet(logger), options.References, loadOptions, logger); return(ReturnCode.Status(loaded)); }
// publicly accessible routines /// <summary> /// Builds the compilation for the Q# code or Q# snippet and referenced assemblies defined by the given options. /// Returns a suitable error code if one of the compilation or generation steps fails. /// Throws an ArgumentNullException if any of the given arguments is null. /// </summary> public static int Run(BuildOptions options, ConsoleLogger logger) { if (options == null) { throw new ArgumentNullException(nameof(options)); } if (logger == null) { throw new ArgumentNullException(nameof(logger)); } if (options?.ResponseFiles != null && options.ResponseFiles.Any()) { options = FromResponseFiles(options.ResponseFiles); } if (options == null) { return(ReturnCode.INVALID_ARGUMENTS); } var usesPlugins = options.Plugins != null && options.Plugins.Any(); var loadOptions = new CompilationLoader.Configuration { ProjectName = options.ProjectName, GenerateFunctorSupport = true, SkipSyntaxTreeTrimming = options.TrimLevel == 0, ConvertClassicalControl = options.TrimLevel >= 2, AttemptFullPreEvaluation = options.TrimLevel > 2, DocumentationOutputFolder = options.DocFolder, BuildOutputFolder = options.OutputFolder ?? (usesPlugins ? "." : null), DllOutputPath = options.EmitDll ? " " : null, // set to e.g. an empty space to generate the dll in the same location as the .bson file RewriteSteps = options.Plugins?.Select(step => (step, (string)null)) ?? ImmutableArray <(string, string)> .Empty, EnableAdditionalChecks = false // todo: enable debug mode? }; if (options.PerfFolder != null) { CompilationLoader.CompilationTaskEvent += CompilationTracker.OnCompilationTaskEvent; } var loaded = new CompilationLoader(options.LoadSourcesOrSnippet(logger), options.References, loadOptions, logger); if (options.PerfFolder != null) { try { CompilationTracker.PublishResults(options.PerfFolder); } catch (Exception ex) { logger.Log(ErrorCode.PublishingPerfResultsFailed, new string[] { options.PerfFolder }); logger.Log(ex); } } return(ReturnCode.Status(loaded)); } }
// publicly accessible routines /// <summary> /// Builds the compilation for the Q# code or Q# snippet and referenced assemblies defined by the given options. /// Returns a suitable error code if one of the compilation or generation steps fails. /// Throws an ArgumentNullException if any of the given arguments is null. /// </summary> public static int Run(BuildOptions options, ConsoleLogger logger) { if (options == null) { throw new ArgumentNullException(nameof(options)); } if (logger == null) { throw new ArgumentNullException(nameof(logger)); } if (!BuildOptions.IncorporateResponseFiles(options, out options)) { logger.Log(ErrorCode.InvalidCommandLineArgsInResponseFiles, Array.Empty <string>()); return(ReturnCode.INVALID_ARGUMENTS); } var usesPlugins = options.Plugins != null && options.Plugins.Any(); if (!options.ParseAssemblyProperties(out var assemblyConstants)) { logger.Log(WarningCode.InvalidAssemblyProperties, Array.Empty <string>()); } var loadOptions = new CompilationLoader.Configuration { ProjectName = options.ProjectName, AssemblyConstants = assemblyConstants, TargetPackageAssemblies = options.TargetSpecificDecompositions, RuntimeCapabilities = options.RuntimeCapabilites, SkipMonomorphization = options.RuntimeCapabilites == RuntimeCapabilities.Unknown, GenerateFunctorSupport = true, SkipSyntaxTreeTrimming = options.TrimLevel == 0, AttemptFullPreEvaluation = options.TrimLevel > 2, DocumentationOutputFolder = options.DocFolder, BuildOutputFolder = options.OutputFolder ?? (usesPlugins ? "." : null), DllOutputPath = options.EmitDll ? " " : null, // set to e.g. an empty space to generate the dll in the same location as the .bson file IsExecutable = options.MakeExecutable, RewriteSteps = options.Plugins?.Select(step => (step, (string)null)) ?? ImmutableArray <(string, string)> .Empty, EnableAdditionalChecks = false, // todo: enable debug mode? ExposeReferencesViaTestNames = options.ExposeReferencesViaTestNames }; if (options.PerfFolder != null) { CompilationLoader.CompilationTaskEvent += CompilationTracker.OnCompilationTaskEvent; } var loaded = new CompilationLoader(options.LoadSourcesOrSnippet(logger), options.References, loadOptions, logger); if (options.PerfFolder != null) { try { CompilationTracker.PublishResults(options.PerfFolder); } catch (Exception ex) { logger.Log(ErrorCode.PublishingPerfResultsFailed, new string[] { options.PerfFolder }); logger.Log(ex); } } return(ReturnCode.Status(loaded)); } }