45 lines
2.1 KiB
Python
45 lines
2.1 KiB
Python
#!/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)
|