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 45 Skip the invoke of Xcode to test the runtime on OS X. 46 --skip-objc-conformance 47 Skip the Objective C conformance tests (run on OS X). 48 49EOF 50} 51 52header() { 53 echo "" 54 echo "========================================================================" 55 echo " ${@}" 56 echo "========================================================================" 57} 58 59# Thanks to libtool, builds can fail in odd ways and since it eats some output 60# it can be hard to spot, so force error output if make exits with a non zero. 61wrapped_make() { 62 set +e # Don't stop if the command fails. 63 make $* 64 MAKE_EXIT_STATUS=$? 65 if [ ${MAKE_EXIT_STATUS} -ne 0 ]; then 66 echo "Error: 'make $*' exited with status ${MAKE_EXIT_STATUS}" 67 exit ${MAKE_EXIT_STATUS} 68 fi 69 set -e 70} 71 72NUM_MAKE_JOBS=$(/usr/sbin/sysctl -n hw.ncpu) 73if [[ "${NUM_MAKE_JOBS}" -lt 2 ]] ; then 74 NUM_MAKE_JOBS=2 75fi 76 77DO_AUTOGEN=no 78DO_CLEAN=no 79REGEN_DESCRIPTORS=no 80CORE_ONLY=no 81DO_XCODE_IOS_TESTS=yes 82DO_XCODE_OSX_TESTS=yes 83DO_XCODE_DEBUG=yes 84DO_XCODE_RELEASE=yes 85DO_OBJC_CONFORMANCE_TESTS=yes 86while [[ $# != 0 ]]; do 87 case "${1}" in 88 -h | --help ) 89 printUsage 90 exit 0 91 ;; 92 -c | --clean ) 93 DO_CLEAN=yes 94 ;; 95 -a | --autogen ) 96 DO_AUTOGEN=yes 97 ;; 98 -r | --regenerate-descriptors ) 99 REGEN_DESCRIPTORS=yes 100 ;; 101 -j | --jobs ) 102 shift 103 NUM_MAKE_JOBS="${1}" 104 ;; 105 --core-only ) 106 CORE_ONLY=yes 107 ;; 108 --skip-xcode ) 109 DO_XCODE_IOS_TESTS=no 110 DO_XCODE_OSX_TESTS=no 111 ;; 112 --skip-xcode-ios ) 113 DO_XCODE_IOS_TESTS=no 114 ;; 115 --skip-xcode-osx ) 116 DO_XCODE_OSX_TESTS=no 117 ;; 118 --skip-xcode-debug ) 119 DO_XCODE_DEBUG=no 120 ;; 121 --skip-xcode-release ) 122 DO_XCODE_RELEASE=no 123 ;; 124 --skip-objc-conformance ) 125 DO_OBJC_CONFORMANCE_TESTS=no 126 ;; 127 -*) 128 echo "ERROR: Unknown option: ${1}" 1>&2 129 printUsage 130 exit 1 131 ;; 132 *) 133 echo "ERROR: Unknown argument: ${1}" 1>&2 134 printUsage 135 exit 1 136 ;; 137 esac 138 shift 139done 140 141# Into the proto dir. 142cd "${ProtoRootDir}" 143 144# if no Makefile, force the autogen. 145if [[ ! -f Makefile ]] ; then 146 DO_AUTOGEN=yes 147fi 148 149if [[ "${DO_AUTOGEN}" == "yes" ]] ; then 150 header "Running autogen & configure" 151 ./autogen.sh 152 ./configure \ 153 CPPFLAGS="-mmacosx-version-min=10.9 -Wunused-const-variable -Wunused-function" \ 154 CXXFLAGS="-Wnon-virtual-dtor -Woverloaded-virtual" 155fi 156 157if [[ "${DO_CLEAN}" == "yes" ]] ; then 158 header "Cleaning" 159 wrapped_make clean 160 if [[ "${DO_XCODE_IOS_TESTS}" == "yes" ]] ; then 161 XCODEBUILD_CLEAN_BASE_IOS=( 162 xcodebuild 163 -project objectivec/ProtocolBuffers_iOS.xcodeproj 164 -scheme ProtocolBuffers 165 ) 166 if [[ "${DO_XCODE_DEBUG}" == "yes" ]] ; then 167 "${XCODEBUILD_CLEAN_BASE_IOS[@]}" -configuration Debug clean 168 fi 169 if [[ "${DO_XCODE_RELEASE}" == "yes" ]] ; then 170 "${XCODEBUILD_CLEAN_BASE_IOS[@]}" -configuration Release clean 171 fi 172 fi 173 if [[ "${DO_XCODE_OSX_TESTS}" == "yes" ]] ; then 174 XCODEBUILD_CLEAN_BASE_OSX=( 175 xcodebuild 176 -project objectivec/ProtocolBuffers_OSX.xcodeproj 177 -scheme ProtocolBuffers 178 ) 179 if [[ "${DO_XCODE_DEBUG}" == "yes" ]] ; then 180 "${XCODEBUILD_CLEAN_BASE_OSX[@]}" -configuration Debug clean 181 fi 182 if [[ "${DO_XCODE_RELEASE}" == "yes" ]] ; then 183 "${XCODEBUILD_CLEAN_BASE_OSX[@]}" -configuration Release clean 184 fi 185 fi 186fi 187 188if [[ "${REGEN_DESCRIPTORS}" == "yes" ]] ; then 189 header "Regenerating the descriptor sources." 190 ./generate_descriptor_proto.sh -j "${NUM_MAKE_JOBS}" 191fi 192 193if [[ "${CORE_ONLY}" == "yes" ]] ; then 194 header "Building core Only" 195 wrapped_make -j "${NUM_MAKE_JOBS}" 196else 197 header "Building" 198 # Can't issue these together, when fully parallel, something sometimes chokes 199 # at random. 200 wrapped_make -j "${NUM_MAKE_JOBS}" all 201 wrapped_make -j "${NUM_MAKE_JOBS}" check 202 # Fire off the conformance tests also. 203 cd conformance 204 wrapped_make -j "${NUM_MAKE_JOBS}" test_cpp 205 cd .. 206fi 207 208# Ensure the WKT sources checked in are current. 209objectivec/generate_well_known_types.sh --check-only -j "${NUM_MAKE_JOBS}" 210 211header "Checking on the ObjC Runtime Code" 212objectivec/DevTools/pddm_tests.py 213if ! objectivec/DevTools/pddm.py --dry-run objectivec/*.[hm] objectivec/Tests/*.[hm] ; then 214 echo "" 215 echo "Update by running:" 216 echo " objectivec/DevTools/pddm.py objectivec/*.[hm] objectivec/Tests/*.[hm]" 217 exit 1 218fi 219 220if [[ "${DO_XCODE_IOS_TESTS}" == "yes" ]] ; then 221 XCODEBUILD_TEST_BASE_IOS=( 222 xcodebuild 223 -project objectivec/ProtocolBuffers_iOS.xcodeproj 224 -scheme ProtocolBuffers 225 ) 226 # Don't need to worry about form factors or retina/non retina; 227 # just pick a mix of OS Versions and 32/64 bit. 228 # NOTE: Different Xcode have different simulated hardware/os support. 229 readonly XCODE_VERSION_LINE="$(xcodebuild -version | grep Xcode\ )" 230 readonly XCODE_VERSION="${XCODE_VERSION_LINE/Xcode /}" # drop the prefix. 231 IOS_SIMULATOR_NAME="Simulator" 232 case "${XCODE_VERSION}" in 233 6.* ) 234 echo "ERROR: Xcode 6.3/6.4 no longer supported for building, please use 7.0 or higher." 1>&2 235 exit 10 236 ;; 237 7.1* ) 238 XCODEBUILD_TEST_BASE_IOS+=( 239 -destination "platform=iOS Simulator,name=iPhone 4s,OS=8.1" # 32bit 240 -destination "platform=iOS Simulator,name=iPhone 6,OS=9.0" # 64bit 241 -destination "platform=iOS Simulator,name=iPad 2,OS=8.1" # 32bit 242 -destination "platform=iOS Simulator,name=iPad Air,OS=9.0" # 64bit 243 ) 244 ;; 245 7.2* ) 246 XCODEBUILD_TEST_BASE_IOS+=( 247 -destination "platform=iOS Simulator,name=iPhone 4s,OS=8.1" # 32bit 248 -destination "platform=iOS Simulator,name=iPhone 6,OS=9.2" # 64bit 249 -destination "platform=iOS Simulator,name=iPad 2,OS=8.1" # 32bit 250 -destination "platform=iOS Simulator,name=iPad Air,OS=9.2" # 64bit 251 ) 252 ;; 253 7.3* ) 254 XCODEBUILD_TEST_BASE_IOS+=( 255 -destination "platform=iOS Simulator,name=iPhone 4s,OS=8.1" # 32bit 256 -destination "platform=iOS Simulator,name=iPhone 6,OS=9.3" # 64bit 257 -destination "platform=iOS Simulator,name=iPad 2,OS=8.1" # 32bit 258 -destination "platform=iOS Simulator,name=iPad Air,OS=9.3" # 64bit 259 ) 260 ;; 261 * ) 262 echo "Time to update the simulator targets for Xcode ${XCODE_VERSION}" 263 exit 2 264 ;; 265 esac 266 if [[ "${DO_XCODE_DEBUG}" == "yes" ]] ; then 267 header "Doing Xcode iOS build/tests - Debug" 268 "${XCODEBUILD_TEST_BASE_IOS[@]}" -configuration Debug test 269 fi 270 if [[ "${DO_XCODE_RELEASE}" == "yes" ]] ; then 271 header "Doing Xcode iOS build/tests - Release" 272 "${XCODEBUILD_TEST_BASE_IOS[@]}" -configuration Release test 273 fi 274 # Don't leave the simulator in the developer's face. 275 killall "${IOS_SIMULATOR_NAME}" 276fi 277if [[ "${DO_XCODE_OSX_TESTS}" == "yes" ]] ; then 278 XCODEBUILD_TEST_BASE_OSX=( 279 xcodebuild 280 -project objectivec/ProtocolBuffers_OSX.xcodeproj 281 -scheme ProtocolBuffers 282 # Since the ObjC 2.0 Runtime is required, 32bit OS X isn't supported. 283 -destination "platform=OS X,arch=x86_64" # 64bit 284 ) 285 if [[ "${DO_XCODE_DEBUG}" == "yes" ]] ; then 286 header "Doing Xcode OS X build/tests - Debug" 287 "${XCODEBUILD_TEST_BASE_OSX[@]}" -configuration Debug test 288 fi 289 if [[ "${DO_XCODE_RELEASE}" == "yes" ]] ; then 290 header "Doing Xcode OS X build/tests - Release" 291 "${XCODEBUILD_TEST_BASE_OSX[@]}" -configuration Release test 292 fi 293fi 294 295if [[ "${DO_OBJC_CONFORMANCE_TESTS}" == "yes" ]] ; then 296 header "Running ObjC Conformance Tests" 297 cd conformance 298 wrapped_make -j "${NUM_MAKE_JOBS}" test_objc 299 cd .. 300fi 301