diff --git a/src/QuantumSdk/Tools/BuildConfiguration/Generate.cs b/src/QuantumSdk/Tools/BuildConfiguration/Generate.cs
index d4ab25b086..ceec4a43f3 100644
--- a/src/QuantumSdk/Tools/BuildConfiguration/Generate.cs
+++ b/src/QuantumSdk/Tools/BuildConfiguration/Generate.cs
@@ -2,15 +2,28 @@
// Licensed under the MIT License.
using System;
+using System.Collections.Generic;
using System.IO;
using System.Linq;
-using System.Text;
namespace Microsoft.Quantum.Sdk.Tools
{
public static partial class BuildConfiguration
{
+ ///
+ /// Assembly names that are not compatible with the Q# compiler when loaded as a plugin.
+ ///
+ private static readonly IReadOnlyCollection IncompatibleQscReferences = new[]
+ {
+ // TODO: This is to work around an assembly that is included with the C# generation package, but which
+ // can't be loaded as a compiler reference. If the SDK gains support for packages containing a combination
+ // of assemblies that can be loaded as rewrite steps and those that can't, this should be removed.
+ //
+ // See: https://github.com/microsoft/qsharp-compiler/issues/435
+ "Microsoft.Quantum.CsharpGeneration.EntryPointDriver.dll"
+ };
+
///
/// Generates a suitable configuration file for the Q# compiler based on the given options.
/// Encountered exceptions are logged to the console, and indicated by the returned status.
@@ -24,21 +37,12 @@ public static ReturnCode Generate(Options options)
"diagnostic".Equals(options.Verbosity, StringComparison.InvariantCultureIgnoreCase) ||
"diag".Equals(options.Verbosity, StringComparison.InvariantCultureIgnoreCase);
- static (string, int) ParseQscReference(string qscRef)
- {
- var pieces = qscRef.Trim().TrimStart('(').TrimEnd(')').Split(',');
- var path = pieces.First().Trim();
- return (path, Int32.TryParse(pieces.Skip(1).SingleOrDefault(), out var priority) ? priority : 0);
- }
-
- var qscReferences = options.QscReferences?.ToArray() ?? new string[0];
- var orderedQscReferences = new string[0];
+ IEnumerable compatibleQscReferences;
+ IEnumerable incompatibleQscReferences;
try
{
- orderedQscReferences = qscReferences
- .Select(ParseQscReference)
- .OrderByDescending(qscRef => qscRef.Item2)
- .Select(qscRef => qscRef.Item1).ToArray();
+ (compatibleQscReferences, incompatibleQscReferences) =
+ ParseQscReferences(options.QscReferences ?? Array.Empty());
}
catch (Exception ex)
{
@@ -49,16 +53,45 @@ public static ReturnCode Generate(Options options)
return ReturnCode.INVALID_ARGUMENTS;
}
- return BuildConfiguration.WriteConfigFile(options.OutputFile, orderedQscReferences, verbose)
+ if (verbose)
+ {
+ foreach (var reference in incompatibleQscReferences)
+ {
+ Console.Error.WriteLine($"Skipped incompatible QSC reference: {reference}");
+ }
+ }
+ return WriteConfigFile(options.OutputFile, compatibleQscReferences, verbose)
? ReturnCode.SUCCESS
: ReturnCode.IO_EXCEPTION;
}
+ ///
+ /// Parses the QSC reference strings in the format "(path, priority)" and partitions them into compatible and
+ /// incompatible references.
+ ///
+ /// The QSC reference strings to parse.
+ /// A tuple of compatible and incompatible QSC references.
+ private static (IEnumerable, IEnumerable) ParseQscReferences(IEnumerable qscReferences)
+ {
+ static (string, int) ParseQscReference(string qscRef)
+ {
+ var pieces = qscRef.Trim().TrimStart('(').TrimEnd(')').Split(',');
+ var path = pieces.First().Trim();
+ return (path, int.TryParse(pieces.Skip(1).SingleOrDefault(), out var priority) ? priority : 0);
+ }
+ var compatible = qscReferences
+ .Select(ParseQscReference)
+ .OrderByDescending(qscRef => qscRef.Item2)
+ .Select(qscRef => qscRef.Item1)
+ .ToLookup(qscRef => !IncompatibleQscReferences.Contains(Path.GetFileName(qscRef)));
+ return (compatible[true], compatible[false]);
+ }
+
///
/// Work in progress:
/// The signature and output of this method will change in the future.
///
- private static bool WriteConfigFile(string configFile, string[] qscReferences, bool verbose = false)
+ private static bool WriteConfigFile(string configFile, IEnumerable qscReferences, bool verbose = false)
{
try
{