예제 #1
0
        public CompilationEngine(
            CompilationCache compilationCache, 
            CompilationEngineContext context)
        {
            _context = context;
            RootLibraryExporter = new LibraryExporter(_context.LibraryManager, this, _context.TargetFramework, _context.Configuration);
            _compilerLoadContext = new Lazy<IAssemblyLoadContext>(() =>
            {
                var factory = (IAssemblyLoadContextFactory)_context.Services.GetService(typeof(IAssemblyLoadContextFactory));

                // Ensure this compilation engine is in the service provider
                var services = new ServiceProvider(_context.Services);
                services.Add(typeof(ICompilationEngine), this);
                return factory.Create(services);
            });

            CompilationCache = compilationCache;

            // Register compiler services
            // TODO(anurse): Switch to project factory model to avoid needing to do this.
            _context.AddService(typeof(ICache), CompilationCache.Cache);
            _context.AddService(typeof(ICacheContextAccessor), CompilationCache.CacheContextAccessor);
            _context.AddService(typeof(INamedCacheDependencyProvider), CompilationCache.NamedCacheDependencyProvider);
            _context.AddService(typeof(IFileWatcher), context.FileWatcher);
        }
예제 #2
0
        public BuildContext(CompilationEngine compilationEngine,
                            Runtime.Project project,
                            FrameworkName targetFramework,
                            string configuration,
                            string outputPath)
        {
            _project = project;
            _targetFramework = targetFramework;
            _configuration = configuration;
            _targetFrameworkFolder = VersionUtility.GetShortFrameworkName(_targetFramework);
            _outputPath = Path.Combine(outputPath, _targetFrameworkFolder);

            _libraryExporter = compilationEngine.CreateProjectExporter(
                _project, _targetFramework, _configuration);

            _libraryManager = _libraryExporter.LibraryManager;
        }
예제 #3
0
        private LibraryExport ExportProject(ProjectDescription project, string aspect, LibraryExporter exporter)
        {
            Logger.TraceInformation($"[{nameof(LibraryExporter)}]: {nameof(ExportProject)}({project.Identity.Name}, {aspect}, {project.Framework}, {_configuration})");

            var key = Tuple.Create(project.Identity.Name, project.Framework, _configuration, aspect);

            return(_compilationEngine.CompilationCache.Cache.Get <LibraryExport>(key, ctx =>
            {
                var metadataReferences = new List <IMetadataReference>();
                var sourceReferences = new List <ISourceReference>();

                // Create the compilation context
                var compilationContext = project.Project.ToCompilationContext(project.Framework, _configuration, aspect);

                if (!string.IsNullOrEmpty(project.TargetFrameworkInfo.AssemblyPath))
                {
                    // Project specifies a pre-compiled binary. We're done!

                    var assemblyPath = ResolvePath(project.Project, _configuration, project.TargetFrameworkInfo.AssemblyPath);
                    var pdbPath = ResolvePath(project.Project, _configuration, project.TargetFrameworkInfo.PdbPath);

                    metadataReferences.Add(new CompiledProjectMetadataReference(compilationContext, assemblyPath, pdbPath));
                }
                else
                {
                    // We need to compile the project.
                    var compilerTypeInfo = project.Project.CompilerServices?.ProjectCompiler ?? Project.DefaultCompiler;

                    // Create the project exporter
                    exporter = exporter ?? _compilationEngine.CreateProjectExporter(project.Project, project.Framework, _configuration);

                    // Get the exports for the project dependencies
                    var projectDependenciesExport = new Lazy <LibraryExport>(() => exporter.GetAllDependencies(project.Identity.Name, aspect));

                    // Find the project compiler
                    var projectCompiler = _compilationEngine.GetCompiler(compilerTypeInfo, exporter._loadContext);

                    Logger.TraceInformation($"[{nameof(LibraryExporter)}]: GetProjectReference({compilerTypeInfo.TypeName}, {project.Identity.Name}, {project.Framework}, {aspect})");

                    // Resolve the project export
                    IMetadataProjectReference projectReference = projectCompiler.CompileProject(
                        compilationContext,
                        () => projectDependenciesExport.Value,
                        () => CompositeResourceProvider.Default.GetResources(project.Project));

                    metadataReferences.Add(projectReference);

                    // Shared sources
                    foreach (var sharedFile in project.Project.Files.SharedFiles)
                    {
                        sourceReferences.Add(new SourceFileReference(sharedFile));
                    }
                }

                return new LibraryExport(metadataReferences, sourceReferences);
            }));
        }
