Using Objective C class in Swift (open source, Linux)

As Joe suggested, I try to build swiftc and libSwiftCore on linux with some OpenSource ObjC runtime. Now, I have successfully built swiftc, but when building Swift.o, it generates a lot of homogenous errorsl for example:

home/itrub/swift-root/swift/stdlib/public/core/ObjCMirrors.swift:23:45: error: argument type '_swift_shims_CFStringRef' (aka 'UnsafeMutablePointer<objc_object>') does not conform to expected type '_CocoaStringType' (aka 'AnyObject')
  return _cocoaStringToSwiftString_NonASCII(theDescription)
                                            ^~~~~~~~~~~~~~
/home/itrub/swift-root/swift/stdlib/public/core/StringBridge.swift:27:54: error: cannot convert value of type '_CocoaStringType' (aka 'AnyObject') to expected argument type '_swift_shims_CFStringRef' (aka 'UnsafeMutablePointer<objc_object>')
  let result = _swift_stdlib_CFStringCreateCopy(nil, source)

There are also other errors, but all of them concern with mutual convertation of AnyObject and UnsafeMutablePointer<objc_object> or UnsafeMutablePointer<U>. Could somebody hint me direction of further researches? What swift compiler code and existence of which Objc-runtime functions I have to check firstly?

The errors suggest that it isn't recognizing CFStringRef as a CoreFoundation type, and is just importing it as a plain 'struct objc_object*' pointer type. The C importer is tuned toward Apple's headers so might need a lot of tweaking to properly handle a different CF implementation. The bridging code in the standard library is generally pretty intimately tied to the Apple implementation of NSString/NSArray/NSDictionary, so you might want to disable it altogether in order to make progress on the core interop.

-Joe

···

On Feb 12, 2016, at 3:13 AM, Труб Илья via swift-dev <swift-dev@swift.org> wrote:

As Joe suggested, I try to build swiftc and libSwiftCore on linux with some OpenSource ObjC runtime. Now, I have successfully built swiftc, but when building Swift.o, it generates a lot of homogenous errorsl for example:

home/itrub/swift-root/swift/stdlib/public/core/ObjCMirrors.swift:23:45: error: argument type '_swift_shims_CFStringRef' (aka 'UnsafeMutablePointer<objc_object>') does not conform to expected type '_CocoaStringType' (aka 'AnyObject')
return _cocoaStringToSwiftString_NonASCII(theDescription)
                                           ^~~~~~~~~~~~~~
/home/itrub/swift-root/swift/stdlib/public/core/StringBridge.swift:27:54: error: cannot convert value of type '_CocoaStringType' (aka 'AnyObject') to expected argument type '_swift_shims_CFStringRef' (aka 'UnsafeMutablePointer<objc_object>')
let result = _swift_stdlib_CFStringCreateCopy(nil, source)

There are also other errors, but all of them concern with mutual convertation of AnyObject and UnsafeMutablePointer<objc_object> or UnsafeMutablePointer<U>. Could somebody hint me direction of further researches? What swift compiler code and existence of which Objc-runtime functions I have to check firstly?

As Joe suggested, I try to build swiftc and libSwiftCore on linux with some OpenSource ObjC runtime. Now, I have successfully built swiftc, but when building Swift.o, it generates a lot of homogenous errorsl for example:

home/itrub/swift-root/swift/stdlib/public/core/ObjCMirrors.swift:23:45: error: argument type '_swift_shims_CFStringRef' (aka 'UnsafeMutablePointer<objc_object>') does not conform to expected type '_CocoaStringType' (aka 'AnyObject')
return _cocoaStringToSwiftString_NonASCII(theDescription)
                                          ^~~~~~~~~~~~~~
/home/itrub/swift-root/swift/stdlib/public/core/StringBridge.swift:27:54: error: cannot convert value of type '_CocoaStringType' (aka 'AnyObject') to expected argument type '_swift_shims_CFStringRef' (aka 'UnsafeMutablePointer<objc_object>')
let result = _swift_stdlib_CFStringCreateCopy(nil, source)

There are also other errors, but all of them concern with mutual convertation of AnyObject and UnsafeMutablePointer<objc_object> or UnsafeMutablePointer<U>. Could somebody hint me direction of further researches? What swift compiler code and existence of which Objc-runtime functions I have to check firstly?

The errors suggest that it isn't recognizing CFStringRef as a CoreFoundation type, and is just importing it as a plain 'struct objc_object*' pointer type. The C importer is tuned toward Apple's headers so might need a lot of tweaking to properly handle a different CF implementation. The bridging code in the standard library is generally pretty intimately tied to the Apple implementation of NSString/NSArray/NSDictionary, so you might want to disable it altogether in order to make progress on the core interop.

-Joe

The bigger issue would be that IRGen only emits Objective-C metadata in a format compatible with Apple's runtime, right? Even if you got the headers to import and your code to link, we would need to change code generation to support the GNU runtime.

Slava

···

On Feb 12, 2016, at 10:11 AM, Joe Groff via swift-dev <swift-dev@swift.org> wrote:

On Feb 12, 2016, at 3:13 AM, Труб Илья via swift-dev <swift-dev@swift.org> wrote:

_______________________________________________
swift-dev mailing list
swift-dev@swift.org <mailto:swift-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-dev

Definitely, I think you'd want to get the runtime ABI squared away before trying to get the standard library bridging code ported over. It might be a good idea to hack up the stdlib so that its ObjC interop support can be disabled independent of the compiler and runtime.

