(args)
| 69 | |
| 70 | |
| 71 | def preprocess(args): |
| 72 | compiler = find_compiler() |
| 73 | input_path = normalize_path(args.input) |
| 74 | output = Path(normalize_path(args.output)) |
| 75 | include_dirs = [normalize_path(include_dir) for include_dir in args.include_dir] |
| 76 | include_dirs.append(str(output.parent)) |
| 77 | include_dirs = unique_paths(include_dirs) |
| 78 | output.parent.mkdir(parents=True, exist_ok=True) |
| 79 | |
| 80 | if os.name == 'nt' and Path(compiler[0]).name.lower() in ('cl.exe', 'cl', 'clang-cl.exe', 'clang-cl'): |
| 81 | command = compiler + ['/nologo', '/EP', '/TC'] |
| 82 | command += [f'/I{include_dir}' for include_dir in include_dirs] |
| 83 | command += [f'/D{define}' for define in args.define] |
| 84 | command += [input_path] |
| 85 | else: |
| 86 | command = compiler + ['-E', '-P', '-x', 'c'] |
| 87 | command += [f'-I{include_dir}' for include_dir in include_dirs] |
| 88 | command += [f'-D{define}' for define in args.define] |
| 89 | command += [input_path] |
| 90 | |
| 91 | result = subprocess.run(command, capture_output=True, text=True) |
| 92 | if result.returncode != 0: |
| 93 | sys.stderr.write(result.stderr) |
| 94 | raise RuntimeError(f'Preprocessing failed: {" ".join(command)}') |
| 95 | |
| 96 | # Strip all preprocessor directives that assemblers can't handle |
| 97 | # (e.g., armasm64.exe doesn't accept any # directives) |
| 98 | # Remove lines starting with # (preprocessor output like #line, # 1 "file", etc.) |
| 99 | lines = result.stdout.splitlines(keepends=True) |
| 100 | cleaned_lines = [line for line in lines if not line.lstrip().startswith('#')] |
| 101 | cleaned = ''.join(cleaned_lines) |
| 102 | |
| 103 | output.write_text(cleaned, encoding='utf-8') |
| 104 | |
| 105 | # If --assemble is specified, also run the assembler to produce an object file |
| 106 | if args.assemble: |
| 107 | assemble_output = Path(normalize_path(args.assemble)) |
| 108 | assemble_output.parent.mkdir(parents=True, exist_ok=True) |
| 109 | |
| 110 | armasm64 = find_armasm64() |
| 111 | asm_command = [armasm64, '-nologo', '-g', str(output), '-o', str(assemble_output)] |
| 112 | |
| 113 | asm_result = subprocess.run(asm_command, capture_output=True, text=True) |
| 114 | if asm_result.returncode != 0: |
| 115 | sys.stderr.write(asm_result.stderr) |
| 116 | sys.stderr.write(asm_result.stdout) |
| 117 | raise RuntimeError(f'Assembly failed: {" ".join(asm_command)}') |
| 118 | |
| 119 | |
| 120 | def main(argv=None): |
no test coverage detected
searching dependent graphs…