Skip to content

feat(docker): add Linux LSP support by fixing compile_commands.json paths#2303

Open
abhatem wants to merge 1 commit intoTheSuperHackers:mainfrom
abhatem:compile-commands
Open

feat(docker): add Linux LSP support by fixing compile_commands.json paths#2303
abhatem wants to merge 1 commit intoTheSuperHackers:mainfrom
abhatem:compile-commands

Conversation

@abhatem
Copy link

@abhatem abhatem commented Feb 13, 2026

Summary

This PR improves the development experience for Linux contributors by making the compile_commands.json generated inside the Docker container usable on the host machine.

Problem

Currently, when building with docker-build.sh, the generated compile_commands.json contains:

  1. Container paths: /build/cnc/... instead of the host's workspace path.
  2. Windows-style backslashes: \ which confuse Linux LSP servers (like clangd/ccls).
  3. Drive letters: Z: references from Wine.

This causes "Go to Definition" and other LSP features to fail in Linux editors (VS Code, Emacs, Neovim) because they cannot locate the source files.

Solution

  1. Added scripts/fix_compile_commands.py: A Python script that:
    • Rewrites container paths to host absolute paths.
    • Normalizes backslashes to forward slashes.
    • Strips Wine drive letters.
  2. Updated scripts/docker-build.sh: Automatically runs the fix script after a successful build if python3 is detected.

Testing

  • Verified docker-build.sh still compiles the game successfully.
  • Verified compile_commands.json is generated and paths are correctly mapped to the host.
  • Verified LSP (clangd) works in Emacs/Eglot on Linux.

Notes

scripts/fix_compile_commands.py was mostly AI generated but human verified and tested

@greptile-apps
Copy link

greptile-apps bot commented Feb 13, 2026

Greptile Overview

Greptile Summary

This PR successfully enables LSP support for Linux developers by automatically fixing compile_commands.json paths after Docker builds. The implementation adds a post-build step that transforms container paths (/build/cnc) to host paths, normalizes Windows backslashes to forward slashes, and strips Wine drive letters.

Key Changes:

  • Added fix_compile_commands() function in docker-build.sh that runs automatically after successful non-interactive builds
  • Created scripts/fix_compile_commands.py to perform path transformations on the JSON compilation database
  • The fix runs conditionally (only if python3 is available and compile_commands.json exists) with graceful error handling

Notes:

  • Previous review comments about missing copyright header and unused re import appear to have been addressed (copyright is present, no re import in current version)
  • The dead code comment about the if path.startswith('/') block with only pass is no longer relevant - that code doesn't exist in the current version
  • Path replacement order in command strings works correctly but relies on final Z: stripping to handle edge cases where /build/cnc is replaced before Z:/build/cnc

Confidence Score: 4/5

  • Safe to merge with minor considerations about path replacement robustness
  • The implementation is well-tested and addresses a real developer experience issue. The bash integration is clean with proper error handling. The Python script logic works correctly, though the string replacement order in the command processing could theoretically cause issues if a Linux path contained 'Z:' (extremely unlikely). Since the author tested it with actual LSP tools and the changes are isolated to developer tooling (not production code), the risk is minimal.
  • No files require special attention - both changes are straightforward tooling improvements

Important Files Changed

Filename Overview
scripts/docker-build.sh Added fix_compile_commands() function to automatically fix compile_commands.json paths after build, with proper error handling
scripts/fix_compile_commands.py New Python script to transform Docker container paths to host paths for LSP support; logic works but replacement order could be more robust

Sequence Diagram

sequenceDiagram
    participant User
    participant docker-build.sh
    participant Docker Container
    participant fix_compile_commands.py
    participant Host Filesystem

    User->>docker-build.sh: Execute build script
    docker-build.sh->>Docker Container: Run build in container
    Docker Container->>Host Filesystem: Generate compile_commands.json<br/>(with container paths /build/cnc)
    docker-build.sh->>fix_compile_commands.py: Run post-build fix script
    fix_compile_commands.py->>Host Filesystem: Read compile_commands.json<br/>from build/docker/
    fix_compile_commands.py->>fix_compile_commands.py: Transform paths:<br/>- /build/cnc → host path<br/>- backslashes → forward slashes<br/>- strip Wine drive letters
    fix_compile_commands.py->>Host Filesystem: Write fixed compile_commands.json<br/>to project root
    docker-build.sh->>User: Build complete, LSP ready
