diff --git a/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeBuildConfiguration.java b/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeBuildConfiguration.java index 7c6a9e65b67..1bc008aa377 100644 --- a/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeBuildConfiguration.java +++ b/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeBuildConfiguration.java @@ -144,7 +144,7 @@ public class CMakeBuildConfiguration extends CBuildConfiguration { runCMake = true; } - ICMakeProperties cmakeProperties = pc.load(); + ICMakeProperties cmakeProperties = getPropertiesController().load(); runCMake |= !Files.exists(buildDir.resolve("CMakeCache.txt")); //$NON-NLS-1$ IOsOverrides overrides = extractCMakeOsOverrides(cmakeProperties); @@ -263,7 +263,7 @@ public class CMakeBuildConfiguration extends CBuildConfiguration { project.deleteMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE); - ICMakeProperties cmakeProperties = pc.load(); + ICMakeProperties cmakeProperties = getPropertiesController().load(); IOsOverrides overrides = extractCMakeOsOverrides(cmakeProperties); List command = makeCMakeBuildCommandline(cmakeProperties, overrides, "clean"); //$NON-NLS-1$ ConsoleOutputStream outStream = console.getOutputStream(); @@ -430,8 +430,9 @@ public class CMakeBuildConfiguration extends CBuildConfiguration { * @param monitor the job's progress monitor */ private void processCompileCommandsFile(IConsole console, IProgressMonitor monitor) throws CoreException { + IFile file = getBuildContainer().getFile(new org.eclipse.core.runtime.Path("compile_commands.json")); //$NON-NLS-1$ CompileCommandsJsonParser parser = new CompileCommandsJsonParser( - new ParseRequest(this, new CMakeIndexerInfoConsumer(this::setScannerInformation), + new ParseRequest(file, new CMakeIndexerInfoConsumer(this::setScannerInformation), CommandLauncherManager.getInstance().getCommandLauncher(this), console)); parser.parse(monitor); } @@ -464,7 +465,7 @@ public class CMakeBuildConfiguration extends CBuildConfiguration { */ private CMakePropertiesController getPropertiesController() { if (pc == null) { - Path filePath = Path.of(getProject().getFile(".settings/CDT-cmake.yaml").getLocationURI()); //$NON-NLS-1$ + final Path filePath = Path.of(getProject().getFile(".settings/CDT-cmake.yaml").getLocationURI()); //$NON-NLS-1$ pc = new CMakePropertiesController(filePath, () -> { deleteCMakeCache = true; // TODO delete cache file here for the case a user restarts the workbench diff --git a/cmake/org.eclipse.cdt.cmake.is.core/src/org/eclipse/cdt/cmake/is/core/CompileCommandsJsonParser.java b/cmake/org.eclipse.cdt.cmake.is.core/src/org/eclipse/cdt/cmake/is/core/CompileCommandsJsonParser.java index e7164ff8139..1445ff14853 100644 --- a/cmake/org.eclipse.cdt.cmake.is.core/src/org/eclipse/cdt/cmake/is/core/CompileCommandsJsonParser.java +++ b/cmake/org.eclipse.cdt.cmake.is.core/src/org/eclipse/cdt/cmake/is/core/CompileCommandsJsonParser.java @@ -13,7 +13,6 @@ import java.io.FileReader; import java.io.IOException; import java.io.Reader; import java.nio.file.Files; -import java.nio.file.Paths; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -39,7 +38,6 @@ import org.eclipse.cdt.cmake.is.core.participant.IToolCommandlineParser; import org.eclipse.cdt.cmake.is.core.participant.IToolCommandlineParser.IResult; import org.eclipse.cdt.cmake.is.core.participant.IToolDetectionParticipant; import org.eclipse.cdt.cmake.is.core.participant.builtins.IBuiltinsDetectionBehavior; -import org.eclipse.cdt.core.build.CBuildConfiguration; import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; @@ -142,15 +140,14 @@ public class CompileCommandsJsonParser { * @throws CoreException */ private boolean processJsonFile(IProgressMonitor monitor) throws CoreException { - final CBuildConfiguration configuration = parseRequest.getBuildConfiguration(); - final IProject project = configuration.getBuildConfiguration().getProject(); - java.nio.file.Path buildRoot = Paths.get(configuration.getBuildDirectoryURI()); + final IFile jsonFile = parseRequest.getFile(); + final IProject project = jsonFile.getProject(); project.deleteMarkers(MARKER_ID, false, IResource.DEPTH_INFINITE); - final java.nio.file.Path jsonFile = buildRoot.resolve("compile_commands.json"); //$NON-NLS-1$ - if (!Files.exists(jsonFile)) { + final java.nio.file.Path jsonDiskFile = java.nio.file.Path.of(jsonFile.getLocationURI()); + if (!Files.exists(jsonDiskFile)) { // no json file was produced in the build - final String msg = String.format(Messages.CompileCommandsJsonParser_errmsg_file_not_found, jsonFile, + final String msg = String.format(Messages.CompileCommandsJsonParser_errmsg_file_not_found, jsonDiskFile, WORKBENCH_WILL_NOT_KNOW_ALL_MSG); createMarker(project, msg); return false; @@ -158,42 +155,41 @@ public class CompileCommandsJsonParser { // file exists on disk... long tsJsonModified = 0; try { - tsJsonModified = Files.getLastModifiedTime(jsonFile).toMillis(); + tsJsonModified = Files.getLastModifiedTime(jsonDiskFile).toMillis(); } catch (IOException e) { // treat as 'file is not modified' return false; } - IContainer buildContainer = configuration.getBuildContainer(); - final IFile jsonFileRc = buildContainer.getFile(new Path("compile_commands.json")); //$NON-NLS-1$ - Long sessionLastModified = (Long) buildContainer.getSessionProperty(TIMESTAMP_COMPILE_COMMANDS_PROPERTY); + IContainer buildRootFolder = jsonFile.getParent(); + Long sessionLastModified = (Long) buildRootFolder.getSessionProperty(TIMESTAMP_COMPILE_COMMANDS_PROPERTY); if (sessionLastModified == null || sessionLastModified.longValue() < tsJsonModified) { // must parse json file... monitor.setTaskName(Messages.CompileCommandsJsonParser_msg_processing); - try (Reader in = new FileReader(jsonFile.toFile())) { + try (Reader in = new FileReader(jsonDiskFile.toFile())) { // parse file... Gson gson = new Gson(); CommandEntry[] sourceFileInfos = gson.fromJson(in, CommandEntry[].class); for (CommandEntry sourceFileInfo : sourceFileInfos) { - processCommandEntry(sourceFileInfo, jsonFileRc); + processCommandEntry(sourceFileInfo, jsonFile); } } catch (JsonSyntaxException | JsonIOException ex) { // file format error - final String msg = String.format(Messages.CompileCommandsJsonParser_errmsg_not_json, jsonFile, + final String msg = String.format(Messages.CompileCommandsJsonParser_errmsg_not_json, jsonDiskFile, WORKBENCH_WILL_NOT_KNOW_ALL_MSG); - createMarker(jsonFileRc, msg); + createMarker(jsonFile, msg); return false; } catch (IOException ex) { - final String msg = String.format(Messages.CompileCommandsJsonParser_errmsg_read_error, jsonFile, + final String msg = String.format(Messages.CompileCommandsJsonParser_errmsg_read_error, jsonDiskFile, WORKBENCH_WILL_NOT_KNOW_ALL_MSG); - createMarker(jsonFileRc, msg); + createMarker(jsonFile, msg); return false; } detectBuiltins(monitor); // store time-stamp - buildContainer.setSessionProperty(TIMESTAMP_COMPILE_COMMANDS_PROPERTY, tsJsonModified); + buildRootFolder.setSessionProperty(TIMESTAMP_COMPILE_COMMANDS_PROPERTY, tsJsonModified); return true; } return false; @@ -266,13 +262,15 @@ public class CompileCommandsJsonParser { return; monitor.setTaskName(Messages.CompileCommandsJsonParser_msg_detecting_builtins); - java.nio.file.Path buildDir = parseRequest.getBuildConfiguration().getBuildDirectory(); + final IFile jsonFile = parseRequest.getFile(); + final IContainer buildRootFolder = jsonFile.getParent(); + + java.nio.file.Path buildDir = java.nio.file.Path.of(buildRootFolder.getLocationURI()); // run each built-in detector and collect the results.. Map builtinDetectorsResults = new HashMap<>(); for (Entry entry : builtinDetectorsToRun.entrySet()) { - IRawIndexerInfo result = entry.getValue().detectBuiltins( - parseRequest.getBuildConfiguration().getBuildConfiguration(), buildDir, parseRequest.getLauncher(), - parseRequest.getConsole(), monitor); + IRawIndexerInfo result = entry.getValue().detectBuiltins(jsonFile.getProject(), buildDir, + parseRequest.getLauncher(), parseRequest.getConsole(), monitor); // store detector key with result builtinDetectorsResults.put(entry.getKey(), result); } @@ -431,8 +429,8 @@ public class CompileCommandsJsonParser { try { if (DEBUG_TIME) { - System.out.printf("Project %s parsing compile_commands.json ...%n", //$NON-NLS-1$ - parseRequest.getBuildConfiguration().getProject().getName()); + System.out.printf("Parsing file '%s' ...%n", //$NON-NLS-1$ + parseRequest.getFile().getLocationURI().getPath()); start = System.currentTimeMillis(); } return processJsonFile(monitor); @@ -440,8 +438,8 @@ public class CompileCommandsJsonParser { parseRequest.getIndexerInfoConsumer().shutdown(); if (DEBUG_TIME) { long end = System.currentTimeMillis(); - System.out.printf("Project %s parsed compile_commands.json file in %dms%n", //$NON-NLS-1$ - parseRequest.getBuildConfiguration().getProject().getName(), end - start); + System.out.printf("Parsed file '%s' in %dms%n", //$NON-NLS-1$ + parseRequest.getFile().getLocationURI().getPath(), end - start); } // clean up builtinDetectorsToRun = null; diff --git a/cmake/org.eclipse.cdt.cmake.is.core/src/org/eclipse/cdt/cmake/is/core/ParseRequest.java b/cmake/org.eclipse.cdt.cmake.is.core/src/org/eclipse/cdt/cmake/is/core/ParseRequest.java index 913e042056e..d6ab7b15db7 100644 --- a/cmake/org.eclipse.cdt.cmake.is.core/src/org/eclipse/cdt/cmake/is/core/ParseRequest.java +++ b/cmake/org.eclipse.cdt.cmake.is.core/src/org/eclipse/cdt/cmake/is/core/ParseRequest.java @@ -14,22 +14,22 @@ package org.eclipse.cdt.cmake.is.core; import java.util.Objects; import org.eclipse.cdt.core.ICommandLauncher; -import org.eclipse.cdt.core.build.CBuildConfiguration; import org.eclipse.cdt.core.resources.IConsole; +import org.eclipse.core.resources.IFile; /** Holds the arguments used to create a {@link CompileCommandsJsonParser}. * * @author weber */ public final class ParseRequest { - private final CBuildConfiguration buildConfiguration; + private final IFile compileCommandsJson; private final IIndexerInfoConsumer indexerInfoConsumer; private final ICommandLauncher launcher; private final IConsole console; /** Creates a new ParseRequest object. * - * @param buildConfiguration the build configuration of the project + * @param compileCommandsJsonFile the file to parse * @param indexerInfoConsumer the object that receives the indexer relevant * information for each source file * @param launcher the launcher to run the compiler for built-ins detection. @@ -39,18 +39,18 @@ public final class ParseRequest { * detection to or null if no console output is requested. * Ignored if workspace preferences indicate that no console output is wanted. */ - public ParseRequest(CBuildConfiguration buildConfiguration, IIndexerInfoConsumer indexerInfoConsumer, + public ParseRequest(IFile compileCommandsJsonFile, IIndexerInfoConsumer indexerInfoConsumer, ICommandLauncher launcher, IConsole console) { - this.buildConfiguration = Objects.requireNonNull(buildConfiguration, "buildConfiguration"); //$NON-NLS-1$ + this.compileCommandsJson = Objects.requireNonNull(compileCommandsJsonFile, "compileCommandsJsonFile"); //$NON-NLS-1$ this.indexerInfoConsumer = Objects.requireNonNull(indexerInfoConsumer, "indexerInfoConsumer"); //$NON-NLS-1$ this.launcher = Objects.requireNonNull(launcher, "launcher"); //$NON-NLS-1$ this.console = console; } - /** Gets the build configuration of the project. + /** Gets the 'compile_commands.json' file to parse. */ - public CBuildConfiguration getBuildConfiguration() { - return buildConfiguration; + public IFile getFile() { + return compileCommandsJson; } /** Gets the object that receives the indexer relevant diff --git a/cmake/org.eclipse.cdt.cmake.is.core/src/org/eclipse/cdt/cmake/is/core/internal/builtins/CompilerBuiltinsDetector.java b/cmake/org.eclipse.cdt.cmake.is.core/src/org/eclipse/cdt/cmake/is/core/internal/builtins/CompilerBuiltinsDetector.java index dc72cf15f58..a16f97d6bca 100644 --- a/cmake/org.eclipse.cdt.cmake.is.core/src/org/eclipse/cdt/cmake/is/core/internal/builtins/CompilerBuiltinsDetector.java +++ b/cmake/org.eclipse.cdt.cmake.is.core/src/org/eclipse/cdt/cmake/is/core/internal/builtins/CompilerBuiltinsDetector.java @@ -14,10 +14,8 @@ import java.nio.file.Files; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; -import java.util.HashSet; import java.util.List; import java.util.Objects; -import java.util.Set; import org.eclipse.cdt.cmake.is.core.IParserPreferences; import org.eclipse.cdt.cmake.is.core.IParserPreferencesAccess; @@ -26,13 +24,9 @@ import org.eclipse.cdt.cmake.is.core.participant.IRawIndexerInfo; import org.eclipse.cdt.cmake.is.core.participant.builtins.IBuiltinsDetectionBehavior; import org.eclipse.cdt.cmake.is.core.participant.builtins.IBuiltinsOutputProcessor; import org.eclipse.cdt.cmake.is.core.participant.builtins.OutputSniffer; -import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.ConsoleOutputStream; import org.eclipse.cdt.core.ICommandLauncher; -import org.eclipse.cdt.core.envvar.IEnvironmentVariable; -import org.eclipse.cdt.core.envvar.IEnvironmentVariableManager; import org.eclipse.cdt.core.resources.IConsole; -import org.eclipse.core.resources.IBuildConfiguration; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; @@ -59,7 +53,7 @@ public class CompilerBuiltinsDetector { private final List builtinsDetectionArgs; private final IBuiltinsDetectionBehavior builtinsDetectionBehavior; - private IBuildConfiguration buildConfiguration; + private IProject project; private java.nio.file.Path buildDirectory; /** @@ -84,18 +78,18 @@ public class CompilerBuiltinsDetector { /** * Runs built-in detection. * - * @param buildConfiguration the project build configuration to use - * @param theBuildDirectory the build directory of the build configuration - * @param launcher the launcher that can run in docker container, if - * any + * @param project the project + * @param buildDirectory the build root directory. This is the working directory of the compiler process. Temporary, + * but cacheable input files for the compiler are generated her also + * @param launcher the launcher for the compiler process * @param console the console to print the compiler output to or * null if no console output is requested. * @throws CoreException */ - public IRawIndexerInfo detectBuiltins(IBuildConfiguration buildConfiguration, java.nio.file.Path theBuildDirectory, + public IRawIndexerInfo detectBuiltins(IProject project, java.nio.file.Path buildDirectory, ICommandLauncher launcher, IConsole console, IProgressMonitor monitor) throws CoreException { - this.buildConfiguration = Objects.requireNonNull(buildConfiguration, "buildConfiguration"); //$NON-NLS-1$ - this.buildDirectory = Objects.requireNonNull(theBuildDirectory, "buildDirectory"); //$NON-NLS-1$ + this.project = Objects.requireNonNull(project, "project"); //$NON-NLS-1$ + this.buildDirectory = Objects.requireNonNull(buildDirectory, "buildDirectory"); //$NON-NLS-1$ if (monitor == null) { monitor = new NullProgressMonitor(); @@ -108,7 +102,7 @@ public class CompilerBuiltinsDetector { console = startOutputConsole(console); - launcher.setProject(buildConfiguration.getProject()); + launcher.setProject(project); launcher.showCommand(console != null); final Process proc = launcher.execute(new Path(command), argList.toArray(new String[argList.size()]), getEnvp(), new Path(this.buildDirectory.toString()), monitor); @@ -166,33 +160,25 @@ public class CompilerBuiltinsDetector { } /** - * Get environment variables from configuration as array of "var=value" suitable - * for using as "envp" with Runtime.exec(String[] cmdarray, String[] envp, File - * dir) + * Get environment variables from configuration as array of "var=value". * * @return String array of environment variables in format "var=value". Does not * return {@code null}. */ private String[] getEnvp() { - IEnvironmentVariableManager mngr = CCorePlugin.getDefault().getBuildEnvironmentManager(); - IEnvironmentVariable[] vars = mngr.getVariables(buildConfiguration, true); - // Convert into envp strings - Set strings = new HashSet<>(vars.length); - for (IEnvironmentVariable var : vars) { - if (var.getName().startsWith("LANGUAGE" + '=') || var.getName().startsWith("LC_ALL" + '=')) //$NON-NLS-1$ //$NON-NLS-2$ - continue; - strings.add(var.getName() + '=' + var.getValue()); - } // On POSIX (Linux, UNIX) systems reset language variables to default (English) // with UTF-8 encoding since GNU compilers can handle only UTF-8 characters. // Include paths with locale characters will be handled properly regardless // of the language as long as the encoding is set to UTF-8. // English language is set for parser because it relies on English messages - // in the output of the 'gcc -v' builtinsDetectionArgs. - strings.add("LANGUAGE" + "=en"); // override for GNU gettext //$NON-NLS-1$ //$NON-NLS-2$ - strings.add("LC_ALL" + "=C.UTF-8"); // for other parts of the system libraries //$NON-NLS-1$ //$NON-NLS-2$ + // in the output of the 'gcc -v'. + String[] strings = { + // override for GNU gettext + "LANGUAGE" + "=en", //$NON-NLS-1$//$NON-NLS-2$ + // for other parts of the system libraries + "LC_ALL" + "=C.UTF-8" }; //$NON-NLS-1$ //$NON-NLS-2$ - return strings.toArray(new String[strings.size()]); + return strings; } /** @@ -218,7 +204,7 @@ public class CompilerBuiltinsDetector { } private void createMarker(String message) throws CoreException { - IMarker marker = buildConfiguration.getProject().createMarker(MARKER_ID); + IMarker marker = project.createMarker(MARKER_ID); marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_INFO); marker.setAttribute(IMarker.MESSAGE, message); } @@ -235,15 +221,12 @@ public class CompilerBuiltinsDetector { .getServiceContext(FrameworkUtil.getBundle(getClass()).getBundleContext()) .get(IParserPreferencesAccess.class).getWorkspacePreferences(); if (console != null && prefs.getAllocateConsole()) { - IProject project = buildConfiguration.getProject(); console.start(project); try { final ConsoleOutputStream cis = console.getInfoStream(); String msg; msg = String.format(Messages.CompilerBuiltinsDetector_msg_detection_start, - SimpleDateFormat.getTimeInstance().format(new Date()), project.getName(), - buildConfiguration.getName().isEmpty() ? "?" : buildConfiguration.getName(), //$NON-NLS-1$ - String.join(" ", builtinsDetectionArgs)); //$NON-NLS-1$ + SimpleDateFormat.getTimeInstance().format(new Date()), project.getName()); cis.write(msg.getBytes()); cis.write("\n".getBytes()); //$NON-NLS-1$ } catch (IOException ignore) { diff --git a/cmake/org.eclipse.cdt.cmake.is.core/src/org/eclipse/cdt/cmake/is/core/internal/builtins/messages.properties b/cmake/org.eclipse.cdt.cmake.is.core/src/org/eclipse/cdt/cmake/is/core/internal/builtins/messages.properties index 72bdef23577..03b19c5f6cf 100644 --- a/cmake/org.eclipse.cdt.cmake.is.core/src/org/eclipse/cdt/cmake/is/core/internal/builtins/messages.properties +++ b/cmake/org.eclipse.cdt.cmake.is.core/src/org/eclipse/cdt/cmake/is/core/internal/builtins/messages.properties @@ -13,5 +13,5 @@ ############################################################################### CompilerBuiltinsDetector_errmsg_command_failed=%1$s exited with status %2$d. CompilerBuiltinsDetector_msg_detection_finished=Detecting compiler built-ins took %d ms. -CompilerBuiltinsDetector_msg_detection_start=%1$s Detecting compiler built-ins: %2$s::%3$s for '%4$s' +CompilerBuiltinsDetector_msg_detection_start=%1$s Detecting compiler built-ins for project '%2$s' DetectorConsole_title=Compiler Built-ins Detection Console