appium: Xcode 14 beta 3: Failed to build WDA as XCTAutomationSupport.framework/XCTAutomationSupport linking failure

[update] Please use newer xcuitest driver with appium 2.

https://github.com/appium/appium/blob/master/packages/appium/docs/en/guides/migrating-1-to-2.md

npm install --location=global appium@next
appium driver install xcuitest  # or "appium driver update xcuitest"
appium server --base-path=/wd/hub

Still the error occurred:

rm ~/.appium # or remove $APPIUM_HOME
appium driver install xcuitest
appium server --base-path=/wd/hub

The problem

This happens only XCTAutomationSupport.framework/XCTAutomationSupport included in Xcode 14 beta 3. XCTAutomationSupport in Xcode 14 beta 2 did not have. So as a workaround, you can use Xcode 14 beta 3 by replacing XCTAutomationSupport in Xcode 14 beta 3 with Xcode beta 2 for now.

(This does not mean Appium/WDA does not work on iOS 16 beta 3.)

mac2/WDA does not have this issue since it does not have a binary link to XCTAutomationSupport.

Environment

Details

Xcode build caused below errors:

  • simulator (on an intel mac)
error build: Cannot link directly with dylib/framework, your binary is not an allowed client of /Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/XCTAutomationSupport.framework/XCTAutomationSupport for architecture x86_64
  • real device
error build: Cannot link directly with dylib/framework, your binary is not an allowed client of /Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/PrivateFrameworks/XCTAutomationSupport.framework/XCTAutomationSupport for architecture arm64

Xcode build example…:

xcodebuild build-for-testing -project WebDriverAgent.xcodeproj -scheme WebDriverAgentRunner -destination id=00008030-000C51E13C29802E IPHONEOS_DEPLOYMENT_TARGET=15.4 GCC_TREAT_WARNINGS_AS_ERRORS=0 COMPILER_INDEX_STORE_ENABLE=NO

then:

ld: cannot link directly with dylib/framework, your binary is not an allowed client of /Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/PrivateFrameworks/XCTAutomationSupport.framework/XCTAutomationSupport for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

So far, the workaround is to replace XCTAutomationSupport.framework/XCTAutomationSupport in beta 3 with the framework binary in beta 2.

Link to Appium logs

Code To Reproduce Issue [ Good To Have ]

Build Appium/WDA with Xcode 14 beta 3.

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 5
  • Comments: 42 (20 by maintainers)

Most upvoted comments

Here are my findings upon an initial investigation:

  • Apple are indeed make things a little more strict, looks like XCTest’s private frameworks were compiled with allowable_client flags specifying which clients are allowed to link to the XCTAutomationSupport framework (new LC_SUB_CLIENT load commands were added).

For dynamically linked shared libraries that are subframework of an umbrella framework they can allow clients other than the umbrella framework or other subframeworks in the same umbrella framework. To do this the subframework is built with “-allowable_client client_name” and an LC_SUB_CLIENT load command is created for each -allowable_client flag. The client_name is usually a framework name. It can also be a name used for bundles clients where the bundle is built with “-client_name client_name”.

  • As of Xcode 14 beta 3 XCTAutomationSupport is defined to only allow the following clients: AutomationInfrastructureIntegrationTests, IDEApplicationTests, IDETestingFoundationTests, IDEXcodeUITesting, XCTAutomationSupportTests, XCTDaemon, XCTDaemonControl, XCTDaemonControlTests, XCTDaemonTests, XCTHarness, XCTest-AppHostedTests, XCTest-PerformanceTests, XCTest-ToolHostedTests, XCTest-UITests-iOS, XCTest-UITests-macOS, XCTest-UITests-tvOS, XCTestCore, XCUIAutomation, XCUIRecorderService, testmanagerd, xctest.
  • We can tell the linker to use one of the whitelisted client names by adding -client_name xctest to the other linkers flags section of WebDriverAgentLib, however then the compiler will complain that the flag can only be used when building a bundle, not a dynamic library. Changing WebDriverAgentLib’s Mach-O type to Bundle will result in an inability for the main test bundle to link against it, stating that only dynamic libraries can be linked against.
  • As of now, the only solution I can think of in order to build with Xcode 14 beta 3 is to change the project structure by removing the WebDriverAgentLib target entirely and add all linked libraries references, header files and source files directly to the WebDriverAgent runner targets. After combining this method with the added flag (the main test bundle is already defined as a Mach-O bundle type) and adding the frameworks search path from WebDriverAgentLib (so that the XCTest frameworks can be located during link time) I managed to get WebDriverAgent runner to run on a simulator and on my iPhone running the iOS 16.0 beta 3.

Information regarding load commands taken from here: https://opensource.apple.com/source/cctools/cctools-921/include/mach-o/loader.h

We’d have to change WDA code to avoid dependencies on private frameworks. It looks like Apple is becoming more and more paranoid: https://developer.apple.com/forums/thread/124782

thanks for the investigation @Dan-Maor This makes sense, however I’m not quite sure it is not going to create another issues related to project building or configuration, which would require to rewrite xcuitest driver wrappers for it. I’ve started working on another solution, which removes private classes from the dependencies list. However, this change requires to refactor a lot of dependant code (really, a lot) and will require some weeks to land before I can even make it to compile successfully. Although it is safer from the perspective that all the other building infra should remain as is.

All the related changes could be found at https://github.com/appium/WebDriverAgent/tree/xcode_upd

@KazuCocoa my problem eventually was solved, the nice guy above @Dan-Maor noticed that I was using old JS packages, I was showing him the packages.json file. What I did to solve it is uninstalled Appium, and also deleted ~/.appium folder manually, without it the problem did not resolve.

Installing fresh appium, also installed the latest needed JS packages.

Thank you both.

@KazuCocoa I retrieved the list from Hopper by going through the load commands and listing the strings of the LC_SUB_CLIENT load commands.

They can also be retrieved in the same manner by using otool -l on the XCTAutomationSupport framework.