Skip to content

Commit 976e5ed

Browse files
committed
C#: Pass --compiler flag to extractor on Linux
1 parent 8158d45 commit 976e5ed

File tree

6 files changed

+60
-36
lines changed

6 files changed

+60
-36
lines changed

csharp/config/tracer/linux/csharp-compiler-settings

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
**/mcs.exe:
22
**/csc.exe:
33
invoke ${env.SEMMLE_PLATFORM_TOOLS}/csharp/Semmle.Extraction.CSharp.Driver
4+
prepend --compiler
5+
prepend "${compiler}"
46
prepend --cil
57
**/bin/mono*:
68
**/dotnet:

csharp/config/tracer/linux/extract-csharp.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ do
99
if [[ `basename -- "$i"` =~ csc.exe|mcs.exe|csc.dll ]]
1010
then
1111
echo extract-csharp.sh: exec $extractor --cil $@
12-
exec "$extractor" --cil $@
12+
exec "$extractor" --compiler $i --cil $@
1313
fi
1414
done
1515

csharp/extractor/Semmle.Extraction.CSharp/Analyser.cs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,12 @@ public Analyser(IProgressMonitor pm, ILogger logger)
4646
/// <param name="commandLineArguments">Arguments passed to csc.</param>
4747
/// <param name="compilationIn">The Roslyn compilation.</param>
4848
/// <param name="options">Extractor options.</param>
49+
/// <param name="roslynArgs">The arguments passed to Roslyn.</param>
4950
public void Initialize(
5051
CSharpCommandLineArguments commandLineArguments,
5152
CSharpCompilation compilationIn,
52-
Options options)
53+
Options options,
54+
string[] roslynArgs)
5355
{
5456
compilation = compilationIn;
5557

@@ -58,7 +60,7 @@ public void Initialize(
5860

5961
extractor = new Extraction.Extractor(false, GetOutputName(compilation, commandLineArguments), Logger);
6062

61-
LogDiagnostics();
63+
LogDiagnostics(roslynArgs);
6264
SetReferencePaths();
6365

6466
CompilationErrors += FilteredDiagnostics.Count();
@@ -113,7 +115,7 @@ public void InitializeStandalone(CSharpCompilation compilationIn, CommonOptions
113115
layout = new Layout();
114116
extractor = new Extraction.Extractor(true, null, Logger);
115117
this.options = options;
116-
LogDiagnostics();
118+
LogDiagnostics(null);
117119
SetReferencePaths();
118120
}
119121

@@ -409,7 +411,8 @@ void AppendQuoted(StringBuilder sb, string s)
409411
/// Logs detailed information about this invocation,
410412
/// in the event that errors were detected.
411413
/// </summary>
412-
public void LogDiagnostics()
414+
/// <param name="roslynArgs">The arguments passed to Roslyn.</param>
415+
public void LogDiagnostics(string[] roslynArgs)
413416
{
414417
Logger.Log(Severity.Info, " Current working directory: {0}", Directory.GetCurrentDirectory());
415418
Logger.Log(Severity.Info, " Extractor: {0}", Environment.GetCommandLineArgs().First());
@@ -438,6 +441,9 @@ public void LogDiagnostics()
438441
}
439442
Logger.Log(Severity.Info, sb.ToString());
440443

444+
if (roslynArgs != null)
445+
Logger.Log(Severity.Info, $" Arguments to Roslyn: {string.Join(' ', roslynArgs)}");
446+
441447
foreach (var error in FilteredDiagnostics)
442448
{
443449
Logger.Log(Severity.Error, " Compilation error: {0}", error);

csharp/extractor/Semmle.Extraction.CSharp/CompilerVersion.cs

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
using System.Collections.Generic;
12
using System.Diagnostics;
23
using System.IO;
4+
using System.Linq;
35
using System.Runtime.InteropServices;
46

57
namespace Semmle.Extraction.CSharp
@@ -53,24 +55,34 @@ public CompilerVersion(Options options)
5355
var versionInfo = FileVersionInfo.GetVersionInfo(SpecifiedCompiler);
5456

5557
var compilerDir = Path.GetDirectoryName(SpecifiedCompiler);
56-
bool known_compiler_name = versionInfo.OriginalFilename == "csc.exe" || versionInfo.OriginalFilename == "csc2.exe";
57-
bool copyright_microsoft = versionInfo.LegalCopyright != null && versionInfo.LegalCopyright.Contains("Microsoft");
58-
bool mscorlib_exists = File.Exists(Path.Combine(compilerDir, "mscorlib.dll"));
58+
var known_compiler_names = new Dictionary<string, string>
59+
{
60+
{ "csc.exe", "Microsoft" },
61+
{ "csc2.exe", "Microsoft" },
62+
{ "csc.dll", "Microsoft" },
63+
{ "mcs.exe", "Novell" }
64+
};
65+
var mscorlib_exists = File.Exists(Path.Combine(compilerDir, "mscorlib.dll"));
5966

6067
if (specifiedFramework == null && mscorlib_exists)
6168
{
6269
specifiedFramework = compilerDir;
6370
}
6471

65-
if (!known_compiler_name)
72+
if (!known_compiler_names.TryGetValue(versionInfo.OriginalFilename, out var vendor))
6673
{
67-
SkipExtractionBecause("the exe name is not recognised");
74+
SkipExtractionBecause("the compiler name is not recognised");
75+
return;
6876
}
69-
else if (!copyright_microsoft)
77+
78+
if (versionInfo.LegalCopyright == null || !versionInfo.LegalCopyright.Contains(vendor))
7079
{
71-
SkipExtractionBecause("the exe isn't copyright Microsoft");
80+
SkipExtractionBecause($"the compiler isn't copyright {vendor}, but instead {versionInfo.LegalCopyright ?? "<null>"}");
81+
return;
7282
}
7383
}
84+
85+
ArgsWithResponse = AddDefaultResponse(CscRsp, options.CompilerArguments).ToArray();
7486
}
7587

7688
void SkipExtractionBecause(string reason)
@@ -87,7 +99,7 @@ void SkipExtractionBecause(string reason)
8799
/// <summary>
88100
/// The file csc.rsp.
89101
/// </summary>
90-
public string CscRsp => Path.Combine(FrameworkPath, csc_rsp);
102+
string CscRsp => Path.Combine(FrameworkPath, csc_rsp);
91103

92104
/// <summary>
93105
/// Should we skip extraction?
@@ -103,5 +115,25 @@ public bool SkipExtraction
103115
/// Gets additional reference directories - the compiler directory.
104116
/// </summary>
105117
public string AdditionalReferenceDirectories => SpecifiedCompiler != null ? Path.GetDirectoryName(SpecifiedCompiler) : null;
118+
119+
/// <summary>
120+
/// Adds @csc.rsp to the argument list to mimic csc.exe.
121+
/// </summary>
122+
/// <param name="responseFile">The full pathname of csc.rsp.</param>
123+
/// <param name="args">The other command line arguments.</param>
124+
/// <returns>Modified list of arguments.</returns>
125+
static IEnumerable<string> AddDefaultResponse(string responseFile, IEnumerable<string> args)
126+
{
127+
return SuppressDefaultResponseFile(args) && File.Exists(responseFile) ?
128+
args :
129+
new[] { "@" + responseFile }.Concat(args);
130+
}
131+
132+
static bool SuppressDefaultResponseFile(IEnumerable<string> args)
133+
{
134+
return args.Any(arg => new[] { "/noconfig", "-noconfig" }.Contains(arg.ToLowerInvariant()));
135+
}
136+
137+
public readonly string[] ArgsWithResponse;
106138
}
107139
}

