Skip to content

Commit 7420b12

Browse files
authored
Compiler path in compile_commands.json must be absolute (#824)
Added code to create the absolute path of the compiler on compile_commands.json file Fixes #822
1 parent 9e1be51 commit 7420b12

File tree

3 files changed

+101
-5
lines changed

3 files changed

+101
-5
lines changed

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

+32
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
import static org.junit.jupiter.api.Assertions.assertEquals;
1414
import static org.junit.jupiter.api.Assertions.assertFalse;
15+
import static org.junit.jupiter.api.Assertions.assertNotNull;
1516
import static org.junit.jupiter.api.Assertions.assertTrue;
1617

1718
import java.io.FileReader;
@@ -20,9 +21,12 @@
2021
import org.eclipse.cdt.managedbuilder.internal.core.CommonBuilder;
2122
import org.eclipse.cdt.managedbuilder.testplugin.AbstractBuilderTest;
2223
import org.eclipse.cdt.managedbuilder.testplugin.ManagedBuildTestHelper;
24+
import org.eclipse.cdt.utils.CommandLineUtil;
2325
import org.eclipse.core.resources.IFile;
2426
import org.eclipse.core.resources.IProject;
2527
import org.eclipse.core.resources.IncrementalProjectBuilder;
28+
import org.eclipse.core.runtime.IPath;
29+
import org.eclipse.core.runtime.Path;
2630
import org.eclipse.core.runtime.preferences.InstanceScope;
2731
import org.eclipse.jface.preference.IPreferenceStore;
2832
import org.eclipse.ui.preferences.ScopedPreferenceStore;
@@ -167,4 +171,32 @@ public void restoreDefaultForGenerateFile() {
167171
"org.eclipse.cdt.managedbuilder.ui");
168172
preferenceStore.setToDefault(CommonBuilder.COMPILATION_DATABASE_ENABLEMENT);
169173
}
174+
175+
@Test
176+
public void testCompilerPath() throws Exception {
177+
setWorkspace("regressions");
178+
final IProject app = loadProject("helloworldC");
179+
setGenerateFileOptionEnabled(true);
180+
app.build(IncrementalProjectBuilder.FULL_BUILD, null);
181+
IFile commandsFile = app.getFile("Debug/compile_commands.json");
182+
183+
if (commandsFile.exists()) {
184+
try (FileReader reader = new FileReader(commandsFile.getLocation().toFile())) {
185+
Gson gson = new Gson();
186+
JsonArray jsonArray = gson.fromJson(reader, JsonArray.class);
187+
for (JsonElement element : jsonArray) {
188+
CompilationDatabaseInformation compileCommand = gson.fromJson(element,
189+
CompilationDatabaseInformation.class);
190+
String command = compileCommand.command();
191+
String[] commandParts = CommandLineUtil.argumentsToArray(command);
192+
String compilerPath = commandParts[0];
193+
assertNotNull("Compiler path should not be null", compilerPath);
194+
assertFalse(compilerPath.isEmpty(), "Compiler path should not be empty");
195+
IPath path = new Path(compilerPath);
196+
boolean isAbsolute = path.isAbsolute();
197+
assertTrue(isAbsolute, "Path should be absolute: " + path);
198+
}
199+
}
200+
}
201+
}
170202
}

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.0.qualifier
5+
Bundle-Version: 9.7.100.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

+68-4
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,19 @@
1010
package org.eclipse.cdt.managedbuilder.internal.core.jsoncdb.generator;
1111

1212
import java.io.ByteArrayInputStream;
13+
import java.io.File;
1314
import java.io.InputStream;
1415
import java.nio.charset.StandardCharsets;
1516
import java.util.ArrayList;
1617
import java.util.Collection;
18+
import java.util.HashMap;
1719
import java.util.LinkedHashSet;
1820
import java.util.List;
21+
import java.util.Map;
1922

