#!/usr/bin/python3 """GCC 15 driver used by IDE toolchains, with the contest language and link options.""" import json import os from pathlib import Path import re import shlex import sys def expand_response_files(arguments, depth=0): # CLion also puts its language/standard probes in GCC response files. # Inspect their contents before choosing C vs C++ or replacing flags. if depth > 16: raise SystemExit('ACPC: response files are nested too deeply') expanded = [] for arg in arguments: if arg.startswith('@') and Path(arg[1:]).is_file(): expanded.extend(expand_response_files(shlex.split(Path(arg[1:]).read_text()), depth + 1)) else: expanded.append(arg) return expanded args = expand_response_files(sys.argv[1:]) name = Path(sys.argv[0]).name sources = [a for a in args if Path(a).suffix in ('.c', '.C', '.cc', '.cpp', '.cxx', '.c++')] explicit_cxx = any(a.startswith('-xc++') or (a == '-x' and i + 1 < len(args) and args[i + 1].startswith('c++')) for i, a in enumerate(args)) cxx = name.endswith(('g++', 'c++')) or explicit_cxx or (name not in ('acpc-gcc', 'gcc', 'cc') and any(not a.endswith('.c') for a in sources)) compiler = '/usr/bin/g++-15' if cxx else '/usr/bin/gcc-15' query = any(a in ('--version', '-dumpversion', '-dumpfullversion', '-dumpmachine', '-print-search-dirs') or a.startswith(('-print-file-name=', '-print-prog-name=')) for a in args) if not query: args = [a for a in args if not a.startswith('-std=') and not re.fullmatch(r'-O(?:[0-3sgz]|fast)?', a)] args = ['-g', '-O2', '-std=gnu++23' if cxx else '-std=gnu23'] + args if not any(a in args for a in ('-c', '-S', '-E', '-M', '-MM', '-fsyntax-only', '-shared')): args += ['-static'] args += ['-lrt', '-Wl,--whole-archive', '-lpthread', '-Wl,--no-whole-archive'] if cxx else ['-lm'] cmd = [compiler] + args if not query and sources: print('ACPC: ' + shlex.join(cmd), file=sys.stderr, flush=True) if log := os.environ.get('ACPC_COMPILER_LOG'): with open(log, 'a') as f: f.write(json.dumps({'cwd': os.getcwd(), 'argv': cmd}) + '\n') os.execv(compiler, cmd)