Kext issue with Xcode 11

I realize that kexts have been deprecated with Catalina, and we are working towards replacing them, but after upgrading to Xcode 11, I am no longer able to build and load my kext at all. With the exact same code and project (only difference is building with Xcode 11), I get the following error when trying to load my built kext:


kxld[com.myorg.kext]: The super class vtable 'vtable for IOUserClient' for vtable 'vtable for com_myorg_kext_UserClient' is out of date. Make sure your kext has been built against the correct headers.
kxld[com.myorg.kext]: The super class vtable 'vtable for IOService' for vtable 'vtable for com_myorg_kext' is out of date. Make sure your kext has been built against the correct headers.

xld[com.myorg.kext]: The super class vtable 'vtable for IOService' for vtable 'vtable for com_myorg_kext' is out ofd

Is there some way to be able to build the kext in Xcode 11, or do I just keep Xcode 10.3 around for the express purpose of building kexts?

Accepted Reply

Thank you for the guidance - I actually was able to take this information and set up something that (I think) is a better solution all around.

Basically, I created an "External Build System" target in my Xcode 11 project that is set up to build my kext target (driver.kext) as follows:

  • Build Tool: /Applications/Xcode-9.4.1.app/Contents/Developer/usr/bin/xcodebuild
  • Arguments: -project "${PROJECT_FILE_PATH}" -target driver.kext -configuration ${CONFIGURATION} -quiet $(ACTION)


This allows me to have all my files in a single project, but build the kext using Xcode-9.4.1 (the latest to support 10.13).

Replies

Are you trying to load the KEXT on 10.14.6? Or 10.15 beta?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Trying to load the kext on 10.14.6.

I am currently building a kext that needs to load on 10.13-10.15. Previously, we were able to achieve this by adding:

-isysroot/Applications/Xcode-9.4.1.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk

to my cflags and and ldflags.


This worked when building with Xcode 10.3 - however, when upgrading to Xcode 11, it appears that the isysroot is not taking effect - instead, ONLY the one added by Xcode (pointing to MacOSX10.15.sdk) is taking effect. I think that’s where the error I’m getting is coming from. The error is shown whenever I try to load the kext on 10.14.6 (and possibly on 10.13…I haven’t tried that one yet).


I am able to work around this by creating a symlink from /Applications/Xcode-9.4.1.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk into /Applications/Xcode-11.0.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk and then building with the “MacOSX 10.13” SDK. That is an acceptable workaround for me, but I am wondering if there is a different approach I should take to build a legacy kernel driver that will load on 10.13-10.15 (realizing it is deprecated on 10.15…we are actually working on updating to use DriverKit for 10.15). However, we support the latest version of the OS minus 2 versions…meaning we’re going to need to support the kext on 10.14 for a couple years still. 😟


If there are any suggestions you could give me that would simplify our process, I would appreciate it.

Previously, we were able to achieve this by adding

-isysroot …

So, to be clear, you were doing this so you could use a modern Xcode with an old SDK? If so, that’s not something we support and, as with all unsupported stuff, you run the risk of encountering weird problems.

The only supported way to build a KEXT that loads on 10.13 is to use a version of Xcode that has the 10.13 SDK built in.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thank you for the guidance - I actually was able to take this information and set up something that (I think) is a better solution all around.

Basically, I created an "External Build System" target in my Xcode 11 project that is set up to build my kext target (driver.kext) as follows:

  • Build Tool: /Applications/Xcode-9.4.1.app/Contents/Developer/usr/bin/xcodebuild
  • Arguments: -project "${PROJECT_FILE_PATH}" -target driver.kext -configuration ${CONFIGURATION} -quiet $(ACTION)


This allows me to have all my files in a single project, but build the kext using Xcode-9.4.1 (the latest to support 10.13).

Basically, I created an "External Build System" target in my Xcode 11 project that is set up to build my kext target (driver.kext) as follows:

Ah, that’s quite cunning. Thanks for sharing.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Just to be clear: Does it really mean, that we can never create a KEXT anymore with XCode above 9.4.1?

(I did run in the same problem with an audio KEXT, "vtable out of date" for AudioEngine, AudioDevice and said UserClient Class ).

"The only supported way to build a KEXT that loads on 10.13 is to use a version of Xcode that has the 10.13 SDK built in."


This wording is quite confusing.


You can build a KEXT that loads on 10.13 using a version of Xcode that has the 10.9 SDK built in or a version of Xcode that has the 10.14 SDK built in for instance. This works fine for Network Kernel Extensions for instance.


You actually just need to have a non hacked version of the Xcode application (*).



* which can codesign Kernel Extensions correctly (notarization support is not taken into account here since it's 10.13).

With XCode 12 the issue is still there and the workaround with 9.4.1 prevents me from building a KEXT on Apple Silicon. Are there any news for a "true" solution?
Now I found the basic reason: I my source code for subclassing IOAudioEngine certain functions are declared as "virtual" but some of these functions did only exist in my subclass, so keyword "virtual" finally was wrong. After fixing this I can build the KEXT with XCode 11 and even XCode 12 and it is loaded in 10.15 and 10.16.

XCode 9.4.1. seems to behave different, so the wrong "virtual" it did not lead to problems in loading the KEXT.