はじめに
私は今、iOSの個人アプリでCI/CD環境を構築している最中です。
xcodebuild
コマンドをトライアンドエラーで実行しており、発生したエラーと解決策を備忘録として残します。
環境
- OS:macOS Catalina 10.15.1
- Xcode:11.2.1
xcodebuildコマンドのエラー
Xcodeプロジェクトが存在しない
xcodebuild -sdk iphonesimulator -configuration Debug build
shell: /bin/bash -e {0}
Build settings from command line:
SDKROOT = iphonesimulator13.1
xcodebuild: error: The directory {フォルダパス} does not contain an Xcode project.
##[error]Process completed with exit code 66.
原因
Xcodeプロジェクトが存在しないためです。
解決策
Xcodeプロジェクトを作成します。
ワークスペースのみ指定し、スキームを指定していない
xcodebuild -sdk iphonesimulator -configuration Debug -workspace {ワークスペース名} build
shell: /bin/bash -e {0}
xcodebuild: error: If you specify a workspace then you must also specify a scheme. Use -list to see the schemes in this workspace.
##[error]Process completed with exit code 64.
原因
スキームを指定していないためです。
ワークスペースを指定する場合、スキームも指定する必要があります。
解決策
-scheme {スキーム名}
オプションを追加します。
※後述しますが、ワークスペースに拡張子を付けていないためエラーとなります。
ワークスペースの指定に拡張子を含めていない
xcodebuild -sdk iphonesimulator -configuration Debug -workspace {ワークスペース名} -scheme {スキーム名} build
shell: /bin/bash -e {0}
xcodebuild: error: '{ワークスペース名}' is not a workspace file.
##[error]Process completed with exit code 66.
原因
ワークスペースの指定に拡張子を含めていないためです。
解決策
-workspace {ワークスペース名}.xcworkspace
とします。
テストアクションでスキームを指定していない
xcodebuild -sdk iphonesimulator -configuration Debug clean test
shell: /bin/bash -e {0}
Build settings from command line:
SDKROOT = iphonesimulator13.1
xcodebuild: error: The test action requires that the name of a scheme in the project is provided using the "-scheme" option. The "-list" option can be used to find the names of the schemes in the project.
##[error]Process completed with exit code 65.
原因
スキームを指定していないためです。
テストアクションではスキームの指定が必須です。
解決策
-scheme {スキーム名}
オプションを追加します。
デスティネーションを指定していない
xcodebuild -scheme {スキーム名} -sdk iphonesimulator -configuration Debug clean test
shell: /bin/bash -e {0}
Build settings from command line:
SDKROOT = iphonesimulator13.1
note: Using new build system
** CLEAN SUCCEEDED **
xcodebuild: error: Failed to build project {プロジェクト名} with scheme {スキーム名}.
Reason: A build only device cannot be used to run this target.
Recovery suggestion: No supported devices are available running a compatible version of iOS Simulator. Connect a device with a newer version of iOS Simulator in order to run your application (or choose a simulated device as the destination).
##[error]Process completed with exit code 70.
原因
(おそらく)デスティネーションを指定していないためです。
解決策
-destination '{プラットフォームなど}'
オプションを追加します。
私は -destination 'platform=iOS Simulator'
を指定しました。
※後述しますが、上記のデスティネーションは存在しないためエラーとなります。
デスティネーションの指定に誤りがある
xcodebuild -scheme {スキーム名} -sdk iphonesimulator -configuration Debug -destination 'platform=iOS Simulator' clean test
shell: /bin/bash -e {0}
Build settings from command line:
SDKROOT = iphonesimulator13.1
xcodebuild: error: Unable to find a destination matching the provided destination specifier:
{ platform:iOS Simulator }
Missing required device specifier option.
The device type “iOS Simulator” requires that either “name” or “id” be specified.
Please supply either “name” or “id”.
Available destinations for the "{スキーム名}" scheme:
{ platform:iOS Simulator, id:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX, OS:13.1, name:iPad Air (3rd generation) }
{ platform:iOS Simulator, id:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX, OS:13.1, name:iPad Pro (9.7-inch) }
{ platform:iOS Simulator, id:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX, OS:13.1, name:iPad Pro (11-inch) }
{ platform:iOS Simulator, id:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX, OS:13.1, name:iPad Pro (12.9-inch) (3rd generation) }
{ platform:iOS Simulator, id:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX, OS:13.1, name:iPhone 8 }
{ platform:iOS Simulator, id:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX, OS:13.1, name:iPhone 8 Plus }
{ platform:iOS Simulator, id:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX, OS:13.1, name:iPhone 11 }
{ platform:iOS Simulator, id:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX, OS:13.1, name:iPhone 11 Pro }
{ platform:iOS Simulator, id:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX, OS:13.1, name:iPhone 11 Pro Max }
Ineligible destinations for the "{スキーム名}" scheme:
{ platform:iOS, id:dvtdevice-DVTiPhonePlaceholder-iphoneos:placeholder, name:Generic iOS Device }
{ platform:iOS Simulator, id:dvtdevice-DVTiOSDeviceSimulatorPlaceholder-iphonesimulator:placeholder, name:Generic iOS Simulator Device }
##[error]Process completed with exit code 70.
原因
指定したデスティネーションが存在しないためです。
解決策
指定したスキームで使えるデスティネーションを指定します。
私は -destination 'platform=iOS Simulator, name:iPhone 11 Pro Max'
を指定しました。
※後述しますが、デスティネーションのフォーマットに誤りがあるためエラーとなります。
デスティネーションのフォーマットに誤りがある
xcodebuild -scheme {スキーム名} -sdk iphonesimulator -configuration Debug -destination 'platform=iOS Simulator, name:iPhone 11 Pro Max' clean test
shell: /bin/bash -e {0}
xcodebuild: error: unreadable input ' name:iPhone 11 Pro Max' at end of value for option 'Destination'
Usage: xcodebuild [-project <projectname>] [[-target <targetname>]...|-alltargets] [-configuration <configurationname>] [-arch <architecture>]... [-sdk [<sdkname>|<sdkpath>]] [-showBuildSettings [-json]] [<buildsetting>=<value>]... [<buildaction>]...
xcodebuild [-project <projectname>] -scheme <schemeName> [-destination <destinationspecifier>]... [-configuration <configurationname>] [-arch <architecture>]... [-sdk [<sdkname>|<sdkpath>]] [-showBuildSettings [-json]] [-showdestinations] [<buildsetting>=<value>]... [<buildaction>]...
xcodebuild -workspace <workspacename> -scheme <schemeName> [-destination <destinationspecifier>]... [-configuration <configurationname>] [-arch <architecture>]... [-sdk [<sdkname>|<sdkpath>]] [-showBuildSettings] [-showdestinations] [<buildsetting>=<value>]... [<buildaction>]...
xcodebuild -version [-sdk [<sdkfullpath>|<sdkname>] [-json] [<infoitem>] ]
xcodebuild -list [[-project <projectname>]|[-workspace <workspacename>]] [-json]
xcodebuild -showsdks [-json]
xcodebuild -exportArchive -archivePath <xcarchivepath> [-exportPath <destinationpath>] -exportOptionsPlist <plistpath>
xcodebuild -exportNotarizedApp -archivePath <xcarchivepath> -exportPath <destinationpath>
xcodebuild -exportLocalizations -localizationPath <path> -project <projectname> [-exportLanguage <targetlanguage>...[-includeScreenshots]]
xcodebuild -importLocalizations -localizationPath <path> -project <projectname>
xcodebuild -resolvePackageDependencies [-project <projectname>|-workspace <workspacename>] -clonedSourcePackagesDirPath <path>
xcodebuild -create-xcframework [-help] [-framework <path>] [-library <path> [-headers <path>]] -output <path>
Options:
-usage print brief usage
-help print complete usage
-verbose provide additional status output
-license show the Xcode and SDK license agreements
-checkFirstLaunchStatus Check if any First Launch tasks need to be performed
-runFirstLaunch install packages and agree to the license
-project NAME build the project NAME
-target NAME build the target NAME
-alltargets build all targets
-workspace NAME build the workspace NAME
-scheme NAME build the scheme NAME
-configuration NAME use the build configuration NAME for building each target
-xcconfig PATH apply the build settings defined in the file at PATH as overrides
-arch ARCH build each target for the architecture ARCH; this will override architectures defined in the project
-sdk SDK use SDK as the name or path of the base SDK when building the project
-toolchain NAME use the toolchain with identifier or name NAME
-destination DESTINATIONSPECIFIER use the destination described by DESTINATIONSPECIFIER (a comma-separated set of key=value pairs describing the destination to use)
-destination-timeout TIMEOUT wait for TIMEOUT seconds while searching for the destination device
-parallelizeTargets build independent targets in parallel
-jobs NUMBER specify the maximum number of concurrent build operations
-maximum-concurrent-test-device-destinations NUMBER the maximum number of device destinations to test on concurrently
-maximum-concurrent-test-simulator-destinations NUMBER the maximum number of simulator destinations to test on concurrently
-parallel-testing-enabled YES|NO overrides the per-target setting in the scheme
-parallel-testing-worker-count NUMBER the exact number of test runners that will be spawned during parallel testing
-maximum-parallel-testing-workers NUMBER the maximum number of test runners that will be spawned during parallel testing
-dry-run do everything except actually running the commands
-quiet do not print any output except for warnings and errors
-hideShellScriptEnvironment don't show shell script environment variables in build log
-showsdks display a compact list of the installed SDKs
-showdestinations display a list of destinations
-showTestPlans display a list of test plans
-showBuildSettings display a list of build settings and values
-list lists the targets and configurations in a project, or the schemes in a workspace
-find-executable NAME display the full path to executable NAME in the provided SDK and toolchain
-find-library NAME display the full path to library NAME in the provided SDK and toolchain
-version display the version of Xcode; with -sdk will display info about one or all installed SDKs
-enableAddressSanitizer YES|NO turn the address sanitizer on or off
-enableThreadSanitizer YES|NO turn the thread sanitizer on or off
-enableUndefinedBehaviorSanitizer YES|NO turn the undefined behavior sanitizer on or off
-resultBundlePath PATH specifies the directory where a result bundle describing what occurred will be placed
-resultStreamPath PATH specifies the file where a result stream will be written to (the file must already exist)
-resultBundleVersion 3 [default] specifies which result bundle version should be used
-clonedSourcePackagesDirPath PATH specifies the directory to which remote source packages are fetch or expected to be found
-derivedDataPath PATH specifies the directory where build products and other derived data will go
-archivePath PATH specifies the directory where any created archives will be placed, or the archive that should be exported
-exportArchive specifies that an archive should be exported
-exportNotarizedApp export an archive that has been notarized by Apple
-exportOptionsPlist PATH specifies a path to a plist file that configures archive exporting
-enableCodeCoverage YES|NO turn code coverage on or off when testing
-exportPath PATH specifies the destination for the product exported from an archive
-skipUnavailableActions specifies that scheme actions that cannot be performed should be skipped instead of causing a failure
-exportLocalizations exports completed and outstanding project localizations
-importLocalizations imports localizations for a project, assuming any necessary localized resources have been created in Xcode
-localizationPath specifies a path to XLIFF localization files
-exportLanguage specifies multiple optional ISO 639-1 languages included in a localization export
-xctestrun specifies a path to a test run specification
-testPlan specifies the name of the test plan associated with the scheme to use for testing
-only-testing constrains testing by specifying tests to include, and excluding other tests
-only-testing:TEST-IDENTIFIER constrains testing by specifying tests to include, and excluding other tests
-skip-testing constrains testing by specifying tests to exclude, but including other tests
-skip-testing:TEST-IDENTIFIER constrains testing by specifying tests to exclude, but including other tests
-only-test-configuration constrains testing by specifying test configurations to include, and excluding other test configurations
-skip-test-configuration constrains testing by specifying test configurations to exclude, but including other test configurations
-testLanguage constrains testing by specifying ISO 639-1 language in which to run the tests
-testRegion constrains testing by specifying ISO 3166-1 region in which to run the tests
-resolvePackageDependencies resolves any Swift package dependencies referenced by the project or workspace
-disableAutomaticPackageResolution prevents packages from automatically being resolved to versions other than those recorded in the `Package.resolved` file
-json output as JSON (note: -json implies -quiet)
-allowProvisioningUpdates Allow xcodebuild to communicate with the Apple Developer website. For automatically signed targets, xcodebuild will create and update profiles, app IDs, and certificates. For manually signed targets, xcodebuild will download missing or updated provisioning profiles. Requires a developer account to have been added in Xcode's Accounts preference pane.
-allowProvisioningDeviceRegistration Allow xcodebuild to register your destination device on the developer portal if necessary. This flag only takes effect if -allowProvisioningUpdates is also passed.
-showBuildTimingSummary display a report of the timings of all the commands invoked during the build
-create-xcframework create an xcframework from prebuilt libraries; -help for more information.
##[error]Process completed with exit code 64.
原因
デスティネーションのフォーマットに誤りがあるためです。
-destination 'platform=iOS Simulator, name:iPhone 11 Pro Max'
のように、 カンマの直後に半角スペースを含めてはいけません 。
解決策
-destination 'キー1=値1,キー2=値2,…'
のフォーマットでデスティネーションを指定します。
私は -destination 'platform=iOS Simulator,name=iPhone 11 Pro Max'
を指定しました。
テストケースが存在せず、テストに失敗する
xcodebuild -scheme {スキーム名} -sdk iphonesimulator -configuration Debug -destination 'platform=iOS Simulator,name=iPhone 11 Pro Max' clean test
shell: /bin/bash -e {0}
Build settings from command line:
SDKROOT = iphonesimulator13.1
note: Using new build system
** CLEAN SUCCEEDED **
note: Using new build system
note: Planning build
note: Constructing build description
(省略)
Testing failed:
Test session results, code coverage, and logs:
{.xcresultファイルパス}
Build input file cannot be found: '{UIテストファイルパス}'
Testing cancelled because the build failed.
** TEST FAILED **
The following build commands failed:
CopySwiftLibs {.xctestファイルパス}
(1 failure)
##[error]Process completed with exit code 65.
原因
こちらの不具合はローカルのXcode上でも発生していました。
(おそらく)デフォルトのテストファイル({プロジェクト名}Tests.swift、{プロジェクト名}UITests.swift)を削除し、テストケースが0件になったためです。
解決策
単体テストとUIテストのTARGETSを削除して追加し、デフォルトのテストファイルを生成し直します。
おわりに
この記事で少しでも xcodebuild
コマンドにつまづく方が減ると嬉しいです。
おまけ:xcpretty
xcodebuild
コマンドのログは、デフォルトだと見づらいです。
xcprettyを噛ませることで、ログが整形されて見やすくなるのでオススメです。
使い方は簡単で、xcodebuild
コマンドの標準出力をパイプで渡すのみです。
$ xcodebuild -scheme {スキーム名} -sdk iphonesimulator -configuration Debug -destination 'platform=iOS Simulator,name=iPhone 11 Pro Max' clean test | xcpretty
詳細な使い方は公式リポジトリをご参照ください。
https://github.com/xcpretty/xcpretty