• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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"
237LOCAL_PYTHON=python
238"${LOCAL_PYTHON}" objectivec/DevTools/pddm_tests.py
239if ! "${LOCAL_PYTHON}" objectivec/DevTools/pddm.py --dry-run objectivec/*.[hm] objectivec/Tests/*.[hm] ; then
240  echo ""
241  echo "Update by running:"
242  echo "   objectivec/DevTools/pddm.py objectivec/*.[hm] objectivec/Tests/*.[hm]"
243  exit 1
244fi
245
246readonly XCODE_VERSION_LINE="$(xcodebuild -version | grep Xcode\  )"
247readonly XCODE_VERSION="${XCODE_VERSION_LINE/Xcode /}"  # drop the prefix.
248
249if [[ "${DO_XCODE_IOS_TESTS}" == "yes" ]] ; then
250  XCODEBUILD_TEST_BASE_IOS=(
251    xcodebuild
252      -project objectivec/ProtocolBuffers_iOS.xcodeproj
253      -scheme ProtocolBuffers
254  )
255  if [[ "${XCODE_QUIET}" == "yes" ]] ; then
256    XCODEBUILD_TEST_BASE_IOS+=( -quiet )
257  fi
258  # Don't need to worry about form factors or retina/non retina;
259  # just pick a mix of OS Versions and 32/64 bit.
260  # NOTE: Different Xcode have different simulated hardware/os support.
261  case "${XCODE_VERSION}" in
262    [6-8].* )
263      echo "ERROR: The unittests include Swift code that is now Swift 4.0." 1>&2
264      echo "ERROR: Xcode 9.0 or higher is required to build the test suite, but the library works with Xcode 7.x." 1>&2
265      exit 11
266      ;;
267    9.[0-2]* )
268      XCODEBUILD_TEST_BASE_IOS+=(
269          -destination "platform=iOS Simulator,name=iPhone 4s,OS=8.1" # 32bit
270          -destination "platform=iOS Simulator,name=iPhone 7,OS=latest" # 64bit
271          # 9.0-9.2 all seem to often fail running destinations in parallel
272          -disable-concurrent-testing
273      )
274      ;;
275    9.[3-4]* )
276      XCODEBUILD_TEST_BASE_IOS+=(
277          # Xcode 9.3 chokes targeting iOS 8.x - http://www.openradar.me/39335367
278          -destination "platform=iOS Simulator,name=iPhone 4s,OS=9.0" # 32bit
279          -destination "platform=iOS Simulator,name=iPhone 7,OS=latest" # 64bit
280          # 9.3 also seems to often fail running destinations in parallel
281          -disable-concurrent-testing
282      )
283      ;;
284    10.*)
285      XCODEBUILD_TEST_BASE_IOS+=(
286          -destination "platform=iOS Simulator,name=iPhone 4s,OS=8.1" # 32bit
287          -destination "platform=iOS Simulator,name=iPhone 7,OS=latest" # 64bit
288          # 10.x also seems to often fail running destinations in parallel (with
289          # 32bit one include at least)
290          -disable-concurrent-destination-testing
291      )
292      ;;
293    11.* | 12.* | 13.*)
294      # Dropped 32bit as Apple doesn't seem support the simulators either.
295      XCODEBUILD_TEST_BASE_IOS+=(
296          -destination "platform=iOS Simulator,name=iPhone 8,OS=latest" # 64bit
297      )
298      ;;
299    * )
300      echo ""
301      echo "ATTENTION: Time to update the simulator targets for Xcode ${XCODE_VERSION}"
302      echo ""
303      echo "ERROR: Build aborted!"
304      exit 2
305      ;;
306  esac
307  if [[ "${DO_XCODE_DEBUG}" == "yes" ]] ; then
308    header "Doing Xcode iOS build/tests - Debug"
309    "${XCODEBUILD_TEST_BASE_IOS[@]}" -configuration Debug test
310  fi
311  if [[ "${DO_XCODE_RELEASE}" == "yes" ]] ; then
312    header "Doing Xcode iOS build/tests - Release"
313    "${XCODEBUILD_TEST_BASE_IOS[@]}" -configuration Release test
314  fi
315  # Don't leave the simulator in the developer's face.
316  killall Simulator 2> /dev/null || true
317fi
318if [[ "${DO_XCODE_OSX_TESTS}" == "yes" ]] ; then
319  XCODEBUILD_TEST_BASE_OSX=(
320    xcodebuild
321      -project objectivec/ProtocolBuffers_OSX.xcodeproj
322      -scheme ProtocolBuffers
323      # Since the ObjC 2.0 Runtime is required, 32bit OS X isn't supported.
324      -destination "platform=OS X,arch=x86_64" # 64bit
325  )
326  if [[ "${XCODE_QUIET}" == "yes" ]] ; then
327    XCODEBUILD_TEST_BASE_OSX+=( -quiet )
328  fi
329  case "${XCODE_VERSION}" in
330    [6-8].* )
331      echo "ERROR: The unittests include Swift code that is now Swift 4.0." 1>&2
332      echo "ERROR: Xcode 9.0 or higher is required to build the test suite, but the library works with Xcode 7.x." 1>&2
333      exit 11
334      ;;
335  esac
336  if [[ "${DO_XCODE_DEBUG}" == "yes" ]] ; then
337    header "Doing Xcode OS X build/tests - Debug"
338    "${XCODEBUILD_TEST_BASE_OSX[@]}" -configuration Debug test
339  fi
340  if [[ "${DO_XCODE_RELEASE}" == "yes" ]] ; then
341    header "Doing Xcode OS X build/tests - Release"
342    "${XCODEBUILD_TEST_BASE_OSX[@]}" -configuration Release test
343  fi
344fi
345if [[ "${DO_XCODE_TVOS_TESTS}" == "yes" ]] ; then
346  XCODEBUILD_TEST_BASE_TVOS=(
347    xcodebuild
348      -project objectivec/ProtocolBuffers_tvOS.xcodeproj
349      -scheme ProtocolBuffers
350  )
351  case "${XCODE_VERSION}" in
352    [6-9].* )
353      echo "ERROR: Xcode 10.0 or higher is required to build the test suite." 1>&2
354      exit 11
355      ;;
356    10.* | 11.* | 12.*)
357      XCODEBUILD_TEST_BASE_TVOS+=(
358        -destination "platform=tvOS Simulator,name=Apple TV 4K,OS=latest"
359      )
360      ;;
361    13.*)
362      XCODEBUILD_TEST_BASE_TVOS+=(
363        -destination "platform=tvOS Simulator,name=Apple TV 4K (2nd generation),OS=latest"
364      )
365      ;;
366    * )
367      echo ""
368      echo "ATTENTION: Time to update the simulator targets for Xcode ${XCODE_VERSION}"
369      echo ""
370      echo "ERROR: Build aborted!"
371      exit 2
372      ;;
373  esac
374  if [[ "${XCODE_QUIET}" == "yes" ]] ; then
375    XCODEBUILD_TEST_BASE_TVOS+=( -quiet )
376  fi
377  if [[ "${DO_XCODE_DEBUG}" == "yes" ]] ; then
378    header "Doing Xcode tvOS build/tests - Debug"
379    "${XCODEBUILD_TEST_BASE_TVOS[@]}" -configuration Debug test
380  fi
381  if [[ "${DO_XCODE_RELEASE}" == "yes" ]] ; then
382    header "Doing Xcode tvOS build/tests - Release"
383    "${XCODEBUILD_TEST_BASE_TVOS[@]}" -configuration Release test
384  fi
385fi
386
387if [[ "${DO_OBJC_CONFORMANCE_TESTS}" == "yes" ]] ; then
388  header "Running ObjC Conformance Tests"
389  cd conformance
390  wrapped_make -j "${NUM_MAKE_JOBS}" test_objc
391  cd ..
392fi
393
394echo ""
395echo "$(basename "${0}"): Success!"
396