-Joe

···

On Feb 12, 2016, at 1:02 PM, Slava Pestov <spestov@apple.com> wrote:

On Feb 12, 2016, at 10:11 AM, Joe Groff via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:

On Feb 12, 2016, at 3:13 AM, Труб Илья via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:

As Joe suggested, I try to build swiftc and libSwiftCore on linux with some OpenSource ObjC runtime. Now, I have successfully built swiftc, but when building Swift.o, it generates a lot of homogenous errorsl for example:

home/itrub/swift-root/swift/stdlib/public/core/ObjCMirrors.swift:23:45: error: argument type '_swift_shims_CFStringRef' (aka 'UnsafeMutablePointer<objc_object>') does not conform to expected type '_CocoaStringType' (aka 'AnyObject')
return _cocoaStringToSwiftString_NonASCII(theDescription)
                                          ^~~~~~~~~~~~~~
/home/itrub/swift-root/swift/stdlib/public/core/StringBridge.swift:27:54: error: cannot convert value of type '_CocoaStringType' (aka 'AnyObject') to expected argument type '_swift_shims_CFStringRef' (aka 'UnsafeMutablePointer<objc_object>')
let result = _swift_stdlib_CFStringCreateCopy(nil, source)

There are also other errors, but all of them concern with mutual convertation of AnyObject and UnsafeMutablePointer<objc_object> or UnsafeMutablePointer<U>. Could somebody hint me direction of further researches? What swift compiler code and existence of which Objc-runtime functions I have to check firstly?

The errors suggest that it isn't recognizing CFStringRef as a CoreFoundation type, and is just importing it as a plain 'struct objc_object*' pointer type. The C importer is tuned toward Apple's headers so might need a lot of tweaking to properly handle a different CF implementation. The bridging code in the standard library is generally pretty intimately tied to the Apple implementation of NSString/NSArray/NSDictionary, so you might want to disable it altogether in order to make progress on the core interop.

-Joe

The bigger issue would be that IRGen only emits Objective-C metadata in a format compatible with Apple's runtime, right? Even if you got the headers to import and your code to link, we would need to change code generation to support the GNU runtime.

I want to make sure it's clear that this is (a) a big project, more than just turning on a bunch of flags, and (b) not likely to be something we'd accept into upstream. Improving the notion of "foreign classes", maybe; specifically supporting an ObjC runtime natively on Linux, probably not.

Jordan

···

On Feb 12, 2016, at 13:05, Joe Groff via swift-dev <swift-dev@swift.org> wrote:

On Feb 12, 2016, at 1:02 PM, Slava Pestov <spestov@apple.com <mailto:spestov@apple.com>> wrote:

On Feb 12, 2016, at 10:11 AM, Joe Groff via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:

On Feb 12, 2016, at 3:13 AM, Труб Илья via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:

As Joe suggested, I try to build swiftc and libSwiftCore on linux with some OpenSource ObjC runtime. Now, I have successfully built swiftc, but when building Swift.o, it generates a lot of homogenous errorsl for example:

home/itrub/swift-root/swift/stdlib/public/core/ObjCMirrors.swift:23:45: error: argument type '_swift_shims_CFStringRef' (aka 'UnsafeMutablePointer<objc_object>') does not conform to expected type '_CocoaStringType' (aka 'AnyObject')
return _cocoaStringToSwiftString_NonASCII(theDescription)
                                          ^~~~~~~~~~~~~~
/home/itrub/swift-root/swift/stdlib/public/core/StringBridge.swift:27:54: error: cannot convert value of type '_CocoaStringType' (aka 'AnyObject') to expected argument type '_swift_shims_CFStringRef' (aka 'UnsafeMutablePointer<objc_object>')
let result = _swift_stdlib_CFStringCreateCopy(nil, source)

There are also other errors, but all of them concern with mutual convertation of AnyObject and UnsafeMutablePointer<objc_object> or UnsafeMutablePointer<U>. Could somebody hint me direction of further researches? What swift compiler code and existence of which Objc-runtime functions I have to check firstly?

The errors suggest that it isn't recognizing CFStringRef as a CoreFoundation type, and is just importing it as a plain 'struct objc_object*' pointer type. The C importer is tuned toward Apple's headers so might need a lot of tweaking to properly handle a different CF implementation. The bridging code in the standard library is generally pretty intimately tied to the Apple implementation of NSString/NSArray/NSDictionary, so you might want to disable it altogether in order to make progress on the core interop.

-Joe

The bigger issue would be that IRGen only emits Objective-C metadata in a format compatible with Apple's runtime, right? Even if you got the headers to import and your code to link, we would need to change code generation to support the GNU runtime.

Definitely, I think you'd want to get the runtime ABI squared away before trying to get the standard library bridging code ported over. It might be a good idea to hack up the stdlib so that its ObjC interop support can be disabled independent of the compiler and runtime.

I want to make sure it's clear that this is (a) a big project, more than just turning on a bunch of flags, and (b) not likely to be something we'd accept into upstream. Improving the notion of "foreign classes", maybe; specifically supporting an ObjC runtime natively on Linux, probably not.

Depending on what the end-goal is it might be easier to port the Apple runtime to Linux. I had a crack at this a few years ago, I gave up because of the lack of shared library load notifications but doing something that doesn’t support dynamic loading shouldn’t be too hard. The Apportable port might be a good starting point.

— Luke