private static string GetAssemblyUnderTest(ProjectContext projectContext, string configuration, string outputPath) { var assemblyUnderTest = projectContext.GetOutputPaths(configuration, outputPath: outputPath).CompilationFiles.Assembly; if (!string.IsNullOrEmpty(outputPath)) { assemblyUnderTest = projectContext.GetOutputPaths(configuration, outputPath: outputPath).RuntimeFiles.Assembly; } return(assemblyUnderTest); }
private static void HandleTestExecutionStartMessage(string testRunner, Message message, ReportingChannel channel, ProjectContext projectContext, string configuration) { TestHostTracing.Source.TraceInformation("Starting Execution"); var commandArgs = new List <string> { projectContext.GetOutputPaths(configuration).CompilationFiles.Assembly }; commandArgs.AddRange(new[] { "--designtime" }); var tests = message.Payload?.ToObject <RunTestsMessage>().Tests; if (tests != null) { foreach (var test in tests) { commandArgs.Add("--test"); commandArgs.Add(test); } } ExecuteRunnerCommand(testRunner, channel, commandArgs); channel.Send(new Message() { MessageType = "TestExecution.Response", }); TestHostTracing.Source.TraceInformation("Completed Execution"); }
public static AssemblyLoadContext CreateLoadContext( this ProjectContext context, string configuration = "Debug", string outputPath = null) { var exporter = context.CreateExporter(configuration); var assemblies = new Dictionary <AssemblyName, string>(AssemblyNameComparer.OrdinalIgnoreCase); var dllImports = new Dictionary <string, string>(); foreach (var export in exporter.GetAllExports()) { // TODO: Handle resource assemblies foreach (var asset in export.RuntimeAssemblyGroups.GetDefaultAssets()) { // REVIEW: Should we use the following? // AssemblyLoadContext.GetAssemblyName(asset.ResolvedPath); var assemblyName = new AssemblyName(asset.Name); assemblies[assemblyName] = asset.ResolvedPath; } foreach (var asset in export.NativeLibraryGroups.GetDefaultAssets()) { dllImports[asset.Name] = asset.ResolvedPath; } } return(new ProjectLoadContext( assemblies, dllImports, // Add the project's output directory path to ensure project-to-project references get located new[] { context.GetOutputPaths(configuration, outputPath: outputPath).CompilationOutputPath })); }
public DotNetProjectInformation(ProjectContext projectContext, string configuration, bool includeSourceFiles = false) { this.Path = projectContext.RootProject.Path; this.Name = projectContext.ProjectFile.Name; this.TargetFramework = new DotNetFramework(projectContext.TargetFramework); var outputPaths = projectContext.GetOutputPaths(configuration); this.CompilationOutputPath = outputPaths.CompilationOutputPath; this.CompilationOutputAssemblyFile = outputPaths.CompilationFiles.Assembly; this.CompilationOutputPdbFile = outputPaths.CompilationFiles.PdbPath; var compilationOptions = projectContext.ProjectFile.GetCompilerOptions(targetFramework: projectContext.TargetFramework, configurationName: configuration); this.EmitEntryPoint = compilationOptions.EmitEntryPoint; var sourceFiles = new List <string>(); if (includeSourceFiles) { sourceFiles.AddRange(projectContext.ProjectFile.Files.SourceFiles); } this.SourceFiles = sourceFiles; }
public static AssemblyLoadContext CreateLoadContext( this ProjectContext context, string runtimeIdentifier, string configuration, string outputPath) { var exporter = context.CreateExporter(configuration); var assemblies = new Dictionary <AssemblyName, string>(AssemblyNameComparer.OrdinalIgnoreCase); var nativeLibs = new Dictionary <string, string>(); var rids = DependencyContext.Default?.RuntimeGraph ?? Enumerable.Empty <RuntimeFallbacks>(); var fallbacks = rids.FirstOrDefault(r => r.Runtime.Equals(runtimeIdentifier)); foreach (var export in exporter.GetAllExports()) { // Process managed assets var group = string.IsNullOrEmpty(runtimeIdentifier) ? export.RuntimeAssemblyGroups.GetDefaultGroup() : GetGroup(export.RuntimeAssemblyGroups, runtimeIdentifier, fallbacks); if (group != null) { foreach (var asset in group.Assets) { assemblies[asset.GetAssemblyName()] = asset.ResolvedPath; } } // Process native assets group = string.IsNullOrEmpty(runtimeIdentifier) ? export.NativeLibraryGroups.GetDefaultGroup() : GetGroup(export.NativeLibraryGroups, runtimeIdentifier, fallbacks); if (group != null) { foreach (var asset in group.Assets) { nativeLibs[asset.Name] = asset.ResolvedPath; } } // Process resource assets foreach (var asset in export.ResourceAssemblies) { var name = asset.Asset.GetAssemblyName(); name.CultureName = asset.Locale; assemblies[name] = asset.Asset.ResolvedPath; } } return(new ProjectLoadContext( assemblies, nativeLibs, // Add the project's output directory path to ensure project-to-project references get located new[] { context.GetOutputPaths(configuration, outputPath: outputPath).CompilationOutputPath })); }
public DotNetProjectContext(ProjectContext wrappedProject, string configuration, string outputPath) { _project = wrappedProject; _paths = wrappedProject.GetOutputPaths(configuration, null, outputPath); _isExecutable = wrappedProject.ProjectFile.GetCompilerOptions(wrappedProject.TargetFramework, configuration).EmitEntryPoint ?? wrappedProject.ProjectFile.GetCompilerOptions(null, configuration).EmitEntryPoint.GetValueOrDefault(); _assemblyLoadContext = wrappedProject.CreateLoadContext(configuration); Configuration = configuration; }
// computes all the inputs and outputs that would be used in the compilation of a project // ensures that all paths are files // ensures no missing inputs public CompilerIO GetCompileIO(ProjectContext project, ProjectDependenciesFacade dependencies) { var buildConfiguration = _args.ConfigValue; var buildBasePath = _args.BuildBasePathValue; var outputPath = _args.OutputValue; var isRootProject = project == _rootProject; var compilerIO = new CompilerIO(new List <string>(), new List <string>()); var calculator = project.GetOutputPaths(buildConfiguration, buildBasePath, outputPath); var binariesOutputPath = calculator.CompilationOutputPath; // input: project.json compilerIO.Inputs.Add(project.ProjectFile.ProjectFilePath); // input: lock file; find when dependencies change AddLockFile(project, compilerIO); // input: source files compilerIO.Inputs.AddRange(CompilerUtil.GetCompilationSources(project)); // todo: Factor out dependency resolution between Build and Compile. Ideally Build injects the dependencies into Compile // input: dependencies AddDependencies(dependencies, compilerIO); var allOutputPath = new HashSet <string>(calculator.CompilationFiles.All()); if (isRootProject && project.ProjectFile.HasRuntimeOutput(buildConfiguration)) { var runtimeContext = project.CreateRuntimeContext(_args.GetRuntimes()); foreach (var path in runtimeContext.GetOutputPaths(buildConfiguration, buildBasePath, outputPath).RuntimeFiles.All()) { allOutputPath.Add(path); } } // output: compiler outputs foreach (var path in allOutputPath) { compilerIO.Outputs.Add(path); } // input compilation options files AddCompilationOptions(project, buildConfiguration, compilerIO); // input / output: resources with culture AddNonCultureResources(project, calculator.IntermediateOutputDirectoryPath, compilerIO); // input / output: resources without culture AddCultureResources(project, binariesOutputPath, compilerIO); return(compilerIO); }
public static AssemblyLoadContext CreateLoadContext( [NotNull] this ProjectContext context, [NotNull] string runtimeIdentifier, [NotNull] string configuration, [CanBeNull] string outputPath = null) { var exporter = context.CreateExporter(configuration); var assemblies = new Dictionary <AssemblyName, string>(AssemblyNameComparer.OrdinalIgnoreCase); var dllImports = new Dictionary <string, string>(); var fallbacks = DependencyContext.Default.RuntimeGraph.FirstOrDefault(f => f.Runtime.Equals(runtimeIdentifier)); if (fallbacks == null) { throw new InvalidOperationException($"Failed to load runtime fallback graph for: {runtimeIdentifier}"); } foreach (var export in exporter.GetAllExports()) { var group = SelectGroup(export.RuntimeAssemblyGroups, fallbacks); // TODO: Handle resource assemblies if (group != null) { foreach (var asset in group.Assets) { // REVIEW: Should we use the following? // AssemblyLoadContext.GetAssemblyName(asset.ResolvedPath); var assemblyName = new AssemblyName(asset.Name); assemblies[assemblyName] = asset.ResolvedPath; } } group = SelectGroup(export.NativeLibraryGroups, fallbacks); if (group != null) { foreach (var asset in group.Assets) { dllImports[asset.Name] = asset.ResolvedPath; } } } return(new DesignTimeProjectLoadContext( assemblies, dllImports, // Add the project's output directory path to ensure project-to-project references get located new[] { context.GetOutputPaths(configuration, outputPath: outputPath).CompilationOutputPath })); }
public DotNetProjectContext(ProjectContext wrappedProject, string configuration, string outputPath) { Debug.Assert(wrappedProject != null, "wrappedProject is null."); Debug.Assert(!string.IsNullOrEmpty(configuration), "configuration is null or empty."); _project = wrappedProject; _paths = wrappedProject.GetOutputPaths(configuration, /* buildBasePath: */ null, outputPath); // Workaround https://github.com/dotnet/cli/issues/3164 _isExecutable = wrappedProject.ProjectFile.GetCompilerOptions(wrappedProject.TargetFramework, configuration).EmitEntryPoint ?? wrappedProject.ProjectFile.GetCompilerOptions(null, configuration).EmitEntryPoint.GetValueOrDefault(); Configuration = configuration; }
private static int RunConsole(ProjectContext projectContext, CommandLineApplication app, string testRunner, string configuration) { var commandArgs = new List <string> { projectContext.GetOutputPaths(configuration).CompilationFiles.Assembly }; commandArgs.AddRange(app.RemainingArguments); return(Command.Create($"dotnet-{GetCommandName(testRunner)}", commandArgs, projectContext.TargetFramework, configuration: configuration) .ForwardStdErr() .ForwardStdOut() .Execute() .ExitCode); }
public DotNetConfiguration(ProjectContext context, string configuration) { Name = configuration; var outputPaths = context.GetOutputPaths(configuration); this.CompilationOutputPath = outputPaths.CompilationOutputPath; this.CompilationOutputAssemblyFile = outputPaths.CompilationFiles.Assembly; this.CompilationOutputPdbFile = outputPaths.CompilationFiles.PdbPath; var compilationOptions = context.ProjectFile.GetCompilerOptions(targetFramework: context.TargetFramework, configurationName: configuration); this.EmitEntryPoint = compilationOptions.EmitEntryPoint; }
private int RunExecutable() { CalculateDefaultsForNonAssigned(); // Compile to that directory var result = Build.BuildCommand.Run(new[] { $"--framework", $"{_context.TargetFramework}", $"--configuration", Configuration, $"{_context.ProjectFile.ProjectDirectory}" }); if (result != 0) { return(result); } // Now launch the output and give it the results var outputName = _context.GetOutputPaths(Configuration).RuntimeFiles.Executable; if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { if (_context.TargetFramework.IsDesktop()) { // Run mono if we're running a desktop target on non windows _args.Insert(0, outputName); if (string.Equals(Configuration, "Debug", StringComparison.OrdinalIgnoreCase)) { // If we're compiling for the debug configuration then add the --debug flag // other options may be passed using the MONO_OPTIONS env var _args.Insert(0, "--debug"); } outputName = "mono"; } } result = Command.Create(outputName, _args) .ForwardStdOut() .ForwardStdErr() .Execute() .ExitCode; return(result); }
string ResolveOutputPath( IEnumerable <ProjectContext> frameworkContexts, BuildWorkspace workspace, string configuration, IEnumerable <string> rids) { foreach (ProjectContext frameworkContext in frameworkContexts) { ProjectContext runtimeContext = workspace.GetRuntimeContext(frameworkContext, rids); OutputPaths paths = runtimeContext.GetOutputPaths(configuration); if (File.Exists(paths.RuntimeFiles.Executable)) { return(paths.RuntimeFiles.Executable); } } return(null); }
private static void HandleTestDiscoveryStartMessage(string testRunner, ReportingChannel channel, ProjectContext projectContext, string configuration) { TestHostTracing.Source.TraceInformation("Starting Discovery"); var commandArgs = new List <string> { projectContext.GetOutputPaths(configuration).CompilationFiles.Assembly }; commandArgs.AddRange(new[] { "--list", "--designtime" }); ExecuteRunnerCommand(testRunner, channel, commandArgs); channel.Send(new Message() { MessageType = "TestDiscovery.Response", }); TestHostTracing.Source.TraceInformation("Completed Discovery"); }
public static string GetProjectName(this ProjectContext projectContext) { // _ here is just an arbitrary configuration value so we can obtain the output name return(Path.GetFileNameWithoutExtension(projectContext.GetOutputPaths("_").CompilationFiles.Assembly)); }
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); }
/// <summary> /// Publish the project for given 'framework (ex - netstandardapp1.5)' and 'runtimeID (ex - win7-x64)' /// </summary> /// <param name="context">project that is to be published</param> /// <param name="baseOutputPath">Location of published files</param> /// <param name="configuration">Debug or Release</param> /// <param name="nativeSubdirectories"></param> /// <returns>Return 0 if successful else return non-zero</returns> private bool PublishProjectContext(ProjectContext context, string buildBasePath, string outputPath, string configuration, bool nativeSubdirectories) { var target = context.TargetFramework.DotNetFrameworkName; if (!string.IsNullOrEmpty(context.RuntimeIdentifier)) { target = $"{target}/{context.RuntimeIdentifier}"; } Reporter.Output.WriteLine($"Publishing {context.RootProject.Identity.Name.Yellow()} for {target.Yellow()}"); var options = context.ProjectFile.GetCompilerOptions(context.TargetFramework, configuration); var outputPaths = context.GetOutputPaths(configuration, buildBasePath, outputPath); if (string.IsNullOrEmpty(outputPath)) { outputPath = Path.Combine(outputPaths.RuntimeOutputPath, PublishSubfolderName); } var contextVariables = new Dictionary <string, string> { { "publish:ProjectPath", context.ProjectDirectory }, { "publish:Configuration", configuration }, { "publish:OutputPath", outputPath }, { "publish:TargetFramework", context.TargetFramework.GetShortFolderName() }, { "publish:FullTargetFramework", context.TargetFramework.DotNetFrameworkName }, { "publish:Runtime", context.RuntimeIdentifier }, }; RunScripts(context, ScriptNames.PrePublish, contextVariables); if (!Directory.Exists(outputPath)) { Directory.CreateDirectory(outputPath); } // Compile the project (and transitively, all it's dependencies) if (ShouldBuild && !InvokeBuildOnProject(context, buildBasePath, configuration)) { return(false); } // Use a library exporter to collect publish assets var exporter = context.CreateExporter(configuration); var isPortable = string.IsNullOrEmpty(context.RuntimeIdentifier); // Collect all exports and organize them var exports = exporter.GetAllExports() .Where(e => e.Library.Identity.Type.Equals(LibraryType.Package)) .ToDictionary(e => e.Library.Identity.Name); var collectExclusionList = isPortable ? GetExclusionList(context, exports) : new HashSet <string>(); foreach (var export in exporter.GetAllExports().Where(e => !collectExclusionList.Contains(e.Library.Identity.Name))) { Reporter.Verbose.WriteLine($"Publishing {export.Library.Identity.ToString().Green().Bold()} ..."); PublishAssetGroups(export.RuntimeAssemblyGroups, outputPath, nativeSubdirectories: false, includeRuntimeGroups: isPortable); PublishAssetGroups(export.NativeLibraryGroups, outputPath, nativeSubdirectories, includeRuntimeGroups: isPortable); export.RuntimeAssets.StructuredCopyTo(outputPath, outputPaths.IntermediateOutputDirectoryPath); if (options.PreserveCompilationContext.GetValueOrDefault()) { PublishRefs(export, outputPath); } } if (context.ProjectFile.HasRuntimeOutput(configuration) && !context.TargetFramework.IsDesktop()) { // Get the output paths used by the call to `dotnet build` above (since we didn't pass `--output`, they will be different from // our current output paths) var buildOutputPaths = context.GetOutputPaths(configuration, buildBasePath); PublishFiles( new[] { buildOutputPaths.RuntimeFiles.DepsJson, buildOutputPaths.RuntimeFiles.RuntimeConfigJson }, outputPath); } var contentFiles = new ContentFiles(context); contentFiles.StructuredCopyTo(outputPath); // Publish a host if this is an application if (options.EmitEntryPoint.GetValueOrDefault() && !string.IsNullOrEmpty(context.RuntimeIdentifier)) { Reporter.Verbose.WriteLine($"Copying native host to output to create fully standalone output."); PublishHost(context, outputPath, options); } RunScripts(context, ScriptNames.PostPublish, contextVariables); Reporter.Output.WriteLine($"Published to {outputPath}".Green().Bold()); return(true); }
/// <summary> /// Publish the project for given 'framework (ex - dnxcore50)' and 'runtimeID (ex - win7-x64)' /// </summary> /// <param name="context">project that is to be published</param> /// <param name="baseOutputPath">Location of published files</param> /// <param name="configuration">Debug or Release</param> /// <param name="nativeSubdirectories"></param> /// <returns>Return 0 if successful else return non-zero</returns> private bool PublishProjectContext(ProjectContext context, string buildBasePath, string outputPath, string configuration, bool nativeSubdirectories) { Reporter.Output.WriteLine($"Publishing {context.RootProject.Identity.Name.Yellow()} for {context.TargetFramework.DotNetFrameworkName.Yellow()}/{context.RuntimeIdentifier.Yellow()}"); var options = context.ProjectFile.GetCompilerOptions(context.TargetFramework, configuration); if (string.IsNullOrEmpty(outputPath)) { outputPath = Path.Combine(context.GetOutputPaths(configuration, buildBasePath, outputPath).RuntimeOutputPath, PublishSubfolderName); } var contextVariables = new Dictionary <string, string> { { "publish:ProjectPath", context.ProjectDirectory }, { "publish:Configuration", configuration }, { "publish:OutputPath", outputPath }, { "publish:TargetFramework", context.TargetFramework.GetShortFolderName() }, { "publish:FullTargetFramework", context.TargetFramework.DotNetFrameworkName }, { "publish:Runtime", context.RuntimeIdentifier }, }; RunScripts(context, ScriptNames.PrePublish, contextVariables); if (!Directory.Exists(outputPath)) { Directory.CreateDirectory(outputPath); } // Compile the project (and transitively, all it's dependencies) var args = new List <string>() { "--framework", $"{context.TargetFramework.DotNetFrameworkName}", "--runtime", context.RuntimeIdentifier, "--configuration", configuration, context.ProjectFile.ProjectDirectory }; if (!string.IsNullOrEmpty(VersionSuffix)) { args.Add("--version-suffix"); args.Add(VersionSuffix); } if (!string.IsNullOrEmpty(buildBasePath)) { args.Add("--build-base-path"); args.Add(buildBasePath); } var result = Build.BuildCommand.Run(args.ToArray()); if (result != 0) { return(false); } // Use a library exporter to collect publish assets var exporter = context.CreateExporter(configuration); foreach (var export in exporter.GetAllExports()) { Reporter.Verbose.WriteLine($"Publishing {export.Library.Identity.ToString().Green().Bold()} ..."); PublishFiles(export.RuntimeAssemblies, outputPath, nativeSubdirectories: false); PublishFiles(export.NativeLibraries, outputPath, nativeSubdirectories); export.RuntimeAssets.StructuredCopyTo(outputPath); if (options.PreserveCompilationContext.GetValueOrDefault()) { PublishRefs(export, outputPath); } } var contentFiles = new ContentFiles(context); contentFiles.StructuredCopyTo(outputPath); // Publish a host if this is an application if (options.EmitEntryPoint.GetValueOrDefault()) { Reporter.Verbose.WriteLine($"Making {context.ProjectFile.Name.Cyan()} runnable ..."); PublishHost(context, outputPath); } RunScripts(context, ScriptNames.PostPublish, contextVariables); Reporter.Output.WriteLine($"Published to {outputPath}".Green().Bold()); return(true); }
internal void LoadProject(ProjectContext context) { var outputPaths = context.GetOutputPaths(Configuration); var assemblyPath = outputPaths.CompilationFiles.Assembly; var assemblyFolderPath = outputPaths.CompilationOutputPath; var libraryExporter = context.CreateExporter(Configuration); var runtimeIds = GetRuntimeIdentifiers(); foreach (var dependency in libraryExporter.GetAllExports()) { var library = dependency.Library as ProjectDescription; var package = dependency.Library as PackageDescription; // Check for an unresolved library if (library != null && !library.Resolved) { if (!IsAmbientAssembly(library.Identity.Name)) { var assetFileName = CompilerUtility.GetAssemblyFileName(library.Identity.Name); var assetResolvedPath = ResolveAssemblyPath(assemblyFolderPath, 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)) { LoadFromAssemblyPath(assetResolvedPath); PopulateBinaryFolder(assemblyFolderPath, assetResolvedPath); PopulateProbingFolder(assetResolvedPath); var resourceFileName = library.Identity.Name + ".resources.dll"; var assemblyFolderName = Paths.GetFolderName(assemblyFolderPath); var assetFolderPath = Paths.GetParentFolderPath(assetResolvedPath); var assetFolderName = Paths.GetFolderName(assetFolderPath); var resourceAssemblies = Directory.GetFiles(assetFolderPath, resourceFileName, SearchOption.AllDirectories) .Union(Directory.GetFiles(assemblyFolderPath, resourceFileName, SearchOption.AllDirectories)) .Union(Directory.GetFiles(_probingFolderPath, resourceFileName, SearchOption.AllDirectories)); foreach (var asset in resourceAssemblies) { var locale = Paths.GetParentFolderName(asset) .Replace(assetFolderName, String.Empty) .Replace(assemblyFolderName, String.Empty) .Replace(_probingDirectoryName, String.Empty); PopulateBinaryFolder(assemblyFolderPath, asset, locale); PopulateProbingFolder(asset, locale); PopulateRuntimeFolder(asset, locale); } } } } // Check for an unresolved package else if (package != null && !package.Resolved) { string fallbackBinPath = null; foreach (var asset in package.RuntimeAssemblies) { var assetName = Path.GetFileNameWithoutExtension(asset.Path); if (!IsAmbientAssembly(assetName)) { var assetFileName = Path.GetFileName(asset.Path); var assetResolvedPath = ResolveAssemblyPath(assemblyFolderPath, assetFileName); 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, assetFileName); if (File.Exists(path)) { assetResolvedPath = path; fallbackBinPath = binaryPath; break; } } } else if (!String.IsNullOrEmpty(fallbackBinPath)) { var path = Path.Combine(fallbackBinPath, assetFileName); assetResolvedPath = File.Exists(path) ? path : null; } } if (!String.IsNullOrEmpty(assetResolvedPath)) { LoadFromAssemblyPath(assetResolvedPath); PopulateBinaryFolder(assemblyFolderPath, assetResolvedPath); PopulateProbingFolder(assetResolvedPath); } } } foreach (var asset in package.RuntimeTargets) { var assetName = Path.GetFileNameWithoutExtension(asset.Path); if (!IsAmbientAssembly(assetName)) { var assetFileName = Path.GetFileName(asset.Path); var relativeFolderPath = !String.IsNullOrEmpty(asset.Runtime) ? Paths.GetParentFolderPath(asset.Path) : String.Empty; var assetResolvedPath = ResolveAssemblyPath(assemblyFolderPath, assetFileName, relativeFolderPath); if (String.IsNullOrEmpty(assetResolvedPath) && !String.IsNullOrEmpty(fallbackBinPath)) { var path = Path.Combine(fallbackBinPath, relativeFolderPath, assetFileName); assetResolvedPath = File.Exists(path) ? path : null; } if (!String.IsNullOrEmpty(assetResolvedPath)) { if (runtimeIds.Contains(asset.Runtime)) { LoadFromAssemblyPath(assetResolvedPath); } PopulateBinaryFolder(assemblyFolderPath, assetResolvedPath, relativeFolderPath); PopulateProbingFolder(assetResolvedPath, relativeFolderPath); } } } var runtimeAssets = new HashSet <string>(package.RuntimeAssemblies.Select(x => x.Path), StringComparer.OrdinalIgnoreCase); foreach (var asset in package.CompileTimeAssemblies) { var assetFileName = Path.GetFileName(asset.Path); if (!IsAmbientAssembly(assetFileName) && !runtimeAssets.Contains(asset.Path)) { var assetResolvedPath = ResolveAssemblyPath(assemblyFolderPath, assetFileName, CompilerUtility.RefsDirectoryName); if (String.IsNullOrEmpty(assetResolvedPath) && !String.IsNullOrEmpty(fallbackBinPath)) { var path = Path.Combine(fallbackBinPath, CompilerUtility.RefsDirectoryName, assetFileName); assetResolvedPath = File.Exists(path) ? path : null; } if (!String.IsNullOrEmpty(assetResolvedPath)) { _compileOnlyAssemblies[assetFileName] = assetResolvedPath; PopulateBinaryFolder(assemblyFolderPath, assetResolvedPath, CompilerUtility.RefsDirectoryName); PopulateProbingFolder(assetResolvedPath, CompilerUtility.RefsDirectoryName); } } } if (!IsAmbientAssembly(package.Identity.Name)) { foreach (var asset in package.ResourceAssemblies) { string locale; if (asset.Properties.TryGetValue(CompilerUtility.LocaleLockFilePropertyName, out locale)) { var assetFileName = Path.GetFileName(asset.Path); var assetResolvedPath = ResolveAssemblyPath(assemblyFolderPath, assetFileName, locale); if (String.IsNullOrEmpty(assetResolvedPath) && !String.IsNullOrEmpty(fallbackBinPath)) { var path = Path.Combine(fallbackBinPath, locale, assetFileName); assetResolvedPath = File.Exists(path) ? path : null; } if (!String.IsNullOrEmpty(assetResolvedPath)) { PopulateBinaryFolder(assemblyFolderPath, assetResolvedPath, locale); PopulateProbingFolder(assetResolvedPath, locale); PopulateRuntimeFolder(assetResolvedPath, locale); } } } } } // Check for a precompiled library else if (library != null && !dependency.RuntimeAssemblyGroups.Any()) { if (!IsAmbientAssembly(library.Identity.Name)) { var assetFileName = CompilerUtility.GetAssemblyFileName(library.Identity.Name); var assetResolvedPath = ResolveAssemblyPath(assemblyFolderPath, assetFileName); if (String.IsNullOrEmpty(assetResolvedPath)) { // Fallback to this precompiled project output path var outputPath = CompilerUtility.GetAssemblyFolderPath(library.Project.ProjectDirectory, Configuration, context.TargetFramework.DotNetFrameworkName); var path = Path.Combine(outputPath, assetFileName); assetResolvedPath = File.Exists(path) ? path : null; } if (!String.IsNullOrEmpty(assetResolvedPath)) { LoadFromAssemblyPath(assetResolvedPath); PopulateBinaryFolder(assemblyFolderPath, assetResolvedPath); PopulateProbingFolder(assetResolvedPath); var resourceFileName = library.Identity.Name + ".resources.dll"; var assemblyFolderName = Paths.GetFolderName(assemblyFolderPath); var assetFolderPath = Paths.GetParentFolderPath(assetResolvedPath); var assetFolderName = Paths.GetFolderName(assetFolderPath); var resourceAssemblies = Directory.GetFiles(assetFolderPath, resourceFileName, SearchOption.AllDirectories) .Union(Directory.GetFiles(assemblyFolderPath, resourceFileName, SearchOption.AllDirectories)) .Union(Directory.GetFiles(_probingFolderPath, resourceFileName, SearchOption.AllDirectories)); foreach (var asset in resourceAssemblies) { var locale = Paths.GetParentFolderName(asset) .Replace(assetFolderName, String.Empty) .Replace(assemblyFolderName, String.Empty) .Replace(_probingDirectoryName, String.Empty); PopulateBinaryFolder(assemblyFolderPath, asset, locale); PopulateProbingFolder(asset, locale); PopulateRuntimeFolder(asset, locale); } } } } else { foreach (var assetGroup in dependency.RuntimeAssemblyGroups) { foreach (var asset in assetGroup.Assets) { if (!IsAmbientAssembly(asset.Name)) { if (runtimeIds.Contains(assetGroup.Runtime)) { LoadFromAssemblyPath(asset.ResolvedPath); } var relativeFolderPath = !String.IsNullOrEmpty(assetGroup.Runtime) ? Paths.GetParentFolderPath(asset.RelativePath) : String.Empty; PopulateBinaryFolder(assemblyFolderPath, asset.ResolvedPath, relativeFolderPath); PopulateProbingFolder(asset.ResolvedPath, relativeFolderPath); } } } var runtimeAssets = new HashSet <LibraryAsset>(dependency.RuntimeAssemblyGroups.GetDefaultAssets()); foreach (var asset in dependency.CompilationAssemblies) { if (!IsAmbientAssembly(asset.Name) && !runtimeAssets.Contains(asset)) { _compileOnlyAssemblies[asset.Name] = asset.ResolvedPath; PopulateBinaryFolder(assemblyFolderPath, asset.ResolvedPath, CompilerUtility.RefsDirectoryName); PopulateProbingFolder(asset.ResolvedPath, CompilerUtility.RefsDirectoryName); } } if (!IsAmbientAssembly(dependency.Library.Identity.Name)) { foreach (var asset in dependency.ResourceAssemblies) { var assetResolvedPath = asset.Asset.ResolvedPath; if (!String.IsNullOrEmpty(assetResolvedPath) && File.Exists(assetResolvedPath)) { PopulateBinaryFolder(assemblyFolderPath, assetResolvedPath, asset.Locale); PopulateProbingFolder(assetResolvedPath, asset.Locale); PopulateRuntimeFolder(assetResolvedPath, asset.Locale); } } } } } }
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); }
private bool InvokeCompileOnRootProject() { // todo: add methods to CompilerCommandApp to generate the arg string? var args = new List <string>(); args.Add("--framework"); args.Add(_rootProject.TargetFramework.ToString()); args.Add("--configuration"); args.Add(_args.ConfigValue); if (!string.IsNullOrWhiteSpace(_args.RuntimeValue)) { args.Add("--runtime"); args.Add(_args.RuntimeValue); } if (!string.IsNullOrEmpty(_args.OutputValue)) { args.Add("--output"); args.Add(_args.OutputValue); } if (!string.IsNullOrEmpty(_args.VersionSuffixValue)) { args.Add("--version-suffix"); args.Add(_args.VersionSuffixValue); } if (!string.IsNullOrEmpty(_args.BuildBasePathValue)) { args.Add("--build-base-path"); args.Add(_args.BuildBasePathValue); } //native args if (_args.IsNativeValue) { args.Add("--native"); } if (_args.IsCppModeValue) { args.Add("--cpp"); } if (!string.IsNullOrWhiteSpace(_args.ArchValue)) { args.Add("--arch"); args.Add(_args.ArchValue); } foreach (var ilcArg in _args.IlcArgsValue) { args.Add("--ilcarg"); args.Add(ilcArg); } if (!string.IsNullOrWhiteSpace(_args.IlcPathValue)) { args.Add("--ilcpath"); args.Add(_args.IlcPathValue); } if (!string.IsNullOrWhiteSpace(_args.IlcSdkPathValue)) { args.Add("--ilcsdkpath"); args.Add(_args.IlcSdkPathValue); } args.Add(_rootProject.ProjectDirectory); var compileResult = CommpileCommand.Run(args.ToArray()); var succeeded = compileResult == 0; if (succeeded) { if (_rootProject.ProjectFile.HasRuntimeOutput(_args.ConfigValue)) { MakeRunnable(); } else if (!string.IsNullOrEmpty(_args.OutputValue)) { var outputPaths = _rootProject.GetOutputPaths(_args.ConfigValue, _args.BuildBasePathValue, _args.OutputValue); CopyCompilationOutput(outputPaths); } } return(succeeded); }
public override bool Compile(ProjectContext context, CompilerCommandApp 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 (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 = outputPaths.CompilationFiles.Assembly; // 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.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 = context.CreateRuntimeContext(args.GetRuntimes()); var runtimeOutputPath = runtimeContext.GetOutputPaths(args.ConfigValue, args.BuildBasePathValue, args.OutputValue); contextVariables.Add( "compile:RuntimeOutputDir", runtimeOutputPath.RuntimeOutputPath.TrimEnd('\\', '/')); } _scriptRunner.RunScripts(context, ScriptNames.PreCompile, contextVariables); var result = _commandFactory.Create($"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(); _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, intermediateOutputPath, outputPath); } return(PrintSummary(diagnostics, sw, success)); }
/// <summary> /// Publish the project for given 'framework (ex - netcoreapp1.0)' and 'runtimeID (ex - win7-x64)' /// </summary> /// <param name="context">project that is to be published</param> /// <param name="baseOutputPath">Location of published files</param> /// <param name="configuration">Debug or Release</param> /// <param name="nativeSubdirectories"></param> /// <returns>Return 0 if successful else return non-zero</returns> private bool PublishProjectContext(ProjectContext context, string buildBasePath, string outputPath, string configuration, bool nativeSubdirectories) { var target = context.TargetFramework.DotNetFrameworkName; if (!string.IsNullOrEmpty(context.RuntimeIdentifier)) { target = $"{target}/{context.RuntimeIdentifier}"; } Reporter.Output.WriteLine($"Publishing {context.RootProject.Identity.Name.Yellow()} for {target.Yellow()}"); var options = context.ProjectFile.GetCompilerOptions(context.TargetFramework, configuration); var outputPaths = context.GetOutputPaths(configuration, buildBasePath, outputPath); if (string.IsNullOrEmpty(outputPath)) { outputPath = Path.Combine(outputPaths.RuntimeOutputPath, PublishSubfolderName); } var contextVariables = new Dictionary <string, string> { { "publish:ProjectPath", context.ProjectDirectory }, { "publish:Configuration", configuration }, { "publish:OutputPath", outputPath }, { "publish:TargetFramework", context.TargetFramework.GetShortFolderName() }, { "publish:FullTargetFramework", context.TargetFramework.DotNetFrameworkName }, { "publish:Runtime", context.RuntimeIdentifier }, }; RunScripts(context, ScriptNames.PrePublish, contextVariables); if (!Directory.Exists(outputPath)) { Directory.CreateDirectory(outputPath); } // Compile the project (and transitively, all it's dependencies) if (ShouldBuild && !InvokeBuildOnProject(context, buildBasePath, configuration)) { return(false); } // Use a library exporter to collect publish assets var exporter = context.CreateExporter(configuration, buildBasePath); // Get the output paths used by the call to `dotnet build` above (since we didn't pass `--output`, they will be different from // our current output paths) var buildOutputPaths = context.GetOutputPaths(configuration, buildBasePath); var exports = exporter.GetAllExports(); var exportsLookup = exports.ToDictionary(e => e.Library.Identity.Name, StringComparer.OrdinalIgnoreCase); var platformExclusionList = context.GetPlatformExclusionList(exportsLookup); var buildExclusionList = context.GetTypeBuildExclusionList(exportsLookup); var allExclusionList = new HashSet <string>(platformExclusionList); allExclusionList.UnionWith(buildExclusionList); var filteredExports = exports.FilterExports(allExclusionList); foreach (var export in filteredExports) { Reporter.Verbose.WriteLine($"publish: Publishing {export.Library.Identity.ToString().Green().Bold()} ..."); PublishAssetGroups(export.RuntimeAssemblyGroups, outputPath, nativeSubdirectories: false, includeRuntimeGroups: context.IsPortable); PublishAssetGroups(export.NativeLibraryGroups, outputPath, nativeSubdirectories, includeRuntimeGroups: context.IsPortable); var runtimeAssetsToCopy = export.RuntimeAssets.Where(a => ShouldCopyExportRuntimeAsset(context, buildOutputPaths, export, a)); runtimeAssetsToCopy.StructuredCopyTo(outputPath, outputPaths.IntermediateOutputDirectoryPath); foreach (var resourceAsset in export.ResourceAssemblies) { var dir = Path.Combine(outputPath, resourceAsset.Locale); if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } File.Copy(resourceAsset.Asset.ResolvedPath, Path.Combine(dir, resourceAsset.Asset.FileName), overwrite: true); } } foreach (var export in exports) { if (options.PreserveCompilationContext.GetValueOrDefault()) { PublishRefs(export, outputPath); } } if (context.ProjectFile.HasRuntimeOutput(configuration) && !context.TargetFramework.IsDesktop()) { // Make executable in the new location var executable = new Executable(context, buildOutputPaths, outputPath, buildOutputPaths.IntermediateOutputDirectoryPath, exporter, configuration); var runtimeExports = filteredExports; var compilationExports = exports.FilterExports(buildExclusionList); executable.WriteConfigurationFiles(exports, runtimeExports, compilationExports, includeDevConfig: false); } var contentFiles = new ContentFiles(context); if (context.ProjectFile.PublishOptions != null) { var includeEntries = IncludeFilesResolver.GetIncludeFiles( context.ProjectFile.PublishOptions, PathUtility.EnsureTrailingSlash(outputPath), diagnostics: null); contentFiles.StructuredCopyTo(outputPath, includeEntries); } else { contentFiles.StructuredCopyTo(outputPath); } // Publish a host if this is an application if (options.EmitEntryPoint.GetValueOrDefault() && !string.IsNullOrEmpty(context.RuntimeIdentifier)) { Reporter.Verbose.WriteLine($"publish: Renaming native host in output to create fully standalone output."); RenamePublishedHost(context, outputPath, options); } RunScripts(context, ScriptNames.PostPublish, contextVariables); Reporter.Output.WriteLine($"publish: Published to {outputPath}".Green().Bold()); return(true); }
internal Assembly LoadProject(ProjectContext context) { var outputPaths = context.GetOutputPaths(Configuration); var assemblyPath = outputPaths.CompilationFiles.Assembly; var assembly = LoadFromAssemblyPath(assemblyPath); PopulateProbingFolder(assemblyPath); var assemblyFolderPath = outputPaths.CompilationOutputPath; var libraryExporter = context.CreateExporter(Configuration); var runtimeIds = GetRuntimeIdentifiers(); foreach (var dependency in libraryExporter.GetAllExports()) { var library = dependency.Library as ProjectDescription; var package = dependency.Library as PackageDescription; // Check for an unresolved library if (library != null && !library.Resolved) { if (!IsAmbientAssembly(library.Identity.Name)) { var assetFileName = GetAssemblyFileName(library.Identity.Name); var assetResolvedPath = ResolveAssemblyPath(assemblyFolderPath, assetFileName); if (!String.IsNullOrEmpty(assetResolvedPath)) { LoadFromAssemblyPath(assetResolvedPath); PopulateBinaryFolder(assemblyFolderPath, assetResolvedPath); PopulateProbingFolder(assetResolvedPath); var resourceFileName = library.Identity.Name + ".resources.dll"; var assemblyFolderName = PathUtility.GetDirectoryName(assemblyFolderPath); var resourceAssemblies = Directory.GetFiles(assemblyFolderPath, resourceFileName, SearchOption.AllDirectories) .Union(Directory.GetFiles(_probingFolderPath, resourceFileName, SearchOption.AllDirectories)); foreach (var asset in resourceAssemblies) { var locale = Directory.GetParent(asset).Name .Replace(assemblyFolderName, String.Empty) .Replace(ProbingDirectoryName, String.Empty); PopulateBinaryFolder(assemblyFolderPath, asset, locale); PopulateProbingFolder(asset, locale); PopulateRuntimeFolder(asset, locale); } } } } // Check for an unresolved package else if (package != null && !package.Resolved) { foreach (var asset in package.RuntimeAssemblies) { var assetName = Path.GetFileNameWithoutExtension(asset.Path); if (!IsAmbientAssembly(assetName)) { var assetFileName = Path.GetFileName(asset.Path); var assetResolvedPath = ResolveAssemblyPath(assemblyFolderPath, assetFileName); if (!String.IsNullOrEmpty(assetResolvedPath)) { LoadFromAssemblyPath(assetResolvedPath); PopulateBinaryFolder(assemblyFolderPath, assetResolvedPath); PopulateProbingFolder(assetResolvedPath); } } } foreach (var asset in package.RuntimeTargets) { var assetName = Path.GetFileNameWithoutExtension(asset.Path); if (!IsAmbientAssembly(assetName)) { var assetFileName = Path.GetFileName(asset.Path); var relativeFolderPath = !String.IsNullOrEmpty(asset.Runtime) ? Path.GetDirectoryName(asset.Path) : String.Empty; var assetResolvedPath = ResolveAssemblyPath(assemblyFolderPath, assetFileName, relativeFolderPath); if (!String.IsNullOrEmpty(assetResolvedPath)) { if (runtimeIds.Contains(asset.Runtime)) { LoadFromAssemblyPath(assetResolvedPath); } PopulateBinaryFolder(assemblyFolderPath, assetResolvedPath, relativeFolderPath); PopulateProbingFolder(assetResolvedPath, relativeFolderPath); } } } var runtimeAssets = new HashSet <string>(package.RuntimeAssemblies.Select(x => x.Path), StringComparer.OrdinalIgnoreCase); foreach (var asset in package.CompileTimeAssemblies) { var assetFileName = Path.GetFileName(asset.Path); if (!IsAmbientAssembly(assetFileName) && !runtimeAssets.Contains(asset.Path)) { var assetResolvedPath = ResolveAssemblyPath(assemblyFolderPath, assetFileName, CompilerUtility.RefsDirectoryName); if (!String.IsNullOrEmpty(assetResolvedPath)) { PopulateBinaryFolder(assemblyFolderPath, assetResolvedPath, CompilerUtility.RefsDirectoryName); PopulateProbingFolder(assetResolvedPath, CompilerUtility.RefsDirectoryName); } } } if (!IsAmbientAssembly(package.Identity.Name)) { foreach (var asset in package.ResourceAssemblies) { string locale; if (asset.Properties.TryGetValue(CompilerUtility.LocaleLockFilePropertyName, out locale)) { var assetFileName = Path.GetFileName(asset.Path); var assetResolvedPath = ResolveAssemblyPath(assemblyFolderPath, assetFileName, locale); if (!String.IsNullOrEmpty(assetResolvedPath)) { PopulateBinaryFolder(assemblyFolderPath, assetResolvedPath, locale); PopulateProbingFolder(assetResolvedPath, locale); PopulateRuntimeFolder(assetResolvedPath, locale); } } } } } // Check for a precompiled library else if (library != null && !dependency.RuntimeAssemblyGroups.Any()) { if (!IsAmbientAssembly(library.Identity.Name)) { var projectContext = GetProjectContextFromPath(library.Project.ProjectDirectory); if (projectContext != null) { var assetFileName = GetAssemblyFileName(library.Identity.Name); var outputPath = projectContext.GetOutputPaths(Configuration).CompilationOutputPath; var assetResolvedPath = Path.Combine(outputPath, assetFileName); if (!File.Exists(assetResolvedPath)) { assetResolvedPath = ResolveAssemblyPath(assemblyFolderPath, assetFileName); } if (!String.IsNullOrEmpty(assetResolvedPath)) { LoadFromAssemblyPath(assetResolvedPath); PopulateBinaryFolder(assemblyFolderPath, assetResolvedPath); PopulateProbingFolder(assetResolvedPath); } var compilationOptions = projectContext.ResolveCompilationOptions(Configuration); var resourceAssemblies = CompilerUtility.GetCultureResources(projectContext.ProjectFile, outputPath, compilationOptions); foreach (var asset in resourceAssemblies) { assetFileName = Path.GetFileName(asset.OutputFile); assetResolvedPath = asset.OutputFile; if (!File.Exists(assetResolvedPath)) { assetResolvedPath = ResolveAssemblyPath(assemblyFolderPath, assetFileName, asset.Culture); } if (!String.IsNullOrEmpty(assetResolvedPath)) { PopulateBinaryFolder(assemblyFolderPath, assetResolvedPath, asset.Culture); PopulateProbingFolder(assetResolvedPath, asset.Culture); PopulateRuntimeFolder(assetResolvedPath, asset.Culture); } } } } } else { foreach (var assetGroup in dependency.RuntimeAssemblyGroups) { foreach (var asset in assetGroup.Assets) { if (!IsAmbientAssembly(asset.Name)) { if (runtimeIds.Contains(assetGroup.Runtime)) { LoadFromAssemblyPath(asset.ResolvedPath); } var relativeFolderPath = !String.IsNullOrEmpty(assetGroup.Runtime) ? Path.GetDirectoryName(asset.RelativePath) : String.Empty; PopulateBinaryFolder(assemblyFolderPath, asset.ResolvedPath, relativeFolderPath); PopulateProbingFolder(asset.ResolvedPath, relativeFolderPath); } } } var runtimeAssets = new HashSet <LibraryAsset>(dependency.RuntimeAssemblyGroups.GetDefaultAssets()); foreach (var asset in dependency.CompilationAssemblies) { if (!IsAmbientAssembly(asset.Name) && !runtimeAssets.Contains(asset)) { PopulateBinaryFolder(assemblyFolderPath, asset.ResolvedPath, CompilerUtility.RefsDirectoryName); PopulateProbingFolder(asset.ResolvedPath, CompilerUtility.RefsDirectoryName); } } if (!IsAmbientAssembly(dependency.Library.Identity.Name)) { foreach (var asset in dependency.ResourceAssemblies) { var assetResolvedPath = asset.Asset.ResolvedPath; if (!String.IsNullOrEmpty(assetResolvedPath) && File.Exists(assetResolvedPath)) { PopulateBinaryFolder(assemblyFolderPath, assetResolvedPath, asset.Locale); PopulateProbingFolder(assetResolvedPath, asset.Locale); PopulateRuntimeFolder(assetResolvedPath, asset.Locale); } } } } } return(assembly); }
public override bool Compile(ProjectContext context, CompilerCommandApp args) { var outputPaths = context.GetOutputPaths(args.ConfigValue, args.BuildBasePathValue, args.OutputValue); var outputPath = outputPaths.RuntimeOutputPath; var nativeOutputPath = Path.Combine(outputPath, "native"); var intermediateOutputPath = outputPaths.IntermediateOutputDirectoryPath; var nativeTempOutput = Path.Combine(intermediateOutputPath, "native"); Directory.CreateDirectory(nativeOutputPath); Directory.CreateDirectory(nativeTempOutput); var managedOutput = outputPaths.CompilationFiles.Assembly; // Create the library exporter var exporter = context.CreateExporter(args.ConfigValue); var exports = exporter.GetDependencies(); // Runtime assemblies. // TODO: native assets/resources. var references = exports .SelectMany(export => export.RuntimeAssemblies) .Select(r => r.ResolvedPath) .ToList(); // Setup native args. var nativeArgs = new List <string>(); // Input Assembly nativeArgs.Add($"{managedOutput}"); // Add Resolved Assembly References foreach (var reference in references) { nativeArgs.Add("--reference"); nativeArgs.Add(reference); } // ILC Args foreach (var ilcArg in args.IlcArgsValue) { nativeArgs.Add("--ilcarg"); nativeArgs.Add($"\"{ilcArg}\""); } // ILC Path if (!string.IsNullOrWhiteSpace(args.IlcPathValue)) { nativeArgs.Add("--ilcpath"); nativeArgs.Add(args.IlcPathValue); } // ILC SDK Path if (!string.IsNullOrWhiteSpace(args.IlcSdkPathValue)) { nativeArgs.Add("--ilcsdkpath"); nativeArgs.Add(args.IlcSdkPathValue); } // AppDep SDK Path if (!string.IsNullOrWhiteSpace(args.AppDepSdkPathValue)) { nativeArgs.Add("--appdepsdk"); nativeArgs.Add(args.AppDepSdkPathValue); } // CodeGen Mode if (args.IsCppModeValue) { nativeArgs.Add("--mode"); nativeArgs.Add("cpp"); } if (!string.IsNullOrWhiteSpace(args.CppCompilerFlagsValue)) { nativeArgs.Add("--cppcompilerflags"); nativeArgs.Add(args.CppCompilerFlagsValue); } // Configuration if (args.ConfigValue != null) { nativeArgs.Add("--configuration"); nativeArgs.Add(args.ConfigValue); } // Architecture if (args.ArchValue != null) { nativeArgs.Add("--arch"); nativeArgs.Add(args.ArchValue); } // Intermediate Path nativeArgs.Add("--temp-output"); nativeArgs.Add($"{nativeTempOutput}"); // Output Path nativeArgs.Add("--output"); nativeArgs.Add($"{nativeOutputPath}"); // Write Response File var rsp = Path.Combine(nativeTempOutput, $"dotnet-compile-native.{context.ProjectFile.Name}.rsp"); File.WriteAllLines(rsp, nativeArgs); // TODO Add -r assembly.dll for all Nuget References // Need CoreRT Framework published to nuget // Do Native Compilation var result = Native.CompileNativeCommand.Run(new string[] { "--rsp", $"{rsp}" }); return(result == 0); }
public static string IncrementalCacheFile(this ProjectContext context, string configuration, string buildBasePath, string outputPath) { var intermediatePath = context.GetOutputPaths(configuration, buildBasePath, outputPath).IntermediateOutputDirectoryPath; return(Path.Combine(intermediatePath, ".IncrementalCache")); }
private int RunExecutable() { CalculateDefaultsForNonAssigned(); // Compile to that directory var result = Build.BuildCommand.Run(new[] { $"--framework", $"{_context.TargetFramework}", $"--configuration", Configuration, $"{_context.ProjectFile.ProjectDirectory}" }); if (result != 0) { return(result); } if (!_context.TargetFramework.IsDesktop()) { // Add Nuget Packages Probing Path var nugetPackagesRoot = _context.PackagesDirectory; var probingPathArg = "--additionalprobingpath"; _args.Insert(0, nugetPackagesRoot); _args.Insert(0, probingPathArg); } // Now launch the output and give it the results var outputPaths = _context.GetOutputPaths(Configuration); var outputName = outputPaths.RuntimeFiles.Executable; if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { if (_context.TargetFramework.IsDesktop()) { // Run mono if we're running a desktop target on non windows _args.Insert(0, outputName); if (string.Equals(Configuration, "Debug", StringComparison.OrdinalIgnoreCase)) { // If we're compiling for the debug configuration then add the --debug flag // other options may be passed using the MONO_OPTIONS env var _args.Insert(0, "--debug"); } outputName = "mono"; } } Command command; if (outputName.EndsWith(FileNameSuffixes.DotNet.DynamicLib, StringComparison.OrdinalIgnoreCase)) { // The executable is a ".dll", we need to call it through dotnet.exe var muxer = new Muxer(); command = Command.Create(muxer.MuxerPath, Enumerable.Concat(new[] { "exec", outputName }, _args)); } else { command = Command.Create(outputName, _args); } result = command .ForwardStdOut() .ForwardStdErr() .Execute() .ExitCode; return(result); }