diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/CompilationDatabaseGenerationTest.java b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/CompilationDatabaseGenerationTest.java index 6bb958844b5..6f5e47011bc 100644 --- a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/CompilationDatabaseGenerationTest.java +++ b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/CompilationDatabaseGenerationTest.java @@ -10,9 +10,10 @@ *******************************************************************************/ package org.eclipse.cdt.managedbuilder.core.tests; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertNotNull; import java.io.FileReader; @@ -20,9 +21,12 @@ import org.eclipse.cdt.managedbuilder.internal.core.CommonBuilder; import org.eclipse.cdt.managedbuilder.testplugin.AbstractBuilderTest; import org.eclipse.cdt.managedbuilder.testplugin.ManagedBuildTestHelper; +import org.eclipse.cdt.utils.CommandLineUtil; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IncrementalProjectBuilder; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.ui.preferences.ScopedPreferenceStore; @@ -167,4 +171,32 @@ public void restoreDefaultForGenerateFile() { "org.eclipse.cdt.managedbuilder.ui"); preferenceStore.setToDefault(CommonBuilder.COMPILATION_DATABASE_ENABLEMENT); } + + @Test + public void testCompilerPath() throws Exception { + setWorkspace("regressions"); + final IProject app = loadProject("helloworldC"); + setGenerateFileOptionEnabled(true); + app.build(IncrementalProjectBuilder.FULL_BUILD, null); + IFile commandsFile = app.getFile("Debug/compile_commands.json"); + + if (commandsFile.exists()) { + try (FileReader reader = new FileReader(commandsFile.getLocation().toFile())) { + Gson gson = new Gson(); + JsonArray jsonArray = gson.fromJson(reader, JsonArray.class); + for (JsonElement element : jsonArray) { + CompilationDatabaseInformation compileCommand = gson.fromJson(element, + CompilationDatabaseInformation.class); + String command = compileCommand.command(); + String[] commandParts = CommandLineUtil.argumentsToArray(command); + String compilerPath = commandParts[0]; + assertNotNull("Compiler path should not be null", compilerPath); + assertFalse("Compiler path should not be empty", compilerPath.isEmpty()); + IPath path = new Path(compilerPath); + boolean isAbsolute = path.isAbsolute(); + assertTrue("Path should be absolute: " + path, isAbsolute); + } + } + } + } } diff --git a/build/org.eclipse.cdt.managedbuilder.core/META-INF/MANIFEST.MF b/build/org.eclipse.cdt.managedbuilder.core/META-INF/MANIFEST.MF index 3d59b08efd7..ed04c80138c 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/META-INF/MANIFEST.MF +++ b/build/org.eclipse.cdt.managedbuilder.core/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.cdt.managedbuilder.core; singleton:=true -Bundle-Version: 9.7.0.qualifier +Bundle-Version: 9.7.100.qualifier Bundle-Activator: org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin Bundle-Vendor: %providerName Bundle-Localization: plugin diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/jsoncdb/generator/CompilationDatabaseGenerator.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/jsoncdb/generator/CompilationDatabaseGenerator.java index 70382ed667d..6c144d9c01f 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/jsoncdb/generator/CompilationDatabaseGenerator.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/jsoncdb/generator/CompilationDatabaseGenerator.java @@ -10,13 +10,19 @@ package org.eclipse.cdt.managedbuilder.internal.core.jsoncdb.generator; import java.io.ByteArrayInputStream; +import java.io.File; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.LinkedHashSet; import java.util.List; +import java.util.Map; +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.envvar.IEnvironmentVariable; +import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICSourceEntry; import org.eclipse.cdt.core.settings.model.util.CDataUtil; import org.eclipse.cdt.managedbuilder.core.BuildException; @@ -34,6 +40,8 @@ import org.eclipse.cdt.managedbuilder.internal.macros.FileContextData; import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; +import org.eclipse.cdt.utils.CommandLineUtil; +import org.eclipse.cdt.utils.PathUtil; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; @@ -58,7 +66,11 @@ public final class CompilationDatabaseGenerator { private static final String CDB_FILENAME = "compile_commands.json"; //$NON-NLS-1$ private static final String ERROR_MESSAGE = "Can not set contents to compile_commands.json file"; //$NON-NLS-1$ - + /** + * Checked on each build + * Used before we look up the environment + */ + private Map toolMap = new HashMap<>(); private IProject project; private IConfiguration configuration; private ICSourceEntry[] srcEntries; @@ -217,10 +229,22 @@ private List populateObjList(IProject project, I outputLocation + "", inputStrings, sourceLocation, outputLocation); //$NON-NLS-1$ IBuildMacroProvider provider = ManagedBuildManager.getBuildMacroProvider(); - String resolvedOptionFileContents = provider.resolveValueToMakefileFormat(cmdLInfo.getCommandLine(), "", //$NON-NLS-1$ - " ", IBuildMacroProvider.CONTEXT_FILE, //$NON-NLS-1$ - new FileContextData(sourceLocation, outputLocation, null, tool)); + String compilerName = CompilationDatabaseGenerator.getCompilerName(tool); + String commandLine = cmdLInfo.getCommandLine(); + commandLine = commandLine.replace(compilerName, "").trim(); //$NON-NLS-1$ + String compilerPath = findCompilerInPath(tool, config); + String resolvedOptionFileContents; + if (compilerPath != null && !compilerPath.isEmpty()) { + resolvedOptionFileContents = provider.resolveValueToMakefileFormat(compilerPath + " " + commandLine, //$NON-NLS-1$ + "", " ", //$NON-NLS-1$//$NON-NLS-2$ + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(sourceLocation, outputLocation, null, tool)); + } else { + resolvedOptionFileContents = provider.resolveValueToMakefileFormat(commandLine, "", " ", //$NON-NLS-1$//$NON-NLS-2$ + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(sourceLocation, outputLocation, null, tool)); + } objList.add(new CompilationDatabaseInformation(project.getLocation().toString(), resolvedOptionFileContents, resource.getLocation().toString())); } @@ -414,4 +438,44 @@ public boolean visit(IResourceProxy proxy) throws CoreException { } + private String findCompilerInPath(ITool tool, IConfiguration config) { + if (toolMap.containsKey(tool)) { + return "\"" + toolMap.get(tool) + "\""; //$NON-NLS-1$//$NON-NLS-2$ + } + String compilerName = CompilationDatabaseGenerator.getCompilerName(tool); + File pathToCompiler = new File(compilerName); + + if (pathToCompiler.isAbsolute()) { + toolMap.put(tool, compilerName); + return "\"" + compilerName + "\""; //$NON-NLS-1$ //$NON-NLS-2$ + } + ICConfigurationDescription cfg = ManagedBuildManager.getDescriptionForConfiguration(config); + IEnvironmentVariable[] variables = CCorePlugin.getDefault().getBuildEnvironmentManager().getVariables(cfg, + true); + + for (IEnvironmentVariable variable : variables) { + if ("PATH".equalsIgnoreCase(variable.getName())) { //$NON-NLS-1$ + IPath resolvedPath = PathUtil.findProgramLocation(compilerName, variable.getValue()); + if (resolvedPath != null) { + String path = resolvedPath.toString(); + toolMap.put(tool, path); + return "\"" + path + "\""; //$NON-NLS-1$ //$NON-NLS-2$ + } else { + return null; // Only one PATH so can exit early + } + } + } + + return null; + } + + private static String getCompilerName(ITool tool) { + String compilerCommand = tool.getToolCommand(); + String[] arguments = CommandLineUtil.argumentsToArray(compilerCommand); + if (arguments.length == 0) { + return ""; //$NON-NLS-1$ + } + return arguments[0]; + } + }