build.sh 55 KB

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