Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions scripts/docker-build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,17 @@ build_docker_image() {
print_success "Docker image ready"
}

fix_compile_commands() {
local fix_script="$SCRIPT_DIR/fix_compile_commands.py"
if [[ -f "$fix_script" ]] && command -v python3 &>/dev/null; then
# Only run if compile_commands.json exists in the build dir
if [[ -f "$BUILD_DIR/compile_commands.json" ]]; then
print_info "Fixing compile_commands.json for host environment..."
python3 "$fix_script" || print_warning "Failed to fix compile_commands.json"
fi
fi
}

run_build() {
local force_cmake="$1"
local target="$2"
Expand Down Expand Up @@ -266,6 +277,7 @@ build_docker_image
run_build "$FORCE_CMAKE" "$TARGET" "$INTERACTIVE"

if [[ "$INTERACTIVE" != "true" ]]; then
fix_compile_commands
list_outputs

echo ""
Expand Down
101 changes: 101 additions & 0 deletions scripts/fix_compile_commands.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#!/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:).
"""

import json
import os
import sys

def fix_path(path, root_dir):
# Normalize path separators
path = path.replace('\\', '/')

# Remove drive letter if present
if len(path) > 1 and path[1] == ':':
path = path[2:]

# 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

def main():
script_dir = os.path.dirname(os.path.abspath(__file__))
project_root = os.path.dirname(script_dir)

build_dir = os.path.join(project_root, 'build', 'docker')
input_file = os.path.join(build_dir, 'compile_commands.json')
output_file = os.path.join(project_root, 'compile_commands.json')

if not os.path.exists(input_file):
print(f"Error: {input_file} not found. Please run the docker build first.")
sys.exit(1)

print(f"Reading from: {input_file}")

with open(input_file, 'r') as f:
data = json.load(f)

for entry in data:
# Fix directory
if 'directory' in entry:
entry['directory'] = fix_path(entry['directory'], project_root)

# Fix file
if 'file' in entry:
entry['file'] = fix_path(entry['file'], project_root)

# Fix command
if 'command' in entry:
command = entry['command']

# Normalize to forward slashes.
command = command.replace('\\', '/')

# Replace container path with host project root.
command = command.replace('/build/cnc', project_root)

# Handle potential drive letter artifacts from Wine (Z:/build/cnc).
command = command.replace('Z:/build/cnc', project_root)
command = command.replace('z:/build/cnc', project_root)

# Strip remaining drive letters from tools (e.g., Z:/build/tools/...).
command = command.replace('Z:', '')
command = command.replace('z:', '')

entry['command'] = command

print(f"Writing to: {output_file}")
with open(output_file, 'w') as f:
json.dump(data, f, indent=2)

print("Done. compile_commands.json is now ready for use.")

if __name__ == '__main__':
main()