Пример #1
0
        private static CSharpCompilationOptions AddSigningOptions(CSharpCompilationOptions options, CommonCompilerOptions compilerOptions, string projectDirectory)
        {
            var useOssSigning = compilerOptions.PublicSign == true;
            var keyFile = compilerOptions.KeyFile;

            if (!string.IsNullOrEmpty(keyFile))
            {
                keyFile = Path.GetFullPath(Path.Combine(projectDirectory, compilerOptions.KeyFile));

                if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || useOssSigning)
                {
                    return options.WithCryptoPublicKey(
                        SnkUtils.ExtractPublicKey(File.ReadAllBytes(keyFile)));
                }

                options = options.WithCryptoKeyFile(keyFile);

                return options.WithDelaySign(compilerOptions.DelaySign);
            }

            return options;
        }
Пример #2
0
        private static CompilationSettings ToCompilationSettings(CommonCompilerOptions compilerOptions,
                                                                 NuGetFramework targetFramework,
                                                                 string projectDirectory)
        {
            var options = GetCompilationOptions(compilerOptions, projectDirectory);

            options = options.WithSpecificDiagnosticOptions(compilerOptions.SuppressWarnings.ToDictionary(
                suppress => suppress, _ => ReportDiagnostic.Suppress));

            AssemblyIdentityComparer assemblyIdentityComparer =
                targetFramework.IsDesktop() ?
                DesktopAssemblyIdentityComparer.Default :
                null;

            options = options.WithAssemblyIdentityComparer(assemblyIdentityComparer);

            LanguageVersion languageVersion;
            if (!Enum.TryParse<LanguageVersion>(value: compilerOptions.LanguageVersion,
                                                ignoreCase: true,
                                                result: out languageVersion))
            {
                languageVersion = LanguageVersion.CSharp6;
            }

            var settings = new CompilationSettings
            {
                LanguageVersion = languageVersion,
                Defines = compilerOptions.Defines ?? Enumerable.Empty<string>(),
                CompilationOptions = options
            };

            return settings;
        }
Пример #3
0
        private static CSharpCompilationOptions GetCompilationOptions(CommonCompilerOptions compilerOptions, string projectDirectory)
        {
            var outputKind = compilerOptions.EmitEntryPoint.GetValueOrDefault() ?
                OutputKind.ConsoleApplication : OutputKind.DynamicallyLinkedLibrary;
            var options = new CSharpCompilationOptions(outputKind);

            string platformValue = compilerOptions.Platform;
            bool allowUnsafe = compilerOptions.AllowUnsafe ?? false;
            bool optimize = compilerOptions.Optimize ?? false;
            bool warningsAsErrors = compilerOptions.WarningsAsErrors ?? false;

            Platform platform;
            if (!Enum.TryParse(value: platformValue, ignoreCase: true, result: out platform))
            {
                platform = Platform.AnyCpu;
            }

            options = options
                        .WithAllowUnsafe(allowUnsafe)
                        .WithPlatform(platform)
                        .WithGeneralDiagnosticOption(warningsAsErrors ? ReportDiagnostic.Error : ReportDiagnostic.Default)
                        .WithOptimizationLevel(optimize ? OptimizationLevel.Release : OptimizationLevel.Debug);

            return AddSigningOptions(options, compilerOptions, projectDirectory);
        }
