blob: 3b11a2361bf339619df17b46baea8b9ea41e9e2c [file] [log] [blame]
#!/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|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}"