full_mac_build.sh 9.6 KB

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