From 61aad90f94141aa2c00120606a2987e1a1b7e31f Mon Sep 17 00:00:00 2001 From: Steve Date: Wed, 28 Dec 2022 04:38:19 +0900 Subject: [PATCH] Various enhancements for dotnet (#4362) --- etc/config/csharp.defaults.properties | 26 ++++---- etc/config/fsharp.defaults.properties | 26 ++++---- etc/config/vb.defaults.properties | 26 ++++---- lib/compilers/dotnet.ts | 94 +++++++++++++++------------ 4 files changed, 93 insertions(+), 79 deletions(-) diff --git a/etc/config/csharp.defaults.properties b/etc/config/csharp.defaults.properties index 22fcb4b309a..20c93164192 100644 --- a/etc/config/csharp.defaults.properties +++ b/etc/config/csharp.defaults.properties @@ -1,17 +1,19 @@ -compilers=dotnet6csharp:dotnet7csharp +compilers=&csharpdef supportsBinary=true needsMulti=false compilerType=csharp -defaultCompiler=dotnet7csharp +defaultCompiler=dotnet7csharpdef -compiler.dotnet6csharp.exe=/opt/compiler-explorer/dotnet-v6.0.11/.dotnet/dotnet -compiler.dotnet6csharp.name=.NET 6.0.403 -compiler.dotnet6csharp.clrDir=/opt/compiler-explorer/dotnet-v6.0.11 -compiler.dotnet6csharp.buildConfig=Release -compiler.dotnet6csharp.langVersion=latest +group.csharpdef.compilers=dotnet6csharpdef:dotnet7csharpdef -compiler.dotnet7csharp.exe=/opt/compiler-explorer/dotnet-v7.0.0/.dotnet/dotnet -compiler.dotnet7csharp.name=.NET 7.0.100 -compiler.dotnet7csharp.clrDir=/opt/compiler-explorer/dotnet-v7.0.0 -compiler.dotnet7csharp.buildConfig=Release -compiler.dotnet7csharp.langVersion=latest +compiler.dotnet6csharpdef.exe=/opt/compiler-explorer/dotnet-v6.0.11/.dotnet/dotnet +compiler.dotnet6csharpdef.name=.NET 6.0.403 +compiler.dotnet6csharpdef.clrDir=/opt/compiler-explorer/dotnet-v6.0.11 +compiler.dotnet6csharpdef.buildConfig=Release +compiler.dotnet6csharpdef.langVersion=latest + +compiler.dotnet7csharpdef.exe=/opt/compiler-explorer/dotnet-v7.0.0/.dotnet/dotnet +compiler.dotnet7csharpdef.name=.NET 7.0.100 +compiler.dotnet7csharpdef.clrDir=/opt/compiler-explorer/dotnet-v7.0.0 +compiler.dotnet7csharpdef.buildConfig=Release +compiler.dotnet7csharpdef.langVersion=latest diff --git a/etc/config/fsharp.defaults.properties b/etc/config/fsharp.defaults.properties index b7f473cc87a..8f2d76d42fa 100644 --- a/etc/config/fsharp.defaults.properties +++ b/etc/config/fsharp.defaults.properties @@ -1,17 +1,19 @@ -compilers=dotnet6fsharp:dotnet7fsharp +compilers=&fsharpdef supportsBinary=true needsMulti=false compilerType=fsharp -defaultCompiler=dotnet7fsharp +defaultCompiler=dotnet7fsharpdef -compiler.dotnet6fsharp.exe=/opt/compiler-explorer/dotnet-v6.0.11/.dotnet/dotnet -compiler.dotnet6fsharp.name=.NET 6.0.403 -compiler.dotnet6fsharp.clrDir=/opt/compiler-explorer/dotnet-v6.0.11 -compiler.dotnet6fsharp.buildConfig=Release -compiler.dotnet6fsharp.langVersion=latest +group.fsharpdef.compilers=dotnet6fsharpdef:dotnet7fsharpdef -compiler.dotnet7fsharp.exe=/opt/compiler-explorer/dotnet-v7.0.0/.dotnet/dotnet -compiler.dotnet7fsharp.name=.NET 7.0.100 -compiler.dotnet7fsharp.clrDir=/opt/compiler-explorer/dotnet-v7.0.0 -compiler.dotnet7fsharp.buildConfig=Release -compiler.dotnet7fsharp.langVersion=latest +compiler.dotnet6fsharpdef.exe=/opt/compiler-explorer/dotnet-v6.0.11/.dotnet/dotnet +compiler.dotnet6fsharpdef.name=.NET 6.0.403 +compiler.dotnet6fsharpdef.clrDir=/opt/compiler-explorer/dotnet-v6.0.11 +compiler.dotnet6fsharpdef.buildConfig=Release +compiler.dotnet6fsharpdef.langVersion=latest + +compiler.dotnet7fsharpdef.exe=/opt/compiler-explorer/dotnet-v7.0.0/.dotnet/dotnet +compiler.dotnet7fsharpdef.name=.NET 7.0.100 +compiler.dotnet7fsharpdef.clrDir=/opt/compiler-explorer/dotnet-v7.0.0 +compiler.dotnet7fsharpdef.buildConfig=Release +compiler.dotnet7fsharpdef.langVersion=latest diff --git a/etc/config/vb.defaults.properties b/etc/config/vb.defaults.properties index ccba0e2cfce..2f16c82da1d 100644 --- a/etc/config/vb.defaults.properties +++ b/etc/config/vb.defaults.properties @@ -1,17 +1,19 @@ -compilers=dotnet6vb:dotnet7vb +compilers=&vbdef supportsBinary=true needsMulti=false compilerType=vb -defaultCompiler=dotnet7vb +defaultCompiler=dotnet7vbdef -compiler.dotnet6vb.exe=/opt/compiler-explorer/dotnet-v6.0.11/.dotnet/dotnet -compiler.dotnet6vb.name=.NET 6.0.403 -compiler.dotnet6vb.clrDir=/opt/compiler-explorer/dotnet-v6.0.11 -compiler.dotnet6vb.buildConfig=Release -compiler.dotnet6vb.langVersion=latest +group.vbdef.compilers=dotnet6vbdef:dotnet7vbdef -compiler.dotnet7vb.exe=/opt/compiler-explorer/dotnet-v7.0.0/.dotnet/dotnet -compiler.dotnet7vb.name=.NET 7.0.100 -compiler.dotnet7vb.clrDir=/opt/compiler-explorer/dotnet-v7.0.0 -compiler.dotnet7vb.buildConfig=Release -compiler.dotnet7vb.langVersion=latest +compiler.dotnet6vbdef.exe=/opt/compiler-explorer/dotnet-v6.0.11/.dotnet/dotnet +compiler.dotnet6vbdef.name=.NET 6.0.403 +compiler.dotnet6vbdef.clrDir=/opt/compiler-explorer/dotnet-v6.0.11 +compiler.dotnet6vbdef.buildConfig=Release +compiler.dotnet6vbdef.langVersion=latest + +compiler.dotnet7vbdef.exe=/opt/compiler-explorer/dotnet-v7.0.0/.dotnet/dotnet +compiler.dotnet7vbdef.name=.NET 7.0.100 +compiler.dotnet7vbdef.clrDir=/opt/compiler-explorer/dotnet-v7.0.0 +compiler.dotnet7vbdef.buildConfig=Release +compiler.dotnet7vbdef.langVersion=latest diff --git a/lib/compilers/dotnet.ts b/lib/compilers/dotnet.ts index 90f410402dc..5b1af77fc02 100644 --- a/lib/compilers/dotnet.ts +++ b/lib/compilers/dotnet.ts @@ -114,74 +114,88 @@ class DotNetCompiler extends BaseCompiler { await fs.writeFile(projectFilePath, projectFileContent); } + setCompilerExecOptions(execOptions: ExecutionOptions, programDir: string) { + if (!execOptions) { + execOptions = this.getDefaultExecOptions(); + } + + // See https://github.com/dotnet/runtime/issues/50391 - the .NET runtime tries to make a 2TB memfile if we have + // this feature enabled (which is on by default on .NET 7) This blows out our nsjail sandbox limit, so for now + // we disable it. + execOptions.env.DOTNET_EnableWriteXorExecute = '0'; + // Disable any phone-home. + execOptions.env.DOTNET_CLI_TELEMETRY_OPTOUT = 'true'; + // Some versions of .NET complain if they can't work out what the user's directory is. We force it to the output + // directory here. + execOptions.env.DOTNET_CLI_HOME = programDir; + // Place nuget packages in the output directory. + execOptions.env.NUGET_PACKAGES = path.join(programDir, '.nuget'); + // Try to be less chatty + execOptions.env.DOTNET_SKIP_FIRST_TIME_EXPERIENCE = 'true'; + execOptions.env.DOTNET_NOLOGO = 'true'; + + execOptions.customCwd = programDir; + } + override async buildExecutable(compiler, options, inputFilename, execOptions) { const dirPath = path.dirname(inputFilename); const inputFilenameSafe = this.filename(inputFilename); const sourceFile = path.basename(inputFilenameSafe); await this.writeProjectfile(dirPath, true, sourceFile); - - return super.buildExecutable(compiler, options, inputFilename, execOptions); + return await this.buildToDll(compiler, options, inputFilename, execOptions); } override async doCompilation(inputFilename, dirPath, key, options, filters, backendOptions, libraries, tools) { const inputFilenameSafe = this.filename(inputFilename); const sourceFile = path.basename(inputFilenameSafe); await this.writeProjectfile(dirPath, filters.binary, sourceFile); - return super.doCompilation(inputFilename, dirPath, key, options, filters, backendOptions, libraries, tools); } - override async runCompiler( + async buildToDll( compiler: string, options: string[], inputFilename: string, execOptions: ExecutionOptions, ): Promise { - if (!execOptions) { - execOptions = this.getDefaultExecOptions(); - } - const programDir = path.dirname(inputFilename); - - const crossgen2Path = path.join(this.clrBuildDir, 'crossgen2', 'crossgen2.dll'); const nugetConfigPath = path.join(programDir, 'nuget.config'); - - const programOutputPath = path.join(programDir, 'bin', this.buildConfig, this.targetFramework); - const programDllPath = path.join(programOutputPath, 'CompilerExplorer.dll'); - const nugetConfigFileContent = ` - `; - // See https://github.com/dotnet/runtime/issues/50391 - the .NET runtime tries to make a 2TB memfile if we have - // this feature enabled (which is on by default on .NET 7) This blows out our nsjail sandbox limit, so for now - // we disable it. - execOptions.env.DOTNET_EnableWriteXorExecute = '0'; - // Disable any phone-home. - execOptions.env.DOTNET_CLI_TELEMETRY_OPTOUT = 'true'; - // Some versions of .NET complain if they can't work out what the user's directory is. We force it to the output - // directory here. - execOptions.env.DOTNET_CLI_HOME = programDir; - // Place nuget packages in the output directory. - execOptions.env.NUGET_PACKAGES = path.join(programDir, '.nuget'); - // Try to be less chatty - execOptions.env.DOTNET_SKIP_FIRST_TIME_EXPERIENCE = 'true'; - execOptions.env.DOTNET_NOLOGO = 'true'; - - execOptions.customCwd = programDir; await fs.writeFile(nugetConfigPath, nugetConfigFileContent); + this.setCompilerExecOptions(execOptions, programDir); + const restoreOptions = ['restore', '--configfile', nugetConfigPath, '-v', 'q', '--nologo', '/clp:NoSummary']; + const restoreResult = await this.exec(compiler, restoreOptions, execOptions); + if (restoreResult.code !== 0) { + return this.transformToCompilationResult(restoreResult, inputFilename); + } + + const compilerResult = await super.runCompiler(compiler, this.compilerOptions, inputFilename, execOptions); + if (compilerResult.code === 0) { + await fs.createFile(this.getOutputFilename(programDir, this.outputFilebase)); + } + return compilerResult; + } + + override async runCompiler( + compiler: string, + options: string[], + inputFilename: string, + execOptions: ExecutionOptions, + ): Promise { + const crossgen2Path = path.join(this.clrBuildDir, 'crossgen2', 'crossgen2.dll'); const crossgen2Options: string[] = []; const configurableOptions = this.configurableOptions; + const programDir = path.dirname(inputFilename); + const programOutputPath = path.join(programDir, 'bin', this.buildConfig, this.targetFramework); + const programDllPath = path.join(programOutputPath, 'CompilerExplorer.dll'); for (const configurableOption of configurableOptions) { const optionIndex = options.indexOf(configurableOption); @@ -200,14 +214,8 @@ class DotNetCompiler extends BaseCompiler { crossgen2Options.push(options[switchIndex]); } - const restoreOptions = ['restore', '--configfile', nugetConfigPath, '-v', 'q', '--nologo', '/clp:NoSummary']; - const restoreResult = await this.exec(compiler, restoreOptions, execOptions); - if (restoreResult.code !== 0) { - return this.transformToCompilationResult(restoreResult, inputFilename); - } - - const compilerResult = await super.runCompiler(compiler, this.compilerOptions, inputFilename, execOptions); - + this.setCompilerExecOptions(execOptions, programDir); + const compilerResult = await this.buildToDll(compiler, options, inputFilename, execOptions); if (compilerResult.code !== 0) { return compilerResult; }