public TestApp Build(TestApp testApp) { RuntimeConfig runtimeConfig = null; if (File.Exists(testApp.RuntimeConfigJson)) { runtimeConfig = RuntimeConfig.FromFile(testApp.RuntimeConfigJson); } else if (RuntimeConfigCustomizer != null) { runtimeConfig = new RuntimeConfig(testApp.RuntimeConfigJson); } if (runtimeConfig != null) { RuntimeConfigCustomizer?.Invoke(runtimeConfig); runtimeConfig.Save(); } BuildContext buildContext = new BuildContext() { App = testApp }; DependencyContext dependencyContext = BuildDependencyContext(buildContext); DependencyContextWriter writer = new DependencyContextWriter(); using (FileStream stream = new FileStream(testApp.DepsJson, FileMode.Create)) { writer.Write(dependencyContext, stream); } return(testApp); }
private void EnsureToolJsonDepsFileExists( LibraryRange toolLibrary, LockFile toolLockFile, string depsPath) { if (!File.Exists(depsPath)) { var projectContext = new ProjectContextBuilder() .WithLockFile(toolLockFile) .WithTargetFramework(s_toolPackageFramework.ToString()) .Build(); var exporter = projectContext.CreateExporter(Constants.DefaultConfiguration); var dependencyContext = new DependencyContextBuilder() .Build(null, null, exporter.GetAllExports(), true, s_toolPackageFramework, string.Empty); using (var fileStream = File.Create(depsPath)) { var dependencyContextWriter = new DependencyContextWriter(); dependencyContextWriter.Write(dependencyContext, fileStream); } } }
public void WriteDeps(LibraryExporter exporter) { var path = Path.Combine(_runtimeOutputPath, _context.ProjectFile.Name + FileNameSuffixes.Deps); CreateDirectoryIfNotExists(path); File.WriteAllLines(path, exporter .GetDependencies(LibraryType.Package) .SelectMany(GenerateLines)); var compilerOptions = _context.ResolveCompilationOptions(_configuration); var includeCompile = compilerOptions.PreserveCompilationContext == true; var exports = exporter.GetAllExports().ToArray(); var dependencyContext = new DependencyContextBuilder().Build( compilerOptions: includeCompile? compilerOptions: null, compilationExports: includeCompile ? exports : null, runtimeExports: exports, portable: string.IsNullOrEmpty(_context.RuntimeIdentifier), target: _context.TargetFramework, runtime: _context.RuntimeIdentifier ?? string.Empty); var writer = new DependencyContextWriter(); var depsJsonFile = Path.Combine(_runtimeOutputPath, _context.ProjectFile.Name + FileNameSuffixes.DepsJson); using (var fileStream = File.Create(depsJsonFile)) { writer.Write(dependencyContext, fileStream); } }
private static void Write(DependencyContext context, string path) { using (FileStream stream = File.Open(path, FileMode.Create, FileAccess.Write, FileShare.Read)) { var writer = new DependencyContextWriter(); // unlike reader, writer is not disposable writer.Write(context, stream); } }
protected override void ExecuteCore() { LoadFilesToSkip(); LockFile lockFile = new LockFileCache(BuildEngine4).GetLockFile(AssetsFilePath); CompilationOptions compilationOptions = CompilationOptionsConverter.ConvertFrom(CompilerOptions); SingleProjectInfo mainProject = SingleProjectInfo.Create( ProjectPath, AssemblyName, AssemblyExtension, AssemblyVersion, AssemblySatelliteAssemblies); IEnumerable <ReferenceInfo> frameworkReferences = ReferenceInfo.CreateFrameworkReferenceInfos(ReferencePaths); IEnumerable <ReferenceInfo> directReferences = ReferenceInfo.CreateDirectReferenceInfos(ReferencePaths, ReferenceSatellitePaths); Dictionary <string, SingleProjectInfo> referenceProjects = SingleProjectInfo.CreateProjectReferenceInfos( ReferencePaths, ReferenceSatellitePaths); IEnumerable <string> excludeFromPublishAssets = PackageReferenceConverter.GetPackageIds(ExcludeFromPublishPackageReferences); ProjectContext projectContext = lockFile.CreateProjectContext( NuGetUtils.ParseFrameworkName(TargetFramework), RuntimeIdentifier, PlatformLibraryName, IsSelfContained); DependencyContext dependencyContext = new DependencyContextBuilder(mainProject, projectContext) .WithMainProjectInDepsFile(IncludeMainProject) .WithFrameworkReferences(frameworkReferences) .WithDirectReferences(directReferences) .WithReferenceProjectInfos(referenceProjects) .WithExcludeFromPublishAssets(excludeFromPublishAssets) .WithCompilationOptions(compilationOptions) .WithReferenceAssembliesPath(FrameworkReferenceResolver.GetDefaultReferenceAssembliesPath()) .WithPackagesThatWhereFiltered(GetFilteredPackages()) .Build(); if (compileFilesToSkip.Any() || runtimeFilesToSkip.Any()) { dependencyContext = TrimFilesToSkip(dependencyContext); } var writer = new DependencyContextWriter(); using (var fileStream = File.Create(DepsFilePath)) { writer.Write(dependencyContext, fileStream); } _filesWritten.Add(new TaskItem(DepsFilePath)); }
// Need to unit test this, so public public void GenerateDepsJsonFile( LockFile toolLockFile, string depsPath) { Reporter.Verbose.WriteLine($"Generating deps.json at: {depsPath}"); var projectContext = new ProjectContextBuilder() .WithLockFile(toolLockFile) .WithTargetFramework(s_toolPackageFramework.ToString()) .Build(); var exporter = projectContext.CreateExporter(Constants.DefaultConfiguration); var dependencyContext = new DependencyContextBuilder() .Build(null, null, exporter.GetAllExports(), true, s_toolPackageFramework, string.Empty); var tempDepsFile = Path.GetTempFileName(); using (var fileStream = File.Open(tempDepsFile, FileMode.Open, FileAccess.Write)) { var dependencyContextWriter = new DependencyContextWriter(); dependencyContextWriter.Write(dependencyContext, fileStream); } try { File.Copy(tempDepsFile, depsPath); } catch (Exception e) { Reporter.Verbose.WriteLine($"unable to generate deps.json, it may have been already generated: {e.Message}"); } finally { try { File.Delete(tempDepsFile); } catch (Exception e2) { Reporter.Verbose.WriteLine($"unable to delete temporary deps.json file: {e2.Message}"); } } }
public static DependencyContext Merge(string pathToFunctionEntryAssembly, string pathToFunctionAssembly) { var reader = new DependencyContextJsonReader(); var writer = new DependencyContextWriter(); var entryDependencies = Read(pathToFunctionEntryAssembly, reader); var functionDependencies = Read(pathToFunctionAssembly, reader); var combinedDependencies = functionDependencies.Merge(entryDependencies); using (var file = File.Open(GetDependenciesPathFromAssemblyPath(pathToFunctionEntryAssembly), FileMode.Create, FileAccess.Write)) { writer.Write(combinedDependencies, file); } return(combinedDependencies); }
internal void GenerateDepsJsonFile( LockFile toolLockFile, NuGetFramework framework, string depsPath, SingleProjectInfo toolLibrary) { Reporter.Verbose.WriteLine(string.Format( LocalizableStrings.GeneratingDepsJson, depsPath)); var dependencyContext = new DepsJsonBuilder() .Build(toolLibrary, null, toolLockFile, framework, null); var tempDepsFile = Path.GetTempFileName(); using (var fileStream = File.Open(tempDepsFile, FileMode.Open, FileAccess.Write)) { var dependencyContextWriter = new DependencyContextWriter(); dependencyContextWriter.Write(dependencyContext, fileStream); } try { File.Move(tempDepsFile, depsPath); } catch (Exception e) { Reporter.Verbose.WriteLine(string.Format( LocalizableStrings.UnableToGenerateDepsJson, e.Message)); try { File.Delete(tempDepsFile); } catch (Exception e2) { Reporter.Verbose.WriteLine(string.Format( LocalizableStrings.UnableToDeleteTemporaryDepsJson, e2.Message)); } } }
protected override void ExecuteCore() { LockFile lockFile = new LockFileCache(BuildEngine4).GetLockFile(AssetsFilePath); CompilationOptions compilationOptions = CompilationOptionsConverter.ConvertFrom(CompilerOptions); SingleProjectInfo mainProject = SingleProjectInfo.Create( ProjectPath, AssemblyName, AssemblyExtension, AssemblyVersion, AssemblySatelliteAssemblies); IEnumerable <ReferenceInfo> frameworkReferences = ReferenceInfo.CreateFrameworkReferenceInfos(ReferencePaths); Dictionary <string, SingleProjectInfo> referenceProjects = SingleProjectInfo.CreateProjectReferenceInfos( ReferencePaths, ReferenceSatellitePaths); IEnumerable <string> privateAssets = PackageReferenceConverter.GetPackageIds(PrivateAssetsPackageReferences); ProjectContext projectContext = lockFile.CreateProjectContext( NuGetUtils.ParseFrameworkName(TargetFramework), RuntimeIdentifier, PlatformLibraryName); DependencyContext dependencyContext = new DependencyContextBuilder(mainProject, projectContext) .WithFrameworkReferences(frameworkReferences) .WithReferenceProjectInfos(referenceProjects) .WithPrivateAssets(privateAssets) .WithCompilationOptions(compilationOptions) .WithReferenceAssembliesPath(FrameworkReferenceResolver.GetDefaultReferenceAssembliesPath()) .Build(); var writer = new DependencyContextWriter(); using (var fileStream = File.Create(DepsFilePath)) { writer.Write(dependencyContext, fileStream); } _filesWritten.Add(new TaskItem(DepsFilePath)); }
public override bool Execute() { LoadConflicts(); DependencyContext sourceDeps; using (var sourceStream = File.Open(DepsFilePath, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete)) { sourceDeps = new DependencyContextJsonReader().Read(sourceStream); } DependencyContext trimmedDeps = TrimConflicts(sourceDeps); var writer = new DependencyContextWriter(); using (var fileStream = File.Create(DepsFilePath)) { writer.Write(trimmedDeps, fileStream); } return(!Log.HasLoggedErrors); }
internal void GenerateDepsJsonFile( LockFile toolLockFile, string depsPath, SingleProjectInfo toolLibrary) { Reporter.Verbose.WriteLine($"Generating deps.json at: {depsPath}"); var dependencyContext = new DepsJsonBuilder() .Build(toolLibrary, null, toolLockFile, s_toolPackageFramework, null); var tempDepsFile = Path.GetTempFileName(); using (var fileStream = File.Open(tempDepsFile, FileMode.Open, FileAccess.Write)) { var dependencyContextWriter = new DependencyContextWriter(); dependencyContextWriter.Write(dependencyContext, fileStream); } try { File.Copy(tempDepsFile, depsPath); } catch (Exception e) { Reporter.Verbose.WriteLine($"unable to generate deps.json, it may have been already generated: {e.Message}"); } finally { try { File.Delete(tempDepsFile); } catch (Exception e2) { Reporter.Verbose.WriteLine($"unable to delete temporary deps.json file: {e2.Message}"); } } }
private void WriteDeps(IEnumerable <LibraryExport> runtimeExports, IEnumerable <LibraryExport> compilationExports) { Directory.CreateDirectory(_runtimeOutputPath); var includeCompile = _compilerOptions.PreserveCompilationContext == true; var dependencyContext = new DependencyContextBuilder().Build( compilerOptions: includeCompile ? _compilerOptions : null, compilationExports: includeCompile ? compilationExports : null, runtimeExports: runtimeExports, portable: _context.IsPortable, target: _context.TargetFramework, runtime: _context.RuntimeIdentifier ?? string.Empty); var writer = new DependencyContextWriter(); var depsJsonFilePath = Path.Combine(_runtimeOutputPath, _compilerOptions.OutputName + FileNameSuffixes.DepsJson); using (var fileStream = File.Create(depsJsonFilePath)) { writer.Write(dependencyContext, fileStream); } }
private static void RemoveLibraryFromDepsJson(string depsJsonPath, string libraryName) { DependencyContext context; using (FileStream fileStream = File.Open(depsJsonPath, FileMode.Open)) { using (DependencyContextJsonReader reader = new DependencyContextJsonReader()) { context = reader.Read(fileStream); } } context = new DependencyContext(context.Target, context.CompilationOptions, context.CompileLibraries, context.RuntimeLibraries.Select(lib => new RuntimeLibrary( lib.Type, lib.Name, lib.Version, lib.Hash, lib.RuntimeAssemblyGroups.Select(assemblyGroup => new RuntimeAssetGroup( assemblyGroup.Runtime, assemblyGroup.RuntimeFiles.Where(f => !f.Path.EndsWith("SharedLibrary.dll")))).ToList().AsReadOnly(), lib.NativeLibraryGroups, lib.ResourceAssemblies, lib.Dependencies, lib.Serviceable, lib.Path, lib.HashPath, lib.RuntimeStoreManifestName)), context.RuntimeGraph); using (FileStream fileStream = File.Open(depsJsonPath, FileMode.Truncate, FileAccess.Write)) { DependencyContextWriter writer = new DependencyContextWriter(); writer.Write(context, fileStream); } }
public void WriteDeps(LibraryExporter exporter) { Directory.CreateDirectory(_runtimeOutputPath); var includeCompile = _compilerOptions.PreserveCompilationContext == true; var exports = exporter.GetAllExports().ToArray(); var dependencyContext = new DependencyContextBuilder().Build( compilerOptions: includeCompile ? _compilerOptions : null, compilationExports: includeCompile ? exports : null, runtimeExports: exports, portable: string.IsNullOrEmpty(_context.RuntimeIdentifier), target: _context.TargetFramework, runtime: _context.RuntimeIdentifier ?? string.Empty); var writer = new DependencyContextWriter(); var depsJsonFilePath = Path.Combine(_runtimeOutputPath, _compilerOptions.OutputName + FileNameSuffixes.DepsJson); using (var fileStream = File.Create(depsJsonFilePath)) { writer.Write(dependencyContext, fileStream); } }
public bool Compile(ProjectContext context, string config, string buildBasePath) { // Set up Output Paths var outputPaths = context.GetOutputPaths(config, buildBasePath); var outputPath = outputPaths.CompilationOutputPath; var intermediateOutputPath = outputPaths.IntermediateOutputDirectoryPath; Directory.CreateDirectory(outputPath); Directory.CreateDirectory(intermediateOutputPath); // Create the library exporter var exporter = context.CreateExporter(config, buildBasePath); // Gather exports for the project var dependencies = exporter.GetDependencies().ToList(); var diagnostics = new List <DiagnosticMessage>(); var missingFrameworkDiagnostics = new List <DiagnosticMessage>(); // Collect dependency diagnostics foreach (var diag in context.LibraryManager.GetAllDiagnostics()) { if (diag.ErrorCode == ErrorCodes.DOTNET1011 || diag.ErrorCode == ErrorCodes.DOTNET1012) { missingFrameworkDiagnostics.Add(diag); } diagnostics.Add(diag); } if (diagnostics.Any(d => d.Severity == DiagnosticMessageSeverity.Error)) { // We got an unresolved dependency or missing framework. Don't continue the compilation. return(false); } // Get compilation options var outputName = outputPaths.CompilationFiles.Assembly; var compilationOptions = context.ResolveCompilationOptions(config); // Set default platform if it isn't already set and we're on desktop if (compilationOptions.EmitEntryPoint == true && string.IsNullOrEmpty(compilationOptions.Platform) && context.TargetFramework.IsDesktop()) { // See https://github.com/dotnet/cli/issues/2428 for more details. compilationOptions.Platform = RuntimeInformation.ProcessArchitecture == Architecture.X64 ? "x64" : "anycpu32bitpreferred"; } var references = new List <string>(); var sourceFiles = new List <string>(); // Add metadata options var assemblyInfoOptions = AssemblyInfoOptions.CreateForProject(context); foreach (var dependency in dependencies) { references.AddRange(dependency.CompilationAssemblies.Select(r => r.ResolvedPath)); sourceFiles.AddRange(dependency.SourceReferences.Select(s => s.GetTransformedFile(intermediateOutputPath))); } var resources = new List <string>(); if (compilationOptions.PreserveCompilationContext == true) { var allExports = exporter.GetAllExports().ToList(); var dependencyContext = new DependencyContextBuilder().Build(compilationOptions, allExports, allExports, false, // For now, just assume non-portable mode in the legacy deps file (this is going away soon anyway) context.TargetFramework, context.RuntimeIdentifier ?? string.Empty); var writer = new DependencyContextWriter(); var depsJsonFile = Path.Combine(intermediateOutputPath, compilationOptions.OutputName + "dotnet-compile.deps.json"); using (var fileStream = File.Create(depsJsonFile)) { writer.Write(dependencyContext, fileStream); } resources.Add($"\"{depsJsonFile}\",{compilationOptions.OutputName}.deps.json"); } // Add project source files if (compilationOptions.CompileInclude == null) { sourceFiles.AddRange(context.ProjectFile.Files.SourceFiles); } else { var includeFiles = IncludeFilesResolver.GetIncludeFiles(compilationOptions.CompileInclude, "/", diagnostics: null); sourceFiles.AddRange(includeFiles.Select(f => f.SourcePath)); } if (String.IsNullOrEmpty(intermediateOutputPath)) { return(false); } var translated = TranslateCommonOptions(compilationOptions, outputName); var allArgs = new List <string>(translated); allArgs.AddRange(GetDefaultOptions()); // Generate assembly info var assemblyInfo = Path.Combine(intermediateOutputPath, $"dotnet-compile.assemblyinfo.cs"); File.WriteAllText(assemblyInfo, AssemblyInfoFileGenerator.GenerateCSharp(assemblyInfoOptions, sourceFiles)); allArgs.Add($"\"{assemblyInfo}\""); if (!String.IsNullOrEmpty(outputName)) { allArgs.Add($"-out:\"{outputName}\""); } allArgs.AddRange(references.Select(r => $"-r:\"{r}\"")); allArgs.AddRange(resources.Select(resource => $"-resource:{resource}")); allArgs.AddRange(sourceFiles.Select(s => $"\"{s}\"")); allArgs.Prepend($"-noconfig"); // Execute CSC! var result = RunCsc(allArgs.ToArray()) .WorkingDirectory(Directory.GetCurrentDirectory()) .ForwardStdErr() .ForwardStdOut() .Execute(); return(result.ExitCode == 0); }
public override bool Compile(ProjectContext context, BuildCommandApp args) { // Set up Output Paths var outputPaths = context.GetOutputPaths(args.ConfigValue, args.BuildBasePathValue); var outputPath = outputPaths.CompilationOutputPath; var intermediateOutputPath = outputPaths.IntermediateOutputDirectoryPath; Directory.CreateDirectory(outputPath); Directory.CreateDirectory(intermediateOutputPath); // Create the library exporter var exporter = context.CreateExporter(args.ConfigValue, args.BuildBasePathValue); // Gather exports for the project var dependencies = exporter.GetDependencies().ToList(); Reporter.Output.WriteLine($"Compiling {context.RootProject.Identity.Name.Yellow()} for {context.TargetFramework.DotNetFrameworkName.Yellow()}"); var sw = Stopwatch.StartNew(); var diagnostics = new List <DiagnosticMessage>(); var missingFrameworkDiagnostics = new List <DiagnosticMessage>(); // Collect dependency diagnostics foreach (var diag in context.LibraryManager.GetAllDiagnostics()) { if (diag.ErrorCode == ErrorCodes.DOTNET1011 || diag.ErrorCode == ErrorCodes.DOTNET1012) { missingFrameworkDiagnostics.Add(diag); } diagnostics.Add(diag); } if (diagnostics.Any(d => d.Severity == DiagnosticMessageSeverity.Error)) { // We got an unresolved dependency or missing framework. Don't continue the compilation. PrintSummary(diagnostics, sw); return(false); } // Get compilation options var outputName = outputPaths.CompilationFiles.Assembly; // Assemble args var compilerArgs = new List <string>() { $"--temp-output:{intermediateOutputPath}", $"--out:{outputName}" }; var compilationOptions = context.ResolveCompilationOptions(args.ConfigValue); // Set default platform if it isn't already set and we're on desktop if (compilationOptions.EmitEntryPoint == true && string.IsNullOrEmpty(compilationOptions.Platform) && context.TargetFramework.IsDesktop()) { // See https://github.com/dotnet/cli/issues/2428 for more details. compilationOptions.Platform = RuntimeInformation.ProcessArchitecture == Architecture.X64 ? "x64" : "anycpu32bitpreferred"; } var languageId = CompilerUtil.ResolveLanguageId(context); var references = new List <string>(); // Add compilation options to the args compilerArgs.AddRange(compilationOptions.SerializeToArgs()); // Add metadata options compilerArgs.AddRange(AssemblyInfoOptions.SerializeToArgs(AssemblyInfoOptions.CreateForProject(context))); foreach (var dependency in dependencies) { references.AddRange(dependency.CompilationAssemblies.Select(r => r.ResolvedPath)); compilerArgs.AddRange(dependency.SourceReferences.Select(s => s.GetTransformedFile(intermediateOutputPath))); foreach (var resourceFile in dependency.EmbeddedResources) { var transformedResource = resourceFile.GetTransformedFile(intermediateOutputPath); var resourceName = ResourceManifestName.CreateManifestName( Path.GetFileName(resourceFile.ResolvedPath), compilationOptions.OutputName); compilerArgs.Add($"--resource:\"{transformedResource}\",{resourceName}"); } // Add analyzer references compilerArgs.AddRange(dependency.AnalyzerReferences .Where(a => a.AnalyzerLanguage == languageId) .Select(a => $"--analyzer:{a.AssemblyPath}")); } compilerArgs.AddRange(references.Select(r => $"--reference:{r}")); if (compilationOptions.PreserveCompilationContext == true) { var allExports = exporter.GetAllExports().ToList(); var dependencyContext = new DependencyContextBuilder().Build(compilationOptions, allExports, allExports, false, // For now, just assume non-portable mode in the legacy deps file (this is going away soon anyway) context.TargetFramework, context.RuntimeIdentifier ?? string.Empty); var writer = new DependencyContextWriter(); var depsJsonFile = Path.Combine(intermediateOutputPath, compilationOptions.OutputName + "dotnet-compile.deps.json"); using (var fileStream = File.Create(depsJsonFile)) { writer.Write(dependencyContext, fileStream); } compilerArgs.Add($"--resource:\"{depsJsonFile}\",{compilationOptions.OutputName}.deps.json"); } if (!AddNonCultureResources(context.ProjectFile, compilerArgs, intermediateOutputPath, compilationOptions)) { return(false); } // Add project source files var sourceFiles = CompilerUtil.GetCompilationSources(context, compilationOptions); compilerArgs.AddRange(sourceFiles); var compilerName = compilationOptions.CompilerName; // Write RSP file var rsp = Path.Combine(intermediateOutputPath, $"dotnet-compile.rsp"); File.WriteAllLines(rsp, compilerArgs); // Run pre-compile event var contextVariables = new Dictionary <string, string>() { { "compile:TargetFramework", context.TargetFramework.GetShortFolderName() }, { "compile:FullTargetFramework", context.TargetFramework.DotNetFrameworkName }, { "compile:Configuration", args.ConfigValue }, { "compile:OutputFile", outputName }, { "compile:OutputDir", outputPath.TrimEnd('\\', '/') }, { "compile:ResponseFile", rsp } }; if (context.ProjectFile.HasRuntimeOutput(args.ConfigValue)) { var runtimeContext = args.Workspace.GetRuntimeContext(context, args.GetRuntimes()); var runtimeOutputPath = runtimeContext.GetOutputPaths(args.ConfigValue, args.BuildBasePathValue, args.OutputValue); contextVariables.Add( "compile:RuntimeOutputDir", runtimeOutputPath.RuntimeOutputPath.TrimEnd('\\', '/')); contextVariables.Add( "compile:RuntimeIdentifier", runtimeContext.RuntimeIdentifier); } _scriptRunner.RunScripts(context, ScriptNames.PreCompile, contextVariables); // Cache the reporters before invoking the command in case it is a built-in command, which replaces // the static Reporter instances. Reporter errorReporter = Reporter.Error; Reporter outputReporter = Reporter.Output; CommandResult result = _commandFactory.Create($"compile-{compilerName}", new[] { $"@{rsp}" }) .WorkingDirectory(context.ProjectDirectory) .OnErrorLine(line => HandleCompilerOutputLine(line, context, diagnostics, errorReporter)) .OnOutputLine(line => HandleCompilerOutputLine(line, context, diagnostics, outputReporter)) .Execute(); // Run post-compile event contextVariables["compile:CompilerExitCode"] = result.ExitCode.ToString(); _scriptRunner.RunScripts(context, ScriptNames.PostCompile, contextVariables); var success = result.ExitCode == 0; if (!success) { Reporter.Error.WriteLine($"{result.StartInfo.FileName} {result.StartInfo.Arguments} returned Exit Code {result.ExitCode}"); } if (success) { success &= GenerateCultureResourceAssemblies(context.ProjectFile, dependencies, outputPath, compilationOptions); } return(PrintSummary(diagnostics, sw, success)); }
internal bool CompileInternal(ProjectContext context, string config, string probingFolderPath) { // Check if ambient library if (AmbientLibraries.Contains(context.ProjectName())) { return(true); } bool compilationResult; // Check if already compiled if (_compiledLibraries.TryGetValue(context.ProjectName(), out compilationResult)) { return(compilationResult); } // Get compilation options and source files var compilationOptions = context.ResolveCompilationOptions(config); var projectSourceFiles = CompilerUtility.GetCompilationSources(context, compilationOptions); // Check if precompiled if (!projectSourceFiles.Any()) { return(_compiledLibraries[context.ProjectName()] = true); } // Set up Output Paths var outputPaths = context.GetOutputPaths(config); var outputPath = outputPaths.CompilationOutputPath; var intermediateOutputPath = outputPaths.IntermediateOutputDirectoryPath; Directory.CreateDirectory(outputPath); Directory.CreateDirectory(intermediateOutputPath); // Create the library exporter var exporter = context.CreateExporter(config); // Gather exports for the project var dependencies = exporter.GetDependencies().ToList(); // Get compilation options var outputName = outputPaths.CompilationFiles.Assembly; // Set default platform if it isn't already set and we're on desktop if (compilationOptions.EmitEntryPoint == true && String.IsNullOrEmpty(compilationOptions.Platform) && context.TargetFramework.IsDesktop()) { // See https://github.com/dotnet/cli/issues/2428 for more details. compilationOptions.Platform = RuntimeInformation.ProcessArchitecture == Architecture.X64 ? "x64" : "anycpu32bitpreferred"; } var references = new List <string>(); var sourceFiles = new List <string>(); var resources = new List <string>(); // Get the runtime directory var runtimeDirectory = Paths.GetParentFolderPath(EntryAssembly.Location); foreach (var dependency in dependencies) { sourceFiles.AddRange(dependency.SourceReferences.Select(s => s.GetTransformedFile(intermediateOutputPath))); foreach (var resourceFile in dependency.EmbeddedResources) { var transformedResource = resourceFile.GetTransformedFile(intermediateOutputPath); var resourceName = ResourceManifestName.CreateManifestName( Path.GetFileName(resourceFile.ResolvedPath), compilationOptions.OutputName); resources.Add($"\"{transformedResource}\",{resourceName}"); } var library = dependency.Library as ProjectDescription; var package = dependency.Library as PackageDescription; // Compile other referenced libraries if (library != null && !AmbientLibraries.Contains(library.Identity.Name) && dependency.CompilationAssemblies.Any()) { if (!_compiledLibraries.ContainsKey(library.Identity.Name)) { var projectContext = GetProjectContextFromPath(library.Project.ProjectDirectory); if (projectContext != null) { // Right now, if !success we try to use the last build var success = Compile(projectContext, config, probingFolderPath); } } } // Check for an unresolved library if (library != null && !library.Resolved) { var assetFileName = CompilerUtility.GetAssemblyFileName(library.Identity.Name); // Search in the runtime directory var assetResolvedPath = Path.Combine(runtimeDirectory, assetFileName); if (!File.Exists(assetResolvedPath)) { // Fallback to the project output path or probing folder assetResolvedPath = ResolveAssetPath(outputPath, probingFolderPath, assetFileName); if (String.IsNullOrEmpty(assetResolvedPath)) { // Fallback to this (possible) precompiled module bin folder var path = Path.Combine(Paths.GetParentFolderPath(library.Path), Constants.BinDirectoryName, assetFileName); assetResolvedPath = File.Exists(path) ? path : null; } } if (!String.IsNullOrEmpty(assetResolvedPath)) { references.Add(assetResolvedPath); } } // Check for an unresolved package else if (package != null && !package.Resolved) { var runtimeAssets = new HashSet <string>(package.RuntimeAssemblies.Select(x => x.Path), StringComparer.OrdinalIgnoreCase); string fallbackBinPath = null; foreach (var asset in package.CompileTimeAssemblies) { var assetFileName = Path.GetFileName(asset.Path); var isRuntimeAsset = runtimeAssets.Contains(asset.Path); // Search in the runtime directory var relativeFolderPath = isRuntimeAsset ? String.Empty : CompilerUtility.RefsDirectoryName; var assetResolvedPath = Path.Combine(runtimeDirectory, relativeFolderPath, assetFileName); if (!File.Exists(assetResolvedPath)) { // Fallback to the project output path or probing folder assetResolvedPath = ResolveAssetPath(outputPath, probingFolderPath, assetFileName, relativeFolderPath); } if (String.IsNullOrEmpty(assetResolvedPath)) { if (fallbackBinPath == null) { fallbackBinPath = String.Empty; // Fallback to a (possible) parent precompiled module bin folder var parentBinPaths = CompilerUtility.GetOtherParentProjectsLocations(context, package) .Select(x => Path.Combine(x, Constants.BinDirectoryName)); foreach (var binaryPath in parentBinPaths) { var path = Path.Combine(binaryPath, relativeFolderPath, assetFileName); if (File.Exists(path)) { assetResolvedPath = path; fallbackBinPath = binaryPath; break; } } } else if (!String.IsNullOrEmpty(fallbackBinPath)) { var path = Path.Combine(fallbackBinPath, relativeFolderPath, assetFileName); assetResolvedPath = File.Exists(path) ? path : null; } } if (!String.IsNullOrEmpty(assetResolvedPath)) { references.Add(assetResolvedPath); } } } // Check for a precompiled library else if (library != null && !dependency.CompilationAssemblies.Any()) { // Search in the project output path or probing folder var assetFileName = CompilerUtility.GetAssemblyFileName(library.Identity.Name); var assetResolvedPath = ResolveAssetPath(outputPath, probingFolderPath, assetFileName); if (String.IsNullOrEmpty(assetResolvedPath)) { // Fallback to this precompiled project output path var path = Path.Combine(CompilerUtility.GetAssemblyFolderPath(library.Project.ProjectDirectory, config, context.TargetFramework.DotNetFrameworkName), assetFileName); assetResolvedPath = File.Exists(path) ? path : null; } if (!String.IsNullOrEmpty(assetResolvedPath)) { references.Add(assetResolvedPath); } } // Check for a resolved but ambient library (compiled e.g by VS) else if (library != null && AmbientLibraries.Contains(library.Identity.Name)) { // Search in the regular project output path, fallback to the runtime directory references.AddRange(dependency.CompilationAssemblies.Select(r => File.Exists(r.ResolvedPath) ? r.ResolvedPath : Path.Combine(runtimeDirectory, r.FileName))); } else { references.AddRange(dependency.CompilationAssemblies.Select(r => r.ResolvedPath)); } } // Check again if already compiled, here through the dependency graph if (_compiledLibraries.TryGetValue(context.ProjectName(), out compilationResult)) { return(compilationResult); } var sw = Stopwatch.StartNew(); string depsJsonFile = null; DependencyContext dependencyContext = null; // Add dependency context as a resource if (compilationOptions.PreserveCompilationContext == true) { var allExports = exporter.GetAllExports().ToList(); var exportsLookup = allExports.ToDictionary(e => e.Library.Identity.Name); var buildExclusionList = context.GetTypeBuildExclusionList(exportsLookup); var filteredExports = allExports .Where(e => e.Library.Identity.Type.Equals(LibraryType.ReferenceAssembly) || !buildExclusionList.Contains(e.Library.Identity.Name)); dependencyContext = new DependencyContextBuilder().Build(compilationOptions, filteredExports, filteredExports, false, // For now, just assume non-portable mode in the legacy deps file (this is going away soon anyway) context.TargetFramework, context.RuntimeIdentifier ?? string.Empty); depsJsonFile = Path.Combine(intermediateOutputPath, compilationOptions.OutputName + "dotnet-compile.deps.json"); resources.Add($"\"{depsJsonFile}\",{compilationOptions.OutputName}.deps.json"); } // Add project source files sourceFiles.AddRange(projectSourceFiles); // Add non culture resources var resgenFiles = CompilerUtility.GetNonCultureResources(context.ProjectFile, intermediateOutputPath, compilationOptions); AddNonCultureResources(resources, resgenFiles); var translated = TranslateCommonOptions(compilationOptions, outputName); var allArgs = new List <string>(translated); allArgs.AddRange(GetDefaultOptions()); // Add assembly info var assemblyInfo = Path.Combine(intermediateOutputPath, $"dotnet-compile.assemblyinfo.cs"); allArgs.Add($"\"{assemblyInfo}\""); if (!String.IsNullOrEmpty(outputName)) { allArgs.Add($"-out:\"{outputName}\""); } allArgs.AddRange(references.Select(r => $"-r:\"{r}\"")); allArgs.AddRange(resources.Select(resource => $"-resource:{resource}")); allArgs.AddRange(sourceFiles.Select(s => $"\"{s}\"")); // Gather all compile IO var inputs = new List <string>(); var outputs = new List <string>(); inputs.Add(context.ProjectFile.ProjectFilePath); if (context.LockFile != null) { inputs.Add(context.LockFile.LockFilePath); } if (context.LockFile.ExportFile != null) { inputs.Add(context.LockFile.ExportFile.ExportFilePath); } inputs.AddRange(sourceFiles); inputs.AddRange(references); inputs.AddRange(resgenFiles.Select(x => x.InputFile)); var cultureResgenFiles = CompilerUtility.GetCultureResources(context.ProjectFile, outputPath, compilationOptions); inputs.AddRange(cultureResgenFiles.SelectMany(x => x.InputFileToMetadata.Keys)); outputs.AddRange(outputPaths.CompilationFiles.All()); outputs.AddRange(resgenFiles.Where(x => x.OutputFile != null).Select(x => x.OutputFile)); //outputs.AddRange(cultureResgenFiles.Where(x => x.OutputFile != null).Select(x => x.OutputFile)); // Locate RSP file var rsp = Path.Combine(intermediateOutputPath, $"dotnet-compile-csc.rsp"); // Check if there is no need to compile if (!CheckMissingIO(inputs, outputs) && !TimestampsChanged(inputs, outputs)) { if (File.Exists(rsp)) { // Check if the compilation context has been changed var prevInputs = new HashSet <string>(File.ReadAllLines(rsp)); var newInputs = new HashSet <string>(allArgs); if (!prevInputs.Except(newInputs).Any() && !newInputs.Except(prevInputs).Any()) { PrintMessage($"{context.ProjectName()}: Previously compiled, skipping dynamic compilation."); return(_compiledLibraries[context.ProjectName()] = true); } } else { // Write RSP file for the next time File.WriteAllLines(rsp, allArgs); PrintMessage($"{context.ProjectName()}: Previously compiled, skipping dynamic compilation."); return(_compiledLibraries[context.ProjectName()] = true); } } if (!CompilerUtility.GenerateNonCultureResources(context.ProjectFile, resgenFiles, Diagnostics)) { return(_compiledLibraries[context.ProjectName()] = false); } PrintMessage(String.Format($"{context.ProjectName()}: Dynamic compiling for {context.TargetFramework.DotNetFrameworkName}")); // Write the dependencies file if (dependencyContext != null) { var writer = new DependencyContextWriter(); using (var fileStream = File.Create(depsJsonFile)) { writer.Write(dependencyContext, fileStream); } } // Write assembly info and RSP files var assemblyInfoOptions = AssemblyInfoOptions.CreateForProject(context); File.WriteAllText(assemblyInfo, AssemblyInfoFileGenerator.GenerateCSharp(assemblyInfoOptions, sourceFiles)); File.WriteAllLines(rsp, allArgs); // Locate runtime config files var runtimeConfigPath = Path.Combine(runtimeDirectory, EntryAssembly.GetName().Name + FileNameSuffixes.RuntimeConfigJson); var cscRuntimeConfigPath = Path.Combine(runtimeDirectory, "csc" + FileNameSuffixes.RuntimeConfigJson); // Automatically create the csc runtime config file if (Files.IsNewer(runtimeConfigPath, cscRuntimeConfigPath)) { lock (_syncLock) { if (Files.IsNewer(runtimeConfigPath, cscRuntimeConfigPath)) { File.Copy(runtimeConfigPath, cscRuntimeConfigPath, true); } } } // Locate csc.dll and the csc.exe asset var cscDllPath = Path.Combine(runtimeDirectory, CompilerUtility.GetAssemblyFileName("csc")); // Search in the runtime directory var cscRelativePath = Path.Combine("runtimes", "any", "native", "csc.exe"); var cscExePath = Path.Combine(runtimeDirectory, cscRelativePath); // Fallback to the packages storage if (!File.Exists(cscExePath) && !String.IsNullOrEmpty(context.PackagesDirectory)) { cscExePath = Path.Combine(context.PackagesDirectory, CscLibrary?.Name ?? String.Empty, CscLibrary?.Version ?? String.Empty, cscRelativePath); } // Automatically create csc.dll if (Files.IsNewer(cscExePath, cscDllPath)) { lock (_syncLock) { if (Files.IsNewer(cscExePath, cscDllPath)) { File.Copy(cscExePath, cscDllPath, true); } } } // Locate the csc dependencies file var cscDepsPath = Path.Combine(runtimeDirectory, "csc.deps.json"); // Automatically create csc.deps.json if (NativePDBWriter != null && Files.IsNewer(cscDllPath, cscDepsPath)) { lock (_syncLock) { if (Files.IsNewer(cscDllPath, cscDepsPath)) { // Only reference windows native pdb writers var runtimeLibraries = new List <RuntimeLibrary>(); runtimeLibraries.Add(NativePDBWriter); DependencyContext cscDependencyContext = new DependencyContext( DependencyContext.Default.Target, CompilationOptions.Default, new List <CompilationLibrary>(), runtimeLibraries, new List <RuntimeFallbacks>()); // Write the csc.deps.json file if (cscDependencyContext != null) { var writer = new DependencyContextWriter(); using (var fileStream = File.Create(cscDepsPath)) { writer.Write(cscDependencyContext, fileStream); } } // Windows native pdb writers are outputed on dotnet publish. // But not on dotnet build during development, we do it here. // Check if there is a packages storage if (!String.IsNullOrEmpty(context.PackagesDirectory)) { var assetPaths = NativePDBWriter.NativeLibraryGroups.SelectMany(l => l.AssetPaths); foreach (var assetPath in assetPaths) { // Resolve the pdb writer from the packages storage var pdbResolvedPath = Path.Combine(context.PackagesDirectory, NativePDBWriter.Name, NativePDBWriter.Version, assetPath); var pdbOutputPath = Path.Combine(runtimeDirectory, assetPath); // Store the pdb writer in the runtime directory if (Files.IsNewer(pdbResolvedPath, pdbOutputPath)) { Directory.CreateDirectory(Paths.GetParentFolderPath(pdbOutputPath)); File.Copy(pdbResolvedPath, pdbOutputPath, true); } } } } } } // Execute CSC! var result = Command.Create("csc.dll", new string[] { $"-noconfig", "@" + $"{rsp}" }) .WorkingDirectory(runtimeDirectory) .OnErrorLine(line => Diagnostics.Add(line)) .OnOutputLine(line => Diagnostics.Add(line)) .Execute(); compilationResult = result.ExitCode == 0; if (compilationResult) { compilationResult &= CompilerUtility.GenerateCultureResourceAssemblies(context.ProjectFile, cultureResgenFiles, references, Diagnostics); } PrintMessage(String.Empty); if (compilationResult && Diagnostics.Count == 0) { PrintMessage($"{context.ProjectName()}: Dynamic compilation succeeded."); PrintMessage($"0 Warning(s)"); PrintMessage($"0 Error(s)"); } else if (compilationResult && Diagnostics.Count > 0) { PrintMessage($"{context.ProjectName()}: Dynamic compilation succeeded but has warnings."); PrintMessage($"0 Error(s)"); } else { PrintMessage($"{context.ProjectName()}: Dynamic compilation failed."); } foreach (var diagnostic in Diagnostics) { PrintMessage(diagnostic); } PrintMessage($"Time elapsed {sw.Elapsed}"); PrintMessage(String.Empty); return(_compiledLibraries[context.ProjectName()] = compilationResult); }
private void WriteDepsFile(string depsFilePath) { ProjectContext projectContext; if (AssetsFilePath == null) { projectContext = null; } else { LockFile lockFile = new LockFileCache(this).GetLockFile(AssetsFilePath); projectContext = lockFile.CreateProjectContext( TargetFramework, RuntimeIdentifier, PlatformLibraryName, RuntimeFrameworks, IsSelfContained); } CompilationOptions compilationOptions = CompilationOptionsConverter.ConvertFrom(CompilerOptions); SingleProjectInfo mainProject = SingleProjectInfo.Create( ProjectPath, AssemblyName, AssemblyExtension, AssemblyVersion, AssemblySatelliteAssemblies); var userRuntimeAssemblySet = new HashSet <string>(UserRuntimeAssemblies ?? Enumerable.Empty <string>(), StringComparer.OrdinalIgnoreCase); Func <ITaskItem, bool> isUserRuntimeAssembly = item => userRuntimeAssemblySet.Contains(item.ItemSpec); IEnumerable <ReferenceInfo> referenceAssemblyInfos = ReferenceInfo.CreateReferenceInfos(ReferenceAssemblies); // If there is a generated asset file. The projectContext will have project reference. // So remove it from directReferences to avoid duplication var projectContextHasProjectReferences = projectContext != null; IEnumerable <ReferenceInfo> directReferences = ReferenceInfo.CreateDirectReferenceInfos(ReferencePaths, ReferenceSatellitePaths, projectContextHasProjectReferences, isUserRuntimeAssembly); IEnumerable <ReferenceInfo> dependencyReferences = ReferenceInfo.CreateDependencyReferenceInfos(ReferenceDependencyPaths, ReferenceSatellitePaths, isUserRuntimeAssembly); Dictionary <string, SingleProjectInfo> referenceProjects = SingleProjectInfo.CreateProjectReferenceInfos(ReferencePaths, ReferenceSatellitePaths, isUserRuntimeAssembly); bool ShouldIncludeRuntimeAsset(ITaskItem item) { if (IsSelfContained) { if (!IsSingleFile || !item.GetMetadata(MetadataKeys.DropFromSingleFile).Equals("true")) { return(true); } } else if (item.HasMetadataValue(MetadataKeys.RuntimePackAlwaysCopyLocal, "true")) { return(true); } return(false); } IEnumerable <RuntimePackAssetInfo> runtimePackAssets = RuntimePackAssets.Where(ShouldIncludeRuntimeAsset).Select(RuntimePackAssetInfo.FromItem); DependencyContextBuilder builder; if (projectContext != null) { // Generate the RID-fallback for self-contained builds. // // In order to support loading components with RID-specific assets, // the AssemblyDependencyResolver requires a RID fallback graph. // The component itself should not carry the RID fallback graph with it, because // it would need to carry graph of all the RIDs and needs updates for newer RIDs. // For framework dependent apps, the RID fallback graph comes from the core framework Microsoft.NETCore.App, // so there is no need to write it into the app. // If self-contained apps, the (applicable subset of) RID fallback graph needs to be written to the deps.json manifest. // // If a RID-graph is provided to the DependencyContextBuilder, it generates a RID-fallback // graph with respect to the target RuntimeIdentifier. RuntimeGraph runtimeGraph = IsSelfContained ? new RuntimeGraphCache(this).GetRuntimeGraph(RuntimeGraphPath) : null; builder = new DependencyContextBuilder(mainProject, IncludeRuntimeFileVersions, runtimeGraph, projectContext); } else { builder = new DependencyContextBuilder( mainProject, IncludeRuntimeFileVersions, RuntimeFrameworks, isSelfContained: IsSelfContained, platformLibraryName: PlatformLibraryName, runtimeIdentifier: RuntimeIdentifier, targetFramework: TargetFramework); } builder = builder .WithMainProjectInDepsFile(IncludeMainProject) .WithReferenceAssemblies(referenceAssemblyInfos) .WithDirectReferences(directReferences) .WithDependencyReferences(dependencyReferences) .WithReferenceProjectInfos(referenceProjects) .WithRuntimePackAssets(runtimePackAssets) .WithCompilationOptions(compilationOptions) .WithReferenceAssembliesPath(FrameworkReferenceResolver.GetDefaultReferenceAssembliesPath()) .WithPackagesThatWereFiltered(GetFilteredPackages()); if (CompileReferences.Length > 0) { builder = builder.WithCompileReferences(ReferenceInfo.CreateReferenceInfos(CompileReferences)); } var resolvedNuGetFiles = ResolvedNuGetFiles.Select(f => new ResolvedFile(f, false)) .Concat(ResolvedRuntimeTargetsFiles.Select(f => new ResolvedFile(f, true))); builder = builder.WithResolvedNuGetFiles(resolvedNuGetFiles); DependencyContext dependencyContext = builder.Build(); var writer = new DependencyContextWriter(); using (var fileStream = File.Create(depsFilePath)) { writer.Write(dependencyContext, fileStream); } _filesWritten.Add(new TaskItem(depsFilePath)); }
private static bool CompileProject(ProjectContext context, CompilerCommandApp args) { // Set up Output Paths var outputPathCalculator = context.GetOutputPathCalculator(args.OutputValue); var outputPath = outputPathCalculator.GetOutputDirectoryPath(args.ConfigValue); var intermediateOutputPath = outputPathCalculator.GetIntermediateOutputDirectoryPath(args.ConfigValue, args.IntermediateValue); Directory.CreateDirectory(outputPath); Directory.CreateDirectory(intermediateOutputPath); // Create the library exporter var exporter = context.CreateExporter(args.ConfigValue); // Gather exports for the project var dependencies = exporter.GetDependencies().ToList(); Reporter.Output.WriteLine($"Compiling {context.RootProject.Identity.Name.Yellow()} for {context.TargetFramework.DotNetFrameworkName.Yellow()}"); var sw = Stopwatch.StartNew(); var diagnostics = new List <DiagnosticMessage>(); var missingFrameworkDiagnostics = new List <DiagnosticMessage>(); // Collect dependency diagnostics foreach (var diag in context.LibraryManager.GetAllDiagnostics()) { if (diag.ErrorCode == ErrorCodes.DOTNET1011 || diag.ErrorCode == ErrorCodes.DOTNET1012) { missingFrameworkDiagnostics.Add(diag); } diagnostics.Add(diag); } if (missingFrameworkDiagnostics.Count > 0) { // The framework isn't installed so we should short circuit the rest of the compilation // so we don't get flooded with errors PrintSummary(missingFrameworkDiagnostics, sw); return(false); } // Get compilation options var outputName = outputPathCalculator.GetAssemblyPath(args.ConfigValue); // Assemble args var compilerArgs = new List <string>() { $"--temp-output:\"{intermediateOutputPath}\"", $"--out:\"{outputName}\"" }; var compilationOptions = CompilerUtil.ResolveCompilationOptions(context, args.ConfigValue); var languageId = CompilerUtil.ResolveLanguageId(context); var references = new List <string>(); // Add compilation options to the args compilerArgs.AddRange(compilationOptions.SerializeToArgs()); // Add metadata options compilerArgs.AddRange(AssemblyInfoOptions.SerializeToArgs(AssemblyInfoOptions.CreateForProject(context))); foreach (var dependency in dependencies) { references.AddRange(dependency.CompilationAssemblies.Select(r => r.ResolvedPath)); compilerArgs.AddRange(dependency.SourceReferences.Select(s => $"\"{s}\"")); // Add analyzer references compilerArgs.AddRange(dependency.AnalyzerReferences .Where(a => a.AnalyzerLanguage == languageId) .Select(a => $"--analyzer:\"{a.AssemblyPath}\"")); } compilerArgs.AddRange(references.Select(r => $"--reference:\"{r}\"")); if (compilationOptions.PreserveCompilationContext == true) { var dependencyContext = DependencyContextBuilder.Build(compilationOptions, exporter, args.ConfigValue, context.TargetFramework, context.RuntimeIdentifier); var writer = new DependencyContextWriter(); var depsJsonFile = Path.Combine(intermediateOutputPath, context.ProjectFile.Name + "dotnet-compile.deps.json"); using (var fileStream = File.Create(depsJsonFile)) { writer.Write(dependencyContext, fileStream); } compilerArgs.Add($"--resource:\"{depsJsonFile},{context.ProjectFile.Name}.deps.json\""); } if (!AddNonCultureResources(context.ProjectFile, compilerArgs, intermediateOutputPath)) { return(false); } // Add project source files var sourceFiles = CompilerUtil.GetCompilationSources(context); compilerArgs.AddRange(sourceFiles); var compilerName = CompilerUtil.ResolveCompilerName(context); // Write RSP file var rsp = Path.Combine(intermediateOutputPath, $"dotnet-compile.rsp"); File.WriteAllLines(rsp, compilerArgs); // Run pre-compile event var contextVariables = new Dictionary <string, string>() { { "compile:TargetFramework", context.TargetFramework.DotNetFrameworkName }, { "compile:Configuration", args.ConfigValue }, { "compile:OutputFile", outputName }, { "compile:OutputDir", outputPath }, { "compile:ResponseFile", rsp } }; RunScripts(context, ScriptNames.PreCompile, contextVariables); var result = Command.CreateDotNet($"compile-{compilerName}", new[] { "@" + $"{rsp}" }) .OnErrorLine(line => { var diagnostic = ParseDiagnostic(context.ProjectDirectory, line); if (diagnostic != null) { diagnostics.Add(diagnostic); } else { Reporter.Error.WriteLine(line); } }) .OnOutputLine(line => { var diagnostic = ParseDiagnostic(context.ProjectDirectory, line); if (diagnostic != null) { diagnostics.Add(diagnostic); } else { Reporter.Output.WriteLine(line); } }).Execute(); // Run post-compile event contextVariables["compile:CompilerExitCode"] = result.ExitCode.ToString(); RunScripts(context, ScriptNames.PostCompile, contextVariables); var success = result.ExitCode == 0; if (!success) { Reporter.Error.WriteLine($"{result.StartInfo.FileName} {result.StartInfo.Arguments} returned Exit Code {result.ExitCode}"); } if (success) { success &= GenerateCultureResourceAssemblies(context.ProjectFile, dependencies, intermediateOutputPath, outputPath); } return(PrintSummary(diagnostics, sw, success)); }
private void WriteDepsFileNew(string depsFilePath) { LockFile lockFile = new LockFileCache(this).GetLockFile(AssetsFilePath); CompilationOptions compilationOptions = CompilationOptionsConverter.ConvertFrom(CompilerOptions); SingleProjectInfo mainProject = SingleProjectInfo.Create( ProjectPath, AssemblyName, AssemblyExtension, AssemblyVersion, AssemblySatelliteAssemblies); IEnumerable <ReferenceInfo> referenceAssemblyInfos = ReferenceInfo.CreateReferenceInfos(ReferenceAssemblies); IEnumerable <ReferenceInfo> directReferences = ReferenceInfo.CreateDirectReferenceInfos(ReferencePaths, ReferenceSatellitePaths); IEnumerable <ReferenceInfo> dependencyReferences = ReferenceInfo.CreateDependencyReferenceInfos(ReferenceDependencyPaths, ReferenceSatellitePaths); Dictionary <string, SingleProjectInfo> referenceProjects = SingleProjectInfo.CreateProjectReferenceInfos( ReferencePaths, ReferenceDependencyPaths, ReferenceSatellitePaths); IEnumerable <string> excludeFromPublishAssets = PackageReferenceConverter.GetPackageIds(ExcludeFromPublishPackageReferences); IEnumerable <RuntimePackAssetInfo> runtimePackAssets = RuntimePackAssets.Select(item => RuntimePackAssetInfo.FromItem(item)); ProjectContext projectContext = lockFile.CreateProjectContext( NuGetUtils.ParseFrameworkName(TargetFramework), RuntimeIdentifier, PlatformLibraryName, RuntimeFrameworks, IsSelfContained); var builder = new DependencyContextBuilder2(mainProject, projectContext, IncludeRuntimeFileVersions); builder = builder .WithMainProjectInDepsFile(IncludeMainProject) .WithReferenceAssemblies(referenceAssemblyInfos) .WithDirectReferences(directReferences) .WithDependencyReferences(dependencyReferences) .WithReferenceProjectInfos(referenceProjects) .WithExcludeFromPublishAssets(excludeFromPublishAssets) .WithRuntimePackAssets(runtimePackAssets) .WithCompilationOptions(compilationOptions) .WithReferenceAssembliesPath(FrameworkReferenceResolver.GetDefaultReferenceAssembliesPath()) .WithPackagesThatWereFiltered(GetFilteredPackages()); if (CompileReferences.Length > 0) { builder = builder.WithCompileReferences(ReferenceInfo.CreateReferenceInfos(CompileReferences)); } var resolvedNuGetFiles = ResolvedNuGetFiles.Select(f => new ResolvedFile(f, false)) .Concat(ResolvedRuntimeTargetsFiles.Select(f => new ResolvedFile(f, true))); builder = builder.WithResolvedNuGetFiles(resolvedNuGetFiles); DependencyContext dependencyContext = builder.Build(); var writer = new DependencyContextWriter(); using (var fileStream = File.Create(depsFilePath)) { writer.Write(dependencyContext, fileStream); } _filesWritten.Add(new TaskItem(depsFilePath)); }
/// <summary> /// Fixes service configuration file to pass possible version conflicts in dependent assemblies /// </summary> /// <param name="serviceFolder"> /// The folder with installed service /// </param> /// <param name="executionFileName"> /// The service executable file name without extension /// </param> /// <param name="packageFiles"> /// The list of installed packages and their files /// </param> public static void FixAssemblyVersions(string serviceFolder, string executionFileName, Dictionary <PackageIdentity, IEnumerable <string> > packageFiles) { #if APPDOMAIN var document = new XmlDocument(); var configurationFileName = Path.Combine(serviceFolder, $"{executionFileName}.exe.config"); document.LoadXml(@"<?xml version=""1.0"" encoding=""utf-8""?> <configuration> <runtime> </runtime> </configuration> "); var documentElement = document.DocumentElement; if (documentElement == null) { Console.WriteLine($@"Configuration file {configurationFileName} is broken"); return; } documentElement = (XmlElement)documentElement.SelectSingleNode("/configuration"); if (documentElement == null) { Console.WriteLine($@"Configuration file {configurationFileName} is broken"); return; } var runTimeNode = documentElement.SelectSingleNode("./runtime") ?? documentElement.AppendChild(document.CreateElement("runtime")); var nameTable = document.NameTable; var namespaceManager = new XmlNamespaceManager(nameTable); const string Uri = "urn:schemas-microsoft-com:asm.v1"; namespaceManager.AddNamespace("urn", Uri); var assemblyBindingNode = runTimeNode.SelectSingleNode("./urn:assemblyBinding", namespaceManager) ?? runTimeNode.AppendChild(document.CreateElement("assemblyBinding", Uri)); foreach (var lib in Directory.GetFiles(Path.GetDirectoryName(configurationFileName) ?? configurationFileName, "*.dll")) { var parameters = AssemblyName.GetAssemblyName(lib); if (parameters == null) { continue; } var dependentNode = assemblyBindingNode?.SelectSingleNode( $"./urn:dependentAssembly[./urn:assemblyIdentity/@name='{parameters.Name}']", namespaceManager) ?? assemblyBindingNode?.AppendChild(document.CreateElement("dependentAssembly", Uri)); if (dependentNode == null) { continue; } dependentNode.RemoveAll(); var assemblyIdentityNode = (XmlElement)dependentNode.AppendChild(document.CreateElement("assemblyIdentity", Uri)); assemblyIdentityNode.SetAttribute("name", parameters.Name); var publicKeyToken = BitConverter.ToString(parameters.GetPublicKeyToken()) .Replace("-", string.Empty) .ToLower(CultureInfo.InvariantCulture); assemblyIdentityNode.SetAttribute("publicKeyToken", publicKeyToken); var bindingRedirectNode = (XmlElement)dependentNode.AppendChild(document.CreateElement("bindingRedirect", Uri)); bindingRedirectNode.SetAttribute("oldVersion", $"0.0.0.0-{parameters.Version}"); bindingRedirectNode.SetAttribute("newVersion", parameters.Version.ToString()); } document.Save(configurationFileName); #elif CORECLR // creating runtime config File.WriteAllText( Path.Combine(serviceFolder, $"{executionFileName}.runtimeconfig.json"), ReadTextResource(typeof(ConfigurationUtils).GetTypeInfo().Assembly, "KlusterKite.NodeManager.Launcher.Utils.Resources.runtimeconfig.json")); // creating deps.json var writer = new DependencyContextWriter(); var compilationLibraries = new CompilationLibrary[0]; var runtimeLibraries = packageFiles.Select( p => new RuntimeLibrary( "package", p.Key.Id, p.Key.Version.ToString(), string.Empty, new [] { new RuntimeAssetGroup(string.Empty, p.Value.Where(f => Path.GetExtension(f) == ".dll").Distinct()) }, new RuntimeAssetGroup[] { }, new ResourceAssembly[] { }, new Dependency[] { }, false, null, null)); var context = new DependencyContext( new TargetInfo(".NETCoreApp,Version=v1.1", string.Empty, string.Empty, true), CompilationOptions.Default, compilationLibraries, runtimeLibraries, new RuntimeFallbacks[0]); using (var stream = File.Create(Path.Combine(serviceFolder, $"{executionFileName}.deps.json"))) { writer.Write(context, stream); } #endif }
private static bool CompileProject(ProjectContext context, CompilerCommandApp args) { // Set up Output Paths string outputPath = context.GetOutputPath(args.ConfigValue, args.OutputValue); string intermediateOutputPath = context.GetIntermediateOutputPath(args.ConfigValue, args.IntermediateValue, outputPath); Directory.CreateDirectory(outputPath); Directory.CreateDirectory(intermediateOutputPath); // Create the library exporter var exporter = context.CreateExporter(args.ConfigValue); // Gather exports for the project var dependencies = exporter.GetDependencies().ToList(); Reporter.Output.WriteLine($"Compiling {context.RootProject.Identity.Name.Yellow()} for {context.TargetFramework.DotNetFrameworkName.Yellow()}"); var sw = Stopwatch.StartNew(); var diagnostics = new List <DiagnosticMessage>(); var missingFrameworkDiagnostics = new List <DiagnosticMessage>(); // Collect dependency diagnostics foreach (var diag in context.LibraryManager.GetAllDiagnostics()) { if (diag.ErrorCode == ErrorCodes.DOTNET1011 || diag.ErrorCode == ErrorCodes.DOTNET1012) { missingFrameworkDiagnostics.Add(diag); } diagnostics.Add(diag); } if (missingFrameworkDiagnostics.Count > 0) { // The framework isn't installed so we should short circuit the rest of the compilation // so we don't get flooded with errors PrintSummary(missingFrameworkDiagnostics, sw); return(false); } // Get compilation options var outputName = GetProjectOutput(context.ProjectFile, context.TargetFramework, args.ConfigValue, outputPath); // Assemble args var compilerArgs = new List <string>() { $"--temp-output:{intermediateOutputPath}", $"--out:{outputName}" }; var compilationOptions = context.ProjectFile.GetCompilerOptions(context.TargetFramework, args.ConfigValue); // Path to strong naming key in environment variable overrides path in project.json var environmentKeyFile = Environment.GetEnvironmentVariable(EnvironmentNames.StrongNameKeyFile); if (!string.IsNullOrWhiteSpace(environmentKeyFile)) { compilationOptions.KeyFile = environmentKeyFile; } else if (!string.IsNullOrWhiteSpace(compilationOptions.KeyFile)) { // Resolve full path to key file compilationOptions.KeyFile = Path.GetFullPath(Path.Combine(context.ProjectFile.ProjectDirectory, compilationOptions.KeyFile)); } var references = new List <string>(); // Add compilation options to the args compilerArgs.AddRange(compilationOptions.SerializeToArgs()); // Add metadata options compilerArgs.AddRange(AssemblyInfoOptions.SerializeToArgs(AssemblyInfoOptions.CreateForProject(context))); foreach (var dependency in dependencies) { var projectDependency = dependency.Library as ProjectDescription; if (projectDependency != null) { if (projectDependency.Project.Files.SourceFiles.Any()) { var projectOutputPath = GetProjectOutput(projectDependency.Project, projectDependency.Framework, args.ConfigValue, outputPath); references.Add(projectOutputPath); } } else { references.AddRange(dependency.CompilationAssemblies.Select(r => r.ResolvedPath)); } compilerArgs.AddRange(dependency.SourceReferences); } compilerArgs.AddRange(references.Select(r => $"--reference:{r}")); if (compilationOptions.PreserveCompilationContext == true) { var dependencyContext = DependencyContextBuilder.Build(compilationOptions, exporter, args.ConfigValue, context.TargetFramework, context.RuntimeIdentifier); var writer = new DependencyContextWriter(); var depsJsonFile = Path.Combine(intermediateOutputPath, context.ProjectFile.Name + "dotnet-compile.deps.json"); using (var fileStream = File.Create(depsJsonFile)) { writer.Write(dependencyContext, fileStream); } compilerArgs.Add($"--resource:\"{depsJsonFile}\",{context.ProjectFile.Name}.deps.json"); var refsFolder = Path.Combine(outputPath, "refs"); if (Directory.Exists(refsFolder)) { Directory.Delete(refsFolder, true); } Directory.CreateDirectory(refsFolder); foreach (var reference in references) { File.Copy(reference, Path.Combine(refsFolder, Path.GetFileName(reference))); } } if (!AddNonCultureResources(context.ProjectFile, compilerArgs, intermediateOutputPath)) { return(false); } // Add project source files var sourceFiles = context.ProjectFile.Files.SourceFiles; compilerArgs.AddRange(sourceFiles); var compilerName = CompilerUtil.ResolveCompilerName(context); // Write RSP file var rsp = Path.Combine(intermediateOutputPath, $"dotnet-compile.{context.ProjectFile.Name}.rsp"); File.WriteAllLines(rsp, compilerArgs); // Run pre-compile event var contextVariables = new Dictionary <string, string>() { { "compile:TargetFramework", context.TargetFramework.DotNetFrameworkName }, { "compile:Configuration", args.ConfigValue }, { "compile:OutputFile", outputName }, { "compile:OutputDir", outputPath }, { "compile:ResponseFile", rsp } }; RunScripts(context, ScriptNames.PreCompile, contextVariables); var result = Command.Create($"dotnet-compile-{compilerName}", $"@\"{rsp}\"") .OnErrorLine(line => { var diagnostic = ParseDiagnostic(context.ProjectDirectory, line); if (diagnostic != null) { diagnostics.Add(diagnostic); } else { Reporter.Error.WriteLine(line); } }) .OnOutputLine(line => { var diagnostic = ParseDiagnostic(context.ProjectDirectory, line); if (diagnostic != null) { diagnostics.Add(diagnostic); } else { Reporter.Output.WriteLine(line); } }).Execute(); // Run post-compile event contextVariables["compile:CompilerExitCode"] = result.ExitCode.ToString(); RunScripts(context, ScriptNames.PostCompile, contextVariables); var success = result.ExitCode == 0; if (success) { success &= GenerateCultureResourceAssemblies(context.ProjectFile, dependencies, outputPath); } if (success && !args.NoHostValue && compilationOptions.EmitEntryPoint.GetValueOrDefault()) { var rids = PlatformServices.Default.Runtime.GetAllCandidateRuntimeIdentifiers(); var runtimeContext = ProjectContext.Create(context.ProjectDirectory, context.TargetFramework, rids); runtimeContext .MakeCompilationOutputRunnable(outputPath, args.ConfigValue); } return(PrintSummary(diagnostics, sw, success)); }