build.sh 57 KB

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