File: generate-platform-args

package info (click to toggle)
webkit2gtk 2.51.2-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 457,708 kB
  • sloc: cpp: 3,884,629; javascript: 198,661; ansic: 165,298; python: 49,171; asm: 21,849; ruby: 18,095; perl: 16,914; xml: 4,623; sh: 2,397; yacc: 2,356; java: 2,019; lex: 1,330; pascal: 372; makefile: 197
file content (106 lines) | stat: -rwxr-xr-x 4,861 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#!/usr/bin/env python3
import subprocess
import os
import shlex
import shutil
import re

# Preprocesses wtf/Platform.h with clang, extracts macro definitions, and saves
# the platform flags to a Swift-style response file containing -D arguments.

# For build settings which may be undefined, behave like a shell and implicitly
# fall back to the empty string.
os.environ.setdefault('FRAMEWORK_SEARCH_PATHS', '')
os.environ.setdefault('HEADER_SEARCH_PATHS', '')
os.environ.setdefault('SYSTEM_FRAMEWORK_SEARCH_PATHS', '')
os.environ.setdefault('SYSTEM_HEADER_SEARCH_PATHS', '')
os.environ.setdefault('GCC_PREPROCESSOR_DEFINITIONS', '')

framework_search_paths = shlex.split(
    '{BUILT_PRODUCTS_DIR} {FRAMEWORK_SEARCH_PATHS}'.format_map(os.environ))
header_search_paths = shlex.split(
    '{BUILT_PRODUCTS_DIR} {HEADER_SEARCH_PATHS}'.format_map(os.environ))
system_framework_search_paths = shlex.split(
    '{SYSTEM_FRAMEWORK_SEARCH_PATHS}'.format_map(os.environ))
system_header_search_paths = shlex.split(
    '{SYSTEM_HEADER_SEARCH_PATHS}'.format_map(os.environ))
preprocessor_definitions = shlex.split(
    '__WK_GENERATING_PLATFORM_ARGS__ RELEASE_WITHOUT_OPTIMIZATIONS '
    '{GCC_PREPROCESSOR_DEFINITIONS}'.format_map(os.environ))

archs = shlex.split(os.environ['ARCHS'])
if 'SWIFT_MODULE_ONLY_ARCHS' in os.environ:
    archs.extend(shlex.split(os.environ['SWIFT_MODULE_ONLY_ARCHS']))

output_dir = os.path.dirname(os.environ['SCRIPT_OUTPUT_FILE_0'])

combined_depfile_fd = open(
    '{DERIVED_FILES_DIR}/generate-platform-args.d'.format_map(os.environ), 'w')

# This script is run as a build phase, which Xcode runs once with
# $arch=undefined, so we have to handle multi-arch builds manually. We generate
# argument lists for all active architectures, and the build script phase
# declares all known output paths as outputs.
#
# FIXME: Computing search path arguments is duplicated by migrate-header-rule
# in WebKitLegacy. We could share this implementation and generate
# bash-compatible variables for these use cases as well.

with open(f'{output_dir}/rdar150228472.swift', 'w') as fd:
    fd.write('// generate-platform-args: empty file to work around dependency '
             'bug in rdar://150228472\n')

for arch in archs:
    output_name = f'platform-enabled-swift-args.{arch}.resp'
    output_file = f'{output_dir}/{output_name}'
    depfile = f'{{DERIVED_FILES_DIR}}/{output_name}.d'.format_map(os.environ)
    target_triple = (f'{arch}-'
        '{LLVM_TARGET_TRIPLE_VENDOR}-{LLVM_TARGET_TRIPLE_OS_VERSION}').format_map(os.environ)
    target_triple += os.environ.get('LLVM_TARGET_TRIPLE_SUFFIX', '')

    feature_and_platform_defines = subprocess.check_output(
        ('xcrun', 'clang', '-x', 'c++', '-std={CLANG_CXX_LANGUAGE_STANDARD}'.format_map(os.environ),
         '-target', target_triple, '-E', '-P', '-dM', '-MD', '-MF', depfile, '-MT', output_name,
         *(f'-D{token}' for token in preprocessor_definitions),
         *(arg for path in framework_search_paths for arg in ('-F', path)),
         *(arg for path in header_search_paths for arg in ('-I', path)),
         *(arg for path in system_framework_search_paths for arg in ('-iframework', path)),
         *(arg for path in system_header_search_paths for arg in ('-isystem', path)),
         '-include', 'wtf/Platform.h', '/dev/zero'), text=True)

    # Concatenate all the depfiles, in case a header is only imported on specific architectures.
    shutil.copyfileobj(open(depfile), combined_depfile_fd)

    definitions = {}
    for m in re.finditer(r'^#define (\w+) (.+)', feature_and_platform_defines, re.MULTILINE):
        name = m.group(1)
        value = m.group(2)
        if value == '1':
            definitions[name] = 1
        elif value == '0':
            definitions[name] = 0
        else:
            definitions[name] = value

    # Resolve macros which are defined as the value of another macro. clang -dM
    # prints macros in alphabetical order, so we cannot rely on macros being in
    # topological order. Limit the maximum amount of indirection to prevent a
    # recursive definition from causing the script to loop forever.
    for _ in range(10):
        changed = False
        for name, value in definitions.items():
            if type(value) == str and value in definitions:
                definitions[name] = definitions[value]
                changed = True
        if not changed:
            break

    swift_args = '\n'.join(
        f'-D{name}'
        for name, value in definitions.items()
        if value == 1 and (name.startswith('HAVE_') or name.startswith('USE_') or
                           name.startswith('ENABLE_') or name.startswith('WTF_PLATFORM') or
                           name.startswith('ASSERT_'))
    )
    print(f'{output_file}:\t', swift_args.replace('\n', ' '))
    open(output_file, 'w').write(swift_args)