swiftxcodebuildswift-package-managerswift-package

How to Create a Version-Independent and Scheme-Agnostic Build Script for Swift Package using Xcode and Swift Build?


Consider the following code to verify the compilation of some swift package (for the Swift Package Manager)

xcodebuild \
  -scheme name-Package \
  -sdk iphonesimulator \
  -destination 'platform=iOS Simulator,OS=17.0,name=iPhone 15' \
  -configuration Debug

And the equivalent swift build command:

swift build -Xswiftc -warnings-as-errors -Xswiftc "-sdk" -Xswiftc "$(xcrun --sdk iphonesimulator --show-sdk-path)" -Xswiftc "-target" -Xswiftc "x86_64-apple-ios15.0-simulator"

Questions:

  1. Would it be possible to make this Xcode/Simulator version independent, so that I won't have to include the version of the SDK in each command? i.e. remove this line from the 1st command: Simulator,OS=17.0,name=iPhone 15 and remove this one from the 2nd one: x86_64-apple-ios15.0-simulator
  2. Would it be possible to remove the scheme name from the 1st command, i.e. name-Package, or discover it in some way and paste the scheme containing the Package word, so that the xcodebuild will try to build the whole package and not just some single target in that package.

Motivation: Create a generic build script that can work on any Swift Package repository.


Solution

  • PACKAGE_SCHEME=$(xcodebuild -list | (awk '/Schemes:/ {p=1; next} p && NF; !p {p=0}' | grep "Package" || xcodebuild -list | awk '/Schemes:/ {p=1; next} p && NF; !p {p=0}' | head -1) | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
    xcodebuild \
      -scheme "$PACKAGE_SCHEME" \
      -sdk iphonesimulator \
      -destination "platform=iOS Simulator,name=iPhone" \
      -configuration Debug
    

    It works as follows:

    1. The first line detects the scheme to use, it's either the one with Package suffix or the first scheme
    2. That scheme is inserted into the xcodebuild command that does the actual building.