full_mac_build.sh 8.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
#!/bin/bash
#
# Helper to do build so you don't have to remember all the steps/args.


set -eu

# Some base locations.
readonly ScriptDir=$(dirname "$(echo $0 | sed -e "s,^\([^/]\),$(pwd)/\1,")")
readonly ProtoRootDir="${ScriptDir}/../.."

printUsage() {
  NAME=$(basename "${0}")
  cat << EOF
usage: ${NAME} [OPTIONS]

This script does the common build steps needed.

OPTIONS:

 General:

   -h, --help
         Show this message
   -c, --clean
         Issue a clean before the normal build.
   -a, --autogen
         Start by rerunning autogen & configure.
29 30 31
   -r, --regenerate-descriptors
         Run generate_descriptor_proto.sh to regenerate all the checked in
         proto sources.
32 33
   -j #, --jobs #
         Force the number of parallel jobs (useful for debugging build issues).
34 35
   --core-only
         Skip some of the core protobuf build/checks to shorten the build time.
36 37 38 39
   --skip-xcode
         Skip the invoke of Xcode to test the runtime on both iOS and OS X.
   --skip-xcode-ios
         Skip the invoke of Xcode to test the runtime on iOS.
40 41 42 43
   --skip-xcode-debug
         Skip the Xcode Debug configuration.
   --skip-xcode-release
         Skip the Xcode Release configuration.
44 45
   --skip-xcode-osx
         Skip the invoke of Xcode to test the runtime on OS X.
46 47
   --skip-objc-conformance
         Skip the Objective C conformance tests (run on OS X).
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72

EOF
}

header() {
  echo ""
  echo "========================================================================"
  echo "    ${@}"
  echo "========================================================================"
}

# Thanks to libtool, builds can fail in odd ways and since it eats some output
# it can be hard to spot, so force error output if make exits with a non zero.
wrapped_make() {
  set +e  # Don't stop if the command fails.
  make $*
  MAKE_EXIT_STATUS=$?
  if [ ${MAKE_EXIT_STATUS} -ne 0 ]; then
    echo "Error: 'make $*' exited with status ${MAKE_EXIT_STATUS}"
    exit ${MAKE_EXIT_STATUS}
  fi
  set -e
}

NUM_MAKE_JOBS=$(/usr/sbin/sysctl -n hw.ncpu)
73 74
if [[ "${NUM_MAKE_JOBS}" -lt 2 ]] ; then
  NUM_MAKE_JOBS=2
75 76 77 78
fi

DO_AUTOGEN=no
DO_CLEAN=no
79
REGEN_DESCRIPTORS=no
80
CORE_ONLY=no
81 82
DO_XCODE_IOS_TESTS=yes
DO_XCODE_OSX_TESTS=yes
83 84
DO_XCODE_DEBUG=yes
DO_XCODE_RELEASE=yes
85
DO_OBJC_CONFORMANCE_TESTS=yes
86 87 88 89 90 91 92 93 94 95 96 97
while [[ $# != 0 ]]; do
  case "${1}" in
    -h | --help )
      printUsage
      exit 0
      ;;
    -c | --clean )
      DO_CLEAN=yes
      ;;
    -a | --autogen )
      DO_AUTOGEN=yes
      ;;
98 99
    -r | --regenerate-descriptors )
      REGEN_DESCRIPTORS=yes
100 101 102 103 104
      ;;
    -j | --jobs )
      shift
      NUM_MAKE_JOBS="${1}"
      ;;
105 106 107
    --core-only )
      CORE_ONLY=yes
      ;;
108 109 110 111 112 113 114 115 116 117
    --skip-xcode )
      DO_XCODE_IOS_TESTS=no
      DO_XCODE_OSX_TESTS=no
      ;;
    --skip-xcode-ios )
      DO_XCODE_IOS_TESTS=no
      ;;
    --skip-xcode-osx )
      DO_XCODE_OSX_TESTS=no
      ;;
118 119 120 121 122 123
    --skip-xcode-debug )
      DO_XCODE_DEBUG=no
      ;;
    --skip-xcode-release )
      DO_XCODE_RELEASE=no
      ;;
124 125 126
    --skip-objc-conformance )
      DO_OBJC_CONFORMANCE_TESTS=no
      ;;
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
    -*)
      echo "ERROR: Unknown option: ${1}" 1>&2
      printUsage
      exit 1
      ;;
    *)
      echo "ERROR: Unknown argument: ${1}" 1>&2
      printUsage
      exit 1
      ;;
  esac
  shift
done

# Into the proto dir.
142
cd "${ProtoRootDir}"
143 144 145 146 147 148 149 150 151

# if no Makefile, force the autogen.
if [[ ! -f Makefile ]] ; then
  DO_AUTOGEN=yes
fi

if [[ "${DO_AUTOGEN}" == "yes" ]] ; then
  header "Running autogen & configure"
  ./autogen.sh
152 153 154
  ./configure \
    CPPFLAGS="-mmacosx-version-min=10.9 -Wunused-const-variable -Wunused-function" \
    CXXFLAGS="-Wnon-virtual-dtor -Woverloaded-virtual"
155 156 157 158 159 160 161 162 163 164 165
fi

if [[ "${DO_CLEAN}" == "yes" ]] ; then
  header "Cleaning"
  wrapped_make clean
  if [[ "${DO_XCODE_IOS_TESTS}" == "yes" ]] ; then
    XCODEBUILD_CLEAN_BASE_IOS=(
      xcodebuild
        -project objectivec/ProtocolBuffers_iOS.xcodeproj
        -scheme ProtocolBuffers
    )
166 167 168 169 170 171
    if [[ "${DO_XCODE_DEBUG}" == "yes" ]] ; then
      "${XCODEBUILD_CLEAN_BASE_IOS[@]}" -configuration Debug clean
    fi
    if [[ "${DO_XCODE_RELEASE}" == "yes" ]] ; then
      "${XCODEBUILD_CLEAN_BASE_IOS[@]}" -configuration Release clean
    fi
172 173 174 175 176 177 178
  fi
  if [[ "${DO_XCODE_OSX_TESTS}" == "yes" ]] ; then
    XCODEBUILD_CLEAN_BASE_OSX=(
      xcodebuild
        -project objectivec/ProtocolBuffers_OSX.xcodeproj
        -scheme ProtocolBuffers
    )
179 180 181 182 183 184
    if [[ "${DO_XCODE_DEBUG}" == "yes" ]] ; then
      "${XCODEBUILD_CLEAN_BASE_OSX[@]}" -configuration Debug clean
    fi
    if [[ "${DO_XCODE_RELEASE}" == "yes" ]] ; then
      "${XCODEBUILD_CLEAN_BASE_OSX[@]}" -configuration Release clean
    fi
185 186 187
  fi
fi

188 189
if [[ "${REGEN_DESCRIPTORS}" == "yes" ]] ; then
  header "Regenerating the descriptor sources."
190 191 192
  ./generate_descriptor_proto.sh -j "${NUM_MAKE_JOBS}"
fi

193 194 195 196 197 198 199 200 201 202 203
if [[ "${CORE_ONLY}" == "yes" ]] ; then
  header "Building core Only"
  wrapped_make -j "${NUM_MAKE_JOBS}"
else
  header "Building"
  # Can't issue these together, when fully parallel, something sometimes chokes
  # at random.
  wrapped_make -j "${NUM_MAKE_JOBS}" all
  wrapped_make -j "${NUM_MAKE_JOBS}" check
  # Fire off the conformance tests also.
  cd conformance
204
  wrapped_make -j "${NUM_MAKE_JOBS}" test_cpp
205 206
  cd ..
fi
207

208 209
# Ensure the WKT sources checked in are current.
objectivec/generate_well_known_types.sh --check-only -j "${NUM_MAKE_JOBS}"
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225

header "Checking on the ObjC Runtime Code"
objectivec/DevTools/pddm_tests.py
if ! objectivec/DevTools/pddm.py --dry-run objectivec/*.[hm] objectivec/Tests/*.[hm] ; then
  echo ""
  echo "Update by running:"
  echo "   objectivec/DevTools/pddm.py objectivec/*.[hm] objectivec/Tests/*.[hm]"
  exit 1
fi

if [[ "${DO_XCODE_IOS_TESTS}" == "yes" ]] ; then
  XCODEBUILD_TEST_BASE_IOS=(
    xcodebuild
      -project objectivec/ProtocolBuffers_iOS.xcodeproj
      -scheme ProtocolBuffers
  )
226 227 228 229 230 231 232
  # Don't need to worry about form factors or retina/non retina;
  # just pick a mix of OS Versions and 32/64 bit.
  # NOTE: Different Xcode have different simulated hardware/os support.
  readonly XCODE_VERSION_LINE="$(xcodebuild -version | grep Xcode\  )"
  readonly XCODE_VERSION="${XCODE_VERSION_LINE/Xcode /}"  # drop the prefix.
  case "${XCODE_VERSION}" in
    6.* )
233
      echo "ERROR: Xcode 6.3/6.4 no longer supported for building, please use 8.0 or higher." 1>&2
234
      exit 10
235
      ;;
236 237 238 239
    7.* )
      echo "ERROR: The unittests include Swift code that is now Swift 3.0." 1>&2
      echo "ERROR: Xcode 8.0 or higher is required to build the test suite, but the library works with Xcode 7.x." 1>&2
      exit 11
240
      ;;
241 242
    8.0* )
      # The 8.* device seem to hang and never start under Xcode 8.
243
      XCODEBUILD_TEST_BASE_IOS+=(
244 245 246 247
          -destination "platform=iOS Simulator,name=iPhone 4s,OS=9.0" # 32bit
          -destination "platform=iOS Simulator,name=iPhone 7,OS=10.0" # 64bit
          -destination "platform=iOS Simulator,name=iPad 2,OS=9.0" # 32bit
          -destination "platform=iOS Simulator,name=iPad Pro (9.7 inch),OS=10.0" # 64bit
248 249
      )
      ;;
250 251 252 253 254
    * )
      echo "Time to update the simulator targets for Xcode ${XCODE_VERSION}"
      exit 2
      ;;
  esac
255 256 257 258 259 260 261 262
  if [[ "${DO_XCODE_DEBUG}" == "yes" ]] ; then
    header "Doing Xcode iOS build/tests - Debug"
    "${XCODEBUILD_TEST_BASE_IOS[@]}" -configuration Debug test
  fi
  if [[ "${DO_XCODE_RELEASE}" == "yes" ]] ; then
    header "Doing Xcode iOS build/tests - Release"
    "${XCODEBUILD_TEST_BASE_IOS[@]}" -configuration Release test
  fi
263
  # Don't leave the simulator in the developer's face.
264
  killall Simulator
265 266 267 268 269 270 271 272 273
fi
if [[ "${DO_XCODE_OSX_TESTS}" == "yes" ]] ; then
  XCODEBUILD_TEST_BASE_OSX=(
    xcodebuild
      -project objectivec/ProtocolBuffers_OSX.xcodeproj
      -scheme ProtocolBuffers
      # Since the ObjC 2.0 Runtime is required, 32bit OS X isn't supported.
      -destination "platform=OS X,arch=x86_64" # 64bit
  )
274 275 276 277 278 279 280 281 282 283 284 285 286
  readonly XCODE_VERSION_LINE="$(xcodebuild -version | grep Xcode\  )"
  readonly XCODE_VERSION="${XCODE_VERSION_LINE/Xcode /}"  # drop the prefix.
  case "${XCODE_VERSION}" in
    6.* )
      echo "ERROR: Xcode 6.3/6.4 no longer supported for building, please use 8.0 or higher." 1>&2
      exit 10
      ;;
    7.* )
      echo "ERROR: The unittests include Swift code that is now Swift 3.0." 1>&2
      echo "ERROR: Xcode 8.0 or higher is required to build the test suite, but the library works with Xcode 7.x." 1>&2
      exit 11
      ;;
  esac
287 288 289 290 291 292 293 294
  if [[ "${DO_XCODE_DEBUG}" == "yes" ]] ; then
    header "Doing Xcode OS X build/tests - Debug"
    "${XCODEBUILD_TEST_BASE_OSX[@]}" -configuration Debug test
  fi
  if [[ "${DO_XCODE_RELEASE}" == "yes" ]] ; then
    header "Doing Xcode OS X build/tests - Release"
    "${XCODEBUILD_TEST_BASE_OSX[@]}" -configuration Release test
  fi
295
fi
296 297

if [[ "${DO_OBJC_CONFORMANCE_TESTS}" == "yes" ]] ; then
298
  header "Running ObjC Conformance Tests"
299 300 301 302
  cd conformance
  wrapped_make -j "${NUM_MAKE_JOBS}" test_objc
  cd ..
fi