예제 #4
0
        private static DependencyInformation ResolveDependencyInfo(DnxProject project, FrameworkName frameworkName)
        {
            var cacheKey = Tuple.Create("DependencyInformation", project.Name, "Debug", frameworkName);

            return cache.Get<DependencyInformation>(cacheKey, ctx =>
            {
                var applicationHostContext = GetApplicationHostContext(project, "Debug", frameworkName);

                var info = new DependencyInformation
                {
                    HostContext = applicationHostContext,
                    ProjectReferences = new List<ProjectReference>(),
                    References = new List<string>(),
                    ExportedSourcesFiles = new List<string>()
                };

                foreach (var library in applicationHostContext.LibraryManager.GetLibraryDescriptions())
                {
                    // Skip unresolved libraries
                    if (!library.Resolved)
                    {
                        continue;
                    }

                    if (string.Equals(library.Type, "Project") &&
                       !string.Equals(library.Identity.Name, project.Name))
                    {
                        DnxProject referencedProject = GetProject(library.Path);

                        if (referencedProject == null)
                        {
                            // Should never happen
                            continue;
                        }

                        var targetFrameworkInformation = referencedProject.GetTargetFramework(library.Framework);

                        // If this is an assembly reference then treat it like a file reference
                        if (!string.IsNullOrEmpty(targetFrameworkInformation.AssemblyPath) &&
                            string.IsNullOrEmpty(targetFrameworkInformation.WrappedProject))
                        {
                            string assemblyPath = GetProjectRelativeFullPath(referencedProject, targetFrameworkInformation.AssemblyPath);
                            info.References.Add(assemblyPath);
                        }
                        else
                        {
                            string wrappedProjectPath = null;

                            if (!string.IsNullOrEmpty(targetFrameworkInformation.WrappedProject))
                            {
                                wrappedProjectPath = GetProjectRelativeFullPath(referencedProject, targetFrameworkInformation.WrappedProject);
                            }

                            info.ProjectReferences.Add(new ProjectReference
                            {
                                Name = referencedProject.Name,
                                Framework = library.Framework,
                                Path = library.Path,
                                WrappedProjectPath = wrappedProjectPath,
                                Project = referencedProject
                            });
                        }
                    }
                }

                var libraryExporter = new LibraryExporter(
                    applicationHostContext.LibraryManager,
                    null,
                    "Debug");

                var exportWithoutProjects = libraryExporter.GetNonProjectExports(project.Name);

                foreach (var reference in exportWithoutProjects.MetadataReferences)
                {
                    var fileReference = reference as IMetadataFileReference;
                    if (fileReference != null)
                    {
                        info.References.Add(fileReference.Path);
                    }
                }

                foreach (var sourceFileReference in exportWithoutProjects.SourceReferences.OfType<ISourceFileReference>())
                {
                    info.ExportedSourcesFiles.Add(sourceFileReference.Path);
                }

                return info;
            });
        }
예제 #5
0
        private LibraryExport ExportProject(ProjectDescription project, string aspect, LibraryExporter exporter)
        {
            Logger.TraceInformation($"[{nameof(LibraryExporter)}]: {nameof(ExportProject)}({project.Identity.Name}, {aspect}, {project.Framework}, {_configuration})");

            var key = Tuple.Create(project.Identity.Name, project.Framework, _configuration, aspect);

            return _compilationEngine.CompilationCache.Cache.Get<LibraryExport>(key, ctx =>
            {
                var metadataReferences = new List<IMetadataReference>();
                var sourceReferences = new List<ISourceReference>();

                // Create the compilation context
                var compilationContext = project.Project.ToCompilationContext(project.Framework, _configuration, aspect);

                if (!string.IsNullOrEmpty(project.TargetFrameworkInfo.AssemblyPath))
                {
                    // Project specifies a pre-compiled binary. We're done!

                    var assemblyPath = ResolvePath(project.Project, _configuration, project.TargetFrameworkInfo.AssemblyPath);
                    var pdbPath = ResolvePath(project.Project, _configuration, project.TargetFrameworkInfo.PdbPath);

                    metadataReferences.Add(new CompiledProjectMetadataReference(compilationContext, assemblyPath, pdbPath));
                }
                else
                {
                    // We need to compile the project.
                    var compilerTypeInfo = project.Project.CompilerServices?.ProjectCompiler ?? Project.DefaultCompiler;

                    // Create the project exporter
                    exporter = exporter ?? _compilationEngine.CreateProjectExporter(project.Project, project.Framework, _configuration);

                    // Get the exports for the project dependencies
                    var projectDependenciesExport = new Lazy<LibraryExport>(() => exporter.GetAllDependencies(project.Identity.Name, aspect));

                    // Find the project compiler
                    var projectCompiler = _compilationEngine.GetCompiler(compilerTypeInfo, exporter._loadContext);

                    Logger.TraceInformation($"[{nameof(LibraryExporter)}]: GetProjectReference({compilerTypeInfo.TypeName}, {project.Identity.Name}, {project.Framework}, {aspect})");

                    // Resolve the project export
                    IMetadataProjectReference projectReference = projectCompiler.CompileProject(
                        compilationContext,
                        () => projectDependenciesExport.Value,
                        () => CompositeResourceProvider.Default.GetResources(project.Project));

                    metadataReferences.Add(projectReference);

                    // Shared sources
                    foreach (var sharedFile in project.Project.Files.SharedFiles)
                    {
                        sourceReferences.Add(new SourceFileReference(sharedFile));
                    }
                }

                return new LibraryExport(metadataReferences, sourceReferences);
            });
        }