Skip to content

Commit

Permalink
Do not automatically add -ObjC flag when integrating Objective-C depe…
Browse files Browse the repository at this point in the history
…ndencies (#6244)

* Revert "Fix runtime error when using objc dependencies (#5929)"

This reverts commit 9297022.

* Update app_with_spm_dependencies fixture to rely on -ObjC flag and document
  • Loading branch information
thedavidharris committed May 14, 2024
1 parent 7e474a2 commit 9f0b55b
Show file tree
Hide file tree
Showing 6 changed files with 16 additions and 38 deletions.
33 changes: 0 additions & 33 deletions Sources/TuistGenerator/Mappers/ModuleMapMapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import TuistSupport
public final class ModuleMapMapper: GraphMapping { // swiftlint:disable:this type_body_length
private static let modulemapFileSetting = "MODULEMAP_FILE"
private static let otherCFlagsSetting = "OTHER_CFLAGS"
private static let otherLinkerFlagsSetting = "OTHER_LDFLAGS"
private static let otherSwiftFlagsSetting = "OTHER_SWIFT_FLAGS"
private static let headerSearchPaths = "HEADER_SEARCH_PATHS"

Expand Down Expand Up @@ -82,14 +81,6 @@ public final class ModuleMapMapper: GraphMapping { // swiftlint:disable:this typ
mappedSettingsDictionary[Self.headerSearchPaths] = updatedHeaderSearchPaths
}

if let updatedOtherLinkerFlags = Self.updatedOtherLinkerFlags(
targetID: targetID,
oldOtherLinkerFlags: mappedSettingsDictionary[Self.otherLinkerFlagsSetting],
targetToDependenciesMetadata: targetToDependenciesMetadata
) {
mappedSettingsDictionary[Self.otherLinkerFlagsSetting] = updatedOtherLinkerFlags
}

let targetSettings = target.settings ?? Settings(
base: [:],
configurations: [:],
Expand Down Expand Up @@ -277,28 +268,4 @@ public final class ModuleMapMapper: GraphMapping { // swiftlint:disable:this typ

return .array(mappedOtherCFlags)
}

private static func updatedOtherLinkerFlags(
targetID: TargetID,
oldOtherLinkerFlags: SettingsDictionary.Value?,
targetToDependenciesMetadata: [TargetID: Set<DependencyMetadata>]
) -> SettingsDictionary.Value? {
guard let dependenciesModuleMaps = targetToDependenciesMetadata[targetID]?.compactMap(\.moduleMapPath),
!dependenciesModuleMaps.isEmpty
else { return nil }

var mappedOtherLinkerFlags: [String]
switch oldOtherLinkerFlags ?? .array(["$(inherited)"]) {
case let .array(values):
mappedOtherLinkerFlags = values
case let .string(value):
mappedOtherLinkerFlags = value.split(separator: " ").map(String.init)
}

if !mappedOtherLinkerFlags.contains("-ObjC") {
mappedOtherLinkerFlags.append("-ObjC")
}

return .array(mappedOtherLinkerFlags)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@ final class ModuleMapMapperTests: TuistUnitTestCase {
"-fmodule-map-file=$(SRCROOT)/../B/B2/B2.module",
]),
"HEADER_SEARCH_PATHS": .array(["$(inherited)", "$(SRCROOT)/../B/B1/include", "$(SRCROOT)/../B/B2/include"]),
"OTHER_LDFLAGS": .array(["$(inherited)", "-ObjC"]),
]),
dependencies: [
.project(target: "B1", path: projectBPath),
Expand All @@ -134,7 +133,6 @@ final class ModuleMapMapperTests: TuistUnitTestCase {
"OTHER_CFLAGS": .array(["$(inherited)", "-fmodule-map-file=$(SRCROOT)/B2/B2.module"]),
"OTHER_SWIFT_FLAGS": .array(["$(inherited)", "-Xcc", "-fmodule-map-file=$(SRCROOT)/B2/B2.module"]),
"HEADER_SEARCH_PATHS": .array(["$(SRCROOT)/B1/include", "$(SRCROOT)/B2/include"]),
"OTHER_LDFLAGS": .array(["$(inherited)", "-ObjC"]),
]),
dependencies: [
.target(name: "B2"),
Expand Down Expand Up @@ -262,7 +260,6 @@ final class ModuleMapMapperTests: TuistUnitTestCase {
"-fmodule-map-file=$(SRCROOT)/../B/B/B.module",
]),
"HEADER_SEARCH_PATHS": .array(["$(inherited)", "$(SRCROOT)/../B/B/include"]),
"OTHER_LDFLAGS": .array(["$(inherited)", "-ObjC"]),
],
configurations: [:],
defaultSettings: .recommended
Expand Down
8 changes: 8 additions & 0 deletions docs/docs/guide/project/dependencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,3 +194,11 @@ pod install

> [!WARNING]
> CocoaPods dependencies are not compatible with workflows like `build` or `test` that run `xcodebuild` right after generating the project. They are also incompatible with binary caching and selective testing since the fingerprinting logic doesn't account for the Pods dependencies.
## Objective-C Dependencies

When integrating Objective-C dependencies, the inclusion of certain flags on the consuming target may be necessary to avoid runtime crashes as detailed in [Apple Technical Q&A QA1490](https://developer.apple.com/library/archive/qa/qa1490/_index.html).

Since the build system and Tuist have no way of inferring whether the flag is necessary or not, and since the flag comes with potentially undesirable side effects, Tuist will not automatically apply any of these flags, and because Swift Package Manager considers `-ObjC` to be included via an `.unsafeFlag` most packages cannot include it as part of their default linking settings when required.

Consumers of Objective-C dependencies (or internal Objective-C targets) should apply `-ObjC` or `-force_load` flags when required by setting `OTHER_LDFLAGS` on consuming targets.
4 changes: 2 additions & 2 deletions fixtures/app_with_spm_dependencies/App/Project.swift
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ let project = Project(
with: [
"WKCompanionAppBundleIdentifier": "io.tuist.app",
]
),
sources: ["Sources/Watch/App/**"],
), sources: ["Sources/Watch/App/**"],

dependencies: [
.target(name: "WatchExtension"),
]
Expand Down
5 changes: 5 additions & 0 deletions fixtures/app_with_spm_dependencies/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Application with Swift Package Manager Dependencies

This example contains an example that uses Swift Package Manager dependencies.

It also contains a static Objective-C dependency that relies on the `-ObjC` linker flag to be added to the consuming application.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ extension ProjectDescription.Settings {
.settings(
base: [
"SOME_BASE_FLAG": .string("VALUE"),
"OTHER_LDFLAGS": .string("-ObjC"),
].otherSwiftFlags("-enable-actor-data-race-checks"),
configurations: BuildEnvironment.allCases.map(\.targetConfiguration)
)
Expand Down

0 comments on commit 9f0b55b

Please sign in to comment.