Thank you Pedro,
The solution I landed on was a bit too hacky, so i’ve decided to go with a similar approach to what you suggested.However, that caused a cyclic dependency, given the the outputFilePaths
now equals to the path of the xcframework dependency. Xcode refused to build, I tried to circumvent it, but even if the outputFilePaths could be set it would use the xcframework that was generated from a previous run, despite it being a .pre
target script, it linked prior to it running somehow.
Alternatively, I tried to have the build script run in a separate target that i then depend on, of course not depending on the xcframework
there. That worked, but wasn’t ideal.
In the end, I’ve decided to modify the buildAction in the Scheme and add a ExecutableAction
to the preActions
.
schemes: [
.scheme(
name: "REDACTED",
buildAction: .buildAction(
targets: [.target("REDACTED")],
preActions: {
guard case let .string(zig) = Environment.zig else { return [] }
return [.executionAction(scriptText: "(cd $SRCROOT; \(zig) build ios)", target: "REDACTED")]
}()
)
)
]
This unfortunately does run the build each time, but the build system I’m calling caches well so it’s fine in my case.
One minor nitpick with this approach, given Tuist takes a scriptText
rather than something like a TargetScript
which has an overload that allows me to pass a tool
given I don’t know where the zig executable lives, I had to as you see above take it as an environment variable so TUIST_ZIG
. It’s fine since I just have something equivalent to the generate.sh
you suggested that does the following:
writeShellApplication {
name = "xcgen";
text = "(zig build ios; TUIST_ZIG=${lib.getExe zig} tuist generate)";
runtimeInputs = [zig tuist];
}
Note, if your build system is expensive to call:
The approach I mentioned wasn’t ideal, where you have a separate target that you depend on call the build system, is better in that case. Since you can set the inputFilePaths and outputFilePaths as Pedro mentioned. To only call the build system when the files change.