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