• 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"
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