14
14
import java .io .InputStream ;
15
15
import java .nio .charset .StandardCharsets ;
16
16
import java .util .ArrayList ;
17
+ import java .util .Arrays ;
17
18
import java .util .Collection ;
18
19
import java .util .HashMap ;
19
20
import java .util .LinkedHashSet ;
20
21
import java .util .List ;
21
22
import java .util .Map ;
23
+ import java .util .stream .Collectors ;
22
24
23
25
import org .eclipse .cdt .core .CCorePlugin ;
24
26
import org .eclipse .cdt .core .envvar .IEnvironmentVariable ;
@@ -69,8 +71,9 @@ public final class CompilationDatabaseGenerator {
69
71
/**
70
72
* Checked on each build
71
73
* Used before we look up the environment
74
+ * Map of compiler name (as calculated by {@link #getCompilerName(String)}) to the absolute path of the compiler.
72
75
*/
73
- private Map <ITool , String > toolMap = new HashMap <>();
76
+ private Map <String , String > toolMap = new HashMap <>();
74
77
private IProject project ;
75
78
private IConfiguration configuration ;
76
79
private ICSourceEntry [] srcEntries ;
@@ -229,18 +232,19 @@ private List<CompilationDatabaseInformation> populateObjList(IProject project, I
229
232
outputLocation + "" , inputStrings , sourceLocation , outputLocation ); //$NON-NLS-1$
230
233
231
234
IBuildMacroProvider provider = ManagedBuildManager .getBuildMacroProvider ();
232
- String compilerName = CompilationDatabaseGenerator .getCompilerName (tool );
233
235
String commandLine = cmdLInfo .getCommandLine ();
234
- commandLine = commandLine .replace (compilerName , "" ).trim (); //$NON-NLS-1$
235
- String compilerPath = findCompilerInPath (tool , config );
236
+ String compilerName = CompilationDatabaseGenerator .getCompilerName (commandLine );
237
+ String compilerArguments = getCompilerArgs (commandLine );
238
+ String compilerPath = findCompilerInPath (config , compilerName );
236
239
String resolvedOptionFileContents ;
237
240
if (compilerPath != null && !compilerPath .isEmpty ()) {
238
- resolvedOptionFileContents = provider .resolveValueToMakefileFormat (compilerPath + " " + commandLine , //$NON-NLS-1$
241
+ resolvedOptionFileContents = provider .resolveValueToMakefileFormat (
242
+ compilerPath + " " + compilerArguments , //$NON-NLS-1$
239
243
"" , " " , //$NON-NLS-1$//$NON-NLS-2$
240
244
IBuildMacroProvider .CONTEXT_FILE ,
241
245
new FileContextData (sourceLocation , outputLocation , null , tool ));
242
246
} else {
243
- resolvedOptionFileContents = provider .resolveValueToMakefileFormat (commandLine , "" , " " , //$NON-NLS-1$//$NON-NLS-2$
247
+ resolvedOptionFileContents = provider .resolveValueToMakefileFormat (compilerArguments , "" , " " , //$NON-NLS-1$//$NON-NLS-2$
244
248
IBuildMacroProvider .CONTEXT_FILE ,
245
249
new FileContextData (sourceLocation , outputLocation , null , tool ));
246
250
@@ -438,15 +442,15 @@ public boolean visit(IResourceProxy proxy) throws CoreException {
438
442
439
443
}
440
444
441
- private String findCompilerInPath (ITool tool , IConfiguration config ) {
442
- if (toolMap .containsKey (tool )) {
443
- return "\" " + toolMap .get (tool ) + "\" " ; //$NON-NLS-1$//$NON-NLS-2$
445
+ private String findCompilerInPath (IConfiguration config , String compilerName ) {
446
+ String cacheKey = compilerName ;
447
+ if (toolMap .containsKey (cacheKey )) {
448
+ return "\" " + toolMap .get (cacheKey ) + "\" " ; //$NON-NLS-1$//$NON-NLS-2$
444
449
}
445
- String compilerName = CompilationDatabaseGenerator .getCompilerName (tool );
446
450
File pathToCompiler = new File (compilerName );
447
451
448
452
if (pathToCompiler .isAbsolute ()) {
449
- toolMap .put (tool , compilerName );
453
+ toolMap .put (cacheKey , compilerName );
450
454
return "\" " + compilerName + "\" " ; //$NON-NLS-1$ //$NON-NLS-2$
451
455
}
452
456
ICConfigurationDescription cfg = ManagedBuildManager .getDescriptionForConfiguration (config );
@@ -458,7 +462,7 @@ private String findCompilerInPath(ITool tool, IConfiguration config) {
458
462
IPath resolvedPath = PathUtil .findProgramLocation (compilerName , variable .getValue ());
459
463
if (resolvedPath != null ) {
460
464
String path = resolvedPath .toString ();
461
- toolMap .put (tool , path );
465
+ toolMap .put (cacheKey , path );
462
466
return "\" " + path + "\" " ; //$NON-NLS-1$ //$NON-NLS-2$
463
467
} else {
464
468
return null ; // Only one PATH so can exit early
@@ -469,13 +473,32 @@ private String findCompilerInPath(ITool tool, IConfiguration config) {
469
473
return null ;
470
474
}
471
475
472
- private static String getCompilerName (ITool tool ) {
473
- String compilerCommand = tool .getToolCommand ();
474
- String [] arguments = CommandLineUtil .argumentsToArray (compilerCommand );
476
+ private static String getCompilerName (String commandLine ) {
477
+ String [] arguments = CommandLineUtil .argumentsToArray (commandLine );
475
478
if (arguments .length == 0 ) {
476
479
return "" ; //$NON-NLS-1$
477
480
}
478
481
return arguments [0 ];
479
482
}
480
483
484
+ private static String getCompilerArgs (String commandLine ) {
485
+ String [] arguments = CommandLineUtil .argumentsToArray (commandLine );
486
+ if (arguments .length <= 1 ) {
487
+ return "" ; //$NON-NLS-1$
488
+ }
489
+ List <String > argsList = Arrays .asList (arguments ).subList (1 , arguments .length );
490
+ return escArgsForCompileCommand (argsList );
491
+ }
492
+
493
+ private static String escArgsForCompileCommand (final List <String > args ) {
494
+ return args .stream ().map (arg -> {
495
+ if (arg .contains (" " ) || arg .contains ("\" " ) || arg .contains ("\\ " )) { //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
496
+ String escaped = arg .replace ("\\ " , "\\ \\ " ).replace ("\" " , "\\ \" " ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$//$NON-NLS-4$
497
+ return "\" " + escaped + "\" " ; //$NON-NLS-1$//$NON-NLS-2$
498
+ } else {
499
+ return arg ;
500
+ }
501
+ }).collect (Collectors .joining (" " )); //$NON-NLS-1$
502
+ }
503
+
481
504
}
0 commit comments