Beispiel #1
0
        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);
        }
Beispiel #2
0
        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 }));
        }
Beispiel #4
0
        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;
        }
Beispiel #7
0
        // 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);
        }
Beispiel #8
0
        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;
        }
Beispiel #10
0
        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;
        }
Beispiel #12
0
        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);
        }
Beispiel #14
0
        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");
        }
Beispiel #15
0
 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));
 }
Beispiel #16
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);
        }
Beispiel #18
0
        /// <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);
        }
Beispiel #19
0
        /// <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);
        }
Beispiel #20
0
        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);
                            }
                        }
                    }
                }
            }
        }
Beispiel #21
0
        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);
        }
Beispiel #22
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);
        }
Beispiel #23
0
        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));
        }
Beispiel #24
0
        /// <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);
        }
Beispiel #25
0
        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);
        }
Beispiel #26
0
        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"));
        }
Beispiel #28
0
        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);
        }