openbakery / gradle-xcodePlugin

gradle plugin for building Xcode Projects for iOS, watchOS, macOS or tvOS
Apache License 2.0
457 stars 127 forks source link

xcodebuild error: The run destination My Mac is not valid for running the scheme #418

Closed adil-hussain-84 closed 2 years ago

adil-hussain-84 commented 4 years ago

I'm using version 0.19.1 of the plugin to build an iOS framework by means of the plugin's xcodebuild task. I define the inputs of the xcodebuild task in my build.gradle file as follow:

xcodebuild {
  configuration = 'Release' // I change this to 'Debug' for debug builds
  destination = ['iPhone 11']
  scheme = 'MyAwesomeSDK'
  simulator = false // I change this to true for simulator builds
  target = 'MyAwesomeSDK'
  type = 'iOS'
  workspace = 'MyAwesomeSDK.xcworkspace'
}

The plugin's xcodebuild task has been running fine for me but I just upgraded Xcode to version 11 and it's now failing with the following error:

xcodebuild: error: Failed to build workspace MyAwesomeSDK with scheme MyAwesomeSDK.
  Reason: The run destination My Mac is not valid for Running the scheme 'MyAwesomeSDK'.

I ran the plugin's xcodebuild task with debug logging enabled and I'm see that it's running the xcodebuild command with the following arguments in the case of a simulator build...

xcodebuild -scheme MyAwesomeSDK -workspace MyAwesomeSDK.xcworkspace -configuration Release -destination platform=iOS Simulator,id=786D2FD9-2B41-4EAE-8B05-301D7F7D1584

... and the following arguments in the case of a non-simulator (i.e. device) build...

xcodebuild -scheme MyAwesomeSDK -workspace MyAwesomeSDK.xcworkspace -configuration Release

(I've omitted the code signing and destination path arguments for brevity.)

The first of the two xcodebuild commands above succeeds and I'm guessing it's because it specifies a destination. It's the second command above that fails and I'm guessing it's because it does not specify a destination.

After digging around I've seen that a good way to get this working is to specify that the build is for the iPhone OS or the iPhone Simulator as follows:

xcodebuild -scheme MyAwesomeSDK -workspace MyAwesomeSDK.xcworkspace -configuration Release -sdk iphoneos

xcodebuild -scheme MyAwesomeSDK -workspace MyAwesomeSDK.xcworkspace -configuration Release -sdk iphonesimulator

Is it possible to add this sdk argument to the xcodebuild command which is generated and run by the plugin?

renep commented 4 years ago

Hmm, I have removed the -sdk parameter a long time ago. The question is if I add it again, if this does not break other stuff 🤔. There is only one way to find out, to try it and see if this works. My plan is to make a release of the current changes, and then I will address this.

As workaround you can use the additionalParameters to pass the sdk: additionalParameters= "-sdk iphoneos"

adil-hussain-84 commented 4 years ago

Thanks for the response. I was able to use the additionalParameters property in my build.gradle file to get around the problem. Note however that declaring the additionalParameters value as "-sdk iphoneos" didn't work for me. I had to declare it as additionalParameters = ["-sdk", "iphoneos"]. I had a look at the /Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild command produced by both approaches by passing --debug to my gradle xcodebuild invocation and they both looked identical in the terminal output so can't be sure why one works and the other doesn't.

Going back to my original request, I still think it's worthwhile if the plugin adds this sdk argument automatically to the /Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild command depending on the value of the xcodebuild.simulator boolean property. I might be missing something but can't see why this is problematic.

For now, to avoid having two properties that amount to the same meaning in my project setup, I'm keying off a single xcodebuildSimulatorFlag input property as follows:

xcodebuild {
    additionalParameters = ["-sdk", getSDKForXcodebuild()]
    simulator = isSimulatorBuild()
}

def isSimulatorBuild() {
    return Boolean.parseBoolean(getProperty('xcodebuildSimulatorFlag'))
}

def getSDKForXcodebuild() {
    return isSimulatorBuild() ? "iphonesimulator" : "iphoneos"
}