Skip to content

Fix for the compiler path in compile_commands.json file #1138

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

alicetrifu
Copy link
Contributor

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.

Copy link

github-actions bot commented Apr 10, 2025

Test Results

   602 files   -    34     602 suites   - 34   13m 17s ⏱️ - 23m 13s
10 222 tests  - 1 217  10 198 ✅  - 1 097  24 💤  - 120  0 ❌ ±0 
10 260 runs   - 1 194  10 236 ✅  - 1 076  24 💤  - 118  0 ❌ ±0 

Results for commit 2c4aa3f. ± Comparison against base commit 04105c2.

This pull request removes 1217 tests.
org.eclipse.cdt.debug.gdbjtag.core.tests.jtagdevice.GDBJtagDeviceContributionTest ‑ testGdbJtagDeviceContribution
org.eclipse.cdt.debug.gdbjtag.core.tests.launch.GDBJtagLaunchTest ‑ testGdbJtagLaunch[gdb]
org.eclipse.cdt.debug.gdbjtag.core.tests.launch.GDBJtagLaunchTest ‑ testGdbJtagLaunch[gdbserver]
org.eclipse.cdt.tests.dsf.gdb.tests.CommandLineArgsTest ‑ testSettingArgumentsWithQuotes[gdb]
org.eclipse.cdt.tests.dsf.gdb.tests.CommandLineArgsTest ‑ testSettingArgumentsWithQuotes[gdbserver]
org.eclipse.cdt.tests.dsf.gdb.tests.CommandLineArgsTest ‑ testSettingArgumentsWithSpecialSymbols[gdb]
org.eclipse.cdt.tests.dsf.gdb.tests.CommandLineArgsTest ‑ testSettingArgumentsWithSpecialSymbols[gdbserver]
org.eclipse.cdt.tests.dsf.gdb.tests.CommandLineArgsTest ‑ testSettingArgumentsWithSymbols[gdb]
org.eclipse.cdt.tests.dsf.gdb.tests.CommandLineArgsTest ‑ testSettingArgumentsWithSymbols[gdbserver]
org.eclipse.cdt.tests.dsf.gdb.tests.CommandLineArgsTest ‑ testSettingArgumentsWithTabs[gdb]
…

♻️ This comment has been updated with latest results.

@alicetrifu alicetrifu force-pushed the fixPathForCompiler1130 branch from 1151c1e to dabaf25 Compare April 10, 2025 14:34
private static String getCompilerName(ITool tool) {
private static String getCompilerName(ITool tool, IConfiguration config) {
IToolChain toolchain = config.getToolChain();
IOption option = toolchain.getOptionBySuperClassId("cdt.managedbuild.option.gnu.cross.prefix"); //$NON-NLS-1$
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this solution is sufficient. Or rather it does special case the cross gcc implementation, but does not solve the general case outlined in #1130.

Can you use the result of IManagedCommandLineGenerator (as done cmdLInfo.getCommandLine(); does) to get the resolved command name of the generator?

I am thinking that a better solution to absolute paths is to parse the result of cmdLInfo.getCommandLine(); with CommandLineUtil.argumentsToArray and use that as the compiler name.

Copy link
Member

@jonahgraham jonahgraham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like roughly the correct solution. Just some cleanup and review the caching.

@@ -229,10 +229,10 @@ private List<CompilationDatabaseInformation> populateObjList(IProject project, I
outputLocation + "", inputStrings, sourceLocation, outputLocation); //$NON-NLS-1$

IBuildMacroProvider provider = ManagedBuildManager.getBuildMacroProvider();
String compilerName = CompilationDatabaseGenerator.getCompilerName(tool);
String compilerName = CompilationDatabaseGenerator.getCompilerName(tool, config, cmdLInfo);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor change - instead of passing cmdLInfo to getCompilerName, move this line below String commandLine = cmdLInfo.getCommandLine(); and pass commandLine to getCompilerName

private static String getCompilerName(ITool tool) {
String compilerCommand = tool.getToolCommand();
String[] arguments = CommandLineUtil.argumentsToArray(compilerCommand);
private static String getCompilerName(ITool tool, IConfiguration config, IManagedCommandLineInfo cmdLInfo) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tool and config arguments are unused AFAICT.

@@ -438,11 +438,11 @@ public boolean visit(IResourceProxy proxy) throws CoreException {

}

private String findCompilerInPath(ITool tool, IConfiguration config) {
private String findCompilerInPath(ITool tool, IConfiguration config, IManagedCommandLineInfo cmdLInfo) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the toolMap cache is now incorrect - the key should probably be tool + compiler name before it is expanded, or even just the compiler name before it is expanded

@alicetrifu alicetrifu force-pushed the fixPathForCompiler1130 branch from 080da79 to d448a14 Compare April 10, 2025 15:57
Copy link
Member

@jonahgraham jonahgraham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works well in the normal cases, but there are some corner cases that aren't handled well, see the individual comments.

String commandLine = cmdLInfo.getCommandLine();
String compilerName = CompilationDatabaseGenerator.getCompilerName(commandLine);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The replace on the next line does not work reliabliy. Please revisit this bit of code. For example, if commandLine has this contents:

"name of compiler" -O0 input.c -i output.o

Then compilerName will be name of compiler and after the replace the command line will be:

"" -O0 input.c -i output.o

which leads to, resolvedOptionFileContents being:

"/full/path/to/name of compiler" "" -O0 input.c -i output.o

Instead of doing replace use the parsed information of CommandLineUtil.argumentsToArray to convert the commandLine into two parts, the compilerName (i.e. argv[0]) and the rest of the command line as a string.

if (toolMap.containsKey(tool)) {
return "\"" + toolMap.get(tool) + "\""; //$NON-NLS-1$//$NON-NLS-2$
private String findCompilerInPath(ITool tool, IConfiguration config, String compilerName) {
String cacheKey = tool + " " + compilerName; //$NON-NLS-1$
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The toString of ITool is just the externalized name of the tool, not really suitable for using as a key here.

That said and on further examination, we only need to consider tool for the cache key if the compilerName is not unique enough. AFAICT it is unique with a compilation, so probably easiest to just drop tool entirely here.

Suggested change
String cacheKey = tool + " " + compilerName; //$NON-NLS-1$
String cacheKey = compilerName; //$NON-NLS-1$

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.
@alicetrifu alicetrifu force-pushed the fixPathForCompiler1130 branch from d448a14 to 2c4aa3f Compare April 11, 2025 07:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

CDT fails to generate correct commands in compile_commands.json file
2 participants