diff --git a/.github/actions/build-xcframework/action.yml b/.github/actions/build-xcframework/action.yml index 34e12c8b4..0bee36d29 100644 --- a/.github/actions/build-xcframework/action.yml +++ b/.github/actions/build-xcframework/action.yml @@ -67,7 +67,7 @@ runs: run: Scripts/CI/darwin_setup_build.sh shell: bash - name: Build XCFrameworks - run: Scripts/build_xcframework.sh OpenSwiftUI + run: Scripts/build_xcframework.sh --compute OpenSwiftUI shell: bash - name: Code sign XCFrameworks if: ${{ inputs.signing-certificate-base64 != '' }} @@ -105,6 +105,7 @@ runs: echo '```swift' >> $GITHUB_STEP_SUMMARY for fw in "${FRAMEWORKS[@]}"; do if [ -n "$TAG_NAME" ]; then + rm -f "$fw.xcframework.zip" zip -ry "$fw.xcframework.zip" "$fw.xcframework" CHECKSUM=$(swift package compute-checksum "$fw.xcframework.zip") echo "checksum_${fw}=${CHECKSUM}" >> $GITHUB_OUTPUT @@ -120,6 +121,8 @@ runs: fi done echo '```' >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "body<> $GITHUB_OUTPUT echo "$BODY" >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e283aff5b..1d0ee18d2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,7 +21,10 @@ jobs: checksum_OpenQuartzCoreShims: ${{ steps.build.outputs.checksum_OpenQuartzCoreShims }} checksum_OpenRenderBoxShims: ${{ steps.build.outputs.checksum_OpenRenderBoxShims }} env: - OPENSWIFTUI_OPENATTRIBUTESHIMS_ATTRIBUTEGRAPH: 1 + OPENSWIFTUI_OPENATTRIBUTESHIMS_ATTRIBUTEGRAPH: 0 + OPENSWIFTUI_OPENATTRIBUTESHIMS_DANCEUIGRAPH: 0 + OPENSWIFTUI_OPENATTRIBUTESHIMS_COMPUTE: 1 + OPENSWIFTUI_OPENATTRIBUTESHIMS_COMPUTE_BINARY: 0 OPENSWIFTUI_USE_LOCAL_DEPS: 1 GH_TOKEN: ${{ github.token }} steps: @@ -73,22 +76,56 @@ jobs: cd OpenSwiftUI-spm git config user.name "github-actions[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - sed \ - -e "s|{{VERSION}}|${VERSION}|g" \ - -e "s|{{CHECKSUM_OpenSwiftUI}}|${CHECKSUM_OpenSwiftUI}|g" \ - -e "s|{{CHECKSUM_OpenSwiftUICore}}|${CHECKSUM_OpenSwiftUICore}|g" \ - -e "s|{{CHECKSUM_OpenAttributeGraphShims}}|${CHECKSUM_OpenAttributeGraphShims}|g" \ - -e "s|{{CHECKSUM_OpenCoreGraphicsShims}}|${CHECKSUM_OpenCoreGraphicsShims}|g" \ - -e "s|{{CHECKSUM_OpenObservation}}|${CHECKSUM_OpenObservation}|g" \ - -e "s|{{CHECKSUM_OpenQuartzCoreShims}}|${CHECKSUM_OpenQuartzCoreShims}|g" \ - -e "s|{{CHECKSUM_OpenRenderBoxShims}}|${CHECKSUM_OpenRenderBoxShims}|g" \ - Package.swift.template > Package.swift + + render_package() { + local checksum_OpenSwiftUI="$1" + local checksum_OpenSwiftUICore="$2" + local checksum_OpenAttributeGraphShims="$3" + local checksum_OpenCoreGraphicsShims="$4" + local checksum_OpenObservation="$5" + local checksum_OpenQuartzCoreShims="$6" + local checksum_OpenRenderBoxShims="$7" + + sed \ + -e "s|{{VERSION}}|${VERSION}|g" \ + -e "s|{{CHECKSUM_OpenSwiftUI}}|${checksum_OpenSwiftUI}|g" \ + -e "s|{{CHECKSUM_OpenSwiftUICore}}|${checksum_OpenSwiftUICore}|g" \ + -e "s|{{CHECKSUM_OpenAttributeGraphShims}}|${checksum_OpenAttributeGraphShims}|g" \ + -e "s|{{CHECKSUM_OpenCoreGraphicsShims}}|${checksum_OpenCoreGraphicsShims}|g" \ + -e "s|{{CHECKSUM_OpenObservation}}|${checksum_OpenObservation}|g" \ + -e "s|{{CHECKSUM_OpenQuartzCoreShims}}|${checksum_OpenQuartzCoreShims}|g" \ + -e "s|{{CHECKSUM_OpenRenderBoxShims}}|${checksum_OpenRenderBoxShims}|g" \ + Package.swift.template > Package.swift + } + + update_readme_version() { + perl -0pi -e 's|(\.package\(url:\s*"https://github\.com/OpenSwiftUIProject/OpenSwiftUI-spm",\s*from:\s*")[^"]+(")|$1$ENV{VERSION}$2|g' README.md + } + + commit_package_if_needed() { + local message="$1" + git add Package.swift README.md + if git diff --cached --quiet; then + echo "No changes for $(git branch --show-current)" + return 1 + fi + git commit -m "$message" + } + + render_package \ + "$CHECKSUM_OpenSwiftUI" \ + "$CHECKSUM_OpenSwiftUICore" \ + "$CHECKSUM_OpenAttributeGraphShims" \ + "$CHECKSUM_OpenCoreGraphicsShims" \ + "$CHECKSUM_OpenObservation" \ + "$CHECKSUM_OpenQuartzCoreShims" \ + "$CHECKSUM_OpenRenderBoxShims" + update_readme_version echo "Generated Package.swift:" head -50 Package.swift - git add Package.swift - git diff --cached --quiet && echo "No changes" && exit 0 - git commit -m "Update to ${VERSION} with code-signed XCFrameworks" - git tag "${VERSION}" + if commit_package_if_needed "Update to ${VERSION} with code-signed XCFrameworks"; then + git tag "${VERSION}" + fi git push origin main --tags release-notes: diff --git a/Package.swift b/Package.swift index ad3ee3b08..b120cf6cf 100644 --- a/Package.swift +++ b/Package.swift @@ -944,6 +944,28 @@ if swiftCryptoCondition { #if TUIST import struct ProjectDescription.PackageSettings import enum ProjectDescription.Product +import enum ProjectDescription.SettingValue +import typealias ProjectDescription.SettingsDictionary + +let openSwiftUIBuildAGBackend: String +if let configuredAGBackend = envStringValue("AG_BACKEND_NAME") { + openSwiftUIBuildAGBackend = configuredAGBackend +} else if computeCondition { + openSwiftUIBuildAGBackend = "Compute" +} else if danceUIGraphCondition { + openSwiftUIBuildAGBackend = "DanceUIGraph" +} else if attributeGraphCondition { + openSwiftUIBuildAGBackend = "AttributeGraph" +} else { + openSwiftUIBuildAGBackend = "OpenAttributeGraph" +} +let openSwiftUIBuildRendererBackend = envStringValue("RENDERER_BACKEND_NAME") ?? (swiftUIRenderCondition ? "SwiftUI" : "OpenSwiftUI") +let openSwiftUITargetSettings: SettingsDictionary = [ + "INFOPLIST_KEY_OpenSwiftUIAGBackend": .string(openSwiftUIBuildAGBackend), + "INFOPLIST_KEY_OpenSwiftUIRendererBackend": .string(openSwiftUIBuildRendererBackend), + "INFOPLIST_KEY_OpenSwiftUILibraryType": .string(configuredLibraryType ?? "automatic"), + "INFOPLIST_KEY_OpenSwiftUIUsesLocalDependencies": .string(useLocalDeps ? "YES" : "NO"), +] let packageSettings = PackageSettings( productTypes: [ @@ -961,6 +983,9 @@ let packageSettings = PackageSettings( "OpenRenderBoxShims": ProjectDescription.Product.staticFramework, "SymbolLocator": ProjectDescription.Product.staticFramework, ], - baseProductType: ProjectDescription.Product.staticFramework + baseProductType: ProjectDescription.Product.staticFramework, + targetSettings: [ + "OpenSwiftUI": .settings(base: openSwiftUITargetSettings), + ] ) #endif diff --git a/Scripts/CI/compute_setup.sh b/Scripts/CI/compute_setup.sh new file mode 100755 index 000000000..c80412072 --- /dev/null +++ b/Scripts/CI/compute_setup.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +# A `realpath` alternative using the default C implementation. +filepath() { + [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}" +} + +REPO_ROOT="$(dirname $(dirname $(dirname $(filepath $0))))" + +clone_checkout_compute() { + cd $REPO_ROOT + revision=$(Scripts/CI/get_revision.sh compute) + cd .. + if [ ! -d Compute ]; then + gh repo clone OpenSwiftUIProject/Compute + cd Compute + else + echo "Compute already exists, skipping clone." + cd Compute + git fetch --all --quiet + git stash --quiet || true + git reset --hard --quiet origin/main + fi + if [ -n "$revision" ]; then + git checkout --quiet "$revision" + else + echo "No pinned revision for Compute, using default branch." + fi +} + +update_compute() { + cd $REPO_ROOT/../Compute + git submodule sync --recursive --quiet + git submodule update --init --recursive +} + +clone_checkout_compute +update_compute diff --git a/Scripts/CI/darwin_setup_build.sh b/Scripts/CI/darwin_setup_build.sh index f5e00a0ac..15ed5ca46 100755 --- a/Scripts/CI/darwin_setup_build.sh +++ b/Scripts/CI/darwin_setup_build.sh @@ -10,6 +10,7 @@ cd $REPO_ROOT # The order of these scripts matters. # The more foundational frameworks should be set up last. +Scripts/CI/compute_setup.sh Scripts/CI/openattributegraph_setup.sh Scripts/CI/openrenderbox_setup.sh Scripts/CI/opencoregraphics_setup.sh diff --git a/Scripts/build_xcframework.sh b/Scripts/build_xcframework.sh index 49970a35c..fbac1f04f 100755 --- a/Scripts/build_xcframework.sh +++ b/Scripts/build_xcframework.sh @@ -8,7 +8,6 @@ set -e export OPENSWIFTUI_LIBRARY_TYPE export OPENSWIFTUI_USE_LOCAL_DEPS export OPENSWIFTUI_SWIFTUI_RENDERER -# TODO: replace AG with Compute or OAG by default SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd -P)" PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" @@ -40,8 +39,27 @@ DEFAULT_FRAMEWORK_NAMES=( "OpenSwiftUI" ) +print_usage() { + cat <<'USAGE' +Usage: Scripts/build_xcframework.sh [options] [framework ...] + +Options: + --sdk Build for an SDK. May be passed multiple times. + --archs Override architectures for the previous --sdk. + --debug Keep release metadata and copy dSYMs. + --compute Build OpenAttributeGraphShims with the Compute source backend. + --skip-tuist-install Skip tuist install. + --framework Build one framework. May be passed multiple times. + --help Show this help. +USAGE +} + while [[ $# -gt 0 ]]; do case "$1" in + --help|-h) + print_usage + exit 0 + ;; --sdk) SDKS+=("$2") SDK_ARCHS+=("") @@ -57,6 +75,17 @@ while [[ $# -gt 0 ]]; do DEBUG_MODE=true shift ;; + --compute) + OPENSWIFTUI_OPENATTRIBUTESHIMS_ATTRIBUTEGRAPH=0 + OPENSWIFTUI_OPENATTRIBUTESHIMS_DANCEUIGRAPH=0 + OPENSWIFTUI_OPENATTRIBUTESHIMS_COMPUTE=1 + OPENSWIFTUI_OPENATTRIBUTESHIMS_COMPUTE_BINARY=0 + export OPENSWIFTUI_OPENATTRIBUTESHIMS_ATTRIBUTEGRAPH + export OPENSWIFTUI_OPENATTRIBUTESHIMS_DANCEUIGRAPH + export OPENSWIFTUI_OPENATTRIBUTESHIMS_COMPUTE + export OPENSWIFTUI_OPENATTRIBUTESHIMS_COMPUTE_BINARY + shift + ;; --skip-tuist-install) RUN_TUIST_INSTALL=false shift @@ -83,11 +112,16 @@ if [ ${#FRAMEWORK_NAMES[@]} -eq 0 ] || FRAMEWORK_NAMES=("${DEFAULT_FRAMEWORK_NAMES[@]}") fi -# Default: macosx and iphonesimulator. +# Default: macosx and iphonesimulator. Compute builds also include iphoneos. # Note: iphoneos SDK support is blocked by an AG issue. See #835. if [ ${#SDKS[@]} -eq 0 ]; then - SDKS=("macosx" "iphonesimulator") - SDK_ARCHS=("" "") + if [ "${OPENSWIFTUI_OPENATTRIBUTESHIMS_COMPUTE:-0}" = "1" ]; then + SDKS=("macosx" "iphonesimulator" "iphoneos") + SDK_ARCHS=("" "" "") + else + SDKS=("macosx" "iphonesimulator") + SDK_ARCHS=("" "") + fi fi if [ "${OPENSWIFTUI_SKIP_TUIST_INSTALL:-0}" = "1" ]; then @@ -255,6 +289,11 @@ framework_path() { echo "$archive_path/Products/Library/Frameworks/$scheme.framework" } +xcframework_path() { + local scheme="$1" + echo "$PROJECT_BUILD_DIR/$scheme.xcframework" +} + framework_modules_path() { local framework="$1" if [ -d "$framework/Versions" ]; then @@ -375,15 +414,17 @@ build_framework() { create_xcframework() { local scheme="$1" + local output_path + output_path="$(xcframework_path "$scheme")" - rm -rf "$PROJECT_BUILD_DIR/$scheme.xcframework" + rm -rf "$output_path" local create_args=() for sdk in "${SDKS[@]}"; do create_args+=(-framework "$(framework_path "$PROJECT_BUILD_DIR/$scheme-$sdk.xcarchive" "$scheme")") done - xcodebuild -create-xcframework "${create_args[@]}" -output "$PROJECT_BUILD_DIR/$scheme.xcframework" + xcodebuild -create-xcframework "${create_args[@]}" -output "$output_path" } copy_debug_symbols() { @@ -397,9 +438,9 @@ copy_debug_symbols() { for sdk in "${SDKS[@]}"; do local local_dsym_dir="" case "$sdk" in - iphonesimulator) local_dsym_dir=$(ls -d "$PROJECT_BUILD_DIR/$scheme.xcframework"/ios-*simulator 2>/dev/null | head -1) ;; - iphoneos) local_dsym_dir=$(ls -d "$PROJECT_BUILD_DIR/$scheme.xcframework"/ios-arm64 2>/dev/null | head -1) ;; - macosx) local_dsym_dir=$(ls -d "$PROJECT_BUILD_DIR/$scheme.xcframework"/macos-* 2>/dev/null | head -1) ;; + iphonesimulator) local_dsym_dir=$(ls -d "$(xcframework_path "$scheme")"/ios-*simulator 2>/dev/null | head -1) ;; + iphoneos) local_dsym_dir=$(ls -d "$(xcframework_path "$scheme")"/ios-arm64 2>/dev/null | head -1) ;; + macosx) local_dsym_dir=$(ls -d "$(xcframework_path "$scheme")"/macos-* 2>/dev/null | head -1) ;; esac if [ -n "$local_dsym_dir" ] && [ -d "$PROJECT_BUILD_DIR/$scheme-$sdk.xcarchive/dSYMs" ]; then @@ -418,7 +459,7 @@ for scheme in "${FRAMEWORK_NAMES[@]}"; do done create_xcframework "$scheme" copy_debug_symbols "$scheme" - echo "Created $PROJECT_BUILD_DIR/$scheme.xcframework" + echo "Created $(xcframework_path "$scheme")" done if [ "$DEBUG_MODE" = false ]; then