csharp/extractor/Semmle.Extraction.CSharp/Extractor.cs

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,9 @@ public static ExitCode Run(string[] args)
8787
return ExitCode.Ok;
8888
}
8989

90-
var argsWithResponse = AddDefaultResponse(compilerVersion.CscRsp, commandLineArguments.CompilerArguments);
91-
9290
var cwd = Directory.GetCurrentDirectory();
9391
var compilerArguments = CSharpCommandLineParser.Default.Parse(
94-
argsWithResponse,
92+
compilerVersion.ArgsWithResponse,
9593
cwd,
9694
compilerVersion.FrameworkPath,
9795
compilerVersion.AdditionalReferenceDirectories
@@ -128,7 +126,7 @@ public static ExitCode Run(string[] args)
128126
{
129127
logger.Log(Severity.Error, " No source files");
130128
++analyser.CompilationErrors;
131-
analyser.LogDiagnostics();
129+
analyser.LogDiagnostics(compilerVersion.ArgsWithResponse);
132130
return ExitCode.Failed;
133131
}
134132

@@ -146,7 +144,7 @@ public static ExitCode Run(string[] args)
146144
// already.
147145
);
148146

149-
analyser.Initialize(compilerArguments, compilation, commandLineArguments);
147+
analyser.Initialize(compilerArguments, compilation, commandLineArguments, compilerVersion.ArgsWithResponse);
150148
analyser.AnalyseReferences();
151149

152150
foreach (var tree in compilation.SyntaxTrees)
@@ -172,24 +170,6 @@ public static ExitCode Run(string[] args)
172170
}
173171
}
174172

175-
internal static bool SuppressDefaultResponseFile(IEnumerable<string> args)
176-
{
177-
return args.Any(arg => new[] { "/noconfig", "-noconfig" }.Contains(arg.ToLowerInvariant()));
178-
}
179-
180-
/// <summary>
181-
/// Adds @csc.rsp to the argument list to mimic csc.exe.
182-
/// </summary>
183-
/// <param name="responseFile">The full pathname of csc.rsp.</param>
184-
/// <param name="args">The other command line arguments.</param>
185-
/// <returns>Modified list of arguments.</returns>
186-
static IEnumerable<string> AddDefaultResponse(string responseFile, IEnumerable<string> args)
187-
{
188-
return SuppressDefaultResponseFile(args) && File.Exists(responseFile) ?
189-
args :
190-
new[] { "@" + responseFile }.Concat(args);
191-
}
192-
193173
/// <summary>
194174
/// Gets the complete list of locations to locate references.
195175
/// </summary>

csharp/extractor/Semmle.Extraction/Context.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,10 @@ public void PopulateAll()
171171
{
172172
populateQueue.Dequeue()();
173173
}
174+
catch (InternalError e)
175+
{
176+
Extractor.Message(e.ExtractionMessage);
177+
}
174178
catch (Exception e)
175179
{
176180
Extractor.Message(new Message { severity = Severity.Error, exception = e, message = "Uncaught exception" });

0 commit comments

Comments
 (0)