full_mac_build.sh 11.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
#!/bin/bash
#
# Helper to do build so you don't have to remember all the steps/args.


set -eu

# Some base locations.
readonly ScriptDir=$(dirname "$(echo $0 | sed -e "s,^\([^/]\),$(pwd)/\1,")")
readonly ProtoRootDir="${ScriptDir}/../.."

printUsage() {
  NAME=$(basename "${0}")
  cat << EOF
usage: ${NAME} [OPTIONS]

This script does the common build steps needed.

OPTIONS:

 General:

   -h, --help
         Show this message
   -c, --clean
         Issue a clean before the normal build.
   -a, --autogen
         Start by rerunning autogen & configure.
29 30 31
   -r, --regenerate-descriptors
         Run generate_descriptor_proto.sh to regenerate all the checked in
         proto sources.
32 33
   -j #, --jobs #
         Force the number of parallel jobs (useful for debugging build issues).
34 35
   --core-only
         Skip some of the core protobuf build/checks to shorten the build time.
36 37 38 39
   --skip-xcode
         Skip the invoke of Xcode to test the runtime on both iOS and OS X.
   --skip-xcode-ios
         Skip the invoke of Xcode to test the runtime on iOS.
40 41 42 43
   --skip-xcode-debug
         Skip the Xcode Debug configuration.
   --skip-xcode-release
         Skip the Xcode Release configuration.
44
   --skip-xcode-osx | --skip-xcode-macos
45
         Skip the invoke of Xcode to test the runtime on OS X.
46 47
   --skip-xcode-tvos
         Skip the invoke of Xcode to test the runtime on tvOS.
48 49
   --skip-objc-conformance
         Skip the Objective C conformance tests (run on OS X).
Thomas Van Lenten's avatar
Thomas Van Lenten committed
50 51
   --xcode-quiet
         Pass -quiet to xcodebuild.
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76

EOF
}

header() {
  echo ""
  echo "========================================================================"
  echo "    ${@}"
  echo "========================================================================"
}

# Thanks to libtool, builds can fail in odd ways and since it eats some output
# it can be hard to spot, so force error output if make exits with a non zero.
wrapped_make() {
  set +e  # Don't stop if the command fails.
  make $*
  MAKE_EXIT_STATUS=$?
  if [ ${MAKE_EXIT_STATUS} -ne 0 ]; then
    echo "Error: 'make $*' exited with status ${MAKE_EXIT_STATUS}"
    exit ${MAKE_EXIT_STATUS}
  fi
  set -e
}

NUM_MAKE_JOBS=$(/usr/sbin/sysctl -n hw.ncpu)
77 78
if [[ "${NUM_MAKE_JOBS}" -lt 2 ]] ; then
  NUM_MAKE_JOBS=2
79 80 81 82
fi

DO_AUTOGEN=no
DO_CLEAN=no
83
REGEN_DESCRIPTORS=no
84
CORE_ONLY=no
85 86
DO_XCODE_IOS_TESTS=yes
DO_XCODE_OSX_TESTS=yes
87
DO_XCODE_TVOS_TESTS=yes
88 89
DO_XCODE_DEBUG=yes
DO_XCODE_RELEASE=yes
90
DO_OBJC_CONFORMANCE_TESTS=yes
Thomas Van Lenten's avatar
Thomas Van Lenten committed
91
XCODE_QUIET=no
92 93 94 95 96 97 98 99 100 101 102 103
while [[ $# != 0 ]]; do
  case "${1}" in
    -h | --help )
      printUsage
      exit 0
      ;;
    -c | --clean )
      DO_CLEAN=yes
      ;;
    -a | --autogen )
      DO_AUTOGEN=yes
      ;;
104 105
    -r | --regenerate-descriptors )
      REGEN_DESCRIPTORS=yes
106 107 108 109 110
      ;;
    -j | --jobs )
      shift
      NUM_MAKE_JOBS="${1}"
      ;;
111 112 113
    --core-only )
      CORE_ONLY=yes
      ;;
114 115 116
    --skip-xcode )
      DO_XCODE_IOS_TESTS=no
      DO_XCODE_OSX_TESTS=no
117
      DO_XCODE_TVOS_TESTS=no
118 119 120 121
      ;;
    --skip-xcode-ios )
      DO_XCODE_IOS_TESTS=no
      ;;
122
    --skip-xcode-osx | --skip-xcode-macos)
123 124
      DO_XCODE_OSX_TESTS=no
      ;;
