build.sh 56 KB

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