r""" Rewrite the depfile to reference the PCH output instead of temporary obj file. The compiler-generated depfile has format: C:\path\to\temp.obj: \ dep1.h \ dep2.h We need to change it to: tests/output.pch: \ dep1.h \ dep2.h
(depfile_path: Path, pch_output_path: Path)
| 71 | |
| 72 | |
| 73 | def fix_depfile(depfile_path: Path, pch_output_path: Path) -> None: |
| 74 | r""" |
| 75 | Rewrite the depfile to reference the PCH output instead of temporary obj file. |
| 76 | |
| 77 | The compiler-generated depfile has format: |
| 78 | C:\path\to\temp.obj: \ |
| 79 | dep1.h \ |
| 80 | dep2.h |
| 81 | |
| 82 | We need to change it to: |
| 83 | tests/output.pch: \ |
| 84 | dep1.h \ |
| 85 | dep2.h |
| 86 | |
| 87 | Args: |
| 88 | depfile_path: Path to the .d dependency file |
| 89 | pch_output_path: Path to the .pch output file |
| 90 | """ |
| 91 | if not depfile_path.exists(): |
| 92 | return |
| 93 | |
| 94 | content = depfile_path.read_text(encoding="utf-8") |
| 95 | separator_idx = _find_depfile_separator(content) |
| 96 | |
| 97 | if separator_idx == -1: |
| 98 | return |
| 99 | |
| 100 | # Everything after the separator (including ": ") is the dependencies |
| 101 | deps_str = content[separator_idx + 2 :] |
| 102 | |
| 103 | # Parse individual dependency paths |
| 104 | dep_paths = _tokenize_depfile_deps(deps_str) |
| 105 | |
| 106 | # Normalize paths to absolute, then to forward slashes for Ninja compatibility. |
| 107 | # The depfile may contain relative paths from where the compiler was invoked |
| 108 | # (typically the project root), which need to be resolved to absolute paths before |
| 109 | # normalization. This ensures the hash checking code can find the files. |
| 110 | pch_output_str = Path(pch_output_path).as_posix() |
| 111 | normalized_deps = [] |
| 112 | |
| 113 | for p in dep_paths: |
| 114 | path_obj = Path(p) |
| 115 | # If the path is relative, resolve it relative to the current working directory |
| 116 | # (which is the project root when Meson runs the compile_pch command) |
| 117 | if not path_obj.is_absolute(): |
| 118 | path_obj = path_obj.resolve() |
| 119 | # Convert to forward slashes and use the string representation |
| 120 | normalized_deps.append(path_obj.as_posix()) |
| 121 | |
| 122 | # Rebuild depfile in Make format |
| 123 | # Escape spaces in paths for Make syntax |
| 124 | escaped_deps = [d.replace(" ", "\\ ") for d in normalized_deps] |
| 125 | new_content = pch_output_str + ": \\\n " + " \\\n ".join(escaped_deps) + "\n" |
| 126 | |
| 127 | depfile_path.write_text(new_content, encoding="utf-8") |
| 128 | |
| 129 | |
| 130 | def _tokenize_depfile_deps(deps_str: str) -> list[str]: |
no test coverage detected