Пример #4
0
        public static int Run(string[] args)
        {
            DebugHelper.HandleDebugSwitch(ref args);

            CommandLineApplication app = new CommandLineApplication();

            app.Name                = "dotnet compile-csc";
            app.FullName            = ".NET C# Compiler";
            app.Description         = "C# Compiler for the .NET Platform";
            app.HandleResponseFiles = true;
            app.HelpOption("-h|--help");

            CommonCompilerOptionsCommandLine commonCompilerCommandLine = CommonCompilerOptionsCommandLine.AddOptions(app);
            AssemblyInfoOptionsCommandLine   assemblyInfoCommandLine   = AssemblyInfoOptionsCommandLine.AddOptions(app);

            CommandOption   tempOutput = app.Option("--temp-output <arg>", "Compilation temporary directory", CommandOptionType.SingleValue);
            CommandOption   outputName = app.Option("--out <arg>", "Name of the output assembly", CommandOptionType.SingleValue);
            CommandOption   references = app.Option("--reference <arg>...", "Path to a compiler metadata reference", CommandOptionType.MultipleValue);
            CommandOption   analyzers  = app.Option("--analyzer <arg>...", "Path to an analyzer assembly", CommandOptionType.MultipleValue);
            CommandOption   resources  = app.Option("--resource <arg>...", "Resources to embed", CommandOptionType.MultipleValue);
            CommandArgument sources    = app.Argument("<source-files>...", "Compilation sources", multipleValues: true);

            app.OnExecute(() =>
            {
                if (!tempOutput.HasValue())
                {
                    Reporter.Error.WriteLine("Option '--temp-output' is required");
                    return(ExitFailed);
                }

                CommonCompilerOptions commonOptions = commonCompilerCommandLine.GetOptionValues();

                AssemblyInfoOptions assemblyInfoOptions = assemblyInfoCommandLine.GetOptionValues();

                var translated = TranslateCommonOptions(commonOptions, outputName.Value());

                var allArgs = new List <string>(translated);
                allArgs.AddRange(GetDefaultOptions());

                // Generate assembly info
                var assemblyInfo = Path.Combine(tempOutput.Value(), $"dotnet-compile.assemblyinfo.cs");

                File.WriteAllText(assemblyInfo, AssemblyInfoFileGenerator.GenerateCSharp(assemblyInfoOptions, sources.Values));

                allArgs.Add($"\"{assemblyInfo}\"");

                if (outputName.HasValue())
                {
                    allArgs.Add($"-out:\"{outputName.Value()}\"");
                }

                allArgs.AddRange(analyzers.Values.Select(a => $"-a:\"{a}\""));
                allArgs.AddRange(references.Values.Select(r => $"-r:\"{r}\""));

                // Resource has two parts separated by a comma
                // Only the first should be quoted. This is handled
                // in dotnet-compile where the information is present.
                allArgs.AddRange(resources.Values.Select(resource => $"-resource:{resource}"));

                allArgs.AddRange(sources.Values.Select(s => $"\"{s}\""));

                var rsp = Path.Combine(tempOutput.Value(), "dotnet-compile-csc.rsp");

                File.WriteAllLines(rsp, allArgs, Encoding.UTF8);

                // Execute CSC!
                var result = RunCsc(new string[] { $"-noconfig", "@" + $"{rsp}" })
                             .WorkingDirectory(Directory.GetCurrentDirectory())
                             .ForwardStdErr()
                             .ForwardStdOut()
                             .Execute();

                return(result.ExitCode);
            });

            try
            {
                return(app.Execute(args));
            }
            catch (Exception ex)
            {
#if DEBUG
                Reporter.Error.WriteLine(ex.ToString());
#else
                Reporter.Error.WriteLine(ex.Message);
#endif
                return(ExitFailed);
            }
        }
Пример #5
0
        private bool HasSourceFiles(ProjectDescription project, CommonCompilerOptions compilerOptions)
        {
            if (compilerOptions.CompileInclude == null)
            {
                return project.Project.Files.SourceFiles.Any();
            }

            var includeFiles = IncludeFilesResolver.GetIncludeFiles(compilerOptions.CompileInclude, "/", diagnostics: null);

            return includeFiles.Any();
        }
