1#!/bin/bash 2# 3# Helper to do build so you don't have to remember all the steps/args. 4 5 6set -eu 7 8# Some base locations. 9readonly ScriptDir=$(dirname "$(echo $0 | sed -e "s,^\([^/]\),$(pwd)/\1,")") 10readonly ProtoRootDir="${ScriptDir}/../.." 11 12printUsage() { 13 NAME=$(basename "${0}") 14 cat << EOF 15usage: ${NAME} [OPTIONS] 16 17This script does the common build steps needed. 18 19OPTIONS: 20 21 General: 22 23 -h, --help 24 Show this message 25 -c, --clean 26 Issue a clean before the normal build. 27 -a, --autogen 28 Start by rerunning autogen & configure. 29 -r, --regenerate-descriptors 30 Run generate_descriptor_proto.sh to regenerate all the checked in 31 proto sources. 32 -j #, --jobs # 33 Force the number of parallel jobs (useful for debugging build issues). 34 --core-only 35 Skip some of the core protobuf build/checks to shorten the build time. 36 --skip-xcode 37 Skip the invoke of Xcode to test the runtime on both iOS and OS X. 38 --skip-xcode-ios 39 Skip the invoke of Xcode to test the runtime on iOS. 40 --skip-xcode-debug 41 Skip the Xcode Debug configuration. 42 --skip-xcode-release 43 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 --skip-xcode-tvos 47 Skip the invoke of Xcode to test the runtime on tvOS. 48 --skip-objc-conformance 49 Skip the Objective C conformance tests (run on OS X). 50 --xcode-quiet 51 Pass -quiet to xcodebuild. 52 53EOF 54} 55 56header() { 57 echo "" 58 echo "========================================================================" 59 echo " ${@}" 60 echo "========================================================================" 61} 62 63# Thanks to libtool, builds can fail in odd ways and since it eats some output 64# it can be hard to spot, so force error output if make exits with a non zero. 65wrapped_make() { 66 set +e # Don't stop if the command fails. 67 make $* 68 MAKE_EXIT_STATUS=$? 69 if [ ${MAKE_EXIT_STATUS} -ne 0 ]; then 70 echo "Error: 'make $*' exited with status ${MAKE_EXIT_STATUS}" 71 exit ${MAKE_EXIT_STATUS} 72 fi 73 set -e 74} 75 76NUM_MAKE_JOBS=$(/usr/sbin/sysctl -n hw.ncpu) 77if [[ "${NUM_MAKE_JOBS}" -lt 2 ]] ; then 78 NUM_MAKE_JOBS=2 79fi 80 81DO_AUTOGEN=no 82DO_CLEAN=no 83REGEN_DESCRIPTORS=no 84CORE_ONLY=no 85DO_XCODE_IOS_TESTS=yes 86DO_XCODE_OSX_TESTS=yes 87DO_XCODE_TVOS_TESTS=yes 88DO_XCODE_DEBUG=yes 89DO_XCODE_RELEASE=yes 90DO_OBJC_CONFORMANCE_TESTS=yes 91XCODE_QUIET=no 92while [[ $# != 0 ]]; do 93 case "${1}" in 94 -h | --help ) 95 printUsage 96 exit 0 97 ;; 98 -c | --clean ) 99 DO_CLEAN=yes 100 ;; 101 -a | --autogen ) 102 DO_AUTOGEN=yes 103 ;; 104 -r | --regenerate-descriptors ) 105 REGEN_DESCRIPTORS=yes 106 ;; 107 -j | --jobs ) 108 shift 109 NUM_MAKE_JOBS="${1}" 110 ;; 111 --core-only ) 112 CORE_ONLY=yes 113 ;; 114 --skip-xcode ) 115 DO_XCODE_IOS_TESTS=no 116 DO_XCODE_OSX_TESTS=no 117 DO_XCODE_TVOS_TESTS=no 118 ;; 119 --skip-xcode-ios ) 120 DO_XCODE_IOS_TESTS=no 121 ;; 122 --skip-xcode-osx | --skip-xcode-macos) 123 DO_XCODE_OSX_TESTS=no 124 ;; 125 --skip-xcode-tvos ) 126 DO_XCODE_TVOS_TESTS=no 127 ;; 128 --skip-xcode-debug ) 129 DO_XCODE_DEBUG=no 130 ;; 131 --skip-xcode-release ) 132 DO_XCODE_RELEASE=no 133 ;; 134 --skip-objc-conformance ) 135 DO_OBJC_CONFORMANCE_TESTS=no 136 ;; 137 --xcode-quiet ) 138 XCODE_QUIET=yes 139 ;; 140 -*) 141 echo "ERROR: Unknown option: ${1}" 1>&2 142 printUsage 143 exit 1 144 ;; 145 *) 146 echo "ERROR: Unknown argument: ${1}" 1>&2 147 printUsage 148 exit 1 149 ;; 150 esac 151 shift 152done 153 154# Into the proto dir. 155cd "${ProtoRootDir}" 156 157# if no Makefile, force the autogen. 158if [[ ! -f Makefile ]] ; then 159 DO_AUTOGEN=yes 160fi 161 162if [[ "${DO_AUTOGEN}" == "yes" ]] ; then 163 header "Running autogen & configure" 164 ./autogen.sh 165 ./configure \ 166 CPPFLAGS="-mmacosx-version-min=10.9 -Wunused-const-variable -Wunused-function" 167fi 168 169if [[ "${DO_CLEAN}" == "yes" ]] ; then 170 header "Cleaning" 171 wrapped_make clean 172 if [[ "${DO_XCODE_IOS_TESTS}" == "yes" ]] ; then 173 XCODEBUILD_CLEAN_BASE_IOS=( 174 xcodebuild 175 -project objectivec/ProtocolBuffers_iOS.xcodeproj 176 -scheme ProtocolBuffers 177 ) 178 if [[ "${DO_XCODE_DEBUG}" == "yes" ]] ; then 179 "${XCODEBUILD_CLEAN_BASE_IOS[@]}" -configuration Debug clean 180 fi 181 if [[ "${DO_XCODE_RELEASE}" == "yes" ]] ; then 182 "${XCODEBUILD_CLEAN_BASE_IOS[@]}" -configuration Release clean 183 fi 184 fi 185 if [[ "${DO_XCODE_OSX_TESTS}" == "yes" ]] ; then 186 XCODEBUILD_CLEAN_BASE_OSX=( 187 xcodebuild 188 -project objectivec/ProtocolBuffers_OSX.xcodeproj 189 -scheme ProtocolBuffers 190 ) 191 if [[ "${DO_XCODE_DEBUG}" == "yes" ]] ; then 192 "${XCODEBUILD_CLEAN_BASE_OSX[@]}" -configuration Debug clean 193 fi 194 if [[ "${DO_XCODE_RELEASE}" == "yes" ]] ; then 195 "${XCODEBUILD_CLEAN_BASE_OSX[@]}" -configuration Release clean 196 fi 197 fi 198 if [[ "${DO_XCODE_TVOS_TESTS}" == "yes" ]] ; then 199 XCODEBUILD_CLEAN_BASE_OSX=( 200 xcodebuild 201 -project objectivec/ProtocolBuffers_tvOS.xcodeproj 202 -scheme ProtocolBuffers 203 ) 204 if [[ "${DO_XCODE_DEBUG}" == "yes" ]] ; then 205 "${XCODEBUILD_CLEAN_BASE_OSX[@]}" -configuration Debug clean 206 fi 207 if [[ "${DO_XCODE_RELEASE}" == "yes" ]] ; then 208 "${XCODEBUILD_CLEAN_BASE_OSX[@]}" -configuration Release clean 209 fi 210 fi 211fi 212 213if [[ "${REGEN_DESCRIPTORS}" == "yes" ]] ; then 214 header "Regenerating the descriptor sources." 215 ./generate_descriptor_proto.sh -j "${NUM_MAKE_JOBS}" 216fi 217 218if [[ "${CORE_ONLY}" == "yes" ]] ; then 219 header "Building core Only" 220 wrapped_make -j "${NUM_MAKE_JOBS}" 221else 222 header "Building" 223 # Can't issue these together, when fully parallel, something sometimes chokes 224 # at random. 225 wrapped_make -j "${NUM_MAKE_JOBS}" all 226 wrapped_make -j "${NUM_MAKE_JOBS}" check 227 # Fire off the conformance tests also. 228 cd conformance 229 wrapped_make -j "${NUM_MAKE_JOBS}" test_cpp 230 cd .. 231fi 232 233# Ensure the WKT sources checked in are current. 234objectivec/generate_well_known_types.sh --check-only -j "${NUM_MAKE_JOBS}" 235 236header "Checking on the ObjC Runtime Code" 237objectivec/DevTools/pddm_tests.py 238if ! objectivec/DevTools/pddm.py --dry-run objectivec/*.[hm] objectivec/Tests/*.[hm] ; then 239 echo "" 240 echo "Update by running:" 241 echo " objectivec/DevTools/pddm.py objectivec/*.[hm] objectivec/Tests/*.[hm]" 242 exit 1 243fi 244 245readonly XCODE_VERSION_LINE="$(xcodebuild -version | grep Xcode\ )" 246readonly XCODE_VERSION="${XCODE_VERSION_LINE/Xcode /}" # drop the prefix. 247 248if [[ "${DO_XCODE_IOS_TESTS}" == "yes" ]] ; then 249 XCODEBUILD_TEST_BASE_IOS=( 250 xcodebuild 251 -project objectivec/ProtocolBuffers_iOS.xcodeproj 252 -scheme ProtocolBuffers 253 ) 254 if [[ "${XCODE_QUIET}" == "yes" ]] ; then 255 XCODEBUILD_TEST_BASE_IOS+=( -quiet ) 256 fi 257 # Don't need to worry about form factors or retina/non retina; 258 # just pick a mix of OS Versions and 32/64 bit. 259 # NOTE: Different Xcode have different simulated hardware/os support. 260 case "${XCODE_VERSION}" in 261 [6-8].* ) 262 echo "ERROR: The unittests include Swift code that is now Swift 4.0." 1>&2 263 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 XCODEBUILD_TEST_BASE_IOS+=( 276 # Xcode 9.3 chokes targeting iOS 8.x - http://www.openradar.me/39335367 277 -destination "platform=iOS Simulator,name=iPhone 4s,OS=9.0" # 32bit 278 -destination "platform=iOS Simulator,name=iPhone 7,OS=latest" # 64bit 279 # 9.3 also seems to often fail running destinations in parallel 280 -disable-concurrent-testing 281 ) 282 ;; 283 10.*) 284 XCODEBUILD_TEST_BASE_IOS+=( 285 -destination "platform=iOS Simulator,name=iPhone 4s,OS=8.1" # 32bit 286 -destination "platform=iOS Simulator,name=iPhone 7,OS=latest" # 64bit 287 # 10.x also seems to often fail running destinations in parallel (with 288 # 32bit one include atleast) 289 -disable-concurrent-destination-testing 290 ) 291 ;; 292 11.*) 293 # Dropped 32bit as Apple doesn't seem support the simulators either. 294 XCODEBUILD_TEST_BASE_IOS+=( 295 -destination "platform=iOS Simulator,name=iPhone 8,OS=latest" # 64bit 296 ) 297 ;; 298 * ) 299 echo "" 300 echo "ATTENTION: Time to update the simulator targets for Xcode ${XCODE_VERSION}" 301 echo "" 302 echo "ERROR: Build aborted!" 303 exit 2 304 ;; 305 esac 306 if [[ "${DO_XCODE_DEBUG}" == "yes" ]] ; then 307 header "Doing Xcode iOS build/tests - Debug" 308 "${XCODEBUILD_TEST_BASE_IOS[@]}" -configuration Debug test 309 fi 310 if [[ "${DO_XCODE_RELEASE}" == "yes" ]] ; then 311 header "Doing Xcode iOS build/tests - Release" 312 "${XCODEBUILD_TEST_BASE_IOS[@]}" -configuration Release test 313 fi 314 # Don't leave the simulator in the developer's face. 315 killall Simulator 2> /dev/null || true 316fi 317if [[ "${DO_XCODE_OSX_TESTS}" == "yes" ]] ; then 318 XCODEBUILD_TEST_BASE_OSX=( 319 xcodebuild 320 -project objectivec/ProtocolBuffers_OSX.xcodeproj 321 -scheme ProtocolBuffers 322 # Since the ObjC 2.0 Runtime is required, 32bit OS X isn't supported. 323 -destination "platform=OS X,arch=x86_64" # 64bit 324 ) 325 if [[ "${XCODE_QUIET}" == "yes" ]] ; then 326 XCODEBUILD_TEST_BASE_OSX+=( -quiet ) 327 fi 328 case "${XCODE_VERSION}" in 329 [6-8].* ) 330 echo "ERROR: The unittests include Swift code that is now Swift 4.0." 1>&2 331 echo "ERROR: Xcode 9.0 or higher is required to build the test suite, but the library works with Xcode 7.x." 1>&2 332 exit 11 333 ;; 334 esac 335 if [[ "${DO_XCODE_DEBUG}" == "yes" ]] ; then 336 header "Doing Xcode OS X build/tests - Debug" 337 "${XCODEBUILD_TEST_BASE_OSX[@]}" -configuration Debug test 338 fi 339 if [[ "${DO_XCODE_RELEASE}" == "yes" ]] ; then 340 header "Doing Xcode OS X build/tests - Release" 341 "${XCODEBUILD_TEST_BASE_OSX[@]}" -configuration Release test 342 fi 343fi 344if [[ "${DO_XCODE_TVOS_TESTS}" == "yes" ]] ; then 345 XCODEBUILD_TEST_BASE_TVOS=( 346 xcodebuild 347 -project objectivec/ProtocolBuffers_tvOS.xcodeproj 348 -scheme ProtocolBuffers 349 ) 350 case "${XCODE_VERSION}" in 351 [6-9].* ) 352 echo "ERROR: Xcode 10.0 or higher is required to build the test suite." 1>&2 353 exit 11 354 ;; 355 10.* | 11.* ) 356 XCODEBUILD_TEST_BASE_TVOS+=( 357 # Test on the oldest and current. 358 -destination "platform=tvOS Simulator,name=Apple TV,OS=11.0" 359 -destination "platform=tvOS Simulator,name=Apple TV 4K,OS=latest" 360 ) 361 ;; 362 * ) 363 echo "" 364 echo "ATTENTION: Time to update the simulator targets for Xcode ${XCODE_VERSION}" 365 echo "" 366 echo "ERROR: Build aborted!" 367 exit 2 368 ;; 369 esac 370 if [[ "${XCODE_QUIET}" == "yes" ]] ; then 371 XCODEBUILD_TEST_BASE_TVOS+=( -quiet ) 372 fi 373 if [[ "${DO_XCODE_DEBUG}" == "yes" ]] ; then 374 header "Doing Xcode tvOS build/tests - Debug" 375 "${XCODEBUILD_TEST_BASE_TVOS[@]}" -configuration Debug test 376 fi 377 if [[ "${DO_XCODE_RELEASE}" == "yes" ]] ; then 378 header "Doing Xcode tvOS build/tests - Release" 379 "${XCODEBUILD_TEST_BASE_TVOS[@]}" -configuration Release test 380 fi 381fi 382 383if [[ "${DO_OBJC_CONFORMANCE_TESTS}" == "yes" ]] ; then 384 header "Running ObjC Conformance Tests" 385 cd conformance 386 wrapped_make -j "${NUM_MAKE_JOBS}" test_objc 387 cd .. 388fi 389 390echo "" 391echo "$(basename "${0}"): Success!" 392