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

Applying the -ObjC flag for all Objective-C Swift Package Manager targets is too aggressive and cannot be opted out of #6243

Closed
thedavidharris opened this issue Apr 30, 2024 · 1 comment · Fixed by #6244
Labels
type:bug Something isn't working

Comments

@thedavidharris
Copy link
Collaborator

thedavidharris commented Apr 30, 2024

What happened?

When #5929 was merged, this automatically added -ObjC to any consumer of an Objective-C Swift Package Manager package. While this is necessary for some targets that utilize Objective-C categories (https://developer.apple.com/library/archive/qa/qa1490/_index.html), it also includes side effects of not optimizing dead code stripping and occassionally not playing nice with other libraries such that compilation fails.

We ran into this issue when upgrading to Tuist 4: since the PR automatically adds the -ObjC flag with no way to configure this, our project now fails to build due to duplicate symbol errors because it trips up one of the side effects. In the past, to avoid even just the code size side effects, we would typically will rewrite libraries to use strategies such as google/promises#221 or Instagram/IGListKit#957 so we could avoid using the flag.

The most detailed discussions on those issues and other paths can be found in the CocoaPods and Bazel projects:

As noted in the issues, it is not possible to know whether an Objective-C library actually needs the -ObjC flag or not. Most prior art, such as CocoaPods, will only apply the flag to static library or static framework dependencies; any source-based dependency required OTHER_LDFLAGS to be set in the Podspec itself of the dependency.

Curiously, linking these dependencies via the Swift Package Manager itself tends not to require this; however, if you have an SPM library that is Objective-C and do need to add the -ObjC flag for another library or target that is integrated manually, you will run into duplicate symbol errors as noted at https://forums.swift.org/t/objc-flag-causes-duplicate-symbols-with-swift-packages/27926/18 and can be reproduced with the https://github.com/tuist/tuist/tree/main/fixtures/app_with_spm_dependencies fixture if GoogleSignIn is moved into an SPM native integration.

Suffice to say, there are a lot of issues and pitfalls with the flag and no general purpose solution.

A better workaround would be to let consumers apply the flag themselves, see #3294 (comment). This would also allow a project to choose whether it would like to apply the -ObjC flag or more targeted force-load flags. As noted in the Bazel item, the -ObjC behavior is planned to be removed and instead moved towards targeed force-load flags.

The ecosystem itself also seems to be moving away from making customers apply this flag: Firebase for example has removed the requirement in new versions: firebase/firebase-ios-sdk#10644 (comment).

At a minimum, we should make the -ObjC behavior opt-in or opt-out via flags so that projects can have some level of configuration. As it stands, there is no way to adjust this other than post-generation scripting to undo adding the flag, which is not something we wish to maintain.

How do we reproduce it?

  1. Generate https://github.com/tuist/tuist/tree/main/fixtures/app_with_spm_dependencies
  2. See that -ObjC is added
  3. See the above notes for the pitfalls of this flag

Error log

A number of side effects:

  • XXXX Duplicate Symbols found
  • Dead code not appropriately stripped
  • Errors if native SPM integration is used

macOS version

14.4.1

Tuist version

4.0

Xcode version

15.3.0

@thedavidharris thedavidharris added the type:bug Something isn't working label Apr 30, 2024
@thedavidharris
Copy link
Collaborator Author

I'm looking into this more, but it looks like #5929 applies this to every framework that links an Objective-C SPM dependency which is wrong. The PR should be reverted. Because this is applied to so many targets, we can't even efficiently hack a script around this to remove the flag.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type:bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant