import pathlib
import typing
from graph import all_headers
from graph import calculate_rdeps
from graph import Header
from graph import IncludeDir
from graph import Target
from platforms import Os
if typing.TYPE_CHECKING:
from compiler import Compiler
IGNORED_MODULES = [
'opencl_c',
'_stddef',
]
SYSROOT_DIRS = {
'android_toolchain',
'debian_bullseye_amd64-sysroot',
'debian_bullseye_arm64-sysroot',
'debian_bullseye_armhf-sysroot',
'debian_bullseye_i386-sysroot',
'fuchsia-sdk',
'MacOSX.platform',
'win_toolchain',
}
SYSROOT_PRECOMPILED_HEADERS = [
'fcntl.h',
'getopt.h',
'linux/types.h',
'sys/ioctl.h',
'syscall.h',
]
def fix_graph(graph: dict[str, Header],
compiler: 'Compiler') -> dict[pathlib.Path, str]:
def force_textual(key: str):
if key in graph:
graph[key].textual = True
def add_dep(frm, to, check=True):
if check:
assert to not in frm.deps
if to not in frm.deps:
frm.deps.append(to)
def skip_module(name):
found = False
for hdr in graph.values():
while True:
if hdr.root_module == name:
hdr.textual = True
found = True
if hdr.next is None:
break
hdr = hdr.next
assert found
add_dep(graph['stddef.h'].next, graph['__stddef_size_t.h'], check=False)
if compiler.os in [Os.Android, Os.Win, Os.Fuchsia]:
add_dep(graph['__mbstate_t.h'], graph['wchar.h'])
graph['__mbstate_t.h'].kwargs['defines'].append(
'_LIBCPP_WCHAR_H_HAS_CONST_OVERLOADS')
elif compiler.os.is_apple:
graph['iso646.h'].next.textual = True
rdeps = calculate_rdeps(all_headers(graph))
sysroot = graph['assert.h'].abs.parent
for header in all_headers(graph):
header.direct_deps = header.calculate_direct_deps(graph, sysroot=sysroot)
if compiler.os.is_apple:
skip_module("Darwin")
skip_module("_c_standard_library_obsolete")
else:
for header in all_headers(graph):
if header.include_dir != IncludeDir.Sysroot:
continue
parts = set(pathlib.Path(header.rel).parts)
if header.prev is not None:
header.textual = not header.prev.textual
elif (len(rdeps[header]) < 2
and parts.intersection(['asm', 'asm-generic', 'bits'])):
header.textual = True
elif '#pragma once' in (header.content or ''):
header.textual = False
elif 'bits' in parts:
header.textual = True
graph['assert.h'].textual = True
force_textual('asm-generic/unistd.h')
force_textual('asm-generic/bitsperlong.h')
if compiler.os == Os.Android:
graph['android/legacy_stdlib_inlines.h'].textual = True
graph['android/legacy_threads_inlines.h'].textual = True
graph['android/legacy_unistd_inlines.h'].textual = True
graph['bits/threads_inlines.h'].textual = True
graph['asm-generic/posix_types.h'].textual = True
graph['asm/posix_types.h'].textual = True
for k in graph:
if k.startswith('asm/unistd'):
graph[k].textual = True
graph['bits/glibc-syscalls.h'].textual = True
elif compiler.os == Os.Linux:
graph['linux/limits.h'].textual = True
graph['asm-generic/types.h'].textual = True
for hdr in graph.values():
if '-linux-gnu' in str(hdr.abs):
hdr.textual = True
if compiler.os == Os.Win:
graph['math.h'].kwargs['defines'].append('_USE_MATH_DEFINES')
return {
graph['corecrt.h'].abs.parent.parent: '$windows_kits',
graph['eh.h'].abs.parent: '$msvc',
}
else:
return {sysroot: '$sysroot'}
def should_compile(target: Target) -> bool:
for header in target.headers:
if header.include_dir == IncludeDir.LibCxx:
return True
return False