Skip to content

Commit f79f6be

Browse files
authored
build(docker): Add Linux LSP support by fixing compile_commands.json paths (TheSuperHackers#2303)
1 parent d813f9f commit f79f6be

2 files changed

Lines changed: 113 additions & 0 deletions

File tree

scripts/docker-build.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,17 @@ build_docker_image() {
128128
print_success "Docker image ready"
129129
}
130130

131+
fix_compile_commands() {
132+
local fix_script="$SCRIPT_DIR/fix_compile_commands.py"
133+
if [[ -f "$fix_script" ]] && command -v python3 &>/dev/null; then
134+
# Only run if compile_commands.json exists in the build dir
135+
if [[ -f "$BUILD_DIR/compile_commands.json" ]]; then
136+
print_info "Fixing compile_commands.json for host environment..."
137+
python3 "$fix_script" || print_warning "Failed to fix compile_commands.json"
138+
fi
139+
fi
140+
}
141+
131142
run_build() {
132143
local force_cmake="$1"
133144
local target="$2"
@@ -266,6 +277,7 @@ build_docker_image
266277
run_build "$FORCE_CMAKE" "$TARGET" "$INTERACTIVE"
267278

268279
if [[ "$INTERACTIVE" != "true" ]]; then
280+
fix_compile_commands
269281
list_outputs
270282

271283
echo ""

scripts/fix_compile_commands.py

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
#!/usr/bin/env python3
2+
# Copyright 2026 TheSuperHackers
3+
#
4+
# This file is part of Command & Conquer: Generals and Command & Conquer: Zero Hour.
5+
#
6+
# This program is free software: you can redistribute it and/or modify
7+
# it under the terms of the GNU General Public License as published by
8+
# the Free Software Foundation, either version 3 of the License, or
9+
# (at your option) any later version.
10+
#
11+
# This program is distributed in the hope that it will be useful,
12+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
# GNU General Public License for more details.
15+
#
16+
# You should have received a copy of the GNU General Public License
17+
# along with this program. If not, see <https://www.gnu.org/licenses/>.
18+
19+
"""
20+
Compile commands fixer for Linux development.
21+
22+
This script makes the compile_commands.json generated by the Docker build
23+
usable on the Linux host by:
24+
- Rewriting container paths (/build/cnc) to host absolute paths.
25+
- Converting Windows backslashes to forward slashes.
26+
- Stripping Wine drive letters (Z:).
27+
"""
28+
29+
import json
30+
import os
31+
import sys
32+
33+
def fix_path(path, root_dir):
34+
# Normalize path separators
35+
path = path.replace('\\', '/')
36+
37+
# Remove drive letter if present
38+
if len(path) > 1 and path[1] == ':':
39+
path = path[2:]
40+
41+
# Replace the container mount point with the host root directory
42+
# The container mounts the project at /build/cnc
43+
if path.startswith('/build/cnc'):
44+
return os.path.join(root_dir, path[len('/build/cnc'):].lstrip('/'))
45+
46+
return path
47+
48+
def main():
49+
script_dir = os.path.dirname(os.path.abspath(__file__))
50+
project_root = os.path.dirname(script_dir)
51+
52+
build_dir = os.path.join(project_root, 'build', 'docker')
53+
input_file = os.path.join(build_dir, 'compile_commands.json')
54+
output_file = os.path.join(project_root, 'compile_commands.json')
55+
56+
if not os.path.exists(input_file):
57+
print(f"Error: {input_file} not found. Please run the docker build first.")
58+
sys.exit(1)
59+
60+
print(f"Reading from: {input_file}")
61+
62+
with open(input_file, 'r') as f:
63+
data = json.load(f)
64+
65+
for entry in data:
66+
# Fix directory
67+
if 'directory' in entry:
68+
entry['directory'] = fix_path(entry['directory'], project_root)
69+
70+
# Fix file
71+
if 'file' in entry:
72+
entry['file'] = fix_path(entry['file'], project_root)
73+
74+
# Fix command
75+
if 'command' in entry:
76+
command = entry['command']
77+
78+
# Normalize to forward slashes.
79+
command = command.replace('\\', '/')
80+
81+
# Replace container path with host project root.
82+
command = command.replace('/build/cnc', project_root)
83+
84+
# Handle potential drive letter artifacts from Wine (Z:/build/cnc).
85+
command = command.replace('Z:/build/cnc', project_root)
86+
command = command.replace('z:/build/cnc', project_root)
87+
88+
# Strip remaining drive letters from tools (e.g., Z:/build/tools/...).
89+
command = command.replace('Z:', '')
90+
command = command.replace('z:', '')
91+
92+
entry['command'] = command
93+
94+
print(f"Writing to: {output_file}")
95+
with open(output_file, 'w') as f:
96+
json.dump(data, f, indent=2)
97+
98+
print("Done. compile_commands.json is now ready for use.")
99+
100+
if __name__ == '__main__':
101+
main()

0 commit comments

Comments
 (0)