Пример #6
0
        public static int Run(string[] args)
        {
            DebugHelper.HandleDebugSwitch(ref args);

            CommonCompilerOptions commonOptions = null;
            AssemblyInfoOptions assemblyInfoOptions = null;
            string tempOutDir = null;
            IReadOnlyList<string> references = Array.Empty<string>();
            IReadOnlyList<string> resources = Array.Empty<string>();
            IReadOnlyList<string> sources = Array.Empty<string>();
            IReadOnlyList<string> analyzers = Array.Empty<string>();
            string outputName = null;
            var help = false;
            var returnCode = 0;
            string helpText = null;

            try
            {
                ArgumentSyntax.Parse(args, syntax =>
                {
                    syntax.HandleHelp = false;
                    syntax.HandleErrors = false;

                    commonOptions = CommonCompilerOptionsExtensions.Parse(syntax);

                    assemblyInfoOptions = AssemblyInfoOptions.Parse(syntax);

                    syntax.DefineOption("temp-output", ref tempOutDir, "Compilation temporary directory");

                    syntax.DefineOption("out", ref outputName, "Name of the output assembly");

                    syntax.DefineOptionList("reference", ref references, "Path to a compiler metadata reference");

                    syntax.DefineOptionList("analyzer", ref analyzers, "Path to an analyzer assembly");

                    syntax.DefineOptionList("resource", ref resources, "Resources to embed");

                    syntax.DefineOption("h|help", ref help, "Help for compile native.");

                    syntax.DefineParameterList("source-files", ref sources, "Compilation sources");

                    helpText = syntax.GetHelpText();

                    if (tempOutDir == null)
                    {
                        syntax.ReportError("Option '--temp-output' is required");
                    }
                });
            }
            catch (ArgumentSyntaxException exception)
            {
                Console.Error.WriteLine(exception.Message);
                help = true;
                returnCode = ExitFailed;
            }

            if (help)
            {
                Console.WriteLine(helpText);

                return returnCode;
            }

            var translated = TranslateCommonOptions(commonOptions, outputName.Trim('"'));

            var allArgs = new List<string>(translated);
            allArgs.AddRange(GetDefaultOptions());

            // Generate assembly info
            var tempOutputStrippedSpaces = tempOutDir.Trim('"');
            var assemblyInfo = Path.Combine(tempOutputStrippedSpaces, $"dotnet-compile.assemblyinfo.cs");
            
            File.WriteAllText(assemblyInfo, AssemblyInfoFileGenerator.Generate(assemblyInfoOptions, sources));
            allArgs.Add($"\"{assemblyInfo}\"");

            if (outputName != null)
            {
                allArgs.Add($"-out:\"{outputName.Trim('"')}\"");
            }

            allArgs.AddRange(analyzers.Select(a => $"-a:\"{a.Trim('"')}\""));
            allArgs.AddRange(references.Select(r => $"-r:\"{r.Trim('"')}\""));
            allArgs.AddRange(resources.Select(resource => $"-resource:{resource.Trim('"')}"));
            allArgs.AddRange(sources.Select(s => $"\"{s.Trim('"')}\""));

            var rsp = Path.Combine(tempOutputStrippedSpaces, "dotnet-compile-csc.rsp");

            File.WriteAllLines(rsp, allArgs, Encoding.UTF8);

            // Execute CSC!
            var result = RunCsc(new string[] { $"-noconfig", "@" + $"{rsp}" })
                .ForwardStdErr()
                .ForwardStdOut()
                .Execute();

            return result.ExitCode;
        }
Пример #7
0
        private static IEnumerable <string> TranslateCommonOptions(CommonCompilerOptions options, string outputName)
        {
            List <string> commonArgs = new List <string>();

            if (options.Defines != null)
            {
                commonArgs.AddRange(options.Defines.Select(def => $"-d:{def}"));
            }

            if (options.SuppressWarnings != null)
            {
                commonArgs.AddRange(options.SuppressWarnings.Select(w => $"-nowarn:{w}"));
            }

            // Additional arguments are added verbatim
            if (options.AdditionalArguments != null)
            {
                commonArgs.AddRange(options.AdditionalArguments);
            }

            if (options.LanguageVersion != null)
            {
                commonArgs.Add($"-langversion:{GetLanguageVersion(options.LanguageVersion)}");
            }

            if (options.Platform != null)
            {
                commonArgs.Add($"-platform:{options.Platform}");
            }

            if (options.AllowUnsafe == true)
            {
                commonArgs.Add("-unsafe");
            }

            if (options.WarningsAsErrors == true)
            {
                commonArgs.Add("-warnaserror");
            }

            if (options.Optimize == true)
            {
                commonArgs.Add("-optimize");
            }

            if (options.KeyFile != null)
            {
                commonArgs.Add($"-keyfile:\"{options.KeyFile}\"");

                // If we're not on Windows, full signing isn't supported, so we'll
                // public sign, unless the public sign switch has explicitly been
                // set to false
                if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) &&
                    options.PublicSign == null)
                {
                    commonArgs.Add("-publicsign");
                }
            }

            if (options.DelaySign == true)
            {
                commonArgs.Add("-delaysign");
            }

            if (options.PublicSign == true)
            {
                commonArgs.Add("-publicsign");
            }

            if (options.GenerateXmlDocumentation == true)
            {
                commonArgs.Add($"-doc:\"{Path.ChangeExtension(outputName, "xml")}\"");
            }

            if (options.EmitEntryPoint != true)
            {
                commonArgs.Add("-t:library");
            }

            if (string.IsNullOrEmpty(options.DebugType))
            {
                commonArgs.Add(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
                    ? "-debug:full"
                    : "-debug:portable");
            }
            else
            {
                commonArgs.Add(options.DebugType == "portable"
                    ? "-debug:portable"
                    : "-debug:full");
            }

            return(commonArgs);
        }
Пример #8
0
        public static int Main(string[] args)
        {
            DebugHelper.HandleDebugSwitch(ref args);

            CommonCompilerOptions commonOptions = null;
            string tempOutDir = null;
            IReadOnlyList <string> references = Array.Empty <string>();
            IReadOnlyList <string> resources  = Array.Empty <string>();
            IReadOnlyList <string> sources    = Array.Empty <string>();
            string outputName = null;

            try
            {
                ArgumentSyntax.Parse(args, syntax =>
                {
                    commonOptions = CommonCompilerOptionsExtensions.Parse(syntax);

                    syntax.DefineOption("temp-output", ref tempOutDir, "Compilation temporary directory");

                    syntax.DefineOption("out", ref outputName, "Name of the output assembly");

                    syntax.DefineOptionList("reference", ref references, "Path to a compiler metadata reference");

                    syntax.DefineOptionList("resource", ref resources, "Resources to embed");

                    syntax.DefineParameterList("source-files", ref sources, "Compilation sources");

                    if (tempOutDir == null)
                    {
                        syntax.ReportError("Option '--temp-output' is required");
                    }
                });
            }
            catch (ArgumentSyntaxException)
            {
                return(ExitFailed);
            }

            var translated = TranslateCommonOptions(commonOptions);

            var allArgs = new List <string>(translated);

            allArgs.AddRange(GetDefaultOptions());

            if (outputName != null)
            {
                allArgs.Add($"-out:\"{outputName}\"");
            }

            allArgs.AddRange(references.Select(r => $"-r:\"{r}\""));
            allArgs.AddRange(resources.Select(resource => $"-resource:{resource}"));
            allArgs.AddRange(sources.Select(s => $"\"{s}\""));

            var rsp = Path.Combine(tempOutDir, "dotnet-compile-csc.rsp");

            File.WriteAllLines(rsp, allArgs, Encoding.UTF8);

            // Execute CSC!
            var result = RunCsc($"-noconfig @\"{rsp}\"")
                         .ForwardStdErr()
                         .ForwardStdOut()
                         .Execute();

            return(result.ExitCode);
        }
Пример #9
0
        public static IEnumerable <string> SerializeToArgs(this CommonCompilerOptions options)
        {
            var defines                  = options.Defines;
            var suppressWarnings         = options.SuppressWarnings;
            var languageVersion          = options.LanguageVersion;
            var debugType                = options.DebugType;
            var platform                 = options.Platform;
            var allowUnsafe              = options.AllowUnsafe;
            var warningsAsErrors         = options.WarningsAsErrors;
            var optimize                 = options.Optimize;
            var keyFile                  = options.KeyFile;
            var delaySign                = options.DelaySign;
            var publicSign               = options.PublicSign;
            var emitEntryPoint           = options.EmitEntryPoint;
            var generateXmlDocumentation = options.GenerateXmlDocumentation;
            var additionalArguments      = options.AdditionalArguments;

            var args = new List <string>();

            if (defines != null)
            {
                args.AddRange(defines.Select(def => s_definesTemplate.ToLongArg(def)));
            }

            if (suppressWarnings != null)
            {
                args.AddRange(suppressWarnings.Select(def => s_suppressWarningTemplate.ToLongArg(def)));
            }

            if (additionalArguments != null)
            {
                args.AddRange(additionalArguments.Select(arg => s_additionalArgumentsTemplate.ToLongArg(arg)));
            }

            if (languageVersion != null)
            {
                args.Add(s_languageVersionTemplate.ToLongArg(languageVersion));
            }

            if (platform != null)
            {
                args.Add(s_platformTemplate.ToLongArg(platform));
            }

            if (allowUnsafe != null)
            {
                args.Add(s_allowUnsafeTemplate.ToLongArg(allowUnsafe));
            }

            if (warningsAsErrors != null)
            {
                args.Add(s_warningsAsErrorsTemplate.ToLongArg(warningsAsErrors));
            }

            if (optimize != null)
            {
                args.Add(s_optimizeTemplate.ToLongArg(optimize));
            }

            if (keyFile != null)
            {
                args.Add(s_keyFileTemplate.ToLongArg(keyFile));
            }

            if (delaySign != null)
            {
                args.Add(s_delaySignTemplate.ToLongArg(delaySign));
            }

            if (publicSign != null)
            {
                args.Add(s_publicSignTemplate.ToLongArg(publicSign));
            }

            if (debugType != null)
            {
                args.Add(s_debugTypeTemplate.ToLongArg(debugType));
            }

            if (emitEntryPoint != null)
            {
                args.Add(s_emitEntryPointTemplate.ToLongArg(emitEntryPoint));
            }

            if (generateXmlDocumentation != null)
            {
                args.Add(s_generateXmlDocumentation.ToLongArg(generateXmlDocumentation));
            }

            return(args);
        }
Пример #10
0
        private static IEnumerable <string> TranslateCommonOptions(CommonCompilerOptions options)
        {
            List <string> commonArgs = new List <string>();

            if (options.Defines != null)
            {
                commonArgs.AddRange(options.Defines.Select(def => $"-d:{def}"));
            }

            if (options.LanguageVersion != null)
            {
                commonArgs.Add($"-langversion:{GetLanguageVersion(options.LanguageVersion)}");
            }

            if (options.Platform != null)
            {
                commonArgs.Add($"-platform:{options.Platform}");
            }

            if (options.AllowUnsafe == true)
            {
                commonArgs.Add("-unsafe");
            }

            if (options.WarningsAsErrors == true)
            {
                commonArgs.Add("-warnaserror");
            }

            if (options.Optimize == true)
            {
                commonArgs.Add("-optimize");
            }

            if (options.KeyFile != null)
            {
                commonArgs.Add($"-keyfile:\"{options.KeyFile}\"");

                // If we're not on Windows, full signing isn't supported, so we'll
                // public sign, unless the public sign switch has explicitly been
                // set to false
                if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) &&
                    options.PublicSign == null)
                {
                    commonArgs.Add("-publicsign");
                }
            }

            if (options.DelaySign == true)
            {
                commonArgs.Add("-delaysign");
            }

            if (options.PublicSign == true)
            {
                commonArgs.Add("-publicsign");
            }

            if (options.EmitEntryPoint != true)
            {
                commonArgs.Add("-t:library");
            }

            return(commonArgs);
        }
Пример #11
0
        // used in incremental compilation
        public static IEnumerable <string> GetCompilationSources(ProjectContext project, CommonCompilerOptions compilerOptions)
        {
            if (compilerOptions.CompileInclude == null)
            {
                return(project.ProjectFile.Files.SourceFiles);
            }

            var includeFiles = IncludeFilesResolver.GetIncludeFiles(compilerOptions.CompileInclude, "/", diagnostics: null);

            return(includeFiles.Select(f => f.SourcePath));
        }
Пример #12
0
        public static int Main(string[] args)
        {
            DebugHelper.HandleDebugSwitch(ref args);

            CommonCompilerOptions commonOptions       = null;
            AssemblyInfoOptions   assemblyInfoOptions = null;
            string tempOutDir = null;
            IReadOnlyList <string> references = Array.Empty <string>();
            IReadOnlyList <string> resources  = Array.Empty <string>();
            IReadOnlyList <string> sources    = Array.Empty <string>();
            string outputName = null;
            var    help       = false;
            var    returnCode = 0;
            string helpText   = null;

            try
            {
                ArgumentSyntax.Parse(args, syntax =>
                {
                    syntax.HandleHelp   = false;
                    syntax.HandleErrors = false;

                    commonOptions = CommonCompilerOptionsExtensions.Parse(syntax);

                    assemblyInfoOptions = AssemblyInfoOptions.Parse(syntax);

                    syntax.DefineOption("temp-output", ref tempOutDir, "Compilation temporary directory");

                    syntax.DefineOption("out", ref outputName, "Name of the output assembly");

                    syntax.DefineOptionList("reference", ref references, "Path to a compiler metadata reference");

                    syntax.DefineOptionList("resource", ref resources, "Resources to embed");

                    syntax.DefineOption("h|help", ref help, "Help for compile native.");

                    syntax.DefineParameterList("source-files", ref sources, "Compilation sources");

                    helpText = syntax.GetHelpText();

                    if (tempOutDir == null)
                    {
                        syntax.ReportError("Option '--temp-output' is required");
                    }
                });
            }
            catch (ArgumentSyntaxException exception)
            {
                Console.Error.WriteLine(exception.Message);
                help       = true;
                returnCode = ExitFailed;
            }

            if (help)
            {
                Console.WriteLine(helpText);

                return(returnCode);
            }

            var translated = TranslateCommonOptions(commonOptions);

            var allArgs = new List <string>(translated);

            allArgs.AddRange(GetDefaultOptions());

            // Generate assembly info
            var assemblyInfo = Path.Combine(tempOutDir, $"dotnet-compile.assemblyinfo.fs");

            File.WriteAllText(assemblyInfo, AssemblyInfoFileGenerator.GenerateFSharp(assemblyInfoOptions));
            allArgs.Add($"\"{assemblyInfo}\"");

            //HACK fsc raise error FS0208 if target exe doesnt have extension .exe
            bool   hackFS0208         = commonOptions.EmitEntryPoint == true;
            string originalOutputName = outputName;

            if (outputName != null)
            {
                if (hackFS0208)
                {
                    outputName = Path.ChangeExtension(outputName, ".exe");
                }

                allArgs.Add($"--out:\"{outputName}\"");
            }

            allArgs.AddRange(references.Select(r => $"-r:\"{r}\""));
            allArgs.AddRange(resources.Select(resource => $"--resource:{resource}"));
            allArgs.AddRange(sources.Select(s => $"\"{s}\""));

            var rsp = Path.Combine(tempOutDir, "dotnet-compile-fsc.rsp");

            File.WriteAllLines(rsp, allArgs, Encoding.UTF8);

            // Execute FSC!
            var result = RunFsc(string.Join(" ", allArgs))
                         .ForwardStdErr()
                         .ForwardStdOut()
                         .Execute();

            if (hackFS0208 && File.Exists(outputName))
            {
                if (File.Exists(originalOutputName))
                {
                    File.Delete(originalOutputName);
                }
                File.Move(outputName, originalOutputName);
            }

            return(result.ExitCode);
        }
Пример #13
0
        public static int Main(string[] args)
        {
            DebugHelper.HandleDebugSwitch(ref args);

            CommandLineApplication app = new CommandLineApplication();

            app.Name                = "dotnet compile-fsc";
            app.FullName            = ".NET F# Compiler";
            app.Description         = "F# Compiler for the .NET Platform";
            app.HandleResponseFiles = true;
            app.HelpOption("-h|--help");

            CommonCompilerOptionsCommandLine commonCompilerCommandLine = CommonCompilerOptionsCommandLine.AddOptions(app);
            AssemblyInfoOptionsCommandLine   assemblyInfoCommandLine   = AssemblyInfoOptionsCommandLine.AddOptions(app);

            CommandOption   tempOutputOption = app.Option("--temp-output <arg>", "Compilation temporary directory", CommandOptionType.SingleValue);
            CommandOption   outputNameOption = app.Option("--out <arg>", "Name of the output assembly", CommandOptionType.SingleValue);
            CommandOption   referencesOption = app.Option("--reference <arg>...", "Path to a compiler metadata reference", CommandOptionType.MultipleValue);
            CommandOption   resourcesOption  = app.Option("--resource <arg>...", "Resources to embed", CommandOptionType.MultipleValue);
            CommandArgument sourcesArgument  = app.Argument("<source-files>...", "Compilation sources", multipleValues: true);

            app.OnExecute(() =>
            {
                if (!tempOutputOption.HasValue())
                {
                    Reporter.Error.WriteLine("Option '--temp-output' is required");
                    return(ExitFailed);
                }

                CommonCompilerOptions commonOptions = commonCompilerCommandLine.GetOptionValues();

                AssemblyInfoOptions assemblyInfoOptions = assemblyInfoCommandLine.GetOptionValues();

                // TODO less hacky
                bool targetNetCore =
                    commonOptions.Defines.Contains("DNXCORE50") ||
                    commonOptions.Defines.Where(d => d.StartsWith("NETSTANDARDAPP1_")).Any() ||
                    commonOptions.Defines.Where(d => d.StartsWith("NETCOREAPP1_")).Any() ||
                    commonOptions.Defines.Where(d => d.StartsWith("NETSTANDARD1_")).Any();

                // Get FSC Path upfront to use it for win32manifest path
                string tempOutDir  = tempOutputOption.Value();
                var fscCommandSpec = ResolveFsc(null, tempOutDir);
                var fscExeFile     = fscCommandSpec.FscExeFile;
                var fscExeDir      = fscCommandSpec.FscExeDir;

                // FSC arguments
                var allArgs = new List <string>();

                //HACK fsc raise error FS0208 if target exe doesnt have extension .exe
                bool hackFS0208 = targetNetCore && commonOptions.EmitEntryPoint == true;

                string outputName      = outputNameOption.Value();
                var originalOutputName = outputName;

                if (outputName != null)
                {
                    if (hackFS0208)
                    {
                        outputName = Path.ChangeExtension(outputName, ".exe");
                    }

                    allArgs.Add($"--out:{outputName}");
                }

                //let's pass debugging type only if options.DebugType is specified, until
                //portablepdb are confirmed to work.
                //so it's possibile to test portable pdb without breaking existing build
                if (string.IsNullOrEmpty(commonOptions.DebugType))
                {
                    //debug info (only windows pdb supported, not portablepdb)
                    if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                    {
                        allArgs.Add("--debug");
                        //TODO check if full or pdbonly
                        allArgs.Add("--debug:pdbonly");
                    }
                    else
                    {
                        allArgs.Add("--debug-");
                    }
                }
                else
                {
                    allArgs.Add("--debug");
                    allArgs.Add($"--debug:{commonOptions.DebugType}");
                }

                // Default options
                allArgs.Add("--noframework");
                allArgs.Add("--nologo");
                allArgs.Add("--simpleresolution");
                allArgs.Add("--nocopyfsharpcore");

                // project.json compilationOptions
                if (commonOptions.Defines != null)
                {
                    allArgs.AddRange(commonOptions.Defines.Select(def => $"--define:{def}"));
                }

                if (commonOptions.GenerateXmlDocumentation == true)
                {
                    allArgs.Add($"--doc:{Path.ChangeExtension(outputName, "xml")}");
                }

                if (commonOptions.KeyFile != null)
                {
                    allArgs.Add($"--keyfile:{commonOptions.KeyFile}");
                }

                if (commonOptions.Optimize == true)
                {
                    allArgs.Add("--optimize+");
                }

                //--resource doesnt expect "
                //bad: --resource:"path/to/file",name
                //ok:  --resource:path/to/file,name
                allArgs.AddRange(resourcesOption.Values.Select(resource => $"--resource:{resource.Replace("\"", "")}"));

                allArgs.AddRange(referencesOption.Values.Select(r => $"-r:{r}"));

                if (commonOptions.EmitEntryPoint != true)
                {
                    allArgs.Add("--target:library");
                }
                else
                {
                    allArgs.Add("--target:exe");

                    //HACK we need default.win32manifest for exe
                    var win32manifestPath = Path.Combine(fscExeDir, "..", "..", "runtimes", "any", "native", "default.win32manifest");
                    allArgs.Add($"--win32manifest:{win32manifestPath}");
                }

                if (commonOptions.SuppressWarnings != null && commonOptions.SuppressWarnings.Any())
                {
                    allArgs.Add("--nowarn:" + string.Join(",", commonOptions.SuppressWarnings.ToArray()));
                }

                if (commonOptions.LanguageVersion != null)
                {
                    // Not used in fsc
                }

                if (commonOptions.Platform != null)
                {
                    allArgs.Add($"--platform:{commonOptions.Platform}");
                }

                if (commonOptions.AllowUnsafe == true)
                {
                }

                if (commonOptions.WarningsAsErrors == true)
                {
                    allArgs.Add("--warnaserror");
                }

                //set target framework
                if (targetNetCore)
                {
                    allArgs.Add("--targetprofile:netcore");
                }

                if (commonOptions.DelaySign == true)
                {
                    allArgs.Add("--delaysign+");
                }

                if (commonOptions.PublicSign == true)
                {
                }

                if (commonOptions.AdditionalArguments != null)
                {
                    // Additional arguments are added verbatim
                    allArgs.AddRange(commonOptions.AdditionalArguments);
                }

                // Generate assembly info
                var assemblyInfo = Path.Combine(tempOutDir, $"dotnet-compile.assemblyinfo.fs");
                File.WriteAllText(assemblyInfo, AssemblyInfoFileGenerator.GenerateFSharp(assemblyInfoOptions));

                //source files + assemblyInfo
                allArgs.AddRange(GetSourceFiles(sourcesArgument.Values, assemblyInfo).ToArray());

                //TODO check the switch enabled in fsproj in RELEASE and DEBUG configuration

                var rsp = Path.Combine(tempOutDir, "dotnet-compile-fsc.rsp");
                File.WriteAllLines(rsp, allArgs, Encoding.UTF8);

                // Execute FSC!
                var result = RunFsc(new List <string> {
                    $"@{rsp}"
                }, tempOutDir)
                             .ForwardStdErr()
                             .ForwardStdOut()
                             .Execute();

                bool successFsc = result.ExitCode == 0;

                if (hackFS0208 && File.Exists(outputName))
                {
                    if (File.Exists(originalOutputName))
                    {
                        File.Delete(originalOutputName);
                    }
                    File.Move(outputName, originalOutputName);
                }

                //HACK dotnet build require a pdb (crash without), fsc atm cant generate a portable pdb, so an empty pdb is created
                string pdbPath = Path.ChangeExtension(outputName, ".pdb");
                if (successFsc && !File.Exists(pdbPath))
                {
                    File.WriteAllBytes(pdbPath, Array.Empty <byte>());
                }

                return(result.ExitCode);
            });

            try
            {
                return(app.Execute(args));
            }
            catch (Exception ex)
            {
#if DEBUG
                Reporter.Error.WriteLine(ex.ToString());
#else
                Reporter.Error.WriteLine(ex.Message);
#endif
                return(ExitFailed);
            }
        }
Пример #14
0
        private static int RenamePublishedHost(ProjectContext context, string outputPath, CommonCompilerOptions compilationOptions)
        {
            if (context.TargetFramework.IsDesktop())
            {
                return(0);
            }

            var publishedHostFile = ResolvePublishedHostFile(outputPath);

            if (publishedHostFile == null)
            {
                Reporter.Output.WriteLine($"publish: warning: host executable not available in dependencies, using host for current platform");
                // TODO should this be an error?

                CoreHost.CopyTo(outputPath, compilationOptions.OutputName + Constants.ExeSuffix);
                return(0);
            }

            var publishedHostExtension = Path.GetExtension(publishedHostFile);
            var renamedHostName        = compilationOptions.OutputName + publishedHostExtension;
            var renamedHostFile        = Path.Combine(outputPath, renamedHostName);

            try
            {
                Reporter.Verbose.WriteLine($"publish: renaming published host {publishedHostFile} to {renamedHostFile}");
                File.Copy(publishedHostFile, renamedHostFile, true);
                File.Delete(publishedHostFile);
            }
            catch (Exception e)
            {
                Reporter.Error.WriteLine($"publish: Failed to rename {publishedHostFile} to {renamedHostFile}: {e.Message}");
                return(1);
            }

            return(0);
        }