Hi, I am in the process of writing a build phase script that will parse configuration files and generate Swift wrapper classes to safely access those files at runtime. To get higher adoption and use the latest Xcode 11 features I would very much like to distribute it as an executable Swift Package (under SPM).
Is it currently possible (in Xcode 11), to specify an executable SPM dependency for an iOS project and then run the binary produced by that dependency in a build phase script? I don't want to include or use any code from the package in the app target. I just want to use the executable in a build phase script to generate Swift classes that I will later use in the main iOS project.
For the moment though (last I checked anyway) including an executable target interferes with iOS compatibility packageâwide.
The most vanilla solution in the meantime would be to provide a build phase for users to copy and paste. The short script would clone, build, and execute your package as a separate entity (caching it of course). The .swiftpm directory would be a good place to store the cache. This Gist demonstrates a more complete, permanent, systemâwide install of an arbitrary package tool; you could use it as a starting point, but strip out the parts you donât need.
But for users already familiar with the package manager, all you really have to do is make it obvious that you vend the tool as a Swift package. They will then be able to figure out countless ways of integrating it into their workflow just the way they want. They may use the package manager directly, or they may use some third party tool that further simplifies the process in some way (there are many such tools and scripts out in the wild).
This is possible since executable targets in a package always build for macOS. Add the executable product from the package in the target dependency build phase. Then you should be able to find that executable in the built products directory using the available environment variables.
Do you mean with $ swift build, or do you mean when you click the build button in Xcode while the package scheme and an iPhone device are selected?
(This is not something I have tried with Xcode 11 yet. My information could be stale; Xcode 10 just aborts with error: unable to resolve product type 'com.apple.product-type.tool' for platform 'iphoneos' (in target 'MyExecutable').)
I was never sure if it was a bug or not, since the official status of SwiftPM + iOS was unclear. But Iâd be happy to officially report it if you consider it to be bug, and if it still occurs with Xcode 11.
Ah, I meant when you build Swift packages using the Swift package support in Xcode 11 (not command-line SwiftPM's generated project support). The error you saw is expected if you try to build executables for non-macOS platforms in Xcode.
Thanks a lot this is exactly what I was looking for. I appreciate the additional effort of setting up the example project!
One question regarding the example. You are invoking the CodeGenTool with the command:
$SYMROOT/$CONFIGURATION/CodeGenTool
This looks a little magical. Did you first had to build the tool or does it get built by Xcode when building the app target? Also, what does $SYMROOT/$CONFIGURATION resolve to and will it always contain the CodeGenTool executable?
What I did to replace something I was previously doing with git-submodules is find a way to get a reference to the package repo from a script build-phase. It's a pretty dirty hack that uses Xcode's organization of packages, so use at your own risk
Here's a stripped down version:
#Get the build directory of the project
build_dir=`xcodebuild -project $PROJECT_NAME.xcodeproj -showBuildSettings | grep -m 1 "BUILD_DIR" | grep -oEi "\/.*"`
# This is the path for the checkouts for SPM. Just replace "##PackageName##" with your package name
project_dir=$build_dir/../../SourcePackages/checkouts/##PackageName##
#this is how I'm using it:
buildscript_path=$project_dir/app/buildTool.sh
sh $buildscript_path (...My Parameters...)
when I (have time to) figure out how to make what I'm doing into an SPM executable I'm planning on switching to your approach, but my way made it easier to adapt existing infrastructure.
Hi @Aciid, your example project only seems to work with local dependencies. If I add a remote dependency through a Github repo, Xcode does not show me the executable target hence I cannot build the tool and run it.
Is there a way to use a remote executable dependency as a build phase script?