Skip to content

Commit 70bd427

Browse files
committed
Fix for the compiler path in compile_commands.json file
Compiler path was wrongly created when anything was set on the "Prefix" option from "Cross Settings". The code needs to check if anything is set there before creating the default path for the compiler.
1 parent 04105c2 commit 70bd427

File tree

3 files changed

+65
-16
lines changed

3 files changed

+65
-16
lines changed

build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/CompilationDatabaseGenerationTest.java

+26
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
import static org.junit.jupiter.api.Assertions.assertTrue;
1717

1818
import java.io.FileReader;
19+
import java.util.Arrays;
20+
import java.util.List;
21+
import java.util.stream.Collectors;
1922

2023
import org.eclipse.cdt.managedbuilder.core.IBuilder;
2124
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
@@ -220,4 +223,27 @@ public void testMakeFileGenerationOff() throws Exception {
220223
app.build(IncrementalProjectBuilder.FULL_BUILD, null);
221224
assertFalse(app.getFile("Debug/compile_commands.json").exists());
222225
}
226+
227+
@Test
228+
public void testGetCompilerArgsWithSpacesAndQuotes() {
229+
String[] commandLine = { "gcc", "My file.c", "-o", "My file.o", "-DNAME=\"My Value\"",
230+
"C:\\Program Files\\Lib" };
231+
List<String> argsList = Arrays.asList(commandLine).subList(1, commandLine.length);
232+
String result = escapeArgsForCompileCommand(argsList);
233+
String expected = "\"My file.c\" -o \"My file.o\" \"-DNAME=\\\"My Value\\\"\" \"C:\\\\Program Files\\\\Lib\"";
234+
235+
assertEquals(expected, result);
236+
}
237+
238+
private static String escapeArgsForCompileCommand(List<String> args) {
239+
return args.stream().map(arg -> {
240+
if (arg.contains(" ") || arg.contains("\"") || arg.contains("\\")) {
241+
String escaped = arg.replace("\\", "\\\\").replace("\"", "\\\"");
242+
return "\"" + escaped + "\"";
243+
} else {
244+
return arg;
245+
}
246+
}).collect(Collectors.joining(" "));
247+
}
248+
223249
}

build/org.eclipse.cdt.managedbuilder.core/META-INF/MANIFEST.MF

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
22
Bundle-ManifestVersion: 2
33
Bundle-Name: %pluginName
44
Bundle-SymbolicName: org.eclipse.cdt.managedbuilder.core; singleton:=true
5-
Bundle-Version: 9.7.100.qualifier
5+
Bundle-Version: 9.7.101.qualifier
66
Bundle-Activator: org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin
77
Bundle-Vendor: %providerName
88
Bundle-Localization: plugin

build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/jsoncdb/generator/CompilationDatabaseGenerator.java

+38-15
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@
1414
import java.io.InputStream;
1515
import java.nio.charset.StandardCharsets;
1616
import java.util.ArrayList;
17+
import java.util.Arrays;
1718
import java.util.Collection;
1819
import java.util.HashMap;
1920
import java.util.LinkedHashSet;
2021
import java.util.List;
2122
import java.util.Map;
23+
import java.util.stream.Collectors;
2224

2325
import org.eclipse.cdt.core.CCorePlugin;
2426
import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
@@ -69,8 +71,9 @@ public final class CompilationDatabaseGenerator {
6971
/**
7072
* Checked on each build
7173
* 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.
7275
*/
73-
private Map<ITool, String> toolMap = new HashMap<>();
76+
private Map<String, String> toolMap = new HashMap<>();
7477
private IProject project;
7578
private IConfiguration configuration;
7679
private ICSourceEntry[] srcEntries;
@@ -229,18 +232,19 @@ private List<CompilationDatabaseInformation> populateObjList(IProject project, I
229232
outputLocation + "", inputStrings, sourceLocation, outputLocation); //$NON-NLS-1$
230233

231234
IBuildMacroProvider provider = ManagedBuildManager.getBuildMacroProvider();
232-
String compilerName = CompilationDatabaseGenerator.getCompilerName(tool);
233235
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);
236239
String resolvedOptionFileContents;
237240
if (compilerPath != null && !compilerPath.isEmpty()) {
238-
resolvedOptionFileContents = provider.resolveValueToMakefileFormat(compilerPath + " " + commandLine, //$NON-NLS-1$
241+
resolvedOptionFileContents = provider.resolveValueToMakefileFormat(
242+
compilerPath + " " + compilerArguments, //$NON-NLS-1$
239243
"", " ", //$NON-NLS-1$//$NON-NLS-2$
240244
IBuildMacroProvider.CONTEXT_FILE,
241245
new FileContextData(sourceLocation, outputLocation, null, tool));
242246
} else {
243-
resolvedOptionFileContents = provider.resolveValueToMakefileFormat(commandLine, "", " ", //$NON-NLS-1$//$NON-NLS-2$
247+
resolvedOptionFileContents = provider.resolveValueToMakefileFormat(compilerArguments, "", " ", //$NON-NLS-1$//$NON-NLS-2$
244248
IBuildMacroProvider.CONTEXT_FILE,
245249
new FileContextData(sourceLocation, outputLocation, null, tool));
246250

@@ -438,15 +442,15 @@ public boolean visit(IResourceProxy proxy) throws CoreException {
438442

439443
}
440444

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$
444449
}
445-
String compilerName = CompilationDatabaseGenerator.getCompilerName(tool);
446450
File pathToCompiler = new File(compilerName);
447451

448452
if (pathToCompiler.isAbsolute()) {
449-
toolMap.put(tool, compilerName);
453+
toolMap.put(cacheKey, compilerName);
450454
return "\"" + compilerName + "\""; //$NON-NLS-1$ //$NON-NLS-2$
451455
}
452456
ICConfigurationDescription cfg = ManagedBuildManager.getDescriptionForConfiguration(config);
@@ -458,7 +462,7 @@ private String findCompilerInPath(ITool tool, IConfiguration config) {
458462
IPath resolvedPath = PathUtil.findProgramLocation(compilerName, variable.getValue());
459463
if (resolvedPath != null) {
460464
String path = resolvedPath.toString();
461-
toolMap.put(tool, path);
465+
toolMap.put(cacheKey, path);
462466
return "\"" + path + "\""; //$NON-NLS-1$ //$NON-NLS-2$
463467
} else {
464468
return null; // Only one PATH so can exit early
@@ -469,13 +473,32 @@ private String findCompilerInPath(ITool tool, IConfiguration config) {
469473
return null;
470474
}
471475

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);
475478
if (arguments.length == 0) {
476479
return ""; //$NON-NLS-1$
477480
}
478481
return arguments[0];
479482
}
480483

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+
481504
}

0 commit comments

Comments
 (0)