125 126 127
    --skip-xcode-tvos )
      DO_XCODE_TVOS_TESTS=no
      ;;
128 129 130 131 132 133
    --skip-xcode-debug )
      DO_XCODE_DEBUG=no
      ;;
    --skip-xcode-release )
      DO_XCODE_RELEASE=no
      ;;
134 135 136
    --skip-objc-conformance )
      DO_OBJC_CONFORMANCE_TESTS=no
      ;;
Thomas Van Lenten's avatar
Thomas Van Lenten committed
137 138 139
    --xcode-quiet )
      XCODE_QUIET=yes
      ;;
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
    -*)
      echo "ERROR: Unknown option: ${1}" 1>&2
      printUsage
      exit 1
      ;;
    *)
      echo "ERROR: Unknown argument: ${1}" 1>&2
      printUsage
      exit 1
      ;;
  esac
  shift
done

# Into the proto dir.
155
cd "${ProtoRootDir}"
156 157 158 159 160 161 162 163 164

# if no Makefile, force the autogen.
if [[ ! -f Makefile ]] ; then
  DO_AUTOGEN=yes
fi

if [[ "${DO_AUTOGEN}" == "yes" ]] ; then
  header "Running autogen & configure"
  ./autogen.sh
165
  ./configure \
166
    CPPFLAGS="-mmacosx-version-min=10.9 -Wunused-const-variable -Wunused-function"
167 168 169 170 171 172 173 174 175 176 177
fi

if [[ "${DO_CLEAN}" == "yes" ]] ; then
  header "Cleaning"
  wrapped_make clean
  if [[ "${DO_XCODE_IOS_TESTS}" == "yes" ]] ; then
    XCODEBUILD_CLEAN_BASE_IOS=(
      xcodebuild
        -project objectivec/ProtocolBuffers_iOS.xcodeproj
        -scheme ProtocolBuffers
    )
178 179 180 181 182 183
    if [[ "${DO_XCODE_DEBUG}" == "yes" ]] ; then
      "${XCODEBUILD_CLEAN_BASE_IOS[@]}" -configuration Debug clean
    fi
    if [[ "${DO_XCODE_RELEASE}" == "yes" ]] ; then
      "${XCODEBUILD_CLEAN_BASE_IOS[@]}" -configuration Release clean
    fi
184 185 186 187 188 189 190
  fi
  if [[ "${DO_XCODE_OSX_TESTS}" == "yes" ]] ; then
    XCODEBUILD_CLEAN_BASE_OSX=(
      xcodebuild
        -project objectivec/ProtocolBuffers_OSX.xcodeproj
        -scheme ProtocolBuffers
    )
191 192 193 194 195 196
    if [[ "${DO_XCODE_DEBUG}" == "yes" ]] ; then
      "${XCODEBUILD_CLEAN_BASE_OSX[@]}" -configuration Debug clean
    fi
    if [[ "${DO_XCODE_RELEASE}" == "yes" ]] ; then
      "${XCODEBUILD_CLEAN_BASE_OSX[@]}" -configuration Release clean
    fi
197
  fi
198 199 200 201 202 203 204 205 206 207 208 209 210
  if [[ "${DO_XCODE_TVOS_TESTS}" == "yes" ]] ; then
    XCODEBUILD_CLEAN_BASE_OSX=(
      xcodebuild
        -project objectivec/ProtocolBuffers_tvOS.xcodeproj
        -scheme ProtocolBuffers
    )
    if [[ "${DO_XCODE_DEBUG}" == "yes" ]] ; then
      "${XCODEBUILD_CLEAN_BASE_OSX[@]}" -configuration Debug clean
    fi
    if [[ "${DO_XCODE_RELEASE}" == "yes" ]] ; then
      "${XCODEBUILD_CLEAN_BASE_OSX[@]}" -configuration Release clean
    fi
  fi
211 212
fi

213 214
if [[ "${REGEN_DESCRIPTORS}" == "yes" ]] ; then
  header "Regenerating the descriptor sources."
215 216 217
  ./generate_descriptor_proto.sh -j "${NUM_MAKE_JOBS}"
fi

218 219 220 221 222 223 224 225 226 227 228
if [[ "${CORE_ONLY}" == "yes" ]] ; then
  header "Building core Only"
  wrapped_make -j "${NUM_MAKE_JOBS}"
