Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proper Carthage project: ObjCThemis #604

Merged
merged 2 commits into from
Mar 20, 2020

Conversation

ilammy
Copy link
Collaborator

@ilammy ilammy commented Mar 14, 2020

Our first attempt at providing Carthage support (#427) was a bit haphazard and resulted in an Xcode project that builds ObjCThemis into a framework called themis.framework. This has been done in order to preserve the module name for Swift the same as with CocoaPods. However, this also means that Objective-C has to import this framework as

#import <themis/themis.h>

while CocoaPods use

#import <objcthemis/objcthemis.h>

This discrepancy is not ideal. First of all, this wart special case complicates integration of Themis into projects. We have it described in documentation, but that's an excuse, not a solution. Then, this import conflicts with Themis Core (which also uses <themis/themis.h>). Finally, we are also affected by this discrepancy because ObjCThemis test suite uses <objcthemis/objcthemis.h>, making it impossible to run existing unit tests on Carthage project. (Well, without silly preprocessor tricks, that is.)

Provide an alternate Xcode project which builds ObjCThemis into objcthemis.framework and keeps Swift module name themis. This is how it should have been done from the start. Now, ObjCThemis installed via Carthage can be imported in Objective-C projects as

#import <objcthemis/objcthemis.h>

That is the same import when ObjCThemis is installed via CocoaPods.

Older Objective-C import syntax is still accepted for now but it is considered deprecated and will be removed.

Swift import syntax stays unchanged (for both Carthage and CocoaPods):

import themis

However, aside from imports the users will also need to update their projects to link against objcthemis.framework instead of themis.framework.

Note that this is a separate Xcode project, not an additional pair of targets in existing Themis.xcodeproj. We have to make a new project because of this very issue with conflicting names. It is impossible to add another target that builds ObjCThemis because it uses

#import <themis/themis.h>

to import Themis Core. This works when building themis.framework itself, but for any other target in the project this syntax will import themis.framework, not Themis Core. Sibling projects are included in the search path automatically so there is no way to prevent this conflict other than making a completely separate Xcode project.

Multiple projects are supported by Carthage. It will just build them all. This means that the users will be building ObjCThemis twice if they are using the simple

carthage bootstrap

Unfortunate, but that's how it will be until the next release when we will be able to drop themis.framework (the only alternative is to break compatibility immediately).

Please accept my sincere apologies for increased CI bills. This was my mistake from the start.

Checklist

  • Change is covered by automated tests 1
  • The coding guidelines are followed
  • Public API has proper documentation
  • Example projects and code samples are up-to-date 2
  • Changelog is updated

1 Bitrise probably will not automatically test this, but I remember something about Carthage there. When If this gets merged, I'll look at it in detail (and update GitHub Actions too).

2 No, the code samples are not updated in this PR. Since we pin them to a particular released version of Themis, they will have to be updated after we make a release which this changes. GitHub Actions will test that the examples compile unchanged with updated Themis. We could also add a specific test for this, but that's too much of a bother. I really don't want four more projects there.

Our first attempt at providing Carthage support was a bit haphazard and
resulted in an Xcode project that builds ObjCThemis into a framework
called "themis.framework". This has been done in order to preserve the
module name for Swift the same as with CocoaPods. However, this also
means that Objective-C has to import this framework as

    #import <themis/themis.h>

while CocoaPods use

    #import <objcthemis/objcthemis.h>

This discrepancy is not ideal. First of all, this wart^W special case
complicates integration of Themis into projects. We have it described
in documentation, but that's an excuse, not a solution. Then, this
import conflicts with Themis Core (which also uses <themis/themis.h>).
Finally, *we* are also affected by this discrepancy because ObjCThemis
test suite uses <objcthemis/objcthemis.h>, making it impossible to run
existing unit tests on Carthage project.

Provide an alternate Xcode project which builds ObjCThemis into
"objcthemis.framework" and keeps Swift module name "themis". This is
how it should have been done from the start. Now, ObjCThemis installed
via Carthage can be imported in Objective-C projects as

    #import <objcthemis/objcthemis.h>

That is the same import when ObjCThemis is installed via CocoaPods.

Older Objective-C import syntax is still accepted for now but it is
considered deprecated and will be removed.

Swift import syntax stays unchanged:

    import themis

However, aside from imports the users will also need to update their
projects to link against "objcthemis.framework" instead of
"themis.framework".

Note that this is a separate Xcode project, not an additional pair of
targets in existing Themis.xcodeproj. We have to make a new project
because of this very issue with conflicting names. It is impossible
to add another target that builds ObjCThemis because it uses

    #import <themis/themis.h>

to import Themis Core. This works when building "themis.framework"
itself, but for any other target in the project this syntax will import
"themis.framework", not Themis Core. Sibling projects are included in
the search path automatically so there is no way to prevent this
conflict other than making a completely separate Xcode project.

Multiple projects are supported by Carthage. It will just build them
all. This means that the users will be building ObjCThemis twice if they
are using the simple

    carthage bootstrap

Unfortunate, but that's how it will be until the next release when we
will be able to drop "themis.framework" (the only alternative is to
break compatibility immediately).

Please accept my sincere apologies for increased CI bills. This was my
mistake from the start.
@ilammy ilammy added W-SwiftThemis 🔶 Wrapper: SwiftThemis, Swift API compatibility Backward and forward compatibility, platform interoperability issues, breaking changes installation Installation of Themis core and wrapper packages W-ObjCThemis 🎨 Wrapper: ObjCThemis, Objective-C API M-Carthage Package manager: Carthage, Objective-C and Swift, iOS and macOS labels Mar 14, 2020
@vixentael
Copy link
Contributor

Honestly saying, I hate renaming things.

So, TLDR, not depending on package mananger:

  • for ObjC, people will link #import <objcthemis/objcthemis.h>
  • for Swift, people will link import themis

right?

————-

Also, can we please make sure that we have internal tasks for:

  • updating ObjC Themis guide on docserver
  • updating Swift Themis guide on docserver
  • updating Themis examples

after/before/during 0.13 release?

CHANGELOG.md Show resolved Hide resolved
Co-Authored-By: vixentael <[email protected]>
@ilammy
Copy link
Collaborator Author

ilammy commented Mar 19, 2020 via email

@vixentael
Copy link
Contributor

Merge 'em all!

@ilammy ilammy merged commit 9329a65 into cossacklabs:master Mar 20, 2020
@ilammy ilammy deleted the carthage-objcthemis branch March 20, 2020 13:06
@ilammy
Copy link
Collaborator Author

ilammy commented Mar 20, 2020

I've checked this manually just in case: Bitrise does build the new Xcode project.

So we're safe 🤞

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compatibility Backward and forward compatibility, platform interoperability issues, breaking changes installation Installation of Themis core and wrapper packages M-Carthage Package manager: Carthage, Objective-C and Swift, iOS and macOS W-ObjCThemis 🎨 Wrapper: ObjCThemis, Objective-C API W-SwiftThemis 🔶 Wrapper: SwiftThemis, Swift API
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants