Slide 1

Slide 1 text

Bringing CocoaPods to Linux NSSpain, September 2015 Boris Bügling - @NeoNacho

Slide 2

Slide 2 text

CocoaPods dependency management ✅

Slide 3

Slide 3 text

Contentful content management ✅

Slide 4

Slide 4 text

Xcode?

Slide 5

Slide 5 text

Agenda 4 Why? 4 Xcode's build system 4 How does CocoaPods interact with it? 4 Alternatives 4 Plan

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

No Xcode on Linux

Slide 10

Slide 10 text

Xcode is broken

Slide 11

Slide 11 text

ya tu sabes

Slide 12

Slide 12 text

Quora Post from early 2014

Slide 13

Slide 13 text

Just two examples 4 Archiving watchOS 2.0 apps 4 CLANG_ENABLE_MODULES

Slide 14

Slide 14 text

[Xcode 7 beta] Linking dual (iphoneos and watchos) frameworks with same product name causes archive to fail http://openradar.appspot.com/22392501

Slide 15

Slide 15 text

No content

Slide 16

Slide 16 text

CLANG_ENABLE_MODULES

Slide 17

Slide 17 text

Enables the use of modules for system APIs. System headers are imported as semantic modules instead of raw headers.

Slide 18

Slide 18 text

"system APIs" == any framework outside your target !

Slide 19

Slide 19 text

No content

Slide 20

Slide 20 text

Bring back CocoaPods to its core and move rest (e.g. Xcode integration) into plugins. #2729 From October 2014 https://github.com/CocoaPods/CocoaPods/issues/ 2729

Slide 21

Slide 21 text

Solve everyday problems for Cocoa and Xcode developers.

Slide 22

Slide 22 text

Let's face it, programming sucks.

Slide 23

Slide 23 text

Xcode's build system

Slide 24

Slide 24 text

4 Fairly old (Xcode3Core.ideplugin) 4 Entirely based on mtimes 4 Poorly documented

Slide 25

Slide 25 text

De-facto documentation 4 http://pewpewthespells.com/blog/ managing_xcode.html 4 http://pewpewthespells.com/blog/ buildsettings.html

Slide 26

Slide 26 text

Xcode project files !"#

Slide 27

Slide 27 text

Tomorrow 16:30 - 17:00 Grant Paul - Making Sense of Xcode

Slide 28

Slide 28 text

How does CocoaPods interact with it?

Slide 29

Slide 29 text

4 Pods project 4 Integration into the user project 4 Linting

Slide 30

Slide 30 text

Pods project 4 Generated by our Xcodeproj gem 4 Targets for all Pods 4 XCConfig files

Slide 31

Slide 31 text

Private XCConfig #include "ContentfulDeliveryAPI.xcconfig" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/ContentfulDeliveryAPI" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/Bypass" "${PODS_ROOT}/Headers/Public/CGLMail" "${PODS_ROOT}/Headers/Public/ContentfulDeliveryAPI" "${PODS_ROOT}/Headers/Public/ContentfulDialogs" "${PODS_ROOT}/Headers/Public/ContentfulPersistence" "${PODS_ROOT}/Headers/Public/ContentfulStyle" "${PODS_ROOT}/Headers/Public/DDPageControl" "${PODS_ROOT}/Headers/Public/EDColor" "${PODS_ROOT}/Headers/Public/FBSnapshotTestCase" "${PODS_ROOT}/Headers/Public/ISO8601DateFormatter" "${PODS_ROOT}/Headers/Public/LatoFont" "${PODS_ROOT}/Headers/Public/TSMiniWebBrowser@dblock" OTHER_LDFLAGS = ${CONTENTFULDELIVERYAPI_OTHER_LDFLAGS} -ObjC PODS_ROOT = ${SRCROOT} SKIP_INSTALL = YES

Slide 32

Slide 32 text

Build settings 4 GCC_PREPROCESSOR_DEFINITIONS 4 HEADER_SEARCH_PATHS 4 OTHER_LDFLAGS

Slide 33

Slide 33 text

No content

Slide 34

Slide 34 text

User project 4 Optional integration (--no-integrate) 4 Implicit target dependencies 4 XCConfig files

Slide 35

Slide 35 text

Public XCConfig CONTENTFULDELIVERYAPI_OTHER_LDFLAGS = -framework "MapKit" -framework "UIKit"

Slide 36

Slide 36 text

If you edit OTHER_LDFLAGS in your project, settings will be copied.

Slide 37

Slide 37 text

Build phases

Slide 38

Slide 38 text

Linting 4 Shells out to xcodebuild

Slide 39

Slide 39 text

Alternatives

Slide 40

Slide 40 text

Makefiles

Slide 41

Slide 41 text

package: $(EXECUTABLE_NAME) $(INFO_PLIST) mkdir -p "$(PRODUCT_NAME).app" @/bin/echo -n 'AAPL' > "$(PRODUCT_NAME).app/PkgInfo" @$(PLBUDDY) -c 'Print CFBundleSignature' $(INFO_PLIST) \ >> "$(PRODUCT_NAME).app/PkgInfo" cp $(EXECUTABLE_NAME) "$(PRODUCT_NAME).app" $(BASE_DIR)/sh/build_plist $(INFO_PLIST) "$(PRODUCT_NAME).app/Info.plist" $(BASE_DIR)/sh/build_ipa "$(PRODUCT_NAME).app" $(EXECUTABLE_NAME): $(OBJS) $(LD) $(CFLAGS) $(LDFLAGS) -o $@ $^

Slide 42

Slide 42 text

Makefiles 4 Build rules to transform files (e.g. .m => .o) 4 Based on mtimes 4 "Phony" rules which run unconditionally 4 Dependencies to files or other rules 4 Exists everywhere

Slide 43

Slide 43 text

Rules target: dependencies build step(s)

Slide 44

Slide 44 text

Execution make [options] [target1 target2 ...]

Slide 45

Slide 45 text

Buck

Slide 46

Slide 46 text

No content

Slide 47

Slide 47 text

No content

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

No content

Slide 50

Slide 50 text

No content

Slide 51

Slide 51 text

=> no more DerivedData nonsense !

Slide 52

Slide 52 text

Installation $ brew update $ brew tap facebook/fb $ brew install --HEAD buck

Slide 53

Slide 53 text

Quickstart $ buck quickstart --type ios --dest-dir . [...] $ buck build demo_app_ios [...] $ ls buck-out/gen/ios/BuckDemoApp BuckDemoApp.app BuckDemoApp.dSYM

Slide 54

Slide 54 text

Initial build $ buck build demo_app_ios [...] [-] BUILDING...FINISHED 2.4s (8/8 JOBS, 8 UPDATED, 0.0% CACHE HITS) Subsequent builds $ buck build demo_app_ios [...] [-] BUILDING...FINISHED 0.0s (1/8 JOBS, 0 UPDATED)

Slide 55

Slide 55 text

Faster iterations

Slide 56

Slide 56 text

BUCK apple_binary( [...] ) xcode_project_config( name = 'Hello', src_target = ':Hello', action_config_names={'profile': 'Profile'} )

Slide 57

Slide 57 text

Source files srcs = [ 'Code/AppDelegate.m' 'Code/ViewController.m', 'Code/main.m', ],

Slide 58

Slide 58 text

Headers headers = [ 'Code/AppDelegate.h' 'Code/ViewController.h', ],

Slide 59

Slide 59 text

Linked frameworks frameworks = [ '$SDKROOT/System/Library/Frameworks/Foundation.framework', '$SDKROOT/System/Library/Frameworks/UIKit.framework', ],

Slide 60

Slide 60 text

Dependencies deps = [ '//Libraries/EXExample:EXExample', ],

Slide 61

Slide 61 text

Buck does not support Swift !

Slide 62

Slide 62 text

Plan

Slide 63

Slide 63 text

Plan 4 Prototype with plugins ! 4 Abstraction for the build system 4 Mapping for build settings (*_xcconfig attributes) 4 ??? 4 Profit!

Slide 64

Slide 64 text

Add a new platform

Slide 65

Slide 65 text

Adding a new platform (tvos)

Slide 66

Slide 66 text

Gemfile source 'https://rubygems.org' gem 'cocoapods', :git => 'https://github.com/CocoaPods/CocoaPods.git', :branch => 'tvos' gem 'cocoapods-core', :git => 'https://github.com/CocoaPods/Core.git', :branch => 'tvos-support' gem 'xcodeproj', :git => 'https://github.com/CocoaPods/Xcodeproj.git', :branch => 'tvos-support' Usage: $ bundle exec pod install

Slide 67

Slide 67 text

Xcode is a leaky abstraction, try to learn what's underneath it.

Slide 68

Slide 68 text

Thanks!

Slide 69

Slide 69 text

https://www.facebook.com/events/ 1495505997428211/ _ @NeoNacho [email protected] http://buegling.com/talks