Skip to content

CMake built-ins detection successful when compile_commands.json compiler #1095

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

Merged
merged 1 commit into from
Feb 26, 2025

Conversation

betamaxbandit
Copy link
Contributor

path is relative

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.(Spawner.java:147)
at org.eclipse.cdt.utils.spawner.Spawner.(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__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...

@betamaxbandit
Copy link
Contributor Author

Hi @jonahgraham
I've created a draft PR top fix this env issue.

  1. Is the commit message too long?

  2. I could not think of a way of creating a JUnit for this.
    Ideally I'd like to test the return result of, to check it contains the expected env:
    org.eclipse.cdt.jsoncdb.core.internal.builtins.CompilerBuiltinsDetector.getEnvp(IProject)
    But that method is private.
    Any ideas on how to tackle this please?

  3. I do have detailed instructions for a manual test. Should I simply attach those to this PR?

Copy link

github-actions bot commented Feb 23, 2025

Test Results

   602 files  ± 0     602 suites  ±0   13m 44s ⏱️ -16s
10 222 tests ± 0  10 198 ✅ ± 0  24 💤 ±0  0 ❌ ±0 
10 240 runs   - 20  10 216 ✅  - 20  24 💤 ±0  0 ❌ ±0 

Results for commit 6451743. ± Comparison against base commit 5135c9f.

♻️ This comment has been updated with latest results.

@jonahgraham
Copy link
Member

This code doesn't work right, interestingly it suffers from the same problem as the last point in this comment #1067 (comment)

This is the return value of getenvp:

image

Without your patch it looks like this:

image

Sadly neither is correct. In the first the null is clearly wrong, in the second the PATH is not pre-pended to the incoming PATH.

I think I will fix this @betamaxbandit - but I will send back to you for review.

@jonahgraham
Copy link
Member

In the new code the null arrives here

env.put(name, var.getValue() + var.getDelimiter() + env.get(name));

This code assumes that the value being prepended to is non-null. I will include the fix for this alongside this commit.

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 eclipse-cdt#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 <[email protected]>
@jonahgraham jonahgraham marked this pull request as ready for review February 25, 2025 01:55
@betamaxbandit
Copy link
Contributor Author

This code doesn't work right, interestingly it suffers from the same problem as the last point in this comment #1067 (comment)

This is the return value of getenvp:

image

Without your patch it looks like this:

image

Sadly neither is correct. In the first the null is clearly wrong, in the second the PATH is not pre-pended to the incoming PATH.

I think I will fix this @betamaxbandit - but I will send back to you for review.

Hmm, I never see a null at the end of PATH returned from getEnvp, when building on Windows. Maybe the setup is different on Linux.

I downloaded your latest PS for this change and applied changes from:
#1096
#1097
But when I attempt to launch a debug session on Windows, I get an error:

!MESSAGE Failure to start debug session
!STACK 0
java.util.concurrent.ExecutionException: org.eclipse.core.runtime.CoreException: Failed to execute MI command:
-gdb-set env =:: = ::\\
Error message from debugger back end:
Argument required (environment variable to set).
	at org.eclipse.cdt.dsf.concurrent.Query.get(Query.java:112)
	at org.eclipse.cdt.dsf.gdb.internal.launching.CoreBuildLocalDebugLaunchDelegate.launch(CoreBuildLocalDebugLaunchDelegate.java:149)
	at org.eclipse.debug.internal.core.LaunchConfiguration.launch(LaunchConfiguration.java:777)
	at org.eclipse.debug.internal.core.LaunchConfiguration.launch(LaunchConfiguration.java:688)
	at org.eclipse.debug.internal.ui.DebugUIPlugin.buildAndLaunch(DebugUIPlugin.java:1054)
	at org.eclipse.debug.internal.ui.DebugUIPlugin$1.run(DebugUIPlugin.java:1257)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)
Caused by: org.eclipse.core.runtime.CoreException: Failed to execute MI command:
-gdb-set env =:: = ::\\
Error message from debugger back end:
Argument required (environment variable to set).
	... 7 more

Maybe I'm missing something.

@jonahgraham
Copy link
Member

@betamaxbandit and I reviewed this together in a pair programming session

@jonahgraham jonahgraham merged commit e138646 into eclipse-cdt:main Feb 26, 2025
5 checks passed
@betamaxbandit betamaxbandit deleted the IDE-82683-REQ-011 branch February 26, 2025 10:15
@jonahgraham jonahgraham added this to the 12.0.0 milestone Mar 7, 2025
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.

2 participants