feat(ios): allow keyman engine to be built via Carthage for iOS
This pull request makes changes to allow a project (such as Scripture App Builder) to include the keyman engine through carthage for ios. I pretty much left the standard builds alone to the extent possible, leaving all the project files and the Carthage that is currently there in place and unchanged. The following changes have been made:
Cartfile and Cartfile.resolved have been added to the top level directory, which is where carthage requires them for this purpose. The original Cartfile and Cartfile.resolved in the iOS folder are still there and used for the standard builds.
A workspace for KeymanEngine has been added to the top level for Carthage to detect and run from. It points to a single project, the KeymanEngineCarthage.xcodeproj file, which is specific to this build.
ios/engine/KMEI/KeymanEngineCarthage.xcodeproj. This project is identical to the KeymanEngine.xcodeproj with the following exceptions:
- All targets except for KeymanEngine are turned off and marked non shareable. Carthage will build any shared target with the associated build.
- Frameworks have been modified to look to the Carthage/Build folder at the main directory instead of the one in the ios folder.
- A script phase has been added to call the build.sh build:engine in ios with a parameter of --carthage-build to update the bundle prior to doing the actual build.
ios/build.sh and ios/engine/build.sh have been modified to accept a new parameter --carthage-build. This parameter is used to prevent the build scripts from calling carthage and to run the update_bundle and then quit.
.gitignore is modified to allow the single xcscheme which Carthage requires for the build to be checked in,
A new script file ios/testCarthageBuild.sh is included to allow for testing of the build. It builds all the carthage components and then runs the keyman engine build from within Carthage. A keymanEngine.xcframework is built in the Carthage/Build folder.
This pull request is from an external repo and will not automatically be built. The build must still be passed before it can be merged. Ask one of the team members to make a manual build of this PR.
Cartfile and Cartfile.resolved have been added to the top level directory, which is where carthage requires them for this purpose. The original Cartfile and Cartfile.resolved in the iOS folder are still there and used for the standard builds.
Is there any way to have two versions in parallel? Keep in mind that we also have Keyman Engine for Mac, and somewhere down the line someone may wish for that to be distributed as well. The best I can find in this regard would be to make the workspace capable of producing both engines as schemes, then leaving it to the framework consumer to pick which one they want to use in the project's configuration. We can't filter it for them, and they can't filter it when running carthage bootstrap.
Furthermore... it certainly seems that Carthage has a quite opinionated set of requirements for compatibility. I went searching and found numerous issues + feature requests for them to implement some sort of filter on specified dependency repos, and they pretty much rejected all of 'em. No ability to say "use this subpath"; one (older) issue I could find considered monorepo approaches to be "niche" and "one-off".
The best link I could find re: the root-level requirement: https://github.com/Carthage/Carthage/issues/3042
Cartfile and Cartfile.resolved have been added to the top level directory, which is where carthage requires them for this purpose. The original Cartfile and Cartfile.resolved in the iOS folder are still there and used for the standard builds.
A workspace for KeymanEngine has been added to the top level for Carthage to detect and run from. It points to a single project, the KeymanEngineCarthage.xcodeproj file, which is specific to this build.
There's a decent chance that this will be a "hard sell" to our project lead; we've done a lot of work to set up individual silos for each platform and section, and this kind of muddies those waters. I'll leave it to him to make that decision, though.
Something that I bumped into while researching these details: recent versions of Xcode offer a built-in Swift Package Manager that may be worth shifting to. It seemed capable of at least detecting the iOS engine's project when given this repo's URL, though I admittedly doubt it'll work out of the box due to the Carthage dependencies. I personally think it looks like a promising alternative to Carthage, etc, worth looking at, but for now, that's just my perspective. (The Mac project doesn't show up... but that's probably because it doesn't use Swift at this time.)
A script phase has been added to call the build.sh build:engine in ios with a parameter of --carthage-build to update the bundle prior to doing the actual build.
That may provide us a decent avenue to have the repo run the Carthage setup if necessary as an alternative via whatever (other) dependency system(s) we do land with. It'd take investigative work to get right, of course.
Also, note that our primary team members for the platform are currently out of office, so there may be delays in getting a full response to this PR. Not ideal, I know, but I figure it's best to know about the potential for delays regarding potential acceptance of your submission.
For the one issue about the running mac, it is controlled somewhat there by the --platform ios. That makes it look for all schemes that are ios and could have schemes added for mac that would work and then only build in Carthage when the platform is set to build for mac.
I agree that the requirements that Carthage makes are overly specific and that it doesn't allow you a lot of options. Part of the reason for not trying to modify the existing projects to use the other Carthage was to try and leave everything you're already doing alone as much as possible. If you can figure out a way to make this a package dependency through xcode, I would be more than happy to switch. The problem I have been working against is that there is not a good way with the standard repository here to include the engine as part of an SAB build. Originally, I would build it manually and check in the framework, but that required me to rebuild it every time xcode was updated and you really don't like checking in binaries anyway. Adding the carthage stuff made it easy to include the framework into the project and have it built along with the other carthage components. But if you can come up with another solution that would work, I will be happy to try to use it. And if you can't and can't merge the PR, I'll just keep creating it in my own fork when I upgrade as I have been doing.
Thank you for the update.
I'll be back on deck for a few days next week (and then mostly offline again after that for a few more weeks) but can hopefully review properly then.
In the meantime, I wonder what you think about us providing a binary instead as part of our build process -- Carthage does provide some very basic support for binary frameworks -- because that avoids a complex toolchain requirement including Node, Emscripten, brew coreutils, etc, etc.
I imagine that there are problems with binaries as well though (e.g. Swift version mismatches).
In the meantime, I wonder what you think about us providing a binary instead as part of our build process -- Carthage does provide some very basic support for binary frameworks -- because that avoids a complex toolchain requirement including Node, Emscripten, brew coreutils, etc, etc.
I imagine that there are problems with binaries as well though (e.g. Swift version mismatches).
Awaiting your comment here @davidmoore1.
At present, I am concerned about our emscripten + node toolchain requirements cascading down to consumers, and there doesn't seem to be a good way to mitigate that, that I can see at least.
@davidmoore1 We'd like to get this PR resolved -- do you have time to discuss?
Sorry didn't see this. Yes, we can talk about it whenever you have time
He must increase, but I must decrease (John 3:30)
David Moore (cell and sms) 304 516 1678
On Tue, Nov 12, 2024 at 10:24 PM Marc Durdin @.***> wrote:
@davidmoore1 https://github.com/davidmoore1 We'd like to get this PR resolved -- do you have time to discuss?
— Reply to this email directly, view it on GitHub https://github.com/keymanapp/keyman/pull/11834#issuecomment-2472291950, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABPL5JDAF7Y6XNR7BIXAGGD2ALA6FAVCNFSM6AAAAABJSK4J4CVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDINZSGI4TCOJVGA . You are receiving this because you were mentioned.Message ID: @.***>
We have our Keyman team meeting this week, so could we line something up for first week of December?
I don't think this is going to happen any time soon. We can restart this when/if we have time to work together on it.
@davidmoore1 also wrote:
I think I've finally found a way to get the engine built and into SAB without all the hassles I had to go through with Carthage. I created a repository with build scripts that clone the keyman repository, builds the engine, and then moves the xcframework, along with the Carthage frameworks that were generated, into a package that can be included via the XCode package dependency. And it builds through a github action, which should also simplify some things. I've got a little testing to complete after we get our next release out, but it seems to work correctly. So with that, all I need to do is specify the branch to use (like stable-17.0) and I can upgrade the engine to a new release without all of the changes I was having to make to get it to build for Carthage