Created
April 21, 2026 06:30
-
-
Save dangfan/70bb8dc938c30df60e59e619442b3882 to your computer and use it in GitHub Desktop.
cx-winpath-wrap
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| set -euo pipefail | |
| CX_ROOT="/Applications/CrossOver.app/Contents/SharedSupport/CrossOver/bin" | |
| WINE="$CX_ROOT/wine" | |
| BOTTLE="MDK" | |
| EXE="${1:?missing exe path}" | |
| shift || true | |
| abs_path() { | |
| python3 - "$1" <<'PY' | |
| import os, sys | |
| print(os.path.abspath(sys.argv[1])) | |
| PY | |
| } | |
| to_winpath() { | |
| python3 - "$1" <<'PY' | |
| import os, sys | |
| p = sys.argv[1] | |
| p = os.path.abspath(p) | |
| # Normalize and convert /foo/bar -> Z:\foo\bar | |
| p = p.replace('/', '\\') | |
| if not p.startswith('\\'): | |
| p = '\\' + p | |
| print('Z:' + p) | |
| PY | |
| } | |
| convert_path() { | |
| to_winpath "$1" | |
| } | |
| convert_arg() { | |
| local arg="$1" | |
| case "$arg" in | |
| # -I/path | |
| -I/*|-I./*|-I../*) | |
| printf '%s%s\n' "-I" "$(convert_path "${arg:2}")" | |
| return | |
| ;; | |
| # -L/path | |
| -L/*|-L./*|-L../*) | |
| printf '%s%s\n' "-L" "$(convert_path "${arg:2}")" | |
| return | |
| ;; | |
| # -o/path/file | |
| -o/*|-o./*|-o../*) | |
| printf '%s%s\n' "-o" "$(convert_path "${arg:2}")" | |
| return | |
| ;; | |
| # -MF and its path (keep Unix format for dep file generation) | |
| -MF|*.o.d) | |
| printf '%s\n' "$arg" | |
| return | |
| ;; | |
| # --key=/path | |
| --*=/*|--*=./*|--*=../*) | |
| local key="${arg%%=*}" | |
| local val="${arg#*=}" | |
| printf '%s=%s\n' "$key" "$(convert_path "$val")" | |
| return | |
| ;; | |
| # 单独路径 | |
| /*|./*|../*) | |
| printf '%s\n' "$(convert_path "$arg")" | |
| return | |
| ;; | |
| # Compiler definitions (-DFOO or -DFOO=VALUE) - never path-convert | |
| -D*) | |
| printf '%s\n' "$arg" | |
| return | |
| ;; | |
| # 常见文件参数,可能是相对路径 | |
| *.c|*.cc|*.cpp|*.cxx|*.h|*.hpp|*.s|*.S|*.asm|*.o|*.a|*.elf|*.axf|*.map|*.txt|*.lib|*.sct|*.hex|*.bin) | |
| printf '%s\n' "$(convert_path "$arg")" | |
| return | |
| ;; | |
| *) | |
| printf '%s\n' "$arg" | |
| return | |
| ;; | |
| esac | |
| } | |
| args=() | |
| for a in "$@"; do | |
| args+=("$(convert_arg "$a")") | |
| done | |
| # Run the compiler | |
| "$WINE" --bottle "$BOTTLE" "$EXE" "${args[@]}" | |
| compiler_exit=$? | |
| # Post-process .d dependency files: convert Windows paths back to Unix | |
| for a in "$@"; do | |
| case "$a" in | |
| -MMD|-MD) | |
| # Find the dependency file name from -MF flag (Unix path from args) | |
| dep_file="" | |
| for ((i=0; i<${#args[@]}; i++)); do | |
| if [[ "${args[$i]}" == "-MF" ]]; then | |
| # -MF is a separate argument, dep file is next arg (Unix path) | |
| dep_file="${args[$((i+1))]}" | |
| break | |
| fi | |
| done | |
| # Convert to absolute path for checking | |
| if [[ -n "$dep_file" && "${dep_file:0:1}" != "/" ]]; then | |
| dep_file_abs="$(pwd)/$dep_file" | |
| else | |
| dep_file_abs="$dep_file" | |
| fi | |
| # If we found a dependency file, convert paths using Python | |
| if [[ -n "$dep_file_abs" && -f "$dep_file_abs" ]]; then | |
| python3 - "$dep_file_abs" <<'PY' | |
| import sys, re | |
| with open(sys.argv[1], 'r') as f: | |
| lines = f.readlines() | |
| # Process each line: convert paths but preserve line endings | |
| new_lines = [] | |
| for line in lines: | |
| # Check if line ends with \r\n or just \n | |
| if line.endswith('\\r\n'): | |
| ending = '\r\n' | |
| line = line[:-4] | |
| elif line.endswith('\\\n'): | |
| ending = '\n' | |
| line = line[:-2] | |
| else: | |
| ending = '' | |
| if line.endswith('\n'): | |
| ending = '\n' | |
| line = line[:-1] | |
| # Convert Z:\path -> /path and \\ -> /, but preserve trailing \ for continuation | |
| line = re.sub(r'Z:\\', '/', line) | |
| line = re.sub(r'\\(?!\n|\r|$)', '/', line) # Don't convert trailing backslash | |
| new_lines.append(line + ending) | |
| with open(sys.argv[1], 'w') as f: | |
| f.writelines(new_lines) | |
| PY | |
| fi | |
| break | |
| ;; | |
| esac | |
| done | |
| exit $compiler_exit |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment