/
githubmirror
/
node
Обзор
Документация
Войти
/
githubmirror
/
node
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
deps/libffi/generate-headers.py
278 строк
8 KB
Node.js GitHub Bot
deps: update libffi to 3.8.0
11 авг 2026, 03:35
Не верифицирован
11 авг 2026, 03:35
01f2018
Код
Авторство
О чём код?
#!/usr/bin/env python3 import argparse import os import platform import sys from pathlib import Path LIBFFI_VERSION = '3.8.0' LIBFFI_VERSION_NUMBER = '30800' def normalize_arch(target_arch): aliases = { 'x86': 'ia32', 'x86_64': 'x64', 'arm64': 'arm64', 'aarch64': 'arm64', } return aliases.get(target_arch, target_arch) def get_target(os_name, target_arch): target_arch = normalize_arch(target_arch) if target_arch == 'arm': return ('ARM_WIN32' if os_name == 'win' else 'ARM', 'arm') if target_arch == 'arm64': return ('ARM_WIN64' if os_name == 'win' else 'AARCH64', 'aarch64') if target_arch == 'ia32': if os_name in ('freebsd', 'openbsd'): return ('X86_FREEBSD', 'x86') if os_name in ('ios', 'mac'): return ('X86_DARWIN', 'x86') if os_name == 'win': return ('X86_WIN32', 'x86') return ('X86', 'x86') if target_arch == 'x64': return ('X86_WIN64' if os_name == 'win' else 'X86_64', 'x86') if target_arch == 'riscv64': return ('RISCV', 'riscv') if target_arch == 'loong64': return ('LOONGARCH64', 'loongarch') if target_arch in ('mips', 'mipsel', 'mips64el'): if os_name in ('freebsd', 'linux', 'openbsd'): return ('MIPS', 'mips') if target_arch == 'ppc64': if os_name == 'aix': return ('POWERPC_AIX', 'powerpc') if os_name == 'mac': return ('POWERPC_DARWIN', 'powerpc') if os_name in ('freebsd', 'openbsd'): return ('POWERPC_FREEBSD', 'powerpc') if os_name == 'linux': return ('POWERPC', 'powerpc') raise ValueError(f'Unsupported libffi target {os_name}/{target_arch}.') def has_long_double(os_name, target_arch): target_arch = normalize_arch(target_arch) if os_name == 'win': return '0' if os_name == 'mac' and target_arch == 'arm64': return '0' if target_arch == 'arm': return '0' return '1' def uses_exec_trampoline_table(os_name, target_arch): target_arch = normalize_arch(target_arch) return os_name == 'mac' and target_arch in ('arm', 'arm64') def render_ffi_header(base_dir, os_name, target_arch, target): template = (base_dir / 'include' / 'ffi.h.in').read_text(encoding='utf-8') replacements = { '@FFI_EXEC_TRAMPOLINE_TABLE@': '1' if uses_exec_trampoline_table(os_name, target_arch) else '0', '@FFI_VERSION_NUMBER@': LIBFFI_VERSION_NUMBER, '@FFI_VERSION_STRING@': LIBFFI_VERSION, '@HAVE_LONG_DOUBLE@': has_long_double(os_name, target_arch), '@TARGET@': target, '@VERSION@': LIBFFI_VERSION, } for source, replacement in replacements.items(): template = template.replace(source, replacement) return template def render_fficonfig(os_name, target_arch): target_arch = normalize_arch(target_arch) lines = [ '/* Auto-generated by generate-headers.py. */', '#ifndef LIBFFI_FFICONFIG_H_', '#define LIBFFI_FFICONFIG_H_', '', '#define HAVE_ALLOCA 1', '#define HAVE_MEMCPY 1', '#define HAVE_MEMORY_H 1', '#define HAVE_STDINT_H 1', '#define HAVE_STRING_H 1', '#define STDC_HEADERS 1', ] if os_name != 'win': lines.extend([ '#define HAVE_AS_CFI_PSEUDO_OP 1', '#define HAVE_HIDDEN_VISIBILITY_ATTRIBUTE 1', '#define HAVE_MKOSTEMP 1', '#define HAVE_RO_EH_FRAME 1', '#define EH_FRAME_FLAGS "a"', ]) if target_arch in ('ia32', 'x64') and os_name != 'win': lines.append('#define HAVE_AS_X86_PCREL 1') if uses_exec_trampoline_table(os_name, target_arch): lines.append('#define FFI_EXEC_TRAMPOLINE_TABLE 1') elif os_name in ('freebsd', 'mac', 'openbsd'): lines.append('#define FFI_MMAP_EXEC_WRIT 1') if os_name != 'win': lines.extend([ '#define HAVE_DLFCN_H 1', '#define HAVE_MMAP 1', '#define HAVE_MMAP_ANON 1', '#define HAVE_MMAP_FILE 1', '#define HAVE_SYS_MMAN_H 1', '#define HAVE_UNISTD_H 1', ]) if os_name in ('freebsd', 'ios', 'mac', 'openbsd'): lines.extend([ '#define HAVE_MMAP_DEV_ZERO 1', ]) if os_name == 'mac' and target_arch == 'arm64': lines.extend([ '#if defined(__arm64e__)', '#define HAVE_ARM64E_PTRAUTH 1', '#endif', ]) lines.extend([ '', '#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE', '#ifdef LIBFFI_ASM', '#ifdef __APPLE__', '#define FFI_HIDDEN(name) .private_extern name', '#else', '#define FFI_HIDDEN(name) .hidden name', '#endif', '#else', '#define FFI_HIDDEN __attribute__ ((visibility ("hidden")))', '#endif', '#else', '#ifdef LIBFFI_ASM', '#define FFI_HIDDEN(name)', '#else', '#define FFI_HIDDEN', '#endif', '#endif', '', '#endif /* LIBFFI_FFICONFIG_H_ */', '', ]) return '\n'.join(lines) def generate_headers(output_dir, target_arch, os_name): base_dir = Path(__file__).resolve().parent output_dir = Path(str(output_dir).strip().strip('"')) output_dir.mkdir(parents=True, exist_ok=True) target, target_dir = get_target(os_name, target_arch) ffitarget_src = base_dir / 'src' / target_dir / 'ffitarget.h' if not ffitarget_src.exists(): raise FileNotFoundError(f'Missing libffi target header: {ffitarget_src}') (output_dir / 'ffi.h').write_text( render_ffi_header(base_dir, os_name, target_arch, target), encoding='utf-8') (output_dir / 'fficonfig.h').write_text( render_fficonfig(os_name, target_arch), encoding='utf-8') (output_dir / 'ffitarget.h').write_text( ffitarget_src.read_text(encoding='utf-8'), encoding='utf-8') def detect_os_name(): if sys.platform.startswith('win'): return 'win' if sys.platform == 'darwin': return 'mac' if sys.platform.startswith('linux'): return 'linux' if sys.platform.startswith('freebsd'): return 'freebsd' raise ValueError(f'Unsupported host platform {sys.platform!r}') def detect_target_arch(): candidates = [ os.environ.get('TARGET_ARCH'), os.environ.get('npm_config_arch'), os.environ.get('VSCMD_ARG_TGT_ARCH'), os.environ.get('Platform'), os.environ.get('PROCESSOR_ARCHITECTURE'), platform.machine(), ] aliases = { 'amd64': 'x64', 'x86_64': 'x64', 'x64': 'x64', 'win32': 'x64', 'i386': 'ia32', 'i686': 'ia32', 'ia32': 'ia32', 'x86': 'ia32', 'arm64': 'arm64', 'aarch64': 'arm64', 'arm': 'arm', 'riscv64': 'riscv64', 'loong64': 'loong64', 'ppc64': 'ppc64', 'mips': 'mips', 'mipsel': 'mipsel', 'mips64el': 'mips64el', } for candidate in candidates: if not candidate: continue normalized = aliases.get(candidate.lower()) if normalized is not None: return normalized raise ValueError('Unable to determine target architecture for libffi headers') def main(argv=None): parser = argparse.ArgumentParser(description='Generate libffi headers') parser.add_argument('--output-dir', required=True) parser.add_argument('--target-arch') parser.add_argument('--os') args = parser.parse_args(argv) try: generate_headers(args.output_dir, args.target_arch or detect_target_arch(), args.os or detect_os_name()) except Exception as exc: # pylint: disable=broad-except print(exc, file=sys.stderr) return 1 return 0 if __name__ == '__main__': sys.exit(main())