예제 #1
0
        public CompilationContext CompileProject(
            CompilationProjectContext projectContext,
            IEnumerable <IMetadataReference> incomingReferences,
            IEnumerable <ISourceReference> incomingSourceReferences,
            Func <IList <ResourceDescriptor> > resourcesResolver)
        {
            var path        = projectContext.ProjectDirectory;
            var name        = projectContext.Target.Name;
            var projectInfo = GetProjectInfo(projectContext.ProjectFilePath);

            if (_cacheContextAccessor.Current != null)
            {
                _cacheContextAccessor.Current.Monitor(new FileWriteTimeCacheDependency(projectContext.ProjectFilePath));

                // Monitor the trigger {projectName}_BuildOutputs
                var buildOutputsName = name + "_BuildOutputs";

                _cacheContextAccessor.Current.Monitor(_namedDependencyProvider.GetNamedDependency(buildOutputsName));
                _cacheContextAccessor.Current.Monitor(_namedDependencyProvider.GetNamedDependency(name + "_Dependencies"));
            }

            Logger.TraceInformation("[{0}]: Compiling '{1}'", GetType().Name, name);
            var sw = Stopwatch.StartNew();

            CompilationContext context;

            using (new ResolveHooker())
                using (var files = new TempFiles())
                {
                    var outFileName = $"{name}.dll";
                    var outDir      = files.CreateDir();
                    var outFile     = Path.Combine(outDir, outFileName);
                    var args        = new List <string>();
                    args.Add("fsc.exe");
                    args.Add($"--out:{outFile}");
                    args.Add("--target:library");
                    args.Add("--noframework");
                    args.Add("--optimize-");
                    args.Add("--debug");
                    if (SupportsPdbGeneration)
                    {
                        args.Add($"--pdb:{Path.ChangeExtension(outFile, ".pdb")}");
                    }
                    args.Add($"--doc:{Path.ChangeExtension(outFile, ".xml")}");
                    args.AddRange(projectInfo.Files);

                    // These are the metadata references being used by your project.
                    // Everything in your project.json is resolved and normailzed here:
                    // - Project references
                    // - Package references are turned into the appropriate assemblies
                    // Each IMetadaReference maps to an assembly
                    foreach (var reference in incomingReferences)
                    {
                        string fileName   = null;
                        var    projectRef = reference as IMetadataProjectReference;
                        if (projectRef != null)
                        {
                            var dir = files.CreateDir();
                            projectRef.EmitAssembly(dir);
                            fileName = Path.Combine(dir, $"{projectRef.Name}.dll");
                        }

                        var fileRef = reference as IMetadataFileReference;
                        if (fileRef != null)
                        {
                            fileName = fileRef.Path;
                        }
                        else if (fileName == null)
                        {
                            throw new Exception($"Unknown reference type {reference.GetType()}");
                        }

                        args.Add($"-r:{fileName}");
                    }

                    //Console.WriteLine(string.Join(Environment.NewLine, args));
                    var scs        = new SimpleSourceCodeServices();
                    var result     = scs.Compile(args.ToArray());
                    var errors     = result.Item1.Select(FSharpDiagnosticMessage.CompilationMessage);
                    var resultCode = result.Item2;

                    //System.Diagnostics.Debugger.Launch();
                    MemoryStream assembly = null;
                    MemoryStream pdb      = null;
                    MemoryStream xml      = null;
                    if (resultCode == 0)
                    {
                        assembly = new MemoryStream();
                        xml      = new MemoryStream();

                        using (var fs = File.OpenRead(outFile))
                            fs.CopyTo(assembly);

                        var pdbFile = Path.ChangeExtension(outFile, ".pdb");
                        if (File.Exists(pdbFile))
                        {
                            pdb = new MemoryStream();
                            using (var fs = File.OpenRead(pdbFile))
                                fs.CopyTo(pdb);
                        }

                        var xmlFile = Path.ChangeExtension(outFile, ".xml");
                        if (File.Exists(xmlFile))
                        {
                            xml = new MemoryStream();
                            using (var fs = File.OpenRead(xmlFile))
                                fs.CopyTo(xml);
                        }
                    }

                    context = new CompilationContext(
                        projectContext,
                        projectInfo,
                        resultCode == 0,
                        errors,
                        assembly?.ToArray(),
                        pdb?.ToArray(),
                        xml?.ToArray());

                    assembly?.Dispose();
                    pdb?.Dispose();
                    xml?.Dispose();
                }

            sw.Stop();
            Logger.TraceInformation("[{0}]: Compiled '{1}' in {2}ms", GetType().Name, name, sw.ElapsedMilliseconds);

            return(context);
        }
