├── .gitignore ├── LICENSE ├── example.patch ├── create-xcframework.sh └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.xcframework 2 | *.xcframework.zip 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2022 Keith Smiley (http://keith.so) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the 'Software'), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so, 8 | subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | -------------------------------------------------------------------------------- /example.patch: -------------------------------------------------------------------------------- 1 | diff --git a/tools/libSwiftSyntaxParser/CMakeLists.txt b/tools/libSwiftSyntaxParser/CMakeLists.txt 2 | index 0b33758f923..449cd488e6f 100644 3 | --- a/tools/libSwiftSyntaxParser/CMakeLists.txt 4 | +++ b/tools/libSwiftSyntaxParser/CMakeLists.txt 5 | @@ -51,6 +51,15 @@ if(NOT CMAKE_SYSTEM_NAME STREQUAL Darwin) 6 | endif() 7 | 8 | add_dependencies(parser-lib libSwiftSyntaxParser) 9 | + 10 | +target_compile_options(libSwiftSyntaxParser PRIVATE 11 | + "SHELL:-Xclang --linker-option=-lc" 12 | + "SHELL:-Xclang --linker-option=-lc++" 13 | + "SHELL:-Xclang --linker-option=-lncurses" 14 | + "SHELL:-Xclang --linker-option=-lz" 15 | +) 16 | +target_link_options(libSwiftSyntaxParser PRIVATE -Wl,-x -Wl,-r --ld-path=${CMAKE_CURRENT_SOURCE_DIR}/linker.sh) 17 | + 18 | swift_install_in_component(TARGETS libSwiftSyntaxParser 19 | ARCHIVE DESTINATION "lib${LLVM_LIBDIR_SUFFIX}/swift/${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_LIB_SUBDIR}" COMPONENT parser-lib 20 | LIBRARY DESTINATION "lib${LLVM_LIBDIR_SUFFIX}/swift/${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_LIB_SUBDIR}" COMPONENT parser-lib 21 | diff --git a/tools/libSwiftSyntaxParser/linker.sh b/tools/libSwiftSyntaxParser/linker.sh 22 | new file mode 100755 23 | index 00000000000..f340597b384 24 | --- /dev/null 25 | +++ b/tools/libSwiftSyntaxParser/linker.sh 26 | @@ -0,0 +1,12 @@ 27 | +#!/bin/bash 28 | + 29 | +set -euo pipefail 30 | + 31 | +args=() 32 | +for arg in "$@"; do 33 | + if [[ "$arg" != -dead_strip ]]; then 34 | + args+=("$arg") 35 | + fi 36 | +done 37 | + 38 | +ld "${args[@]}" 39 | -------------------------------------------------------------------------------- /create-xcframework.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | set -x 5 | 6 | if [[ $# -ne 3 ]]; then 7 | echo "Usage: $0 path/to/swift/checkout path/to/arm64 path/to/x86_64" 8 | exit 1 9 | fi 10 | 11 | include_dir=$1/swift/include/swift-c/SyntaxParser 12 | shift 13 | if [[ "$include_dir" != /* ]]; then 14 | include_dir="$PWD/$include_dir" 15 | fi 16 | 17 | if [[ ! -d "$include_dir" ]]; then 18 | echo "error: failed to find syntax parser include directory, please file an issue" >&2 19 | exit 1 20 | fi 21 | 22 | if [[ "$1" == /* ]]; then 23 | binary1="$1" 24 | else 25 | binary1="$PWD/$1" 26 | fi 27 | 28 | if [[ "$2" == /* ]]; then 29 | binary2="$2" 30 | else 31 | binary2="$PWD/$2" 32 | fi 33 | 34 | workdir=$(mktemp -d) 35 | pushd "$workdir" 36 | mkdir -p lib_InternalSwiftSyntaxParser.framework/Headers lib_InternalSwiftSyntaxParser.framework/Modules 37 | cp "$include_dir"/*.h lib_InternalSwiftSyntaxParser.framework/Headers 38 | 39 | echo 'framework module _InternalSwiftSyntaxParser { 40 | umbrella header "SwiftSyntaxParser.h" 41 | export * 42 | module * { export * } 43 | }' > lib_InternalSwiftSyntaxParser.framework/Modules/module.modulemap 44 | lipo -create -output lib_InternalSwiftSyntaxParser.framework/lib_InternalSwiftSyntaxParser "$binary1" "$binary2" 45 | xcodebuild -create-xcframework -framework lib_InternalSwiftSyntaxParser.framework -output lib_InternalSwiftSyntaxParser.xcframework 46 | popd 47 | rm -rf ./lib_InternalSwiftSyntaxParser.xcframework ./lib_InternalSwiftSyntaxParser.xcframework.zip 48 | mv "$workdir/lib_InternalSwiftSyntaxParser.xcframework" . 49 | zip -r lib_InternalSwiftSyntaxParser.xcframework.zip lib_InternalSwiftSyntaxParser.xcframework 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # StaticInternalSwiftSyntaxParser 2 | 3 | NOTE: As of Swift 5.8 this library is no more, instead it has been 4 | reimplemented in Swift as part of 5 | [`SwiftSyntax`](https://github.com/apple/swift-syntax) 6 | 7 | This is a distribution of `lib_InternalSwiftSyntaxParser.dylib` built 8 | statically. This allows you to create a self contained portable binary 9 | that depends on [`swift-syntax`][swift-syntax] instead of having to 10 | depend on your specific Xcode version and path, or distribute the 11 | library alongside your tool. 12 | 13 | # Usage 14 | 15 | See [the releases 16 | page](https://github.com/keith/StaticInternalSwiftSyntaxParser/releases) 17 | to get the right version of the library for your version of Xcode and 18 | [`swift-syntax`][swift-syntax]. 19 | 20 | With Swift Package Manager you can use the `.binaryTarget` type with 21 | this: 22 | 23 | ```swift 24 | targets: [ 25 | // Some targets 26 | .binaryTarget( 27 | name: "lib_InternalSwiftSyntaxParser", 28 | url: "See releases page", 29 | checksum: "See releases page" 30 | ), 31 | ], 32 | ``` 33 | 34 | Then add `lib_InternalSwiftSyntaxParser` to the `dependencies` of 35 | another target. 36 | 37 | If you want to use this without Swift Package Manager you can download 38 | the xcframework and use the internal 39 | `lib_InternalSwiftSyntaxParser.framework` however you'd normally include 40 | dependencies. 41 | 42 | Note: because of [this bug](https://bugs.swift.org/browse/SR-15802) if 43 | you want to depend on this target in SwiftPM and target multiple 44 | architectures in a single build, you must only depend on it from top 45 | level targets such as a test or executable target. 46 | 47 | ## Building 48 | 49 | To create a new release for this project follow these steps: 50 | 51 | - Clone [`apple/swift`](https://github.com/apple/swift) and checkout the 52 | branch you want using the `update-checkout` script as described in 53 | their documentation 54 | - Cherry pick the most recent commit from the releases page, or use the 55 | `example.patch` checked into this repo as a starting point 56 | - Build the project with something like `./swift/utils/build-script 57 | --release` 58 | - If you'd like a fat binary for supporting arm64 and x86_64 macs, build 59 | with `./swift/utils/build-script --release --cross-compile-hosts 60 | macosx-x86_64` 61 | - Run `create-xcframework.sh swift/src/dir binary1 binary2` to create 62 | the combined framework 63 | 64 | ## Notes 65 | 66 | - This method doesn't actually produce a static binary, but it produces 67 | a relocatable object file which is similar enough for this use case. 68 | This is because cmake cannot create distributable static library 69 | targets that include all of their nested dependencies 70 | - Be sure to pass `-dead_strip` to your linker when linking this library 71 | with a binary to save on binary size (you likely already are) 72 | - As of Swift 5.6 Apple bundles a dynamic version of this library as part 73 | of the SwiftSyntax release. In order to ignore that version and prefer 74 | this static version, you must pass `-Xlinker -dead_strip_dylibs` when 75 | building your tool. This can be done by adding it to the `linkerSettings` 76 | of the target that depends on this library in your Package.swift file. 77 | 78 | [swift-syntax]: https://github.com/apple/swift-syntax 79 | --------------------------------------------------------------------------------