File: find-overlay-deps-closure.sh

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (115 lines) | stat: -rwxr-xr-x 3,913 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
107
108
109
110
111
112
113
114
115
#!/bin/bash

# Find the transitive closure of overlay dependencies for a single overlay.
# Runs the following command in a loop until the list stops growing:
# xcrun -sdk macosx clang -arch x86_64 -x objective-c - -M -fmodules < <(echo '@import SceneKit;@import AppKit;')
# There are two ways an overlay ``foo`` shows up in the xcrun output:
# 1) as Foo.framework
# 2) as /usr/include/foo/bar.h
# but not:
# 3) as /usr/include/foo/module.map or /usr/include/foo/modulemap.map
# Overlays that only show up as a module map are not a real dependency.
# Overlays that have a different name in Swift than in the output: Dispatch, ObjectiveC, XPC
# XCTest is hardcoded because this method doesn't work for it.

set -o pipefail
set -e

OVERLAY_NAME_ALTERNATION="AppKit|AssetsLibrary|AVFoundation|CallKit|CloudKit|Compression|Contacts|CoreAudio|CoreData|CoreGraphics|CoreImage|CoreLocation|CoreMedia|CoreML|CryptoTokenKit|dispatch|Foundation|GameplayKit|GLKit|HomeKit|IOKit|Intents|MapKit|objc|OpenCL|os|Photos|QuartzCore|SafariServices|SceneKit|simd|SpriteKit|UIKit|WatchKit|XCTest|xpc"

function find_deps() {
    local OVERLAY_ARG=$1
    local SDK_ARG=$2
    local ARCH_ARG=$3

    local PROGRAM=""
    # shellcheck disable=SC2013
    for overlay in $(sed "s/;/ /g" <<< "$OVERLAY_ARG"); do
        regexp="ObjectiveC|objc|Dispatch|dispatch|XPC|xpc"
        if [[ ! $overlay =~ $regexp ]]; then
            PROGRAM+="@import $overlay;"
        fi
    done

    local DEPS
    DEPS=$(xcrun -sdk "$SDK_ARG" clang -arch "$ARCH_ARG" -x objective-c - -M -fmodules <<< "$PROGRAM" 2>&1)
    local ERROR_REGEX="(.*error:.*)"
    if [[ $DEPS =~ $ERROR_REGEX ]]; then
        echo "${BASH_REMATCH[1]}" >&2
        exit 123
    fi

    local REGEX="./Frameworks/(${OVERLAY_NAME_ALTERNATION}).framework/.*|.*/usr/include/(xpc|dispatch|os|objc|simd|compression)/.*\.h"

    # shellcheck disable=SC1004
    IFS='\
    '
    local USED_OVERLAYS=""
    # shellcheck disable=SC2068
    for line in ${DEPS[@]}; do
        if [[ $line =~ $REGEX ]]; then
            if [[ ${BASH_REMATCH[1]} != "" ]]; then
                USED_OVERLAYS+="${BASH_REMATCH[1]};"
            elif [[ ${BASH_REMATCH[2]} == "dispatch" ]]; then
                USED_OVERLAYS+="Dispatch;"
            elif [[ ${BASH_REMATCH[2]} == "xpc" ]]; then
                USED_OVERLAYS+="XPC;"
            elif [[ ${BASH_REMATCH[2]} == "objc" ]]; then
                USED_OVERLAYS+="ObjectiveC;"
            elif [[ ${BASH_REMATCH[2]} != "" ]]; then
                USED_OVERLAYS+="${BASH_REMATCH[2]};"
            fi
        fi
    done

    # Remove last ;
    if [[ ${#USED_OVERLAYS} -gt 0 ]]; then
        USED_OVERLAYS=${USED_OVERLAYS%?}
    fi

    TRIMMED=$(tr ";" "\n" <<< "$USED_OVERLAYS" | sort | uniq | tr "\n" ";")
    echo "${TRIMMED%?}"
}

if [ "$#" -ne 3 ]; then
    echo "error: $0 needs 3 params, instead got $#"
    echo "usage: $0 Overlay sdk arch"
    echo "example: $0 CloudKit macosx x86_64"
    exit 234
fi

OVERLAY_ARG=$1
SDK_ARG=$2
ARCH_ARG=$3

OUT=$OVERLAY_ARG
LAST_OUT=$OVERLAY_ARG

# Hardcode XCTest because clang can't find its dependencies
if [[ $OVERLAY_ARG == "XCTest" ]]; then
    case "$SDK_ARG" in
        macosx)
            OUT="XCTest;AppKit;CoreData;CoreGraphics;CoreImage;Dispatch;Foundation;IOKit;ObjectiveC;QuartzCore;XPC;os"
            ;;
        iphoneos)
            OUT="XCTest;CoreAudio;CoreGraphics;CoreImage;CoreMedia;Dispatch;Foundation;ObjectiveC;QuartzCore;UIKit;os"
            ;;
        appletvos)
            OUT="XCTest;CoreGraphics;CoreImage;Dispatch;Foundation;ObjectiveC;QuartzCore;UIKit;os"
            ;;
        *)
            echo "Unknown SDK: $SDK_ARG"
            exit 345
            ;;
    esac
else
    while true; do
        OUT=$(find_deps "$LAST_OUT" "$SDK_ARG" "$ARCH_ARG")
        if [[ "$LAST_OUT" == "$OUT" ]]; then
            break
        fi
        LAST_OUT=$OUT
    done
fi

echo "${OUT}"