build.sh 54 KB

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