23+
import org.eclipse.cdt.core.CCorePlugin;
24+
import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
25+
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
2026
import org.eclipse.cdt.core.settings.model.ICSourceEntry;
2127
import org.eclipse.cdt.core.settings.model.util.CDataUtil;
2228
import org.eclipse.cdt.managedbuilder.core.BuildException;
@@ -34,6 +40,8 @@
3440
import org.eclipse.cdt.managedbuilder.internal.macros.FileContextData;
3541
import org.eclipse.cdt.managedbuilder.macros.BuildMacroException;
3642
import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider;
43+
import org.eclipse.cdt.utils.CommandLineUtil;
44+
import org.eclipse.cdt.utils.PathUtil;
3745
import org.eclipse.core.resources.IFile;
3846
import org.eclipse.core.resources.IFolder;
3947
import org.eclipse.core.resources.IProject;
@@ -58,7 +66,11 @@ public final class CompilationDatabaseGenerator {
5866

5967
private static final String CDB_FILENAME = "compile_commands.json"; //$NON-NLS-1$
6068
private static final String ERROR_MESSAGE = "Can not set contents to compile_commands.json file"; //$NON-NLS-1$
61-
69+
/**
70+
* Checked on each build
71+
* Used before we look up the environment
72+
*/
73+
private Map<ITool, String> toolMap = new HashMap<>();
6274
private IProject project;
6375
private IConfiguration configuration;
6476
private ICSourceEntry[] srcEntries;
@@ -217,10 +229,22 @@ private List<CompilationDatabaseInformation> populateObjList(IProject project, I
217229
outputLocation + "", inputStrings, sourceLocation, outputLocation); //$NON-NLS-1$
218230

219231
IBuildMacroProvider provider = ManagedBuildManager.getBuildMacroProvider();
220-
String resolvedOptionFileContents = provider.resolveValueToMakefileFormat(cmdLInfo.getCommandLine(), "", //$NON-NLS-1$
221-
" ", IBuildMacroProvider.CONTEXT_FILE, //$NON-NLS-1$
222-
new FileContextData(sourceLocation, outputLocation, null, tool));
232+
String compilerName = CompilationDatabaseGenerator.getCompilerName(tool);
233+
String commandLine = cmdLInfo.getCommandLine();
234+
commandLine = commandLine.replace(compilerName, "").trim(); //$NON-NLS-1$
235+
String compilerPath = findCompilerInPath(tool, config);
236+
String resolvedOptionFileContents;
237+
if (compilerPath != null && !compilerPath.isEmpty()) {
238+
resolvedOptionFileContents = provider.resolveValueToMakefileFormat(compilerPath + " " + commandLine, //$NON-NLS-1$
239+
"", " ", //$NON-NLS-1$//$NON-NLS-2$
240+
IBuildMacroProvider.CONTEXT_FILE,
241+
new FileContextData(sourceLocation, outputLocation, null, tool));
242+
} else {
243+
resolvedOptionFileContents = provider.resolveValueToMakefileFormat(commandLine, "", " ", //$NON-NLS-1$//$NON-NLS-2$
244+
IBuildMacroProvider.CONTEXT_FILE,
245+
new FileContextData(sourceLocation, outputLocation, null, tool));
223246

247+
}
224248
objList.add(new CompilationDatabaseInformation(project.getLocation().toString(),
225249
resolvedOptionFileContents, resource.getLocation().toString()));
226250
}
@@ -414,4 +438,44 @@ public boolean visit(IResourceProxy proxy) throws CoreException {
414438

415439
}
416440

441+
private String findCompilerInPath(ITool tool, IConfiguration config) {
442+
if (toolMap.containsKey(tool)) {
443+
return "\"" + toolMap.get(tool) + "\""; //$NON-NLS-1$//$NON-NLS-2$
444+
}
445+
String compilerName = CompilationDatabaseGenerator.getCompilerName(tool);
446+
File pathToCompiler = new File(compilerName);
447+
448+
if (pathToCompiler.isAbsolute()) {
449+
toolMap.put(tool, compilerName);
450+
return "\"" + compilerName + "\""; //$NON-NLS-1$ //$NON-NLS-2$
451+
}
452+
ICConfigurationDescription cfg = ManagedBuildManager.getDescriptionForConfiguration(config);
453+
IEnvironmentVariable[] variables = CCorePlugin.getDefault().getBuildEnvironmentManager().getVariables(cfg,
454+
true);
455+
456+
for (IEnvironmentVariable variable : variables) {
457+
if ("PATH".equalsIgnoreCase(variable.getName())) { //$NON-NLS-1$
458+
IPath resolvedPath = PathUtil.findProgramLocation(compilerName, variable.getValue());
459+
if (resolvedPath != null) {
460+
String path = resolvedPath.toString();
461+
toolMap.put(tool, path);
462+
return "\"" + path + "\""; //$NON-NLS-1$ //$NON-NLS-2$
463+
} else {
464+
return null; // Only one PATH so can exit early
465+
}
466+
}
467+
}
468+
469+
return null;
470+
}
471+
472+
private static String getCompilerName(ITool tool) {
473+
String compilerCommand = tool.getToolCommand();
474+
String[] arguments = CommandLineUtil.argumentsToArray(compilerCommand);
475+
if (arguments.length == 0) {
476+
return ""; //$NON-NLS-1$
477+
}
478+
return arguments[0];
479+
}
480+
417481
}

0 commit comments

Comments
 (0)