diff --git a/.gitignore b/.gitignore index 030cd6515d..ffc2722a51 100644 --- a/.gitignore +++ b/.gitignore @@ -168,3 +168,6 @@ resources/environment.sh **/node_modules/ +# Temporary file for logging scripts in xcode runs, see build-utils.sh for +# details +/xcodebuild-scripts.log diff --git a/ios/kmbuild.sh b/ios/kmbuild.sh index f4eb1f822a..9d526e98ff 100755 --- a/ios/kmbuild.sh +++ b/ios/kmbuild.sh @@ -23,18 +23,6 @@ cd "$(dirname "$THIS_SCRIPT")" # Please note that this build script (understandably) assumes that it is running on Mac OS X. verify_on_mac -function printScriptLogs() { - echo "printScriptLogs: reporting script results from previous xcode build" - if [ -f "$KEYMAN_ROOT/ios/scripts.log" ]; then - cat "$KEYMAN_ROOT/ios/scripts.log" - rm "$KEYMAN_ROOT/ios/scripts.log" - else - echo "printScriptLogs: $KEYMAN_ROOT/ios/scripts.log not found" - fi - echo "printScriptLogs: done" - echo -} - display_usage ( ) { echo "build.sh [-clean] [-no-kmw] [-only-framework] [-no-codesign] [-no-archive] [-add-sim-artifact] [-no-build] [-upload-sentry]" echo @@ -258,21 +246,14 @@ if [ -d "$BUILD_PATH/$CONFIG-universal" ]; then rm -r $BUILD_PATH/$CONFIG-universal fi -xcodebuild $XCODEFLAGS_EXT $CODE_SIGN -scheme KME-universal \ +run-xcodebuild $XCODEFLAGS_EXT $CODE_SIGN -scheme KME-universal \ VERSION=$VERSION \ VERSION_WITH_TAG=$VERSION_WITH_TAG \ VERSION_ENVIRONMENT=$VERSION_ENVIRONMENT \ UPLOAD_SENTRY=$UPLOAD_SENTRY -if [ $? -ne 0 ]; then - printScriptLogs - fail "KMEI build failed." -fi - assertDirExists "$KEYMAN_XCFRAMEWORK" -printScriptLogs - echo "KMEI build complete." if [ $DO_KEYMANAPP = true ]; then @@ -291,23 +272,16 @@ if [ $DO_KEYMANAPP = true ]; then fi if [ $DO_ARCHIVE = false ]; then - xcodebuild $XCODEFLAGS_EXT $CODE_SIGN -scheme Keyman \ + run-xcodebuild $XCODEFLAGS_EXT $CODE_SIGN -scheme Keyman \ VERSION=$VERSION \ VERSION_WITH_TAG=$VERSION_WITH_TAG \ VERSION_ENVIRONMENT=$VERSION_ENVIRONMENT \ UPLOAD_SENTRY=$UPLOAD_SENTRY - - if [ $? -ne 0 ]; then - printScriptLogs - fail "Keyman app build failed." - fi - - printScriptLogs else # Time to prepare the deployment archive data. echo "" echo "Preparing .xcarchive for real devices." - xcodebuild $XCODEFLAGS_EXT $CODE_SIGN -scheme Keyman \ + run-xcodebuild $XCODEFLAGS_EXT $CODE_SIGN -scheme Keyman \ -archivePath $ARCHIVE_PATH \ archive -allowProvisioningUpdates \ VERSION=$VERSION \ @@ -315,23 +289,21 @@ if [ $DO_KEYMANAPP = true ]; then VERSION_ENVIRONMENT=$VERSION_ENVIRONMENT \ UPLOAD_SENTRY=$UPLOAD_SENTRY - printScriptLogs assertDirExists "$ARCHIVE_PATH" if [ $DO_CODE_SIGN == true ]; then echo "Preparing .ipa file for deployment to real devices" # Do NOT use the _EXT variant here; there's no scheme to ref, which will lead # Xcode to generate a build error. - xcodebuild $XCODEFLAGS -exportArchive -archivePath $ARCHIVE_PATH \ + run-xcodebuild $XCODEFLAGS -exportArchive -archivePath $ARCHIVE_PATH \ -exportOptionsPlist exportAppStore.plist \ -exportPath $BUILD_PATH/${CONFIG}-iphoneos -allowProvisioningUpdates - printScriptLogs fi fi if [ $DO_SIMULATOR_TARGET == true ]; then echo "Preparing .app file for simulator-targeted artifact for testing" - xcodebuild $XCODEFLAGS_EXT $CODE_SIGN -scheme Keyman \ + run-xcodebuild $XCODEFLAGS_EXT $CODE_SIGN -scheme Keyman \ -sdk iphonesimulator \ VERSION=$VERSION \ VERSION_WITH_TAG=$VERSION_WITH_TAG \ @@ -339,12 +311,6 @@ if [ $DO_KEYMANAPP = true ]; then UPLOAD_SENTRY=$UPLOAD_SENTRY fi - echo "" - if [ $? = 0 ]; then - printScriptLogs - echo "Build succeeded." - else - printScriptLogs - fail "Build failed - please see the log above for details." - fi + echo + echo "Build succeeded." fi diff --git a/ios/samples/build_common.sh b/ios/samples/build_common.sh index 037b77976f..7a959a2483 100755 --- a/ios/samples/build_common.sh +++ b/ios/samples/build_common.sh @@ -127,9 +127,9 @@ if [ $DO_UPDATE = true ]; then fi if [ $CODE_SIGN = true ]; then - xcodebuild -quiet -target "$TARGET" -config "$CONFIG" + run-xcodebuild -quiet -target "$TARGET" -config "$CONFIG" else - xcodebuild -quiet CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED="NO" CODE_SIGNING_ENTITLEMENTS="" -target "$TARGET" -config "$CONFIG" + run-xcodebuild -quiet CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED="NO" CODE_SIGNING_ENTITLEMENTS="" -target "$TARGET" -config "$CONFIG" fi if [ $? = 0 ]; then diff --git a/ios/scripts/kme-universal.sh b/ios/scripts/kme-universal.sh index 43106a9576..3cd8db3c24 100755 --- a/ios/scripts/kme-universal.sh +++ b/ios/scripts/kme-universal.sh @@ -28,10 +28,10 @@ echo "" build_archive ( ) { # Note: while official docs say we should use `xcodebuild archive ...`, that # is not only markedly slower, it also adds undesired side-effects to - # our build processes. + # our build processes. # (It nukes the base .framework file used to build the archive with a # broken alias that subsequent builds [like the main app's!] can't process.) - xcodebuild build \ + run-xcodebuild build \ -scheme "${SCHEME_NAME}" \ -configuration ${CONFIGURATION} \ -sdk "$1" \ @@ -68,7 +68,7 @@ echo "" # -allow-internal-distribution: preserves the .swiftmodule files, greatly # simplifying integration in consuming apps. # - Carthage uses this for its XCFramework support. -xcodebuild -create-xcframework \ +run-xcodebuild -create-xcframework \ -allow-internal-distribution \ -framework ${IPHONE_FRAMEWORK} \ -framework ${SIMULATOR_FRAMEWORK} \ diff --git a/mac/build.sh b/mac/build.sh index 438edb57d1..0d05c7351c 100755 --- a/mac/build.sh +++ b/mac/build.sh @@ -306,6 +306,8 @@ execBuildCommand() { ret_code=$? set -e + printXCodeBuildScriptLogs + if [ $ret_code != 0 ]; then fail "Build of $component failed! Error: [$ret_code] when executing command: '$cmnd'" fi diff --git a/oem/firstvoices/ios/build_common.sh b/oem/firstvoices/ios/build_common.sh index 47ff14ee48..9797b2693f 100755 --- a/oem/firstvoices/ios/build_common.sh +++ b/oem/firstvoices/ios/build_common.sh @@ -170,7 +170,7 @@ if [ $DO_CARTHAGE = true ]; then # Deleted workspace - a test for proper deployment to CocoaPods. Doesn't matter here. rm -r ./Carthage/Checkouts/DeviceKit/CocoaPodsVerification/ || fail "Carthage dependency loading failed" - + # --no-use-binaries: due to https://github.com/Carthage/Carthage/issues/3134, # which affects the sentry-cocoa dependency. carthage build --use-xcframeworks --no-use-binaries --platform iOS || fail "Carthage dependency loading failed" @@ -192,7 +192,7 @@ if [ $CODE_SIGN = true ]; then # Time to prepare the deployment archive data. echo "" echo "Preparing .ipa file for deployment to real devices." - xcodebuild $XCODEFLAGS_EXT -scheme $TARGET -archivePath $ARCHIVE_PATH archive -allowProvisioningUpdates \ + run-xcodebuild $XCODEFLAGS_EXT -scheme $TARGET -archivePath $ARCHIVE_PATH archive -allowProvisioningUpdates \ VERSION=$VERSION \ VERSION_WITH_TAG=$VERSION_WITH_TAG @@ -201,17 +201,17 @@ if [ $CODE_SIGN = true ]; then # Do NOT use the _EXT variant here; there's no scheme to ref, which will lead # Xcode to generate a build error. - xcodebuild $XCODEFLAGS -exportArchive -archivePath $ARCHIVE_PATH -exportOptionsPlist exportAppStore.plist \ + run-xcodebuild $XCODEFLAGS -exportArchive -archivePath $ARCHIVE_PATH -exportOptionsPlist exportAppStore.plist \ -exportPath $BUILD_PATH/${CONFIG}-iphoneos -allowProvisioningUpdates \ VERSION=$VERSION \ VERSION_WITH_TAG=$VERSION_WITH_TAG else - xcodebuild $XCODEFLAGS_EXT -scheme "$TARGET" \ + run-xcodebuild $XCODEFLAGS_EXT -scheme "$TARGET" \ VERSION=$VERSION \ VERSION_WITH_TAG=$VERSION_WITH_TAG fi else - xcodebuild CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO" CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO \ + run-xcodebuild CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO" CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO \ $XCODEFLAGS_EXT -scheme "$TARGET" \ VERSION=$VERSION \ VERSION_WITH_TAG=$VERSION_WITH_TAG @@ -219,7 +219,7 @@ fi if [ $DO_SIMULATOR_TARGET == true ]; then echo "Preparing .app file as Simulator-targeted build artifact." - xcodebuild CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO" CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO \ + run-xcodebuild CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO" CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO \ $XCODEFLAGS_EXT -scheme "$TARGET" \ -sdk iphonesimulator \ VERSION=$VERSION \ diff --git a/resources/build/build-utils.sh b/resources/build/build-utils.sh index 8b02c15d74..9663d2a75f 100755 --- a/resources/build/build-utils.sh +++ b/resources/build/build-utils.sh @@ -374,4 +374,54 @@ builder_report() { set_keyman_standard_build_path() { PATH="$KEYMAN_ROOT/node_modules/.bin:$PATH" +} + +# +# printXCodeBuildScriptLogs: xcodebuild does not emit stdout from scripts in +# PBXShellScriptBuildPhase phases. This is a real problem for us because if +# there is an issue, we just can't see it. So we capture the output in a +# separate logfile, and then call printXCodeBuildScriptLogs after any xcodebuild +# call to get the output. +# +# This file is captured in xcode-utils.sh, logScriptsToFile function, and each +# script phase will append to the log file, until funprintXCodeBuildScriptLogs +# is called, at which point the logfile will be deleted. +# +# The logfile is placed in $KEYMAN_ROOT/xcodebuild-scripts.log. It is used for +# both iOS and macOS builds. +# +# If there is no logfile, then this function will not emit anything. +# +printXCodeBuildScriptLogs() { + local SCRIPT_LOG="$KEYMAN_ROOT/xcodebuild-scripts.log" + if [ -f "$SCRIPT_LOG" ]; then + echo "printXCodeBuildScriptLogs: reporting script results from previous xcode build" + cat "$SCRIPT_LOG" + rm "$SCRIPT_LOG" + echo "printXCodeBuildScriptLogs: done" + echo + fi +} + +# +# Wraps xcodebuild with error handling and log printing +# +run-xcodebuild() { + typeset cmnd="$*" + typeset ret_code + local hasSetErrExit=false + if [ -o errexit ]; then + hasSetErrExit=true + set +e + fi + eval xcodebuild $cmnd + ret_code=$? + if $hasSetErrExit; then + set -e + fi + + printXCodeBuildScriptLogs + if [ $ret_code != 0 ]; then + fail "Build failed! Error: [$ret_code] when executing command: 'xcodebuild $cmnd'" + fi } \ No newline at end of file diff --git a/resources/build/xcode-utils.sh b/resources/build/xcode-utils.sh index b016fbf989..1abd784717 100755 --- a/resources/build/xcode-utils.sh +++ b/resources/build/xcode-utils.sh @@ -156,8 +156,17 @@ function phaseSentryDsymUpload() { fi } +# +# All calls to xcode-utils.sh scripts will have their output redirected to +# $KEYMAN_ROOT/xcodebuild-scripts.log. This will redirect both stdout and stderr +# to this log file. See the corresponding printXCodeBuildScriptLogs function in +# build-utils.sh to print the log after xcodebuild returns. +# +# More information in the build-utils.sh. +# function logScriptsToFile() { - exec >> $KEYMAN_ROOT/ios/scripts.log 2>&1 + local SCRIPT_LOG="$KEYMAN_ROOT/xcodebuild-scripts.log" + exec >> "$SCRIPT_LOG" 2>&1 } logScriptsToFile