else
  header "Building"
  # Can't issue these together, when fully parallel, something sometimes chokes
  # at random.
  wrapped_make -j "${NUM_MAKE_JOBS}" all
  wrapped_make -j "${NUM_MAKE_JOBS}" check
  # Fire off the conformance tests also.
  cd conformance
229
  wrapped_make -j "${NUM_MAKE_JOBS}" test_cpp
230 231
  cd ..
fi
232

233 234
# Ensure the WKT sources checked in are current.
objectivec/generate_well_known_types.sh --check-only -j "${NUM_MAKE_JOBS}"
235 236 237 238 239 240 241 242 243 244

header "Checking on the ObjC Runtime Code"
objectivec/DevTools/pddm_tests.py
if ! objectivec/DevTools/pddm.py --dry-run objectivec/*.[hm] objectivec/Tests/*.[hm] ; then
  echo ""
  echo "Update by running:"
  echo "   objectivec/DevTools/pddm.py objectivec/*.[hm] objectivec/Tests/*.[hm]"
  exit 1
fi

Thomas Van Lenten's avatar
Thomas Van Lenten committed
245 246 247
readonly XCODE_VERSION_LINE="$(xcodebuild -version | grep Xcode\  )"
readonly XCODE_VERSION="${XCODE_VERSION_LINE/Xcode /}"  # drop the prefix.

248 249 250 251 252 253
if [[ "${DO_XCODE_IOS_TESTS}" == "yes" ]] ; then
  XCODEBUILD_TEST_BASE_IOS=(
    xcodebuild
      -project objectivec/ProtocolBuffers_iOS.xcodeproj
      -scheme ProtocolBuffers
  )
Thomas Van Lenten's avatar
Thomas Van Lenten committed
254 255 256
  if [[ "${XCODE_QUIET}" == "yes" ]] ; then
    XCODEBUILD_TEST_BASE_IOS+=( -quiet )
  fi
257 258 259 260
  # Don't need to worry about form factors or retina/non retina;
  # just pick a mix of OS Versions and 32/64 bit.
  # NOTE: Different Xcode have different simulated hardware/os support.
  case "${XCODE_VERSION}" in
261 262 263
    [6-8].* )
      echo "ERROR: The unittests include Swift code that is now Swift 4.0." 1>&2
      echo "ERROR: Xcode 9.0 or higher is required to build the test suite, but the library works with Xcode 7.x." 1>&2
264
      exit 11
265
      ;;
266
    9.[0-2]* )
267
      XCODEBUILD_TEST_BASE_IOS+=(
268
          -destination "platform=iOS Simulator,name=iPhone 4s,OS=8.1" # 32bit
269
          -destination "platform=iOS Simulator,name=iPhone 7,OS=latest" # 64bit
270
          # 9.0-9.2 all seem to often fail running destinations in parallel
271
          -disable-concurrent-testing
272 273
      )
      ;;
274
    9.[3-4]* )
275 276 277 278 279 280 281 282
      XCODEBUILD_TEST_BASE_IOS+=(
          # Xcode 9.3 chokes targeting iOS 8.x - http://www.openradar.me/39335367
          -destination "platform=iOS Simulator,name=iPhone 4s,OS=9.0" # 32bit
          -destination "platform=iOS Simulator,name=iPhone 7,OS=latest" # 64bit
          # 9.3 also seems to often fail running destinations in parallel
          -disable-concurrent-testing
      )
      ;;
283 284 285 286 287 288 289 290 291 292
    10.*)
      XCODEBUILD_TEST_BASE_IOS+=(
          -destination "platform=iOS Simulator,name=iPhone 4s,OS=8.1" # 32bit
          -destination "platform=iOS Simulator,name=iPhone 7,OS=latest" # 64bit
          # 10.x also seems to often fail running destinations in parallel (with
          # 32bit one include atleast)
          -disable-concurrent-destination-testing
      )
      ;;
    11.0* )
293 294 295 296 297 298 299 300
      XCODEBUILD_TEST_BASE_IOS+=(
          -destination "platform=iOS Simulator,name=iPhone 4s,OS=8.1" # 32bit
          -destination "platform=iOS Simulator,name=iPhone 7,OS=latest" # 64bit
          # 10.x also seems to often fail running destinations in parallel (with
          # 32bit one include atleast)
          -disable-concurrent-destination-testing
      )
      ;;
301
    * )
302 303 304
      echo ""
      echo "ATTENTION: Time to update the simulator targets for Xcode ${XCODE_VERSION}"
      echo ""
305
      echo "ERROR: Build aborted!"
306 307 308
      exit 2
      ;;
  esac
309 310 311 312 313 314 315 316
  if [[ "${DO_XCODE_DEBUG}" == "yes" ]] ; then
    header "Doing Xcode iOS build/tests - Debug"
    "${XCODEBUILD_TEST_BASE_IOS[@]}" -configuration Debug test
  fi
  if [[ "${DO_XCODE_RELEASE}" == "yes" ]] ; then
    header "Doing Xcode iOS build/tests - Release"
    "${XCODEBUILD_TEST_BASE_IOS[@]}" -configuration Release test
  fi
317
  # Don't leave the simulator in the developer's face.
318
  killall Simulator 2> /dev/null || true
319 320 321 322 323 324 325 326 327
fi
if [[ "${DO_XCODE_OSX_TESTS}" == "yes" ]] ; then
  XCODEBUILD_TEST_BASE_OSX=(
    xcodebuild
      -project objectivec/ProtocolBuffers_OSX.xcodeproj
      -scheme ProtocolBuffers
      # Since the ObjC 2.0 Runtime is required, 32bit OS X isn't supported.
      -destination "platform=OS X,arch=x86_64" # 64bit
  )
Thomas Van Lenten's avatar
Thomas Van Lenten committed
328 329 330
  if [[ "${XCODE_QUIET}" == "yes" ]] ; then
    XCODEBUILD_TEST_BASE_OSX+=( -quiet )
  fi
331
  case "${XCODE_VERSION}" in
332 333 334
    [6-8].* )
      echo "ERROR: The unittests include Swift code that is now Swift 4.0." 1>&2
      echo "ERROR: Xcode 9.0 or higher is required to build the test suite, but the library works with Xcode 7.x." 1>&2
335 336 337
      exit 11
      ;;
  esac
338 339 340 341 342 343 344 345
  if [[ "${DO_XCODE_DEBUG}" == "yes" ]] ; then
    header "Doing Xcode OS X build/tests - Debug"
    "${XCODEBUILD_TEST_BASE_OSX[@]}" -configuration Debug test
  fi
  if [[ "${DO_XCODE_RELEASE}" == "yes" ]] ; then
    header "Doing Xcode OS X build/tests - Release"
    "${XCODEBUILD_TEST_BASE_OSX[@]}" -configuration Release test
  fi
346
fi
347 348 349 350 351 352
if [[ "${DO_XCODE_TVOS_TESTS}" == "yes" ]] ; then
  XCODEBUILD_TEST_BASE_TVOS=(
    xcodebuild
      -project objectivec/ProtocolBuffers_tvOS.xcodeproj
      -scheme ProtocolBuffers
  )
353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372
  case "${XCODE_VERSION}" in
    [6-9].* )
      echo "ERROR: Xcode 10.0 or higher is required to build the test suite." 1>&2
      exit 11
      ;;
    10.* | 11.* )
      XCODEBUILD_TEST_BASE_TVOS+=(
        # Test on the oldest and current.
        -destination "platform=tvOS Simulator,name=Apple TV,OS=11.0"
        -destination "platform=tvOS Simulator,name=Apple TV 4K,OS=latest"
      )
      ;;
    * )
      echo ""
      echo "ATTENTION: Time to update the simulator targets for Xcode ${XCODE_VERSION}"
      echo ""
      echo "ERROR: Build aborted!"
      exit 2
      ;;
  esac
373 374 375 376 377 378 379 380 381 382 383 384
  if [[ "${XCODE_QUIET}" == "yes" ]] ; then
    XCODEBUILD_TEST_BASE_TVOS+=( -quiet )
  fi
  if [[ "${DO_XCODE_DEBUG}" == "yes" ]] ; then
    header "Doing Xcode tvOS build/tests - Debug"
    "${XCODEBUILD_TEST_BASE_TVOS[@]}" -configuration Debug test
  fi
  if [[ "${DO_XCODE_RELEASE}" == "yes" ]] ; then
    header "Doing Xcode tvOS build/tests - Release"
    "${XCODEBUILD_TEST_BASE_TVOS[@]}" -configuration Release test
  fi
fi
385 386

if [[ "${DO_OBJC_CONFORMANCE_TESTS}" == "yes" ]] ; then
387
  header "Running ObjC Conformance Tests"
388 389 390 391
  cd conformance
  wrapped_make -j "${NUM_MAKE_JOBS}" test_objc
  cd ..
fi
392 393 394

echo ""
echo "$(basename "${0}"): Success!"