Differentiate exclude source files list by platform

I've been trying to add SPM support to an existing Objective-C project that supports 2 platforms: macOS and iOS.

The platform support is achieved by providing some source files that should only be compiled on iOS (they are dependent on UIKit) and some source files that should only be compiled in macOS (they are dependent on AppKit).

In the Xcode project it's done by specifying two targets. In the Podfile it's done via two patterns sources: spec.ios.source_files and spec.osx.source_files.

Does anybody know of the way to express this in Package.swift?

There's an ability to exclude the files (or provide the list of the sources) in the target, but there's no place to express that is should differ based on the platform I'm compiling package for.

Things that I've tried so far are:

  • using #if os(...) in Package.swift (it always reports macOS, which makes sense since the Package.swift file is targeted for either macOS or Linux platforms)
  • using the unsafeFlags with .when(platforms: [.macOS]) (but I've not found a clang flag that would tell the compiler to skip compilation for a file of particular name or matching some pattern)
  • creating a separate target for the macOS and iOS (but then the package fails to compile on either platform because UIKit is unavailable on macOS and AppKit is unavailable on iOS)
  • creating two packages in Package.swift (only one was taken into consideration, the other one was ignored)

If anyone has ever been struggling with similar issue, please share :slight_smile:

1 Like

That cannot be done from the manifest.

At the moment this sort of thing is generally accomplished by gating the entire source of each file behind #if.

1 Like

Thanks for the confirmation on that.

I've tried to avoid any source code changes but if there's no other way, I've just hidden the whole content of platform-dependant .m files behind #if TARGET_OS_...

I'll try to check how easy it is to add support for the platform-based source exclusion to the manifest. It seems like a relatively small addition to manifest as we might leverage BuildSettingCondition.