Loading

Last reviewed commit: db5cdaf

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

2 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

Comment on lines 1 to 10
#!/usr/bin/env python3
"""
Compile commands fixer for Linux development.
This script makes the compile_commands.json generated by the Docker build
usable on the Linux host by:
- Rewriting container paths (/build/cnc) to host absolute paths.
- Converting Windows backslashes to forward slashes.
- Stripping Wine drive letters (Z:).
"""
Copy link

Choose a reason for hiding this comment

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

Missing copyright header. Since this is a newly created community file, add:

Suggested change
#!/usr/bin/env python3
"""
Compile commands fixer for Linux development.
This script makes the compile_commands.json generated by the Docker build
usable on the Linux host by:
- Rewriting container paths (/build/cnc) to host absolute paths.
- Converting Windows backslashes to forward slashes.
- Stripping Wine drive letters (Z:).
"""
#!/usr/bin/env python3
# Copyright 2026 TheSuperHackers
#
# This file is part of Command & Conquer: Generals and Command & Conquer: Zero Hour.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
Compile commands fixer for Linux development.
This script makes the compile_commands.json generated by the Docker build
usable on the Linux host by:
- Rewriting container paths (/build/cnc) to host absolute paths.
- Converting Windows backslashes to forward slashes.
- Stripping Wine drive letters (Z:).
"""

Context Used: Rule from dashboard - Only flag missing GPL license headers in file prologues. Do not comment about missing or incomplete ... (source)

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix With AI
This is a comment left during a code review.
Path: scripts/fix_compile_commands.py
Line: 1:10

Comment:
Missing copyright header. Since this is a newly created community file, add:
```suggestion
#!/usr/bin/env python3
# Copyright 2026 TheSuperHackers
#
# This file is part of Command & Conquer: Generals and Command & Conquer: Zero Hour.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
Compile commands fixer for Linux development.

This script makes the compile_commands.json generated by the Docker build
usable on the Linux host by:
- Rewriting container paths (/build/cnc) to host absolute paths.
- Converting Windows backslashes to forward slashes.
- Stripping Wine drive letters (Z:).
"""
```

**Context Used:** Rule from `dashboard` - Only flag missing GPL license headers in file prologues. Do not comment about missing or incomplete ... ([source](https://app.greptile.com/review/custom-context?memory=1cd6ffcb-aeb0-457d-899f-184a39b97b1e))

<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>

How can I resolve this? If you propose a fix, please make it concise.

import json
import os
import sys
import re
Copy link

Choose a reason for hiding this comment

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

Unused import re - not used anywhere in the code

Suggested change
import re
Prompt To Fix With AI
This is a comment left during a code review.
Path: scripts/fix_compile_commands.py
Line: 15:15

Comment:
Unused import `re` - not used anywhere in the code

```suggestion
```

How can I resolve this? If you propose a fix, please make it concise.

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

2 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines 44 to 48
# Handle paths that might start with just \build\cnc (from Windows context)
if path.startswith('/'):
# Already handled or unrelated absolute path
pass

Copy link

Choose a reason for hiding this comment

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

Dead code - the if path.startswith('/') block only contains a pass statement and always returns the unmodified path at line 49. This doesn't affect functionality but is unnecessary.

Suggested change
# Handle paths that might start with just \build\cnc (from Windows context)
if path.startswith('/'):
# Already handled or unrelated absolute path
pass
# Replace the container mount point with the host root directory
# The container mounts the project at /build/cnc
if path.startswith('/build/cnc'):
return os.path.join(root_dir, path[len('/build/cnc'):].lstrip('/'))
return path
Prompt To Fix With AI
This is a comment left during a code review.
Path: scripts/fix_compile_commands.py
Line: 44:48

Comment:
Dead code - the `if path.startswith('/')` block only contains a `pass` statement and always returns the unmodified `path` at line 49. This doesn't affect functionality but is unnecessary.

```suggestion
    # Replace the container mount point with the host root directory
    # The container mounts the project at /build/cnc
    if path.startswith('/build/cnc'):
        return os.path.join(root_dir, path[len('/build/cnc'):].lstrip('/'))

    return path
```

How can I resolve this? If you propose a fix, please make it concise.

….json

Added scripts/fix_compile_commands.py to rewrite container paths to host paths and updated scripts/docker-build.sh to automatically run it after build.
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.

1 participant