├── .github ├── bootstrap.sh └── workflows │ └── release.yml ├── .gitignore ├── LICENSE ├── Package.swift ├── README.md └── Sources └── SwiftSyntaxWrapper └── Empty.swift /.github/bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SWIFT_SYNTAX_VERSION=$1 4 | SWIFT_SYNTAX_NAME="swift-syntax" 5 | SWIFT_SYNTAX_REPOSITORY_URL="https://github.com/apple/$SWIFT_SYNTAX_NAME.git" 6 | SEMVER_PATTERN="^[0-9]+\.[0-9]+\.[0-9]+$" 7 | WRAPPER_NAME="SwiftSyntaxWrapper" 8 | ARCH="arm64" 9 | CONFIGURATION="release" 10 | DERIVED_DATA_PATH="$PWD/derivedData" 11 | 12 | # 13 | # Verify input 14 | # 15 | 16 | if [ -z "$SWIFT_SYNTAX_VERSION" ]; then 17 | echo "Swift syntax version (git tag) must be supplied as the first argument" 18 | exit 1 19 | fi 20 | 21 | if ! [[ $SWIFT_SYNTAX_VERSION =~ $SEMVER_PATTERN ]]; then 22 | echo "The given version ($SWIFT_SYNTAX_VERSION) does not have the right format (expected X.Y.Z)." 23 | exit 1 24 | fi 25 | 26 | # 27 | # Print input 28 | # 29 | 30 | cat << EOF 31 | 32 | Input: 33 | swift-syntax version to build: $SWIFT_SYNTAX_VERSION 34 | 35 | EOF 36 | 37 | set -eux 38 | 39 | # 40 | # Clone package 41 | # 42 | 43 | git clone --branch $SWIFT_SYNTAX_VERSION --single-branch $SWIFT_SYNTAX_REPOSITORY_URL 44 | 45 | # 46 | # Add static wrapper product 47 | # 48 | 49 | sed -i '' -E "s/(products: \[)$/\1\n .library(name: \"${WRAPPER_NAME}\", type: .static, targets: [\"${WRAPPER_NAME}\"]),/g" "$SWIFT_SYNTAX_NAME/Package.swift" 50 | 51 | # 52 | # Add target for wrapper product 53 | # 54 | 55 | sed -i '' -E "s/(targets: \[)$/\1\n .target(name: \"${WRAPPER_NAME}\", dependencies: [\"SwiftCompilerPlugin\", \"SwiftSyntax\", \"SwiftSyntaxBuilder\", \"SwiftSyntaxMacros\", \"SwiftSyntaxMacrosTestSupport\"]),/g" "$SWIFT_SYNTAX_NAME/Package.swift" 56 | 57 | # for swift 600.x.y 58 | sed -i '' 's/, .version("6")//g' "$SWIFT_SYNTAX_NAME/Package.swift" 59 | 60 | # 61 | # Add exported imports to wrapper target 62 | # 63 | 64 | WRAPPER_TARGET_SOURCES_PATH="$SWIFT_SYNTAX_NAME/Sources/$WRAPPER_NAME" 65 | 66 | mkdir -p $WRAPPER_TARGET_SOURCES_PATH 67 | 68 | tee $WRAPPER_TARGET_SOURCES_PATH/ExportedImports.swift </dev/null 146 | 147 | for ((i = 1; i < ${#PLATFORMS[@]}; i += 2)); do 148 | XCFRAMEWORK_PLATFORM_NAME="${PLATFORMS[i]}" 149 | OUTPUTS_PATH="${PLATFORMS_OUTPUTS_PATH}/${XCFRAMEWORK_PLATFORM_NAME}" 150 | cp $OUTPUTS_PATH/*.swiftinterface "$XCFRAMEWORK_PATH/$XCFRAMEWORK_PLATFORM_NAME" 151 | done 152 | 153 | zip --quiet --recurse-paths $XCFRAMEWORK_NAME.zip $XCFRAMEWORK_NAME 154 | 155 | # 156 | # Create package manifest 157 | # 158 | 159 | CHECKSUM=$(swift package compute-checksum $XCFRAMEWORK_NAME.zip) 160 | URL="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/releases/download/$SWIFT_SYNTAX_VERSION/$XCFRAMEWORK_NAME.zip" 161 | 162 | tee Package.swift <"), 23 | ``` 24 | 25 | with 26 | 27 | ``` 28 | .package(url: "https://github.com/sjavora/swift-syntax-xcframeworks.git", from: ""), 29 | ``` 30 | 31 | #### Update target dependencies with `SwiftSyntaxWrapper` 32 | 33 | Replace 34 | 35 | ``` 36 | .product(name: "SwiftSyntaxMacros", package: "swift-syntax"), 37 | .product(name: "SwiftCompilerPlugin", package: "swift-syntax") 38 | ``` 39 | 40 | and 41 | 42 | ``` 43 | .product(name: "SwiftSyntaxMacrosTestSupport", package: "swift-syntax"), 44 | ``` 45 | 46 | with 47 | 48 | ``` 49 | .product(name: "SwiftSyntaxWrapper", package: "swift-syntax-xcframeworks"), 50 | ``` 51 | 52 | ### Run the package 53 | 54 | The package should now build, tests should run, and the macro in the client should expand correctly. 55 | 56 | ## Compile time comparison 57 | 58 | The purpose of this repository is to be able to use `swift-syntax` while eliminating its compile time. Compare Xcode's build timeline for the default macro package with and without building `swift-syntax`: 59 | 60 | | with `swift-syntax` (18s 72ms) | with `swift-syntax-frameworks` (2s 28ms) | 61 | | ------------------- | -------------------------------| 62 | | ![Build timeline when building with swift-syntax from source, total duration of 18s 72ms](https://github.com/sjavora/swift-syntax-xcframeworks/assets/12349477/d6ca41cd-b56b-4623-90f0-673bab71a6a6) | ![Build timeline when using swift-syntax-xcframeworks, total duration of 2s 28ms](https://github.com/sjavora/swift-syntax-xcframeworks/assets/12349477/b14d4c21-136b-46dd-b570-584d6d726b7d) | 63 | 64 | Measured on a MacBook Pro with M1 Pro and 32 GB RAM, running Xcode 15.0. 65 | 66 | ## Known issues 67 | 68 | ### Warnings 69 | 70 | The linker produces a warning about duplicate libraries. This is only visible when building the macro package itself, though, not when using the macro in some other package. This doesn't seem to cause issues in practice. 71 | 72 | ### Clashes with `swift-syntax` 73 | 74 | If your project depends on `swift-syntax` in any way (e.g., through a third party library), Xcode will fail package resolution due to name clashes. A possible workaround woudl be to rename all the products when building `swift-syntax` in this repository to avoid such clashes, though that would then require renaming all the imports in files that use `SwiftSyntaxWrapper`. 75 | -------------------------------------------------------------------------------- /Sources/SwiftSyntaxWrapper/Empty.swift: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sjavora/swift-syntax-xcframeworks/bcf726ec1608b318b0a6eae30042d7d9c272b34e/Sources/SwiftSyntaxWrapper/Empty.swift --------------------------------------------------------------------------------