I used to have a static library, I turned it into a dynamic library, which was more difficult than I expected.
I already had a small project, containing a command line tool which loads a dynamic library. This was created direct from Xcode 15.3's macOS app and dynamic library templates.
This is how I configured the Dynamic Library Install Name Base to @rpath. Note that there is nothing in the Dynamic Library Install Name target setting, but it resolves to @rpath/libCLI_library.dylib.
If I click on it once, I can see the value
I click on it again to see how this value is generated
The expression it is generated from is $(LD_DYLIB_INSTALL_NAME_$(LLVM_TARGET_TRIPLE_VENDOR):default=$(EXECUTABLE_PATH))
Using a Run Script phase I can see the environment variables, which include
LLVM_TARGET_TRIPLE_VENDOR = “apple”, and LD_DYLIB_INSTALL_NAME_apple = “@rpath/libCLI_.dylib”
If I look at the environment variables in my other dylib project, which started life as a static library, although LLVM_TARGET_TRIPLE_VENDOR is set to "apple", there is no LD_DYLIB_INSTALL_NAME_apple variable at all, so even if I paste the expression above into the LD_DYLIB_INSTALL_NAME setting, it does me no good, because it evaluates to EXECUTABLE_PATH, which is libXXX.dylib, but I'd like @rpath/libXXX.dylib.
So my question are,
where does LD_DYLIB_INSTALL_NAME_apple come from?
where does the magic invisible expression for Dynamic Library Install Name come from?
the quick help for Dynamic Library Install Name mentions "if this option is not specified, the -o path will be used" - what build setting is that?
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I have a USBDriverKit driver which tries to send vendor-specific DeviceRequests to the IOUSBHostDevice. A few short months ago this worked, and as far as I know, the only change since it last worked is an update to macOS 14.5.
The dext user client calls through to the driver, which wants to do this:
ivars->mDevice->Open()
ivars->mDevice->DeviceRequest()
ivars->mDevice->Close()
the problem is that the call to Open returns 0xe00002cde, which is kIOReturnNotOpen. If I don't call Open, but simply call DeviceRequest, I get the same result, kIOReturnNotOpen, which I would expect.
I'm pretty sure that in macOS 14.4, the call to Open() did not return an error. I haven't seen any system logs that clue me in to why Open() is failing. It would be handy if the error gave me some reason why the device cannot be opened.
Has anyone else seen this? I've searched high and low and I can't find any examples of dexts which actually do anything at all with a USB device.
We have an iPad app which can write to user-specified locations on USB-connected storage devices.
On unmanaged devices, this works just fine.
However, when the device is under MDM, although the Files app can see the external USB storage device, it does not show up in the file browser in our own app.
There's a restriction called "allowFilesUSBDriveAccess" which is set to true (the default), but there's no restriction called "allowOtherAppsUSBDriveAccess".
Are MDM-managed iPads simply not allowed to access USB drives (except through the Files app)?
Topic:
App & System Services
SubTopic:
Core OS
Tags:
Entitlements
Managed Settings
Device Management
The presentation "create audio drivers with DriverKit" from WWDC 2021 demonstrates how to use a dext to implement a virtual audio driver. It also says " If a virtual audio driver or device is all that is needed, the audio server plug-in driver model should continue to be used".
Indeed, in AudioDriverKit/AudioDriverKitTypes.h, there is no IOUserAudioTransportType Virtual, although CoreAudio/AudioHardwareBase.h includes kAudioDeviceTransportTypeVirtual.
For one of our products, we require virtual devices to implement a software loopback "cable". We've implemented this using the "traditional" HAL plugin, and as a proof-of-concept, also using a dext. In the dext, I tried setting the transport type to 'virt', which seems to only have the effect of changing the icon shown in Audio Midi Setup.
HAL plugins require an installer, and the installer has to kill coreaudiod in a post-install script. You have to turn off SIP to debug them. Just like AudioDriverKit drivers, they are out-of-process and run in a process not owned by the hosting app. Our HAL plugin's interface is property based; we had to write a lot of boiler-plate code to implement required properties. Writing an AudioDriverKit driver is in most respects easier - a lot of the scaffolding is implemented in the base driver, which we only alter where required. Debugging and installation is much easier.
The dext works just fine, as far as we can ascertain, just as well as a HAL plugin.
So, my question is - is the advice to use a HAL plugin for a virtual device still correct in 2025? And if so, what's the objection? We'd really prefer to ship the AudioDriverKit virtual audio device.
I'm posting this here after reading Quinn's post here: https://developer.apple.com/forums/thread/799000
The above entitlement is mentioned in IOUSBHostControllerInterface.h.
It isn't an entitlement one can add using the + button on the Capabilities panel in Xcode. If I try to add it by hand, Xcode complains that it isn't in my profile.
Is this a managed entitlement?
We'd like to create a local USB "device" to represent a real device reachable over a network.
For some time I've been sharing an internal macOS app with my colleagues by simply building it locally, zipping it up and emailing, or sharing on Slack or Teams.
In the Target Settings in Xcode, Signing and Capabilities, the Team is set to my company, the Signing Certificate is set to Development (not "Sign to run locally").
This has worked for some time. None of the recipients complained that they couldn't run the app. Of course it is not notarized so they need to right-click and select Open the first time around.
When I examine the signature of the app I distribute this way, using `codesign -dvvv, the signing authority is me (not my company).
One of my colleagues recently migrated to a new Mac Mini M1. On this Mac, when attempting to open the app, he saw the "you do not have permission to open the application" alert. He's supposed to consult his sys admin (himself).
I fixed the problem by Archiving a build and explicitly choosing to sign it using the company's Developer ID certificate. The version produced this way has a signing authority of my company, not me, and my colleague can run it.
Does anyone know why my previous builds work on other machines for other users? It appears that the locally-built app was actually signed by my personal certificate, although Xcode's UI said it would be signed by my company - but it didn't only work for me?
What is the expected behavior if you try to open an app signed with a personal certificate on a machine owned by a different person? Should Security & Privacy offer the option of approving that particular personal certificate?
In my keychain, I have one Developer ID Application certificate, with a private key, for my Team.
In Xcode's Accounts/Manage Certificates dialog, there are three Developer ID Application certificates, two of which have a red 'x' badge and the status 'missing private key'.
I can right click on any of those three entries and my only enabled choice is "Export". Email creator or Delete are disabled. Why?
In my Team's account, there are indeed three Developer ID Application certificates, with different expiration dates, but I only have the private key for one of them.
By choosing Manual signing, I can choose a specific certificate from my keychain, but Xcode 13.2.1 tells me that this certificate is missing its private key - but I can see that private key in my keychain!
I'm trying to implement an app Shortcut (Custom Intent) for a macOS app on Monterey. Shortcuts.app finds the shortcut, but when I run it, the progress bar goes to 50% and stops. My handler and resolution code is not called. I'm implementing the handling in-app (not in an extension)
I'm following instructions from the WWDC 2021 video "Meet Shortcuts for macOS" and this link https://developer.apple.com/documentation/sirikit/adding_user_interactivity_with_siri_shortcuts_and_the_shortcuts_app?language=objc
If I filter on "shortcuts" in the Console app, and press the run button in Shortcuts.app for my Shortcut,
I see this message (amongst others)
-[WFAction processParameterStates:withInput:skippingHiddenParameters:askForValuesIfNecessary:workQueue:completionHandler:]_block_invoke Action <WFHandleCustomIntentAction: 0x15c1305b0, identifier: finished processing parameter states. Values:
which looks sort of promising
but I also see this
Sandbox: Shortcuts(9856) deny(1) file-read-data /Users/stu/Library/Developer/Xcode/DerivedData/-hghdaydxzeamopexvfsgfeuvsejw/Build/Products/Debug/.app
I've tried moving my app to /Applications and launching it from there, I see a similar message in the log, but the path leads to the app in /Applications.
I've tried deleting all copies of my app aside from the one I'm currently building and debugging. I've tried deleting the derived data folder, restarting the Mac, re-launching the Shortcuts app. I've tried sandboxing my app. Other Shortcuts (for other apps) work on this machine.
I'm probably missing something extremely simple - does anyone have a suggestion?
Some related questions:
At WWDC 2022, Apple introduced "App Intents", without adequately explaining how these differ from the intents described in the WWDC 2021 video. Can anyone tell me what the difference is?
In the Xcode editor for the .intentdefinition file, there's a button "Convert to App Intent". Clicking it produces some new Swift files in my app, but the thing is an intent handled by an app, and now it is an App Intent - what's the difference? Is one better than the other? Do I have to click the convert button again if I subsequently modify the .intentdefinition file, or is this conversion process intended to replace the .intentdefinition file with those .swift files?
The "deployment target" for a DEXT is a number like 19.0 or 21.4. Xcode seems to pick the latest version on the machine you are creating the target on as a default - so if I make a new Driver target on Xcode 14 and Ventura, the Deployment Target for the driver will be 21.4. If I'm targeting macOS 12 (for example), what version of DriverKit should I choose, and where is this documented?
when I'm not yet logged in to the forums, some text blocks look like this:
once I'm logged in, the same text block looks like this:
This is on Ventura 13.2.1 with Safari Version 16.3 (18614.4.6.1.6)
Does anyone else experience this or is just me?
I'm struggling to build a driver for iPadOS in a particular project configuration.
If I put the driver code and dext target into the same Xcode project which contains the iPad app, all is well. This is the way the Xcode driver template does it.
However, I'd like to build and debug the dext on macOS, while eventually deploying on iPadOS. So I put the dext into a different project, which has a macOS target, a minimal iPadOS target and a DriverKit target.
I made a workspace which contains both projects. I dragged the macOS project into the iPadOS project so that I can refer to the products of the macOS project (specifically, its driver target) as a dependency of the iPadOS target.
Note that the main iPad app target depends on the driver target.
So the workspace organization looks like this:
Workspace
iPad project
main iPad app target (depends on driver)
test project reference
test project
test macOS/iPad app target
DriverKit dext target
When I build the iPadOS target, it builds the dependent driver target in the macOS project, but it fails to link because Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/15.0.0/lib/darwin/libclang_rt.profile_driverkit.a is not found.
If I just build the driver target directly in Xcode, there is no such complaint.
I looked closely at the build logs, and I see for the failed link, there are these two linker flags set which are not set in the successful case
-debug_variant
-fprofile-instr-generate
I can't seem to control the generation of this flag. I tried turning off the Profile switch in the Scheme editor for the driver, but is makes no difference. When I directly build the driver target, no -fprofile-instr-generate is set and it compiles and links. When i build the driver as a dependency of another target, -fprofile-instr-generate is passed to the linker, which fails.
The obvious workaround is to put the driver source code into a separate driver target in the iPadOS project, but I'd rather have just one DriverKit driver for both platforms, with a few settings (such as bundle ID) controlled by a configuration file. Has anyone else encountered this problem, and know of a workaround?
I have a dext target in a project which fails to install on my iPad because "the code signature version is no longer supported". Indeed, when I look at the built dext (before or after is has been copied into the hosting app's System Extensions folder), codesign -dv tells me that it has CodeDirectory = 20200. The hosting app has CodeDirectory = 20400.
Curiously, in the same workspace, I have another iOS app which hosts another version of the driver (using the same source code files). The other app is a minimal test app. It is signed with CodeDirectory = 20500 and the driver has CodeDirectory = 20400 inside this minimal app.
In both the more complex target and the simple target, the codesign invocation has the same options. Only the provisioning profile and the name of the dext differs between the working and non-working version. Here are the options, on multiple lines to make them easier to read
/usr/bin/codesign
--force
--sign D0...A0F (same for both)
-o runtime
--entitlements <path to driver>.dext.xcent
--timestamp\=none
--generate-entitlement-der
<path to driver.dext>
I've searched high and low for a solution to this problem, but found none. It has come up before, in particular here https://developer.apple.com/forums/thread/683214?answerId=679712022#679712022
I'm using Xcode 15 on macOS Sonoma 14.0. I've thrown away the Derived Data for the project, I've thrown away the ModuleCache.index and the SymbolCache.index I've restarted my Mac. I've restarted the iPad.
There's no legacy code here. This is all new, newly built and signed by a new version of Xcode. But I don't seem to have any control over what version of signature Xcode chooses to use - what influences that? Obviously there's some difference, perhaps in the hosting app or target, between the environment where everything works and where nothing works.
If it helps, the more complex app was already built, signed and deployed to the App Store without a driver. The driver is under development, and it is a new addition to the target, so the existing Identifier, Certificate and Profile for the app pre-date the addition of the embedded driver target.
Any ideas. Anyone?
Can anyone advise, or give example of, communicating large (>128 byte) incoming buffers from a dext to a user-space app?
My specific situation is interrupt reads from a USB device. These return reports which are too large to fit into the asyncData field of an AsyncCompletion call. Apple's CommunicatingBetweenADriverKitExtensionAndAClientApp sample shows examples of returning a "large" struct, but the example is synchronous.
The asynchronous example returns data by copying into a IOUserClientAsyncArgumentsArray, which isn't very big.
I can allocate a single buffer larger than 4K in user space, and communicate that buffer to my driver as an IOMemoryDescriptor when I set up my async callback. The driver retains the descriptor, maps it into its memory space and can thus write into it when the hardware returns interrupt data. The driver then calls AsyncCompletion, which will cause my user-side callback to be called, so the user side software knows that there's new data available in the previously allocated buffer.
That's fine, it works, but there are data race problems - since USB interrupt reads complete whenever the hardware has provided data, incoming completions happen at unpredictable times, so the shared buffer contents could change while the user side code is examining them.
Is there an example somewhere of how to deal with this? Can I allocate memory on the driver side on demand, create an IOMemoryDescriptor for it and return that descriptor packed inside the asyncData? If so, how does the driver know when it can relinquish that memory? I have a feeling there's something here I just don't understand...
We have a legacy app written in a mix of C, ObjC, C++ and ObjC++ with .xib files. It is not sandboxed.
It sends an Apple Event to TV (the app of that name from Apple, not a physical TV) using /usr/bin/osascript, calling a compiled Apple Script which is in our app bundle's Resources directory with parameters which we generate in our app at runtime. The first time it does this on a fresh system, the OS puts up a dialog asking for permission to control TV, and after the user clicks Allow, our app appears under Security and Privacy in the Automation section.
That's all fine, but what is unexpected is that the app has no Apple Events entitlement (com.apple.security.automation.apple-events), and it doesn't have a NSAppleEventsUsageDescription string either. The documentation at https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_automation_apple-events says
Your app doesn’t need the Apple Events Entitlement if it only sends Apple events to itself or to other processes signed with the same team ID.
but we're not on the Apple team.
When I filter the log for messages from tccd pertaining to our app, it does indeed complain :
Prompting policy for hardened runtime; service: kTCCServiceAppleEvents requires entitlement com.apple.security.automation.apple-events but it is missing for accessing={TCCDProcess: identifier=<our bundle id>”
But despite those complaints, everything works - I can send the event, and TV acts upon it. Is this working only by accident, and might fail in some minor future OS update?
tccd also complains about the microphone
Prompting policy for hardened runtime; service: kTCCServiceMicrophone requires entitlement com.apple.security.device.audio-input but it is missing for requesting={TCCDProcess: identifier=<our bundle ID>
but we don't use the microphone
tccd complains about this too
<path-to-our-app> attempted to call TCCAccessRequest for kTCCServiceAccessibility without the recommended com.apple.private.tcc.manager.check-by-audit-token entitlement
What does that mean, and should we be concerned?
I have an Xcode project with a main app target, and a dext target which builds a DriverKit driver which is embedded in the main app.
That all works, if I build the DriverKit target first, then switch to the app target and build that. The app and the driver work.
If I make the Driver target a dependency of the App target, building the Driver fails because a header is not found, thus building the app fails.
This doesn't make much sense - why does building a target as a consequence of dependence on another target produce a different result from building the same target manually?
Has anyone else seen behavior like this? Have any hints on how to fix it?
I've tried comparing the detailed build logs, but they don't shed much light - the lines are very long and the build steps appear to be executed in a different order. One strange thing I notice is that although I am building on an M1 Mac, with "build active architectures only" set to YES for both targets, in the Driver-target-only case, Driver.cpp is compiled for arm64, while in the failure case, Driver.cpp is compiled for x86_64. That doesn't make any sense to me either.