예제 #2
0
        public CompilationContext CompileProject(
      CompilationProjectContext projectContext,
      IEnumerable<IMetadataReference> incomingReferences,
      IEnumerable<ISourceReference> incomingSourceReferences,
      Func<IList<ResourceDescriptor>> resourcesResolver)
        {
            var path = projectContext.ProjectDirectory;
              var name = projectContext.Target.Name;
              var projectInfo = GetProjectInfo(projectContext.ProjectFilePath);

              if (_cacheContextAccessor.Current != null)
              {
            _cacheContextAccessor.Current.Monitor(new FileWriteTimeCacheDependency(projectContext.ProjectFilePath));

            // Monitor the trigger {projectName}_BuildOutputs
            var buildOutputsName = name + "_BuildOutputs";

            _cacheContextAccessor.Current.Monitor(_namedDependencyProvider.GetNamedDependency(buildOutputsName));
            _cacheContextAccessor.Current.Monitor(_namedDependencyProvider.GetNamedDependency(name + "_Dependencies"));
              }

              Logger.TraceInformation("[{0}]: Compiling '{1}'", GetType().Name, name);
              var sw = Stopwatch.StartNew();

              CompilationContext context;
              using (new ResolveHooker())
              using (var files = new TempFiles())
              {
            var outFileName = $"{name}.dll";
            var outDir = files.CreateDir();
            var outFile = Path.Combine(outDir, outFileName);
            var args = new List<string>();
            args.Add("fsc.exe");
            args.Add($"--out:{outFile}");
            args.Add("--target:library");
            args.Add("--noframework");
            args.Add("--optimize-");
            args.Add("--debug");
            if (SupportsPdbGeneration)
              args.Add($"--pdb:{Path.ChangeExtension(outFile, ".pdb")}");
            args.Add($"--doc:{Path.ChangeExtension(outFile, ".xml")}");
            args.AddRange(projectInfo.Files);

            // These are the metadata references being used by your project.
            // Everything in your project.json is resolved and normailzed here:
            // - Project references
            // - Package references are turned into the appropriate assemblies
            // Each IMetadaReference maps to an assembly
            foreach (var reference in incomingReferences)
            {
              string fileName = null;
              var projectRef = reference as IMetadataProjectReference;
              if (projectRef != null)
              {
            var dir = files.CreateDir();
            projectRef.EmitAssembly(dir);
            fileName = Path.Combine(dir, $"{projectRef.Name}.dll");
              }

              var fileRef = reference as IMetadataFileReference;
              if (fileRef != null)
            fileName = fileRef.Path;
              else if (fileName == null)
            throw new Exception($"Unknown reference type {reference.GetType()}");

              args.Add($"-r:{fileName}");
            }

            //Console.WriteLine(string.Join(Environment.NewLine, args));
            var scs = new SimpleSourceCodeServices();
            var result = scs.Compile(args.ToArray());
            var errors = result.Item1.Select(FSharpDiagnosticMessage.CompilationMessage);
            var resultCode = result.Item2;

            //System.Diagnostics.Debugger.Launch();
            MemoryStream assembly = null;
            MemoryStream pdb = null;
            MemoryStream xml = null;
            if (resultCode == 0)
            {
              assembly = new MemoryStream();
              xml = new MemoryStream();

              using (var fs = File.OpenRead(outFile))
            fs.CopyTo(assembly);

              var pdbFile = Path.ChangeExtension(outFile, ".pdb");
              if (File.Exists(pdbFile))
              {
            pdb = new MemoryStream();
            using (var fs = File.OpenRead(pdbFile))
              fs.CopyTo(pdb);
              }

              var xmlFile = Path.ChangeExtension(outFile, ".xml");
              if (File.Exists(xmlFile))
              {
            xml = new MemoryStream();
            using (var fs = File.OpenRead(xmlFile))
              fs.CopyTo(xml);
              }
            }

            context = new CompilationContext(
              projectContext,
              projectInfo,
              resultCode == 0,
              errors,
              assembly?.ToArray(),
              pdb?.ToArray(),
              xml?.ToArray());

            assembly?.Dispose();
            pdb?.Dispose();
            xml?.Dispose();
              }

              sw.Stop();
              Logger.TraceInformation("[{0}]: Compiled '{1}' in {2}ms", GetType().Name, name, sw.ElapsedMilliseconds);

              return context;
        }