mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-03-28 14:56:28 +01:00
Ensure full ICBuildConfiguration environment is used during scanning (#1095)
Under certain conditions*, the compiler param in the command field of the compile_commands.json is a relative path rather than absolute. When this happens, the built-ins detection was not successful and the following exception was thrown: !ENTRY org.eclipse.cdt.core 4 0 2025-02-23 20:32:10.752 !MESSAGE Error: Cannot run program "gcc": Launching failed !STACK 0 java.io.IOException: Cannot run program "gcc": Launching failed at org.eclipse.cdt.utils.spawner.Spawner.exec(Spawner.java:450) at org.eclipse.cdt.utils.spawner.Spawner.<init>(Spawner.java:147) at org.eclipse.cdt.utils.spawner.Spawner.<init>(Spawner.java:134) at org.eclipse.cdt.utils.spawner.ProcessFactory$Builder.start(ProcessFactory.java:273) at org.eclipse.cdt.utils.spawner.ProcessFactory.exec(ProcessFactory.java:366) at org.eclipse.cdt.core.CommandLauncher.execute(CommandLauncher.java:189) at org.eclipse.cdt.jsoncdb.core.internal.builtins.CompilerBuiltinsDetector.detectBuiltins(CompilerBuiltinsDetector.java:111) at org.eclipse.cdt.jsoncdb.core.CompileCommandsJsonParser.detectBuiltins(CompileCommandsJsonParser.java:290) at org.eclipse.cdt.jsoncdb.core.CompileCommandsJsonParser.processJsonFile(CompileCommandsJsonParser.java:193) at org.eclipse.cdt.jsoncdb.core.CompileCommandsJsonParser.parse(CompileCommandsJsonParser.java:455) at org.eclipse.cdt.cmake.core.CMakeBuildConfiguration.processCompileCommandsFile(CMakeBuildConfiguration.java:361) at org.eclipse.cdt.cmake.core.CMakeBuildConfiguration.build(CMakeBuildConfiguration.java:241) This meant that source file includes were not indexed and could not be opened using Open Declaration (F3) and info markers of the following type appeared in the Problems view: gcc -E -P -dM -Wp,-v "...extCmakegcc\\build\\cmake.run.win32.x86_64.Local\\detect_compiler_builtins.c" Cannot run program "gcc": Launching failed Error: Program "gcc" not found in PATH PATH=[...] extCmakegcc Unknown Compiler Builtins Detector Problem gcc -E -P -dM -Wp,-v "...extCmakegcc\\build\\cmake.run.win32.x86_64.Local\\detect_compiler_builtins.c" Cannot run program "gcc": Launching failed This patch fixes the environment issue for Core Build projects, by calling ICBuildConfiguration.setBuildEnvironment(Map<String, String>) as part of the built-ins detection setup, thereby supporting absolute and relative compiler paths. Addresses Issue: CDT CMake Improvements #1000, IDE-82683-REQ-011 Source code navigation and Built-ins detection *: CMake produces relative compiler path When the CMAKE_<LANG>_COMPILER variable (eg CMAKE_C_COMPILER) is set in the CMakeLists.txt *after* the project() or language commands, it causes a relative path to be used. For example, in the CMakeLists.txt below, gcc is set after project() command: cmake_minimum_required(VERSION 3.10) project (track2) set(CMAKE_C_COMPILER gcc) add_executable(${PROJECT_NAME} track2.c) The above script creates a relative compiler path in compile_commands.json: "command": "gcc -O3 -DNDEBUG -o ... Normally the CMAKE_C_COMPILER variable should be set before the project() comannd. "command": "C:\\msys64\\mingw64\\bin\\c++.exe -IC... Co-authored-by: Jonah Graham <jonah@kichwacoders.com>
This commit is contained in:
parent
74c4844357
commit
e138646434
1 changed files with 45 additions and 19 deletions
|
@ -17,10 +17,13 @@ import java.util.Date;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.ConsoleOutputStream;
|
||||
import org.eclipse.cdt.core.ICommandLauncher;
|
||||
import org.eclipse.cdt.core.build.ICBuildConfiguration;
|
||||
import org.eclipse.cdt.core.build.ICBuildConfigurationManager;
|
||||
import org.eclipse.cdt.core.resources.IConsole;
|
||||
import org.eclipse.cdt.jsoncdb.core.IParserPreferences;
|
||||
import org.eclipse.cdt.jsoncdb.core.IParserPreferencesAccess;
|
||||
|
@ -29,6 +32,8 @@ import org.eclipse.cdt.jsoncdb.core.participant.IRawSourceFileInfo;
|
|||
import org.eclipse.cdt.jsoncdb.core.participant.builtins.IBuiltinsDetectionBehavior;
|
||||
import org.eclipse.cdt.jsoncdb.core.participant.builtins.IBuiltinsOutputProcessor;
|
||||
import org.eclipse.cdt.jsoncdb.core.participant.builtins.OutputSniffer;
|
||||
import org.eclipse.cdt.utils.spawner.EnvironmentReader;
|
||||
import org.eclipse.core.resources.IBuildConfiguration;
|
||||
import org.eclipse.core.resources.IMarker;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
@ -185,25 +190,8 @@ public class CompilerBuiltinsDetector {
|
|||
* return {@code null}.
|
||||
*/
|
||||
private String[] getEnvp(IProject project) {
|
||||
var map = new HashMap<String, String>();
|
||||
// The cc.exe from mingw64 (part of Msys2) on Windows needs the bin folder to be on the PATH to be executed.
|
||||
// e.g. 'C:\msys64\mingw64\bin' must be part of the PATH environment variable. That's why we need PATH here:
|
||||
// Fixes CDT #407
|
||||
try {
|
||||
final String path = "PATH"; //$NON-NLS-1$
|
||||
var variables = CCorePlugin.getDefault().getBuildEnvironmentManager()
|
||||
.getVariables(project.getActiveBuildConfig(), true);
|
||||
for (var variable : variables) {
|
||||
if (path.equalsIgnoreCase(variable.getName())) {
|
||||
map.put(path, variable.getValue());
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
Plugin.getDefault().getLog().error(
|
||||
String.format(Messages.CompilerBuiltinsDetector_errmsg_determine_PATH_failed, project.getName()),
|
||||
e);
|
||||
}
|
||||
var map = getProjectEnvp(project);
|
||||
|
||||
// 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
|
||||
|
@ -227,6 +215,44 @@ public class CompilerBuiltinsDetector {
|
|||
return envArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the project's environment. This applies any project specific environment
|
||||
* to the system environment.
|
||||
*/
|
||||
private HashMap<String, String> getProjectEnvp(IProject project) {
|
||||
var map = new HashMap<String, String>();
|
||||
Properties environmentVariables = EnvironmentReader.getEnvVars();
|
||||
for (String key : environmentVariables.stringPropertyNames()) {
|
||||
String value = environmentVariables.getProperty(key);
|
||||
map.put(key, value);
|
||||
}
|
||||
|
||||
IBuildConfiguration active = null;
|
||||
try {
|
||||
active = project.getActiveBuildConfig();
|
||||
if (active == null) {
|
||||
// unreachable, getActiveBuildConfig is documented as not returning null.
|
||||
} else {
|
||||
var manager = CCorePlugin.getService(ICBuildConfigurationManager.class);
|
||||
ICBuildConfiguration cBuildConfiguration = manager.getBuildConfiguration(active);
|
||||
|
||||
if (cBuildConfiguration != null) {
|
||||
// If this project is Core Build, use its specialisation of getBuildEnvironmentManager
|
||||
// to get the environment.
|
||||
cBuildConfiguration.setBuildEnvironment(map);
|
||||
} else {
|
||||
CCorePlugin.getDefault().getBuildEnvironmentManager().setEnvironment(map, active, true);
|
||||
}
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
Plugin.getDefault().getLog().error(
|
||||
String.format(Messages.CompilerBuiltinsDetector_errmsg_determine_PATH_failed, project.getName()),
|
||||
e);
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a path to the source file which is the input for the compiler. The file
|
||||
* will be created with no content in the build directory.
|
||||
|
|
Loading…
Add table
Reference in a new issue