dart-lang / native

Dart packages related to FFI and native assets bundling.
BSD 3-Clause "New" or "Revised" License
83 stars 27 forks source link

Missing iOS file when generating bindings for CMPedometer #492

Closed leighajarett closed 9 months ago

leighajarett commented 1 year ago

Hi! I'm trying to use generate bindings for the CMPedometer class that's part of the CoreMotion framework. But, I am just getting a blank bindings file.

Config:

name: PedometerBindings
description: "Bindings for CM pedometer"
language: objc
output: 'lib/pedometer_bindings_generated.dart'
compiler-opts:
  - '-F/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks'
objc-interfaces:
  include:
    - "CMPedometer"
headers:
  entry-points:
    - "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/CoreMotion.framework/Headers/CMPedometer.h"

There are a series of Nullability Issue warnings, such as:

[SEVERE] :     /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/stdlib.h:361:13: warning: pointer is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified) [Nullability Issue]

As well as a Lexical or Preprocessor Issue:

[SEVERE] :     /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSURL.h:10:9: fatal error: 'Foundation/NSURLHandle.h' file not found [Lexical or Preprocessor Issue]

Sorry in advance if I am missing something!!

liamappelbe commented 1 year ago

The nullability issue is a red herring. The second error is the real problem. One of the headers is trying to include Foundation/NSURLHandle.h and can't find it. This usually means that you're missing an include directory or a framework in your compiler-opts.

leighajarett commented 1 year ago

It seems like that file should be in the directory used for compiler-opts?

leighajarett commented 1 year ago

Actually I don't see that header file (NSURLHandle.h) in the Foundations framework, but in NSURL it says:

#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
#import <Foundation/NSURLHandle.h>
#endif

So I guess its not available on the MacOS I'm using?

brianquinlan commented 1 year ago

I think that you just need to add the entry point explicitly. Like:

headers:
  entry-points:
    - "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/CoreMotion.framework/Headers/CMPedometer.h"
    - "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSURLHandle.h"

Maybe replace your first entry point with the macOS version:

headers:
  entry-points:
    - "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/CoreMotion.framework/Headers/CMPedometer.h"
    - "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSURLHandle.h"
liamappelbe commented 1 year ago

Choosing a different entry point might work as a work-around. But I think the fundamental issue is that you're targeting iOS, but clang thinks you're targeting mac (that's why the TARGET_OS_OSX || TARGET_OS_MACCATALYST macro is true). I'll try and find the right compiler flag to get it to target iOS.

leighajarett commented 1 year ago

Thanks Brian and Liam. A few follow ups:

Liam that sounds right to me, because I would expect that you use the SDKs for the platform you'll be targeting in your dart code, right? (in this case iOS).

Additionally, I did try using the macOS SDKs, and while I no longer get that error (so long as I list the MacOSX frameworks in the compiler-opts), it still doesn't generate the bindings. I get the same nullability warnings and:

[SEVERE] :     /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/CoreMotion.framework/Headers/CMPedometer.h:189:115: warning: 'visibility' attribute ignored [Semantic Issue]

Also, I tried using the exclude for NSURLHandle and that didn't work, is that expected?

liamappelbe commented 1 year ago

Found the flag. To target iOS you need to add a minimum iOS version (mios-version-min) to your compile opts:

  compiler-opts:
    - '-F/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks'
    - '-mios-version-min=13.0'
liamappelbe commented 1 year ago

I get the same nullability warnings and:

That warning doesn't look important to me. We should probably add some log spam filters at some point. It's hard to sort through the noise.

Also, I tried using the exclude for NSURLHandle and that didn't work, is that expected?

Yeah, the exclusions are excluding the class, not the header. Ffigen doesn't even get to the stage where it can start applying those class exclusions, because failing to find the header file is a serious compile error.

leighajarett commented 1 year ago

Okay thanks. The error goes away with the minimum ios version flag, but still no bindings are generated.

# Run with `flutter pub run ffigen --config ffigen.yaml`.
name: PedometerBindings
description: "Bindings for CM pedometers"
language: objc
output: "lib/pedometer_bindings_generated.dart"
compiler-opts:
  - '-F/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks'
  - '-mios-version-min=13.0'
objc-interfaces:
  include:
    - "CMPedometer"
headers:
  entry-points:
    - "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/CoreMotion.framework/Headers/CMPedometer.h"

There is also this warning:

[SEVERE] :     warning: using sysroot for 'MacOSX' but targeting 'iPhone'
leighajarett commented 1 year ago

Okay after I upgraded ffigen in the pubspec it worked! Thanks!

liamappelbe commented 1 year ago

Ok, I'm glad it's working. But there's a legit bug here that I'll need to fix. There's a flag you can pass called -isysroot. You can set that to the iOS one. However, inside ffigen we also set that flag to the mac sysroot, and if you try to provide your own, I think ffigen's will override it. So I'll have to change it so we only set the sysroot if the user hasn't set it. Then you could add a compiler-opt to set the sysroot to the iOS one. I'm not really sure why it's started working for you.

leighajarett commented 1 year ago

Ahh okay good to know, do you just pass that into the ffigen command or does it go in the config file? Can you provide an example of where it goes and what the input for iOS is?

liamappelbe commented 1 year ago

It's another option in compiler-opts:

  compiler-opts:
    - '-F/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks'
    - '-mios-version-min=13.0'
    - '-isysroot'
    - '/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.2.sdk'

-isysroot is the option and the following line is its path, which should point to an iOS SDK. You can find that path with xcrun --sdk iphoneos --show-sdk-path

leighajarett commented 1 year ago

Great, thanks!

brianquinlan commented 1 year ago

Can this be closed?