Skip to content
This repository has been archived by the owner on Jun 21, 2023. It is now read-only.

Allow installing prebuilt binary from this repository using Carthage #143

Open
1ec5 opened this issue Jan 10, 2020 · 3 comments · May be fixed by #548
Open

Allow installing prebuilt binary from this repository using Carthage #143

1ec5 opened this issue Jan 10, 2020 · 3 comments · May be fixed by #548
Labels
dependencies Pull requests that update a dependency file p3

Comments

@1ec5
Copy link
Contributor

1ec5 commented Jan 10, 2020

A developer should be able to install this SDK by specifying a github origin in their Cartfile and running carthage update. The origin should point to this repository or, if that isn’t feasible, a repository set up specifically for Carthage installation.

Problem

As of #60 in v5.6.0, developers need to specify a binary origin when installing the SDK via Carthage. The binary origin doesn’t support transitive dependencies, so we also tell them to require MapboxMobileEvents separately. This requirement is expressed only informally on a webpage, not formally in a Cartfile, so Carthage cannot enforce the MapboxMobileEvents specification or detect when it is incompatible with another library’s MapbxoxMobileEvents specification.

mapbox/mapbox-navigation-ios#2299 describes a crash at runtime that occurred because of a version mismatch between the map and navigation SDKs. However, a version mismatch could instead produce a build failure or undefined behavior at runtime, depending on what changed in MapboxMobileEvents between the two required versions.

As long as the map SDK relies on an informal dependency, version mismatches will continue to occur any time the map SDK or the navigation SDK requires something new in MapboxMobileEvents.

Proposed changes

I think the most straightforward solution would require aligning this project to how Carthage is designed to be used:

  • A Cartfile in the repository would specify the MapboxMobileEvents dependency.
  • Each tag going forward would be named according to semver rules, e.g., v5.7.0, not ios-v5.7.0.
  • For each release going forward, a prebuilt archive should be attached to the release with the extension .framework.zip. The Carthage documentation says the archive’s structure is unimportant, but it does need to follow a particular structure if it supports multiple platforms. Running carthage archive is the easiest way to produce a valid archive, but we could mimic its output by following an example like Octokit.swift.

Intended usage

The developer would include just this one line in their Cartfile and run carthage update:

github "mapbox/mapbox-gl-native-ios" ~> 5.7

Carthage will use the GitHub API to fetch the binary artifact from the latest matching release. It will also clone this repository and check out the corresponding tag in order to read the Cartfile, even if this project doesn’t use Carthage internally.

We’d continue to update the JSON binary specification so that anyone following the current installation instructions would continue to get a working build. But we would replace the binary origin with the github origin in the SDK’s installation instructions.

Side effects and caveats

There are some consequences to this approach, but I don’t think they’re showstoppers:

  • There will no longer be any distinction between iOS and macOS tags. The next time I release the macOS map SDK, it’ll be part of the same release as the iOS map SDK with the same version.
  • We’ll need to update build and documentation tools to stop looking for the “ios-” prefix in tag names.
  • As far as I can tell, Carthage makes a full clone of the repository, not a shallow clone. Filtering the repository’s history and pruning old tags would mitigate the time, power, and space required for the clone: Delete old tags after repo migration. #109. It would be convenient to take care of deleting those tags at the same time we switch to semver-compliant tag names.
  • I’m unsure if Carthage also clones this repository’s submodules. Carthage has an optional --use-submodules workflow that maintains submodules in the application’s repository, and this workflow has known performance issues (Checkout spends a lot of time cloning submodules Carthage/Carthage#1833), but I’m unsure whether it also clones submodules just because the repository has submodules.
  • Carthage’s optional --no-use-binaries flag would avoid the prebuilt binary in favor of building from source, which is not supported: Support building from source via Carthage #133. I think it would be perfectly reasonable to enable the github origin – Carthage’s most common use case – with the caveat of not supporting it in combination with the relatively obscure --no-use-binaries option.

Alternative solutions

If it isn’t feasible to point Carthage to this repository for some reason, we could set up a repository specifically for Carthage installation, as proposed in mapbox/mapbox-gl-native#1623 (comment).

#133 proposes to make it possible to build this SDK from source. That would enable the use of a github origin and avoid dependency hell. However, building from source consumes considerable time, power, and disk space. It would also require Carthage to clone this repository’s submodules. For routine installations, we should still support downloading a prebuilt binary – while allowing Carthage to fully manage its dependencies – via the approach proposed above.

/cc @mapbox/maps-ios @mapbox/navigation-ios @mapbox/mobile-telemetry

@captainbarbosa
Copy link
Contributor

Thank you for writing up this very detailed summary @1ec5. I appreciate it.

There will no longer be any distinction between iOS and macOS tags. The next time I release the macOS map SDK, it’ll be part of the same release as the iOS map SDK with the same version.

Could you say more about this? How does a developer distinguish using one versus another then?

@1ec5
Copy link
Contributor Author

1ec5 commented Jan 14, 2020

If the archive is formatted the way carthage archive would normally format it, the iOS framework would be in Carthage/Build/iOS/ and the macOS framework would be in Carthage/Build/Mac/. For example, Octokit.swift provides prebuilt binaries for iOS, macOS, tvOS, and watchOS, all in the same archive.

Carthage will download the whole archive, including both frameworks, no matter which platform you’re developing for. (If you pass --platform iOS into carthage bootstrap, it won’t copy the macOS framework into your project’s Carthage/Build/Mac/ folder, though that doesn’t take much time anyways. The --platform tag is primarily for cross-platform dependencies built from source.) If you’re setting up your project for the first time, it’s up to you to manually add the framework to the application target, but you already have to look inside your Carthage/Build/iOS/ folder today.

In other words, the iOS and macOS map SDKs would be released together as a single SDK from the developer’s perspective. It means the macOS map SDK releases process would need to become more automated, including mapbox/mapbox-gl-native#14754. The fact that I haven’t taken care of this automation blocks future macOS releases but shouldn’t block iOS releases. That said, once I do manage to include a macOS framework in the archive for a given release, all releases after that point will need to include both platforms, because Carthage only bothers fetching the latest matching tag; it doesn’t crawl back through history to find a tag with a framework for the current platform.

@zugaldia
Copy link
Member

cc: @alfwatt @julianrex

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
dependencies Pull requests that update a dependency file p3
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants