build.sh 54 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517
  1. #!/bin/bash
  2. ##################################################################################
  3. # Custom build tool for Realm Objective-C binding.
  4. #
  5. # (C) Copyright 2011-2015 by realm.io.
  6. ##################################################################################
  7. # Warning: pipefail is not a POSIX compatible option, but on macOS it works just fine.
  8. # macOS uses a POSIX complain version of bash as /bin/sh, but apparently it does
  9. # not strip away this feature. Also, this will fail if somebody forces the script
  10. # to be run with zsh.
  11. set -o pipefail
  12. set -e
  13. source_root="$(dirname "$0")"
  14. # You can override the version of the core library
  15. : ${REALM_BASE_URL:="https://static.realm.io/downloads"} # set it if you need to use a remote repo
  16. : ${REALM_CORE_VERSION:=$(sed -n 's/^REALM_CORE_VERSION=\(.*\)$/\1/p' ${source_root}/dependencies.list)} # set to "current" to always use the current build
  17. : ${REALM_SYNC_VERSION:=$(sed -n 's/^REALM_SYNC_VERSION=\(.*\)$/\1/p' ${source_root}/dependencies.list)}
  18. : ${REALM_OBJECT_SERVER_VERSION:=$(sed -n 's/^REALM_OBJECT_SERVER_VERSION=\(.*\)$/\1/p' ${source_root}/dependencies.list)}
  19. # You can override the xcmode used
  20. : ${XCMODE:=xcodebuild} # must be one of: xcodebuild (default), xcpretty, xctool
  21. # Provide a fallback value for TMPDIR, relevant for Xcode Bots
  22. : ${TMPDIR:=$(getconf DARWIN_USER_TEMP_DIR)}
  23. PATH=/usr/libexec:$PATH
  24. if ! [ -z "${JENKINS_HOME}" ]; then
  25. XCPRETTY_PARAMS="--no-utf --report junit --output build/reports/junit.xml"
  26. CODESIGN_PARAMS="CODE_SIGN_IDENTITY= CODE_SIGNING_REQUIRED=NO"
  27. fi
  28. usage() {
  29. cat <<EOF
  30. Usage: sh $0 command [argument]
  31. command:
  32. clean: clean up/remove all generated files
  33. download-core: downloads core library (binary version)
  34. download-sync: downloads sync library (binary version, core+sync)
  35. build: builds all iOS and macOS frameworks
  36. ios-static: builds fat iOS static framework
  37. ios-dynamic: builds iOS dynamic frameworks
  38. ios-swift: builds RealmSwift frameworks for iOS
  39. watchos: builds watchOS framwork
  40. watchos-swift: builds RealmSwift framework for watchOS
  41. tvos: builds tvOS framework
  42. tvos-swift: builds RealmSwift framework for tvOS
  43. osx: builds macOS framework
  44. osx-swift: builds RealmSwift framework for macOS
  45. xcframework [plats]: builds xcframeworks for Realm and RealmSwift for given platforms
  46. analyze-osx: analyzes macOS framework
  47. test: tests all iOS and macOS frameworks
  48. test-all: tests all iOS and macOS frameworks in both Debug and Release configurations
  49. test-ios-static: tests static iOS framework on 32-bit and 64-bit simulators
  50. test-ios-dynamic: tests dynamic iOS framework on 32-bit and 64-bit simulators
  51. test-ios-swift: tests RealmSwift iOS framework on 32-bit and 64-bit simulators
  52. test-ios-devices: tests ObjC & Swift iOS frameworks on all attached iOS devices
  53. test-ios-devices-objc: tests ObjC iOS framework on all attached iOS devices
  54. test-ios-devices-swift: tests Swift iOS framework on all attached iOS devices
  55. test-tvos: tests tvOS framework
  56. test-tvos-swift: tests RealmSwift tvOS framework
  57. test-tvos-devices: tests ObjC & Swift tvOS frameworks on all attached tvOS devices
  58. test-osx: tests macOS framework
  59. test-osx-swift: tests RealmSwift macOS framework
  60. test-swiftpm: tests ObjC and Swift macOS frameworks via SwiftPM
  61. verify: verifies docs, osx, osx-swift, ios-static, ios-dynamic, ios-swift, ios-device in both Debug and Release configurations, swiftlint
  62. verify-osx-object-server: downloads the Realm Object Server and runs the Objective-C and Swift integration tests
  63. docs: builds docs in docs/output
  64. examples: builds all examples
  65. examples-ios: builds all static iOS examples
  66. examples-ios-swift: builds all Swift iOS examples
  67. examples-osx: builds all macOS examples
  68. get-version: get the current version
  69. set-version version: set the version
  70. cocoapods-setup: download realm-core and create a stub RLMPlatform.h file to enable building via CocoaPods
  71. argument:
  72. version: version in the x.y.z format
  73. environment variables:
  74. XCMODE: xcodebuild (default), xcpretty or xctool
  75. CONFIGURATION: Debug or Release (default)
  76. REALM_CORE_VERSION: version in x.y.z format or "current" to use local build
  77. REALM_EXTRA_BUILD_ARGUMENTS: additional arguments to pass to the build tool
  78. REALM_XCODE_VERSION: the version number of Xcode to use (e.g.: 8.1)
  79. EOF
  80. }
  81. ######################################
  82. # Xcode Helpers
  83. ######################################
  84. xcode_version_major() {
  85. echo "${REALM_XCODE_VERSION%%.*}"
  86. }
  87. xcode() {
  88. mkdir -p build/DerivedData
  89. CMD="xcodebuild -IDECustomDerivedDataLocation=build/DerivedData $@"
  90. echo "Building with command:" $CMD
  91. eval "$CMD"
  92. }
  93. xc() {
  94. # Logs xcodebuild output in realtime
  95. : ${NSUnbufferedIO:=YES}
  96. args="$@ SWIFT_VERSION=$REALM_SWIFT_VERSION $REALM_EXTRA_BUILD_ARGUMENTS"
  97. if [[ "$XCMODE" == "xcodebuild" ]]; then
  98. xcode "$args"
  99. elif [[ "$XCMODE" == "xcpretty" ]]; then
  100. mkdir -p build
  101. xcode "$args" | tee build/build.log | xcpretty -c ${XCPRETTY_PARAMS} || {
  102. echo "The raw xcodebuild output is available in build/build.log"
  103. exit 1
  104. }
  105. elif [[ "$XCMODE" == "xctool" ]]; then
  106. xctool "$args"
  107. fi
  108. }
  109. xctest() {
  110. xc "$@" build-for-testing
  111. xc "$@" test
  112. }
  113. copy_bcsymbolmap() {
  114. find "$1" -name '*.bcsymbolmap' -type f -exec cp {} "$2" \;
  115. }
  116. build_combined() {
  117. local scheme="$1"
  118. local module_name="$2"
  119. local os="$3"
  120. local simulator="$4"
  121. local scope_suffix="$5"
  122. local version_suffix="$6"
  123. local config="$CONFIGURATION"
  124. local destination=""
  125. local os_name=""
  126. if [[ "$os" == "iphoneos" ]]; then
  127. os_name="ios"
  128. destination="iPhone 8"
  129. elif [[ "$os" == "watchos" ]]; then
  130. os_name="$os"
  131. destination="Apple Watch Series 3 - 42mm"
  132. elif [[ "$os" == "appletvos" ]]; then
  133. os_name="tvos"
  134. destination="Apple TV"
  135. fi
  136. # Derive build paths
  137. local build_products_path="build/DerivedData/Realm/Build/Products"
  138. local build_intermediates_path="build/DerivedData/Realm/Build/Intermediates.noindex"
  139. local product_name="$module_name.framework"
  140. local binary_path="$module_name"
  141. local os_path="$build_products_path/$config-$os$scope_suffix/$product_name"
  142. local simulator_path="$build_products_path/$config-$simulator$scope_suffix/$product_name"
  143. local out_path="build/$os_name$scope_suffix$version_suffix"
  144. # Build for each platform
  145. xc "-scheme '$scheme' -configuration $config -sdk $os"
  146. xc "-scheme '$scheme' -configuration $config -sdk $simulator -destination 'name=$destination' ONLY_ACTIVE_ARCH=NO"
  147. # Combine .swiftmodule
  148. if [ -d $simulator_path/Modules/$module_name.swiftmodule ]; then
  149. cp $simulator_path/Modules/$module_name.swiftmodule/* $os_path/Modules/$module_name.swiftmodule/
  150. fi
  151. # Xcode 10.2 merges the generated headers together with ifdef guards for
  152. # each of the target platforms. This doesn't handle merging
  153. # device/simulator builds, so we need to take care of that ourselves.
  154. # Currently all platforms have identical headers, so we just pick one and
  155. # use that rather than merging, but this may change in the future.
  156. if [ -f $os_path/Headers/$module_name-Swift.h ]; then
  157. unique_headers=$(find $build_intermediates_path -name $module_name-Swift.h -exec shasum {} \; | cut -d' ' -f 1 | uniq | grep -c '^')
  158. if [ $unique_headers != "1" ]; then
  159. echo "Platform-specific Swift generated headers are not identical. Merging them is required and is not yet implemented."
  160. exit 1
  161. fi
  162. find $build_intermediates_path -name $module_name-Swift.h -exec cp {} $os_path/Headers \; -quit
  163. fi
  164. # Copy *.bcsymbolmap to .framework for submitting app with bitcode
  165. copy_bcsymbolmap "$build_products_path/$config-$os$scope_suffix" "$os_path"
  166. # Retrieve build products
  167. clean_retrieve $os_path $out_path $product_name
  168. # Combine ar archives
  169. LIPO_OUTPUT="$out_path/$product_name/$module_name"
  170. xcrun lipo -create "$simulator_path/$binary_path" "$os_path/$binary_path" -output "$LIPO_OUTPUT"
  171. # Verify that the combined library has bitcode and we didn't accidentally
  172. # remove it somewhere along the line
  173. if [[ "$destination" != "" && "$config" == "Release" ]]; then
  174. sh build.sh binary-has-bitcode "$LIPO_OUTPUT"
  175. fi
  176. }
  177. copy_realm_framework() {
  178. local platform="$1"
  179. rm -rf build/$platform/swift-$REALM_XCODE_VERSION/Realm.framework
  180. cp -R build/$platform/Realm.framework build/$platform/swift-$REALM_XCODE_VERSION
  181. }
  182. clean_retrieve() {
  183. mkdir -p "$2"
  184. rm -rf "$2/$3"
  185. cp -R "$1" "$2"
  186. }
  187. move_to_clean_dir() {
  188. rm -rf "$2"
  189. mkdir -p "$2"
  190. mv "$1" "$2"
  191. }
  192. test_ios_static() {
  193. destination="$1"
  194. xc "-scheme 'Realm iOS static' -configuration $CONFIGURATION -sdk iphonesimulator -destination '$destination' build-for-testing"
  195. xc "-scheme 'Realm iOS static' -configuration $CONFIGURATION -sdk iphonesimulator -destination '$destination' test"
  196. }
  197. plist_get() {
  198. /usr/libexec/PlistBuddy -c "Print :$2" $1 2> /dev/null
  199. }
  200. ######################################
  201. # Device Test Helper
  202. ######################################
  203. test_devices() {
  204. local serial_numbers=()
  205. local awk_script="
  206. /^ +Vendor ID: / { is_apple = 0; }
  207. /^ +Vendor ID: 0x05[aA][cC] / { is_apple = 1; }
  208. /^ +Serial Number: / {
  209. if (is_apple) {
  210. match(\$0, /^ +Serial Number: /);
  211. print substr(\$0, RLENGTH + 1);
  212. }
  213. }
  214. "
  215. local serial_numbers_text=$(/usr/sbin/system_profiler SPUSBDataType | /usr/bin/awk "$awk_script")
  216. while read -r number; do
  217. if [[ "$number" != "" ]]; then
  218. serial_numbers+=("$number")
  219. fi
  220. done <<< "$serial_numbers_text"
  221. if [[ ${#serial_numbers[@]} == 0 ]]; then
  222. echo "At least one iOS/tvOS device must be connected to this computer to run device tests"
  223. if [ -z "${JENKINS_HOME}" ]; then
  224. # Don't fail if running locally and there's no device
  225. exit 0
  226. fi
  227. exit 1
  228. fi
  229. local sdk="$1"
  230. local scheme="$2"
  231. local configuration="$3"
  232. local failed=0
  233. for device in "${serial_numbers[@]}"; do
  234. xc "-scheme '$scheme' -configuration $configuration -destination 'id=$device' -sdk $sdk test" || failed=1
  235. done
  236. return $failed
  237. }
  238. ######################################
  239. # Docs
  240. ######################################
  241. build_docs() {
  242. local language="$1"
  243. local version=$(sh build.sh get-version)
  244. local xcodebuild_arguments="--objc,Realm/Realm.h,--,-x,objective-c,-isysroot,$(xcrun --show-sdk-path),-I,$(pwd)"
  245. local module="Realm"
  246. local objc="--objc"
  247. if [[ "$language" == "swift" ]]; then
  248. sh build.sh set-swift-version
  249. xcodebuild_arguments="-scheme,RealmSwift"
  250. module="RealmSwift"
  251. objc=""
  252. fi
  253. touch Realm/RLMPlatform.h # jazzy will fail if it can't find all public header files
  254. jazzy \
  255. ${objc} \
  256. --clean \
  257. --author Realm \
  258. --author_url https://realm.io \
  259. --github_url https://github.com/realm/realm-cocoa \
  260. --github-file-prefix https://github.com/realm/realm-cocoa/tree/v${version} \
  261. --module-version ${version} \
  262. --xcodebuild-arguments ${xcodebuild_arguments} \
  263. --module ${module} \
  264. --root-url https://realm.io/docs/${language}/${version}/api/ \
  265. --output docs/${language}_output \
  266. --head "$(cat docs/custom_head.html)"
  267. rm Realm/RLMPlatform.h
  268. }
  269. ######################################
  270. # Input Validation
  271. ######################################
  272. if [ "$#" -eq 0 -o "$#" -gt 3 ]; then
  273. usage
  274. exit 1
  275. fi
  276. ######################################
  277. # Downloading
  278. ######################################
  279. download_common() {
  280. local download_type=$1 tries_left=3 version url error temp_dir temp_path tar_path
  281. if [ "$download_type" == "core" ]; then
  282. version=$REALM_CORE_VERSION
  283. url="${REALM_BASE_URL}/core/realm-core-${version}.tar.xz"
  284. elif [ "$download_type" == "sync" ]; then
  285. version=$REALM_SYNC_VERSION
  286. url="${REALM_BASE_URL}/sync/realm-sync-cocoa-${version}.tar.xz"
  287. else
  288. echo "Unknown dowload_type: $download_type"
  289. exit 1
  290. fi
  291. echo "Downloading dependency: ${download_type} ${version} from ${url}"
  292. if [ -z "$TMPDIR" ]; then
  293. TMPDIR='/tmp'
  294. fi
  295. temp_dir=$(dirname "$TMPDIR/waste")/${download_type}_bin
  296. mkdir -p "$temp_dir"
  297. tar_path="${temp_dir}/${download_type}-${version}.tar.xz"
  298. temp_path="${tar_path}.tmp"
  299. while [ 0 -lt $tries_left ] && [ ! -f "$tar_path" ]; do
  300. if ! error=$(/usr/bin/curl --fail --silent --show-error --location "$url" --output "$temp_path" 2>&1); then
  301. tries_left=$[$tries_left-1]
  302. else
  303. mv "$temp_path" "$tar_path"
  304. fi
  305. done
  306. if [ ! -f "$tar_path" ]; then
  307. printf "Downloading ${download_type} failed:\n\t$url\n\t$error\n"
  308. exit 1
  309. fi
  310. (
  311. cd "$temp_dir"
  312. rm -rf "$download_type"
  313. tar xf "$tar_path" --xz
  314. mv core "${download_type}-${version}"
  315. )
  316. rm -rf "${download_type}-${version}" core
  317. mv "${temp_dir}/${download_type}-${version}" .
  318. ln -s "${download_type}-${version}" core
  319. }
  320. download_core() {
  321. download_common "core"
  322. }
  323. download_sync() {
  324. download_common "sync"
  325. }
  326. ######################################
  327. # Variables
  328. ######################################
  329. COMMAND="$1"
  330. # Use Debug config if command ends with -debug, otherwise default to Release
  331. case "$COMMAND" in
  332. *-debug)
  333. COMMAND="${COMMAND%-debug}"
  334. CONFIGURATION="Debug"
  335. ;;
  336. esac
  337. export CONFIGURATION=${CONFIGURATION:-Release}
  338. # Pre-choose Xcode and Swift versions for those operations that do not set them
  339. REALM_XCODE_VERSION=${xcode_version:-$REALM_XCODE_VERSION}
  340. REALM_SWIFT_VERSION=${swift_version:-$REALM_SWIFT_VERSION}
  341. source "${source_root}/scripts/swift-version.sh"
  342. set_xcode_and_swift_versions
  343. ######################################
  344. # Commands
  345. ######################################
  346. case "$COMMAND" in
  347. ######################################
  348. # Clean
  349. ######################################
  350. "clean")
  351. find . -type d -name build -exec rm -r "{}" +
  352. exit 0
  353. ;;
  354. ######################################
  355. # Core
  356. ######################################
  357. "download-core")
  358. if [ "$REALM_CORE_VERSION" = "current" ]; then
  359. echo "Using version of core already in core/ directory"
  360. exit 0
  361. fi
  362. if [ -d core -a -d ../realm-core -a ! -L core ]; then
  363. # Allow newer versions than expected for local builds as testing
  364. # with unreleased versions is one of the reasons to use a local build
  365. if ! $(grep -i "${REALM_CORE_VERSION} Release notes" core/release_notes.txt >/dev/null); then
  366. echo "Local build of core is out of date."
  367. exit 1
  368. else
  369. echo "The core library seems to be up to date."
  370. fi
  371. elif ! [ -L core ]; then
  372. echo "core is not a symlink. Deleting..."
  373. rm -rf core
  374. download_core
  375. # With a prebuilt version we only want to check the first non-empty
  376. # line so that checking out an older commit will download the
  377. # appropriate version of core if the already-present version is too new
  378. elif ! $(grep -m 1 . core/release_notes.txt | grep -i "${REALM_CORE_VERSION} RELEASE NOTES" >/dev/null); then
  379. download_core
  380. else
  381. echo "The core library seems to be up to date."
  382. fi
  383. exit 0
  384. ;;
  385. ######################################
  386. # Sync
  387. ######################################
  388. "download-sync")
  389. if [ "$REALM_SYNC_VERSION" = "current" ]; then
  390. echo "Using version of core already in core/ directory"
  391. exit 0
  392. fi
  393. if [ -d core -a -d ../realm-core -a -d ../realm-sync -a ! -L core ]; then
  394. echo "Using version of core already in core/ directory"
  395. elif ! [ -L core ]; then
  396. echo "core is not a symlink. Deleting..."
  397. rm -rf core
  398. download_sync
  399. elif [[ "$(cat core/version.txt)" != "$REALM_SYNC_VERSION" ]]; then
  400. download_sync
  401. else
  402. echo "The core library seems to be up to date."
  403. fi
  404. exit 0
  405. ;;
  406. ######################################
  407. # Swift versioning
  408. ######################################
  409. "set-swift-version")
  410. version=${2:-$REALM_SWIFT_VERSION}
  411. SWIFT_VERSION_FILE="RealmSwift/SwiftVersion.swift"
  412. CONTENTS="let swiftLanguageVersion = \"$version\""
  413. if [ ! -f "$SWIFT_VERSION_FILE" ] || ! grep -q "$CONTENTS" "$SWIFT_VERSION_FILE"; then
  414. echo "$CONTENTS" > "$SWIFT_VERSION_FILE"
  415. fi
  416. exit 0
  417. ;;
  418. "prelaunch-simulator")
  419. sh ${source_root}/scripts/reset-simulators.sh
  420. ;;
  421. ######################################
  422. # Building
  423. ######################################
  424. "build")
  425. sh build.sh ios-static
  426. sh build.sh ios-dynamic
  427. sh build.sh ios-swift
  428. sh build.sh watchos
  429. sh build.sh watchos-swift
  430. sh build.sh tvos
  431. sh build.sh tvos-swift
  432. sh build.sh osx
  433. sh build.sh osx-swift
  434. exit 0
  435. ;;
  436. "ios-static")
  437. build_combined 'Realm iOS static' Realm iphoneos iphonesimulator "-static"
  438. exit 0
  439. ;;
  440. "ios-dynamic")
  441. build_combined Realm Realm iphoneos iphonesimulator
  442. exit 0
  443. ;;
  444. "ios-swift")
  445. sh build.sh ios-dynamic
  446. build_combined RealmSwift RealmSwift iphoneos iphonesimulator '' "/swift-$REALM_XCODE_VERSION"
  447. copy_realm_framework ios
  448. exit 0
  449. ;;
  450. "watchos")
  451. build_combined Realm Realm watchos watchsimulator
  452. exit 0
  453. ;;
  454. "watchos-swift")
  455. sh build.sh watchos
  456. build_combined RealmSwift RealmSwift watchos watchsimulator '' "/swift-$REALM_XCODE_VERSION"
  457. copy_realm_framework watchos
  458. exit 0
  459. ;;
  460. "tvos")
  461. build_combined Realm Realm appletvos appletvsimulator
  462. exit 0
  463. ;;
  464. "tvos-swift")
  465. sh build.sh tvos
  466. build_combined RealmSwift RealmSwift appletvos appletvsimulator '' "/swift-$REALM_XCODE_VERSION"
  467. copy_realm_framework tvos
  468. exit 0
  469. ;;
  470. "osx")
  471. xc "-scheme Realm -configuration $CONFIGURATION"
  472. clean_retrieve "build/DerivedData/Realm/Build/Products/$CONFIGURATION/Realm.framework" "build/osx" "Realm.framework"
  473. exit 0
  474. ;;
  475. "osx-swift")
  476. sh build.sh osx
  477. xc "-scheme 'RealmSwift' -configuration $CONFIGURATION build"
  478. destination="build/osx/swift-$REALM_XCODE_VERSION"
  479. clean_retrieve "build/DerivedData/Realm/Build/Products/$CONFIGURATION/RealmSwift.framework" "$destination" "RealmSwift.framework"
  480. rm -rf "$destination/Realm.framework"
  481. cp -R build/osx/Realm.framework "$destination"
  482. exit 0
  483. ;;
  484. "catalyst")
  485. if (( $(xcode_version_major) < 11 )); then
  486. echo 'Building for Catalyst requires Xcode 11'
  487. exit 1
  488. fi
  489. xc "-scheme Realm -configuration $CONFIGURATION REALM_CATALYST_FLAGS='-target x86_64-apple-ios13.0-macabi' REALM_PLATFORM_SUFFIX='maccatalyst'"
  490. clean_retrieve "build/DerivedData/Realm/Build/Products/$CONFIGURATION/Realm.framework" "build/catalyst" "Realm.framework"
  491. ;;
  492. "catalyst-swift")
  493. if (( $(xcode_version_major) < 11 )); then
  494. echo 'Building for Catalyst requires Xcode 11'
  495. exit 1
  496. fi
  497. sh build.sh catalyst
  498. # FIXME: change this to just "-destination variant='Mac Catalyst'" once the CI machines are running 10.15
  499. xc "-scheme 'RealmSwift' -configuration $CONFIGURATION build \
  500. REALM_CATALYST_FLAGS='-target x86_64-apple-ios13.0-macabi' \
  501. REALM_PLATFORM_SUFFIX='maccatalyst' \
  502. SWIFT_DEPLOYMENT_TARGET='13.0-macabi' \
  503. SWIFT_PLATFORM_TARGET_PREFIX='ios'"
  504. destination="build/catalyst/swift-$REALM_XCODE_VERSION"
  505. clean_retrieve "build/DerivedData/Realm/Build/Products/$CONFIGURATION/RealmSwift.framework" "$destination" "RealmSwift.framework"
  506. rm -rf "$destination/Realm.framework"
  507. cp -R build/catalyst/Realm.framework "$destination"
  508. ;;
  509. "xcframework")
  510. if (( $(xcode_version_major) < 11 )); then
  511. echo 'Building a xcframework requires Xcode 11'
  512. exit 1
  513. fi
  514. export REALM_EXTRA_BUILD_ARGUMENTS="$REALM_EXTRA_BUILD_ARGUMENTS BUILD_LIBRARY_FOR_DISTRIBUTION=YES REALM_OBJC_MACH_O_TYPE=staticlib"
  515. # Build all of the requested frameworks
  516. shift
  517. PLATFORMS="${*:-osx ios watchos tvos catalyst}"
  518. for platform in $PLATFORMS; do
  519. sh build.sh $platform-swift
  520. done
  521. # Assemble them into xcframeworks
  522. rm -rf build/*.xcframework
  523. find build/DerivedData/Realm/Build/Products -name 'Realm.framework' \
  524. | grep -v '\-static' \
  525. | sed 's/.*/-framework &/' \
  526. | xargs xcodebuild -create-xcframework -output build/Realm.xcframework
  527. find build/DerivedData/Realm/Build/Products -name 'RealmSwift.framework' \
  528. | sed 's/.*/-framework &/' \
  529. | xargs xcodebuild -create-xcframework -output build/RealmSwift.xcframework
  530. # strip-frameworks.sh isn't needed with xcframeworks since we don't
  531. # lipo together device/simulator libs
  532. find build/Realm.xcframework -name 'strip-frameworks.sh' -delete
  533. find build/RealmSwift.xcframework -name 'strip-frameworks.sh' -delete
  534. # swiftinterface files currently have incorrect name resolution which
  535. # results in the RealmSwift.Realm class name clashing with the Realm
  536. # module name. Work around this by renaming the Realm module to
  537. # RealmObjc. This is safe to do with a pre-built library because the
  538. # module name is unrelated to what symbols are exported by an obj-c
  539. # library, and we're statically linking the obj-c library into the
  540. # swift library so it doesn't need to be loaded at runtime.
  541. cd build
  542. cp -R Realm.xcframework RealmObjc.xcframework
  543. find RealmObjc.xcframework -name 'Realm.framework' \
  544. -execdir mv {} RealmObjc.framework \; || true 2> /dev/null
  545. find RealmObjc.xcframework -name '*.h' \
  546. -exec sed -i '' 's/Realm\//RealmObjc\//' {} \;
  547. find RealmObjc.xcframework -name 'module.modulemap' \
  548. -exec sed -i '' 's/module Realm/module RealmObjc/' {} \;
  549. sed -i '' 's/Realm.framework/RealmObjc.framework/' RealmObjc.xcframework/Info.plist
  550. find RealmSwift.xcframework -name '*.swiftinterface' \
  551. -exec sed -i '' 's/import Realm/import RealmObjc/' {} \;
  552. find RealmSwift.xcframework -name '*.swiftinterface' \
  553. -exec sed -i '' 's/Realm.RLM/RealmObjc.RLM/g' {} \;
  554. # Realm is statically linked into RealmSwift so we no longer actually
  555. # need the obj-c static library, and just need the framework shell.
  556. # Remove everything but placeholder.o so that there's still a library
  557. # to link against that just doesn't define any symbols.
  558. find RealmObjc.xcframework -name 'Realm' | while read file; do
  559. (
  560. cd $(dirname $file)
  561. if readlink Realm > /dev/null; then
  562. ln -sf Versions/Current/RealmObjc Realm
  563. elif lipo -info Realm | grep -q 'Non-fat'; then
  564. ar -t Realm | grep -v placeholder | tr '\n' '\0' | xargs -0 ar -d Realm >/dev/null 2>&1
  565. ranlib Realm >/dev/null 2>&1
  566. else
  567. for arch in $(lipo -info Realm | cut -f3 -d':'); do
  568. lipo Realm -thin $arch -output tmp.a
  569. ar -t tmp.a | grep -v placeholder | tr '\n' '\0' | xargs -0 ar -d tmp.a >/dev/null 2>&1
  570. ranlib tmp.a >/dev/null 2>&1
  571. lipo Realm -replace $arch tmp.a -output Realm
  572. rm tmp.a
  573. done
  574. fi
  575. mv Realm RealmObjc
  576. )
  577. done
  578. # We built Realm.framework as a static framework so that we could link
  579. # it into RealmSwift.framework and not have to deal with the runtime
  580. # implications of renaming the shared library, but we want the end
  581. # result to be that Realm.xcframework is a dynamic framework. Our build
  582. # system isn't really set up to build both static and dynamic versions
  583. # of it, so instead just turn each of the static libraries in
  584. # Realm.xcframework into a shared library.
  585. cd Realm.xcframework
  586. i=0
  587. while plist_get Info.plist "AvailableLibraries:$i" > /dev/null; do
  588. arch_dir_name="$(plist_get Info.plist "AvailableLibraries:$i:LibraryIdentifier")"
  589. platform="$(plist_get Info.plist "AvailableLibraries:$i:SupportedPlatform")"
  590. variant="$(plist_get Info.plist "AvailableLibraries:$i:SupportedPlatformVariant" 2> /dev/null || echo 'os')"
  591. deployment_target_name="$platform"
  592. install_name='@rpath/Realm.framework/Realm'
  593. bitcode_flag='-fembed-bitcode'
  594. if [ "$variant" = 'simulator' ]; then
  595. bitcode_flag=''
  596. fi
  597. case "$platform" in
  598. "macos") sdk='macosx'; install_name='@rpath/Realm.framework/Versions/A/Realm'; bitcode_flag='';;
  599. "ios") sdk="iphone$variant"; deployment_target_name='iphoneos';;
  600. "watchos") sdk="watch$variant";;
  601. "tvos") sdk="appletv$variant";;
  602. esac
  603. deployment_target=$(grep -i "$deployment_target_name.*_DEPLOYMENT_TARGET" ../../Configuration/Base.xcconfig \
  604. | sed 's/.*= \(.*\);/\1/')
  605. architectures=""
  606. j=0
  607. while plist_get Info.plist "AvailableLibraries:$i:SupportedArchitectures:$j" > /dev/null; do
  608. architectures="${architectures} -arch $(plist_get Info.plist "AvailableLibraries:$i:SupportedArchitectures:$j")"
  609. j=$(($j + 1))
  610. done
  611. (
  612. cd $arch_dir_name/Realm.framework
  613. realm_lib=$(readlink Realm || echo 'Realm')
  614. # feature_token.cpp.o depends on PKey, which isn't actually
  615. # present in the macOS build of the sync library. This normally
  616. # works fine because we never reference any symbols from
  617. # feature_token.cpp.o so it doesn't get pulled in at all, but
  618. # -all_load makes every object file in the input get linked
  619. # into the shared library.
  620. ar -d $realm_lib feature_token.cpp.o 2> /dev/null || true
  621. clang++ -shared $architectures \
  622. -target ${platform}${deployment_target} \
  623. -isysroot $(xcrun --sdk ${sdk} --show-sdk-path) \
  624. -install_name "$install_name" \
  625. -compatibility_version 1 -current_version 1 \
  626. -fapplication-extension \
  627. $bitcode_flag \
  628. -Wl,-all_load \
  629. -Wl,-unexported_symbol,'__Z*' \
  630. -o realm.dylib \
  631. Realm -lz
  632. mv realm.dylib $realm_lib
  633. )
  634. i=$(($i + 1))
  635. done
  636. exit 0
  637. ;;
  638. ######################################
  639. # Analysis
  640. ######################################
  641. "analyze-osx")
  642. xc "-scheme Realm -configuration $CONFIGURATION analyze"
  643. exit 0
  644. ;;
  645. ######################################
  646. # Testing
  647. ######################################
  648. "test")
  649. set +e # Run both sets of tests even if the first fails
  650. failed=0
  651. sh build.sh test-ios-static || failed=1
  652. sh build.sh test-ios-dynamic || failed=1
  653. sh build.sh test-ios-swift || failed=1
  654. sh build.sh test-ios-devices || failed=1
  655. sh build.sh test-tvos-devices || failed=1
  656. sh build.sh test-osx || failed=1
  657. sh build.sh test-osx-swift || failed=1
  658. exit $failed
  659. ;;
  660. "test-all")
  661. set +e
  662. failed=0
  663. sh build.sh test || failed=1
  664. sh build.sh test-debug || failed=1
  665. exit $failed
  666. ;;
  667. "test-ios-static")
  668. test_ios_static "name=iPhone 8"
  669. exit 0
  670. ;;
  671. "test-ios-dynamic")
  672. xc "-scheme Realm -configuration $CONFIGURATION -sdk iphonesimulator -destination 'name=iPhone 8' build-for-testing"
  673. xc "-scheme Realm -configuration $CONFIGURATION -sdk iphonesimulator -destination 'name=iPhone 8' test"
  674. exit 0
  675. ;;
  676. "test-ios-swift")
  677. xc "-scheme RealmSwift -configuration $CONFIGURATION -sdk iphonesimulator -destination 'name=iPhone 8' build-for-testing"
  678. xc "-scheme RealmSwift -configuration $CONFIGURATION -sdk iphonesimulator -destination 'name=iPhone 8' test"
  679. exit 0
  680. ;;
  681. "test-ios-devices")
  682. failed=0
  683. trap "failed=1" ERR
  684. sh build.sh test-ios-devices-objc
  685. sh build.sh test-ios-devices-swift
  686. exit $failed
  687. ;;
  688. "test-ios-devices-objc")
  689. test_devices iphoneos "Realm" "$CONFIGURATION"
  690. exit $?
  691. ;;
  692. "test-ios-devices-swift")
  693. test_devices iphoneos "RealmSwift" "$CONFIGURATION"
  694. exit $?
  695. ;;
  696. "test-tvos")
  697. destination="Apple TV"
  698. xctest "-scheme Realm -configuration $CONFIGURATION -sdk appletvsimulator -destination 'name=$destination'"
  699. exit $?
  700. ;;
  701. "test-tvos-swift")
  702. destination="Apple TV"
  703. xctest "-scheme RealmSwift -configuration $CONFIGURATION -sdk appletvsimulator -destination 'name=$destination'"
  704. exit $?
  705. ;;
  706. "test-tvos-devices")
  707. test_devices appletvos TestHost "$CONFIGURATION"
  708. ;;
  709. "test-osx")
  710. COVERAGE_PARAMS=""
  711. if [[ "$CONFIGURATION" == "Debug" ]]; then
  712. COVERAGE_PARAMS="GCC_GENERATE_TEST_COVERAGE_FILES=YES GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES"
  713. fi
  714. xctest "-scheme Realm -configuration $CONFIGURATION $COVERAGE_PARAMS"
  715. exit 0
  716. ;;
  717. "test-osx-swift")
  718. xctest "-scheme RealmSwift -configuration $CONFIGURATION"
  719. exit 0
  720. ;;
  721. "test-osx-object-server")
  722. xctest "-scheme 'Object Server Tests' -configuration $CONFIGURATION -sdk macosx"
  723. exit 0
  724. ;;
  725. "test-swiftpm")
  726. xcrun swift test --configuration $(echo $CONFIGURATION | tr "[:upper:]" "[:lower:]")
  727. exit 0
  728. ;;
  729. ######################################
  730. # Full verification
  731. ######################################
  732. "verify")
  733. sh build.sh verify-cocoapods
  734. sh build.sh verify-docs
  735. sh build.sh verify-osx
  736. sh build.sh verify-osx-debug
  737. sh build.sh verify-osx-swift
  738. sh build.sh verify-osx-swift-debug
  739. sh build.sh verify-ios-static
  740. sh build.sh verify-ios-static-debug
  741. sh build.sh verify-ios-dynamic
  742. sh build.sh verify-ios-dynamic-debug
  743. sh build.sh verify-ios-swift
  744. sh build.sh verify-ios-swift-debug
  745. sh build.sh verify-ios-device-objc
  746. sh build.sh verify-ios-device-swift
  747. sh build.sh verify-watchos
  748. sh build.sh verify-tvos
  749. sh build.sh verify-tvos-debug
  750. sh build.sh verify-tvos-device
  751. sh build.sh verify-swiftlint
  752. sh build.sh verify-swiftpm
  753. sh build.sh verify-osx-object-server
  754. ;;
  755. "verify-cocoapods")
  756. if [[ -d .git ]]; then
  757. # Verify the current branch, unless one was already specified in the sha environment variable.
  758. if [[ -z $sha ]]; then
  759. export sha=$(git rev-parse --abbrev-ref HEAD)
  760. fi
  761. if [[ $(git log -1 @{push}..) != "" ]] || ! git diff-index --quiet HEAD; then
  762. echo "WARNING: verify-cocoapods will test the latest revision of $sha found on GitHub."
  763. echo " Any unpushed local changes will not be tested."
  764. echo ""
  765. sleep 1
  766. fi
  767. fi
  768. sh build.sh verify-cocoapods-ios
  769. sh build.sh verify-cocoapods-osx
  770. sh build.sh verify-cocoapods-watchos
  771. # https://github.com/CocoaPods/CocoaPods/issues/7708
  772. export EXPANDED_CODE_SIGN_IDENTITY=''
  773. cd examples/installation
  774. sh build.sh test-ios-objc-cocoapods
  775. sh build.sh test-ios-objc-cocoapods-dynamic
  776. sh build.sh test-ios-swift-cocoapods
  777. sh build.sh test-osx-objc-cocoapods
  778. sh build.sh test-osx-swift-cocoapods
  779. sh build.sh test-watchos-objc-cocoapods
  780. sh build.sh test-watchos-swift-cocoapods
  781. ;;
  782. verify-cocoapods-*)
  783. PLATFORM=$(echo $COMMAND | cut -d - -f 3)
  784. # https://github.com/CocoaPods/CocoaPods/issues/7708
  785. export EXPANDED_CODE_SIGN_IDENTITY=''
  786. cd examples/installation
  787. sh build.sh test-$PLATFORM-objc-cocoapods
  788. sh build.sh test-$PLATFORM-swift-cocoapods
  789. if [[ $PLATFORM = "ios" ]]; then
  790. sh build.sh test-ios-objc-cocoapods-dynamic
  791. fi
  792. ;;
  793. "verify-osx-encryption")
  794. REALM_ENCRYPT_ALL=YES sh build.sh test-osx
  795. exit 0
  796. ;;
  797. "verify-osx")
  798. sh build.sh test-osx
  799. sh build.sh examples-osx
  800. (
  801. cd examples/osx/objc/build/DerivedData/RealmExamples/Build/Products/$CONFIGURATION
  802. DYLD_FRAMEWORK_PATH=. ./JSONImport >/dev/null
  803. )
  804. exit 0
  805. ;;
  806. "verify-osx-swift")
  807. sh build.sh test-osx-swift
  808. exit 0
  809. ;;
  810. "verify-ios-static")
  811. sh build.sh test-ios-static
  812. sh build.sh examples-ios
  813. ;;
  814. "verify-ios-dynamic")
  815. sh build.sh test-ios-dynamic
  816. ;;
  817. "verify-ios-swift")
  818. sh build.sh test-ios-swift
  819. sh build.sh examples-ios-swift
  820. ;;
  821. "verify-ios-device-objc")
  822. sh build.sh test-ios-devices-objc
  823. exit 0
  824. ;;
  825. "verify-ios-device-swift")
  826. sh build.sh test-ios-devices-swift
  827. exit 0
  828. ;;
  829. "verify-docs")
  830. sh build.sh docs
  831. for lang in swift objc; do
  832. undocumented="docs/${lang}_output/undocumented.json"
  833. if ruby -rjson -e "j = JSON.parse(File.read('docs/${lang}_output/undocumented.json')); exit j['warnings'].length != 0"; then
  834. echo "Undocumented Realm $lang declarations:"
  835. cat "$undocumented"
  836. exit 1
  837. fi
  838. done
  839. exit 0
  840. ;;
  841. "verify-watchos")
  842. sh build.sh watchos-swift
  843. exit 0
  844. ;;
  845. "verify-tvos")
  846. sh build.sh test-tvos
  847. sh build.sh examples-tvos
  848. exit 0
  849. ;;
  850. "verify-tvos-swift")
  851. sh build.sh test-tvos-swift
  852. sh build.sh examples-tvos-swift
  853. exit 0
  854. ;;
  855. "verify-tvos-device")
  856. sh build.sh test-tvos-devices
  857. exit 0
  858. ;;
  859. "verify-swiftlint")
  860. swiftlint lint --strict
  861. exit 0
  862. ;;
  863. "verify-swiftpm")
  864. sh build.sh test-swiftpm
  865. exit 0
  866. ;;
  867. "verify-osx-object-server")
  868. sh build.sh test-osx-object-server
  869. exit 0
  870. ;;
  871. ######################################
  872. # Docs
  873. ######################################
  874. "docs")
  875. build_docs objc
  876. build_docs swift
  877. exit 0
  878. ;;
  879. ######################################
  880. # Examples
  881. ######################################
  882. "examples")
  883. sh build.sh clean
  884. sh build.sh examples-ios
  885. sh build.sh examples-ios-swift
  886. sh build.sh examples-osx
  887. sh build.sh examples-tvos
  888. sh build.sh examples-tvos-swift
  889. exit 0
  890. ;;
  891. "examples-ios")
  892. sh build.sh prelaunch-simulator
  893. workspace="examples/ios/objc/RealmExamples.xcworkspace"
  894. pod install --project-directory="$workspace/.." --no-repo-update
  895. xc "-workspace $workspace -scheme Simple -configuration $CONFIGURATION -destination 'name=iPhone 8' build ${CODESIGN_PARAMS}"
  896. xc "-workspace $workspace -scheme TableView -configuration $CONFIGURATION -destination 'name=iPhone 8' build ${CODESIGN_PARAMS}"
  897. xc "-workspace $workspace -scheme Migration -configuration $CONFIGURATION -destination 'name=iPhone 8' build ${CODESIGN_PARAMS}"
  898. xc "-workspace $workspace -scheme Backlink -configuration $CONFIGURATION -destination 'name=iPhone 8' build ${CODESIGN_PARAMS}"
  899. xc "-workspace $workspace -scheme GroupedTableView -configuration $CONFIGURATION -destination 'name=iPhone 8' build ${CODESIGN_PARAMS}"
  900. xc "-workspace $workspace -scheme RACTableView -configuration $CONFIGURATION -destination 'name=iPhone 8' build ${CODESIGN_PARAMS}"
  901. xc "-workspace $workspace -scheme Encryption -configuration $CONFIGURATION -destination 'name=iPhone 8' build ${CODESIGN_PARAMS}"
  902. xc "-workspace $workspace -scheme Draw -configuration $CONFIGURATION -destination 'name=iPhone 8' build ${CODESIGN_PARAMS}"
  903. if [ ! -z "${JENKINS_HOME}" ]; then
  904. xc "-workspace $workspace -scheme Extension -configuration $CONFIGURATION -destination 'name=iPhone 8' build ${CODESIGN_PARAMS}"
  905. fi
  906. exit 0
  907. ;;
  908. "examples-ios-swift")
  909. sh build.sh prelaunch-simulator
  910. workspace="examples/ios/swift/RealmExamples.xcworkspace"
  911. if [[ ! -d "$workspace" ]]; then
  912. workspace="${workspace/swift/swift-$REALM_XCODE_VERSION}"
  913. fi
  914. xc "-workspace $workspace -scheme Simple -configuration $CONFIGURATION -destination 'name=iPhone 8' build ${CODESIGN_PARAMS}"
  915. xc "-workspace $workspace -scheme TableView -configuration $CONFIGURATION -destination 'name=iPhone 8' build ${CODESIGN_PARAMS}"
  916. xc "-workspace $workspace -scheme Migration -configuration $CONFIGURATION -destination 'name=iPhone 8' build ${CODESIGN_PARAMS}"
  917. xc "-workspace $workspace -scheme Encryption -configuration $CONFIGURATION -destination 'name=iPhone 8' build ${CODESIGN_PARAMS}"
  918. xc "-workspace $workspace -scheme Backlink -configuration $CONFIGURATION -destination 'name=iPhone 8' build ${CODESIGN_PARAMS}"
  919. xc "-workspace $workspace -scheme GroupedTableView -configuration $CONFIGURATION -destination 'name=iPhone 8' build ${CODESIGN_PARAMS}"
  920. exit 0
  921. ;;
  922. "examples-osx")
  923. xc "-workspace examples/osx/objc/RealmExamples.xcworkspace -scheme JSONImport -configuration ${CONFIGURATION} build ${CODESIGN_PARAMS}"
  924. ;;
  925. "examples-tvos")
  926. workspace="examples/tvos/objc/RealmExamples.xcworkspace"
  927. destination="Apple TV"
  928. xc "-workspace $workspace -scheme DownloadCache -configuration $CONFIGURATION -destination 'name=$destination' build ${CODESIGN_PARAMS}"
  929. xc "-workspace $workspace -scheme PreloadedData -configuration $CONFIGURATION -destination 'name=$destination' build ${CODESIGN_PARAMS}"
  930. exit 0
  931. ;;
  932. "examples-tvos-swift")
  933. workspace="examples/tvos/swift/RealmExamples.xcworkspace"
  934. if [[ ! -d "$workspace" ]]; then
  935. workspace="${workspace/swift/swift-$REALM_XCODE_VERSION}"
  936. fi
  937. destination="Apple TV"
  938. xc "-workspace $workspace -scheme DownloadCache -configuration $CONFIGURATION -destination 'name=$destination' build ${CODESIGN_PARAMS}"
  939. xc "-workspace $workspace -scheme PreloadedData -configuration $CONFIGURATION -destination 'name=$destination' build ${CODESIGN_PARAMS}"
  940. exit 0
  941. ;;
  942. ######################################
  943. # Versioning
  944. ######################################
  945. "get-version")
  946. echo "$(plist_get 'Realm/Realm-Info.plist' 'CFBundleShortVersionString')"
  947. exit 0
  948. ;;
  949. "set-version")
  950. realm_version="$2"
  951. version_files="Realm/Realm-Info.plist"
  952. if [ -z "$realm_version" ]; then
  953. echo "You must specify a version."
  954. exit 1
  955. fi
  956. # The bundle version can contain only three groups of digits separated by periods,
  957. # so strip off any -beta.x tag from the end of the version string.
  958. bundle_version=$(echo "$realm_version" | cut -d - -f 1)
  959. for version_file in $version_files; do
  960. PlistBuddy -c "Set :CFBundleVersion $bundle_version" "$version_file"
  961. PlistBuddy -c "Set :CFBundleShortVersionString $realm_version" "$version_file"
  962. done
  963. sed -i '' "s/^VERSION=.*/VERSION=$realm_version/" dependencies.list
  964. sed -i '' "s/^let coreVersionStr =.*/let coreVersionStr = \"$REALM_CORE_VERSION\"/" Package.swift
  965. sed -i '' "s/^let cocoaVersionStr =.*/let cocoaVersionStr = \"$realm_version\"/" Package.swift
  966. exit 0
  967. ;;
  968. ######################################
  969. # Bitcode Detection
  970. ######################################
  971. "binary-has-bitcode")
  972. # Disable pipefail as grep -q will make otool fail due to exiting
  973. # before reading all the output
  974. set +o pipefail
  975. BINARY="$2"
  976. if otool -l "$BINARY" | grep -q "segname __LLVM"; then
  977. exit 0
  978. fi
  979. # Work around rdar://21826157 by checking for bitcode in thin binaries
  980. # Get architectures for binary
  981. archs="$(lipo -info "$BINARY" | rev | cut -d ':' -f1 | rev)"
  982. archs_array=( $archs )
  983. if [[ ${#archs_array[@]} -lt 2 ]]; then
  984. echo 'Error: Built library is not a fat binary'
  985. exit 1 # Early exit if not a fat binary
  986. fi
  987. TEMPDIR=$(mktemp -d $TMPDIR/realm-bitcode-check.XXXX)
  988. for arch in $archs; do
  989. lipo -thin "$arch" "$BINARY" -output "$TEMPDIR/$arch"
  990. if otool -l "$TEMPDIR/$arch" | grep -q "segname __LLVM"; then
  991. exit 0
  992. fi
  993. done
  994. echo 'Error: Built library does not contain bitcode'
  995. exit 1
  996. ;;
  997. ######################################
  998. # CocoaPods
  999. ######################################
  1000. "cocoapods-setup")
  1001. if [ ! -d core ]; then
  1002. sh build.sh download-sync
  1003. rm core
  1004. mv sync-* core
  1005. mv core/librealm-ios.a core/librealmcore-ios.a
  1006. mv core/librealm-macosx.a core/librealmcore-macosx.a
  1007. mv core/librealm-tvos.a core/librealmcore-tvos.a
  1008. mv core/librealm-watchos.a core/librealmcore-watchos.a
  1009. fi
  1010. if [[ "$2" != "swift" ]]; then
  1011. if [ ! -d Realm/ObjectStore/src ]; then
  1012. cat >&2 <<EOM
  1013. ERROR: One of Realm's submodules is missing!
  1014. If you're using Realm and/or RealmSwift from a git branch, please add 'submodules: true' to
  1015. their entries in your Podfile.
  1016. EOM
  1017. exit 1
  1018. fi
  1019. rm -rf include
  1020. mkdir -p include
  1021. mv core/include include/core
  1022. mkdir -p include/impl/apple include/util/apple include/sync/impl/apple
  1023. cp Realm/*.hpp include
  1024. cp Realm/ObjectStore/src/*.hpp include
  1025. cp Realm/ObjectStore/src/sync/*.hpp include/sync
  1026. cp Realm/ObjectStore/src/sync/impl/*.hpp include/sync/impl
  1027. cp Realm/ObjectStore/src/sync/impl/apple/*.hpp include/sync/impl/apple
  1028. cp Realm/ObjectStore/src/impl/*.hpp include/impl
  1029. cp Realm/ObjectStore/src/impl/apple/*.hpp include/impl/apple
  1030. cp Realm/ObjectStore/src/util/*.hpp include/util
  1031. cp Realm/ObjectStore/src/util/apple/*.hpp include/util/apple
  1032. echo '' > Realm/RLMPlatform.h
  1033. if [ -n "$COCOAPODS_VERSION" ]; then
  1034. # This variable is set for the prepare_command available
  1035. # from the 1.0 prereleases, which requires a different
  1036. # header layout within the header_mappings_dir.
  1037. cp Realm/*.h include
  1038. else
  1039. # For CocoaPods < 1.0, we need to scope the headers within
  1040. # the header_mappings_dir by another subdirectory to avoid
  1041. # Clang from complaining about non-modular headers.
  1042. mkdir -p include/Realm
  1043. cp Realm/*.h include/Realm
  1044. fi
  1045. else
  1046. sh build.sh set-swift-version
  1047. fi
  1048. ;;
  1049. ######################################
  1050. # Continuous Integration
  1051. ######################################
  1052. "ci-pr")
  1053. mkdir -p build/reports
  1054. export REALM_DISABLE_ANALYTICS=1
  1055. export REALM_DISABLE_UPDATE_CHECKER=1
  1056. # FIXME: Re-enable once CI can properly unlock the keychain
  1057. export REALM_DISABLE_METADATA_ENCRYPTION=1
  1058. # strip off the ios|tvos version specifier, e.g. the last part of: `ios-device-objc-ios8`
  1059. if [[ "$target" =~ ^((ios|tvos)-device(-(objc|swift))?)(-(ios|tvos)[[:digit:]]+)?$ ]]; then
  1060. export target=${BASH_REMATCH[1]}
  1061. fi
  1062. if [ "$target" = "docs" ]; then
  1063. sh build.sh set-swift-version
  1064. sh build.sh verify-docs
  1065. elif [ "$target" = "swiftlint" ]; then
  1066. sh build.sh verify-swiftlint
  1067. else
  1068. export sha=$GITHUB_PR_SOURCE_BRANCH
  1069. export CONFIGURATION=$configuration
  1070. export REALM_EXTRA_BUILD_ARGUMENTS='GCC_GENERATE_DEBUGGING_SYMBOLS=NO -allowProvisioningUpdates'
  1071. if [[ ${target} != *"osx"* ]];then
  1072. sh build.sh prelaunch-simulator
  1073. fi
  1074. source $(brew --prefix nvm)/nvm.sh
  1075. export REALM_NODE_PATH="$(nvm which 8)"
  1076. # Reset CoreSimulator.log
  1077. mkdir -p ~/Library/Logs/CoreSimulator
  1078. echo > ~/Library/Logs/CoreSimulator/CoreSimulator.log
  1079. if [ -d ~/Library/Developer/CoreSimulator/Devices/ ]; then
  1080. # Verify that no Realm files still exist
  1081. ! find ~/Library/Developer/CoreSimulator/Devices/ -name '*.realm' | grep -q .
  1082. fi
  1083. failed=0
  1084. sh build.sh verify-$target 2>&1 | tee build/build.log | xcpretty -r junit -o build/reports/junit.xml || failed=1
  1085. if [ "$failed" = "1" ] && cat build/build.log | grep -E 'DTXProxyChannel|DTXChannel|out of date and needs to be rebuilt|operation never finished bootstrapping'; then
  1086. echo "Known Xcode error detected. Running job again."
  1087. if cat build/build.log | grep -E 'out of date and needs to be rebuilt'; then
  1088. rm -rf build/DerivedData
  1089. fi
  1090. failed=0
  1091. sh build.sh verify-$target | tee build/build.log | xcpretty -r junit -o build/reports/junit.xml || failed=1
  1092. elif [ "$failed" = "1" ] && tail ~/Library/Logs/CoreSimulator/CoreSimulator.log | grep -E "Operation not supported|Failed to lookup com.apple.coreservices.lsuseractivity.simulatorsupport"; then
  1093. echo "Known Xcode error detected. Running job again."
  1094. failed=0
  1095. sh build.sh verify-$target | tee build/build.log | xcpretty -r junit -o build/reports/junit.xml || failed=1
  1096. fi
  1097. if [ "$failed" = "1" ]; then
  1098. echo "\n\n***\nbuild/build.log\n***\n\n" && cat build/build.log || true
  1099. echo "\n\n***\nCoreSimulator.log\n***\n\n" && cat ~/Library/Logs/CoreSimulator/CoreSimulator.log
  1100. exit 1
  1101. fi
  1102. fi
  1103. if [ "$target" = "osx" ] && [ "$configuration" = "Debug" ]; then
  1104. gcovr -r . -f ".*Realm.*" -e ".*Tests.*" -e ".*core.*" --xml > build/reports/coverage-report.xml
  1105. WS=$(pwd | sed "s/\//\\\\\//g")
  1106. sed -i ".bak" "s/<source>\./<source>${WS}/" build/reports/coverage-report.xml
  1107. fi
  1108. ;;
  1109. ######################################
  1110. # Release packaging
  1111. ######################################
  1112. "package-examples")
  1113. ./scripts/package_examples.rb
  1114. zip --symlinks -r realm-examples.zip examples -x "examples/installation/*"
  1115. ;;
  1116. "package-test-examples-objc")
  1117. if ! VERSION=$(echo realm-objc-*.zip | egrep -o '\d*\.\d*\.\d*-[a-z]*(\.\d*)?'); then
  1118. VERSION=$(echo realm-objc-*.zip | egrep -o '\d*\.\d*\.\d*')
  1119. fi
  1120. OBJC="realm-objc-${VERSION}"
  1121. unzip ${OBJC}.zip
  1122. cp $0 ${OBJC}
  1123. cp -r ${source_root}/scripts ${OBJC}
  1124. cd ${OBJC}
  1125. sh build.sh examples-ios
  1126. sh build.sh examples-tvos
  1127. sh build.sh examples-osx
  1128. cd ..
  1129. rm -rf ${OBJC}
  1130. ;;
  1131. "package-test-examples-swift")
  1132. if ! VERSION=$(echo realm-swift-*.zip | egrep -o '\d*\.\d*\.\d*-[a-z]*(\.\d*)?'); then
  1133. VERSION=$(echo realm-swift-*.zip | egrep -o '\d*\.\d*\.\d*')
  1134. fi
  1135. SWIFT="realm-swift-${VERSION}"
  1136. unzip ${SWIFT}.zip
  1137. cp $0 ${SWIFT}
  1138. cp -r ${source_root}/scripts ${SWIFT}
  1139. cd ${SWIFT}
  1140. sh build.sh examples-ios-swift
  1141. sh build.sh examples-tvos-swift
  1142. cd ..
  1143. rm -rf ${SWIFT}
  1144. ;;
  1145. "package-ios-static")
  1146. sh build.sh prelaunch-simulator
  1147. sh build.sh ios-static
  1148. cd build/ios-static
  1149. zip --symlinks -r realm-framework-ios-static.zip Realm.framework
  1150. ;;
  1151. "package")
  1152. PLATFORM="$2"
  1153. REALM_SWIFT_VERSION=
  1154. set_xcode_and_swift_versions
  1155. if [[ "$PLATFORM" = "catalyst" ]] && (( $(xcode_version_major) < 11 )); then
  1156. mkdir -p build/catalyst/swift-$REALM_XCODE_VERSION
  1157. else
  1158. sh build.sh prelaunch-simulator
  1159. sh build.sh $PLATFORM-swift
  1160. fi
  1161. cd build/$PLATFORM
  1162. zip --symlinks -r realm-framework-$PLATFORM-$REALM_XCODE_VERSION.zip swift-$REALM_XCODE_VERSION
  1163. ;;
  1164. "package-release")
  1165. LANG="$2"
  1166. TEMPDIR=$(mktemp -d $TMPDIR/realm-release-package-${LANG}.XXXX)
  1167. VERSION=$(sh build.sh get-version)
  1168. FOLDER=${TEMPDIR}/realm-${LANG}-${VERSION}
  1169. mkdir -p ${FOLDER}/osx ${FOLDER}/ios ${FOLDER}/watchos ${FOLDER}/tvos
  1170. if [[ "${LANG}" == "objc" ]]; then
  1171. mkdir -p ${FOLDER}/ios/static
  1172. mkdir -p ${FOLDER}/ios/dynamic
  1173. mkdir -p ${FOLDER}/Swift
  1174. unzip ${WORKSPACE}/realm-framework-ios-static.zip -d ${FOLDER}/ios/static
  1175. for platform in osx ios watchos tvos catalyst; do
  1176. unzip ${WORKSPACE}/realm-framework-${platform}-${REALM_XCODE_VERSION}.zip -d ${FOLDER}/${platform}
  1177. mv ${FOLDER}/${platform}/swift-*/Realm.framework ${FOLDER}/${platform}
  1178. rm -r ${FOLDER}/${platform}/swift-*
  1179. done
  1180. mv ${FOLDER}/ios/Realm.framework ${FOLDER}/ios/dynamic
  1181. else
  1182. for platform in osx ios watchos tvos catalyst; do
  1183. find ${WORKSPACE} -name "realm-framework-$platform-*.zip" \
  1184. -maxdepth 1 \
  1185. -exec unzip {} -d ${FOLDER}/${platform} \;
  1186. done
  1187. fi
  1188. (
  1189. cd ${WORKSPACE}
  1190. cp -R plugin ${FOLDER}
  1191. cp LICENSE ${FOLDER}/LICENSE.txt
  1192. if [[ "${LANG}" == "objc" ]]; then
  1193. cp Realm/Swift/RLMSupport.swift ${FOLDER}/Swift/
  1194. fi
  1195. )
  1196. (
  1197. cd ${FOLDER}
  1198. unzip ${WORKSPACE}/realm-examples.zip
  1199. cd examples
  1200. if [[ "${LANG}" == "objc" ]]; then
  1201. rm -rf ios/swift-* tvos/swift-*
  1202. else
  1203. rm -rf ios/objc ios/rubymotion osx tvos/objc
  1204. fi
  1205. )
  1206. cat > ${FOLDER}/docs.webloc <<EOF
  1207. <?xml version="1.0" encoding="UTF-8"?>
  1208. <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  1209. <plist version="1.0">
  1210. <dict>
  1211. <key>URL</key>
  1212. <string>https://realm.io/docs/${LANG}/${VERSION}</string>
  1213. </dict>
  1214. </plist>
  1215. EOF
  1216. (
  1217. cd ${TEMPDIR}
  1218. zip --symlinks -r realm-${LANG}-${VERSION}.zip realm-${LANG}-${VERSION}
  1219. mv realm-${LANG}-${VERSION}.zip ${WORKSPACE}
  1220. )
  1221. ;;
  1222. "test-package-release")
  1223. # Generate a release package locally for testing purposes
  1224. # Real releases should always be done via Jenkins
  1225. if [ -z "${WORKSPACE}" ]; then
  1226. echo 'WORKSPACE must be set to a directory to assemble the release in'
  1227. exit 1
  1228. fi
  1229. if [ -d "${WORKSPACE}" ]; then
  1230. echo 'WORKSPACE directory should not already exist'
  1231. exit 1
  1232. fi
  1233. REALM_SOURCE="$(pwd)"
  1234. mkdir -p "$WORKSPACE"
  1235. WORKSPACE="$(cd "$WORKSPACE" && pwd)"
  1236. export WORKSPACE
  1237. cd $WORKSPACE
  1238. git clone --recursive $REALM_SOURCE realm-cocoa
  1239. cd realm-cocoa
  1240. echo 'Packaging iOS'
  1241. sh build.sh package-ios-static
  1242. cp build/ios-static/realm-framework-ios-static.zip .
  1243. sh build.sh package ios
  1244. cp build/ios/realm-framework-ios-$REALM_XCODE_VERSION.zip .
  1245. echo 'Packaging macOS'
  1246. sh build.sh package osx
  1247. cp build/osx/realm-framework-osx-$REALM_XCODE_VERSION.zip .
  1248. echo 'Packaging watchOS'
  1249. sh build.sh package watchos
  1250. cp build/watchos/realm-framework-watchos-$REALM_XCODE_VERSION.zip .
  1251. echo 'Packaging tvOS'
  1252. sh build.sh package tvos
  1253. cp build/tvos/realm-framework-tvos-$REALM_XCODE_VERSION.zip .
  1254. echo 'Packaging Catalyst'
  1255. sh build.sh package catalyst
  1256. cp build/catalyst/realm-framework-catalyst-$REALM_XCODE_VERSION.zip .
  1257. echo 'Packaging examples'
  1258. sh build.sh package-examples
  1259. echo 'Building final release packages'
  1260. export WORKSPACE="${WORKSPACE}/realm-cocoa"
  1261. sh build.sh package-release objc
  1262. sh build.sh package-release swift
  1263. echo 'Testing packaged examples'
  1264. sh build.sh package-test-examples-objc
  1265. sh build.sh package-test-examples-swift
  1266. ;;
  1267. "github-release")
  1268. if [ -z "${GITHUB_ACCESS_TOKEN}" ]; then
  1269. echo 'GITHUB_ACCESS_TOKEN must be set to create GitHub releases'
  1270. exit 1
  1271. fi
  1272. ./scripts/github_release.rb
  1273. ;;
  1274. "add-empty-changelog")
  1275. empty_section=$(cat <<EOS
  1276. x.y.z Release notes (yyyy-MM-dd)
  1277. =============================================================
  1278. ### Enhancements
  1279. * None.
  1280. ### Fixed
  1281. * <How to hit and notice issue? what was the impact?> ([#????](https://github.com/realm/realm-js/issues/????), since v?.?.?)
  1282. * None.
  1283. <!-- ### Breaking Changes - ONLY INCLUDE FOR NEW MAJOR version -->
  1284. ### Compatibility
  1285. * File format: Generates Realms with format v9 (Reads and upgrades all previous formats)
  1286. * Realm Object Server: 3.21.0 or later.
  1287. * APIs are backwards compatible with all previous releases in the 3.x.y series.
  1288. * Carthage release for Swift is built with Xcode 11.0.
  1289. EOS)
  1290. changelog=$(cat CHANGELOG.md)
  1291. echo "$empty_section" > CHANGELOG.md
  1292. echo >> CHANGELOG.md
  1293. echo "$changelog" >> CHANGELOG.md
  1294. ;;
  1295. *)
  1296. echo "Unknown command '$COMMAND'"
  1297. usage
  1298. exit 1
  1299. ;;
  1300. esac