#if Support for Module Presence


(Colin Cornaby) #1

I was augmenting code that used OpenGL with a new Metal backend, but having some issues. MetalKit.framework is present in the iOS SDK, but not the iOS Simulator SDK. Under Obj-C I’d use ifdef to check to see if I was compiling for the simulator, and exclude our Metal backend and associated functions with preprocessor functionality (and fallback to OpenGL). But under Swift I couldn’t get the #if functionality to honor the TARGET_OS_SIMULATOR macro. My best way around was checking for a combination of the iOS platform with an i386 or x86_64 processor types using Swift’s #if functionality. This feels pretty hacky. Having been through the Intel transition, assuming that if I’m on in iOS running on Intel that I must be in the Simulator is not an assumption I want to make. :slight_smile:

A direct way to fix this issue would be to add something to #if that would let me check for the presence of a module. For example, I’d like to see something like:
#if module(MetalKit)

Even with that functionality, I’d still have concerns about other sharp edges that are now exposed without a preprocessor. For example, AVFoundation is present in both the simulator and device SDKs, but AVFoundation is missing some API in simulator. In our existing iOS code, we also just check to see if we’re in a simulator target, and then just drop sections of code that require that API. Being able to check for the presence of a module doesn’t solve that problem. Another ask might be to have #if better support C macros. I can check something like TARGET_OS_SIMULATOR at runtime, but that doesn’t help me if I’m having issues at compile time because API or modules are missing in one SDK but not another. #if TARGET_OS_SIMULATOR is accepted by the Swift compiler, but the code within is never conditionally compiled no matter the current SDK.

Thanks!
Colin


(Greg Parker) #2

Swift's #if doesn't recognize C macros. `#if TARGET_OS_SIMULATOR` will never be true.

(Should #if warn if a condition identifier is not defined and there is a real identifier with the same name in scope? That would catch incorrect use of things like `#if TARGET_OS_SIMULATOR`.)

You should file a bug report requesting #if support for simulator platforms.

Workaround: You can define your own condition for Swift #if to recognize. You could configure your Xcode project to define some condition for iOS device builds and not define it for iOS simulator builds.

···

On Jan 26, 2016, at 8:35 PM, Colin Cornaby via swift-evolution <swift-evolution@swift.org> wrote:

I was augmenting code that used OpenGL with a new Metal backend, but having some issues. MetalKit.framework is present in the iOS SDK, but not the iOS Simulator SDK. Under Obj-C I’d use ifdef to check to see if I was compiling for the simulator, and exclude our Metal backend and associated functions with preprocessor functionality (and fallback to OpenGL). But under Swift I couldn’t get the #if functionality to honor the TARGET_OS_SIMULATOR macro. My best way around was checking for a combination of the iOS platform with an i386 or x86_64 processor types using Swift’s #if functionality. This feels pretty hacky. Having been through the Intel transition, assuming that if I’m on in iOS running on Intel that I must be in the Simulator is not an assumption I want to make. :slight_smile:

A direct way to fix this issue would be to add something to #if that would let me check for the presence of a module. For example, I’d like to see something like:
#if module(MetalKit)

Even with that functionality, I’d still have concerns about other sharp edges that are now exposed without a preprocessor. For example, AVFoundation is present in both the simulator and device SDKs, but AVFoundation is missing some API in simulator. In our existing iOS code, we also just check to see if we’re in a simulator target, and then just drop sections of code that require that API. Being able to check for the presence of a module doesn’t solve that problem. Another ask might be to have #if better support C macros. I can check something like TARGET_OS_SIMULATOR at runtime, but that doesn’t help me if I’m having issues at compile time because API or modules are missing in one SDK but not another. #if TARGET_OS_SIMULATOR is accepted by the Swift compiler, but the code within is never conditionally compiled no matter the current SDK.

--
Greg Parker gparker@apple.com Runtime Wrangler