cocoapods-precompile 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,41 @@
1
+ require_relative '../tool/tool'
2
+
3
+ module Pod
4
+ class Prebuild
5
+
6
+ # Pass the data between the 2 steps
7
+ #
8
+ # At step 2, the normal pod install, it needs some info of the
9
+ # prebuilt step. So we store it here.
10
+ #
11
+ class Passer
12
+
13
+ # indicate the add/remove/update of prebuit pods
14
+ # @return [Analyzer::SpecsState]
15
+ #
16
+ class_attr_accessor :prebuild_pods_changes
17
+
18
+
19
+ # represent the path of resurces to copy
20
+ class ResourcePath
21
+ attr_accessor :real_file_path
22
+ attr_accessor :target_file_path
23
+ end
24
+ # Save the resoures for static framework, and used when installing the prebuild framework
25
+ # static framework needs copy the resurces mannully
26
+ #
27
+ # @return [Hash<String, [Passer::ResourcePath]>]
28
+ class_attr_accessor :resources_to_copy_for_static_framework
29
+ self.resources_to_copy_for_static_framework = {}
30
+
31
+ # Some pod won't be build in prebuild stage even if it have `binary=>true`.
32
+ # The targets of this pods have `oshould_build? == true`.
33
+ # We should skip integration (patch spec) for this pods
34
+ #
35
+ # @return [Array<String>]
36
+ class_attr_accessor :target_names_to_skip_integration_framework
37
+ self.target_names_to_skip_integration_framework = []
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,130 @@
1
+ module Pod
2
+
3
+ class Prebuild
4
+ def self.keyword
5
+ :binary
6
+ end
7
+ end
8
+
9
+ class Podfile
10
+ class TargetDefinition
11
+
12
+ ## --- option for setting using prebuild framework ---
13
+ def parse_prebuild_framework(name, requirements)
14
+
15
+ should_prebuild = Pod::Podfile::DSL.prebuild_all
16
+
17
+ options = requirements.last
18
+ if options.is_a?(Hash) && options[Pod::Prebuild.keyword] != nil
19
+ should_prebuild = options.delete(Pod::Prebuild.keyword)
20
+ requirements.pop if options.empty?
21
+ end
22
+
23
+ pod_name = Specification.root_name(name)
24
+ set_prebuild_for_pod(pod_name, should_prebuild)
25
+ end
26
+
27
+ def set_prebuild_for_pod(pod_name, should_prebuild)
28
+
29
+ if should_prebuild == true
30
+ @prebuild_framework_pod_names ||= []
31
+ @prebuild_framework_pod_names.push pod_name
32
+ else
33
+ @should_not_prebuild_framework_pod_names ||= []
34
+ @should_not_prebuild_framework_pod_names.push pod_name
35
+ end
36
+ end
37
+
38
+ def prebuild_framework_pod_names
39
+ names = @prebuild_framework_pod_names || []
40
+ if parent != nil and parent.kind_of? TargetDefinition
41
+ names += parent.prebuild_framework_pod_names
42
+ end
43
+ names
44
+ end
45
+ def should_not_prebuild_framework_pod_names
46
+ names = @should_not_prebuild_framework_pod_names || []
47
+ if parent != nil and parent.kind_of? TargetDefinition
48
+ names += parent.should_not_prebuild_framework_pod_names
49
+ end
50
+ names
51
+ end
52
+
53
+ # ---- patch method ----
54
+ # We want modify `store_pod` method, but it's hard to insert a line in the
55
+ # implementation. So we patch a method called in `store_pod`.
56
+ old_method = instance_method(:parse_inhibit_warnings)
57
+
58
+ define_method(:parse_inhibit_warnings) do |name, requirements|
59
+ parse_prebuild_framework(name, requirements)
60
+ old_method.bind(self).(name, requirements)
61
+ end
62
+
63
+ end
64
+ end
65
+ end
66
+
67
+
68
+ module Pod
69
+ class Installer
70
+
71
+ def prebuild_pod_targets
72
+ @prebuild_pod_targets ||= (
73
+ all = []
74
+
75
+ aggregate_targets = self.aggregate_targets
76
+ aggregate_targets.each do |aggregate_target|
77
+ target_definition = aggregate_target.target_definition
78
+ targets = aggregate_target.pod_targets || []
79
+
80
+ # filter prebuild
81
+ prebuild_names = target_definition.prebuild_framework_pod_names
82
+ if not Podfile::DSL.prebuild_all
83
+ targets = targets.select { |pod_target| prebuild_names.include?(pod_target.pod_name) }
84
+ end
85
+ dependency_targets = targets.map {|t| t.recursive_dependent_targets }.flatten.uniq || []
86
+ targets = (targets + dependency_targets).uniq
87
+
88
+ # filter should not prebuild
89
+ explict_should_not_names = target_definition.should_not_prebuild_framework_pod_names
90
+ targets = targets.reject { |pod_target| explict_should_not_names.include?(pod_target.pod_name) }
91
+
92
+ all += targets
93
+ end
94
+
95
+ all = all.reject {|pod_target| sandbox.local?(pod_target.pod_name) }
96
+ all.uniq
97
+ )
98
+ end
99
+
100
+ # the root names who needs prebuild, including dependency pods.
101
+ def prebuild_pod_names
102
+ @prebuild_pod_names ||= self.prebuild_pod_targets.map(&:pod_name)
103
+ end
104
+
105
+
106
+ def validate_every_pod_only_have_one_form
107
+
108
+ multi_targets_pods = self.pod_targets.group_by do |t|
109
+ t.pod_name
110
+ end.select do |k, v|
111
+ v.map{|t| t.platform.name }.count > 1
112
+ end
113
+
114
+ multi_targets_pods = multi_targets_pods.reject do |name, targets|
115
+ contained = targets.map{|t| self.prebuild_pod_targets.include? t }
116
+ contained.uniq.count == 1 # all equal
117
+ end
118
+
119
+ return if multi_targets_pods.empty?
120
+
121
+ warnings = "One pod can only be prebuilt or not prebuilt. These pod have different forms in multiple targets:\n"
122
+ warnings += multi_targets_pods.map{|name, targets| " #{name}: #{targets.map{|t|t.platform.name}}"}.join("\n")
123
+ raise Informative, warnings
124
+ end
125
+
126
+ end
127
+ end
128
+
129
+
130
+
@@ -0,0 +1,73 @@
1
+ require_relative "names"
2
+
3
+ module Pod
4
+ class PrebuildSandbox < Sandbox
5
+
6
+ # [String] standard_sandbox_path
7
+ def self.from_standard_sanbox_path(path)
8
+ prebuild_sandbox_path = Pathname.new(path).realpath + "_Prebuild"
9
+ self.new(prebuild_sandbox_path)
10
+ end
11
+
12
+ def self.from_standard_sandbox(sandbox)
13
+ self.from_standard_sanbox_path(sandbox.root)
14
+ end
15
+
16
+ def standard_sanbox_path
17
+ self.root.parent
18
+ end
19
+
20
+ def generate_framework_path
21
+ self.root + "GeneratedFrameworks"
22
+ end
23
+
24
+ # @param name [String] pass the target.name (may containing platform suffix)
25
+ # @return [Pathname] the folder containing the framework file.
26
+ def framework_folder_path_for_target_name(name)
27
+ self.generate_framework_path + name
28
+ end
29
+
30
+
31
+ def exsited_framework_target_names
32
+ exsited_framework_name_pairs.map {|pair| pair[0]}.uniq
33
+ end
34
+ def exsited_framework_pod_names
35
+ exsited_framework_name_pairs.map {|pair| pair[1]}.uniq
36
+ end
37
+ def existed_target_names_for_pod_name(pod_name)
38
+ exsited_framework_name_pairs.select {|pair| pair[1] == pod_name }.map { |pair| pair[0]}
39
+ end
40
+
41
+
42
+
43
+ def save_pod_name_for_target(target)
44
+ folder = framework_folder_path_for_target_name(target.name)
45
+ return unless folder.exist?
46
+ flag_file_path = folder + "#{target.pod_name}.pod_name"
47
+ File.write(flag_file_path.to_s, "")
48
+ end
49
+
50
+
51
+ private
52
+
53
+ def pod_name_for_target_folder(target_folder_path)
54
+ name = Pathname.new(target_folder_path).children.find do |child|
55
+ child.to_s.end_with? ".pod_name"
56
+ end
57
+ name = name.basename(".pod_name").to_s unless name.nil?
58
+ name ||= Pathname.new(target_folder_path).basename.to_s # for compatibility with older version
59
+ end
60
+
61
+ # Array<[target_name, pod_name]>
62
+ def exsited_framework_name_pairs
63
+ return [] unless generate_framework_path.exist?
64
+ generate_framework_path.children().map do |framework_path|
65
+ if framework_path.directory? && (not framework_path.children.empty?)
66
+ [framework_path.basename.to_s, pod_name_for_target_folder(framework_path)]
67
+ else
68
+ nil
69
+ end
70
+ end.reject(&:nil?).uniq
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,138 @@
1
+ require 'fourflusher'
2
+
3
+ CONFIGURATION = "Release"
4
+ PLATFORMS = { 'iphonesimulator' => 'iOS',
5
+ 'appletvsimulator' => 'tvOS',
6
+ 'watchsimulator' => 'watchOS' }
7
+
8
+ # Build specific target to framework file
9
+ # @param [PodTarget] target
10
+ # a specific pod target
11
+ #
12
+ def build_for_iosish_platform(sandbox,
13
+ build_dir,
14
+ output_path,
15
+ target,
16
+ device,
17
+ simulator,
18
+ bitcode_enabled,
19
+ simulator_default_arch)
20
+
21
+ deployment_target = target.platform.deployment_target.to_s
22
+
23
+ target_label = target.label # name with platform if it's used in multiple platforms
24
+ Pod::UI.puts "Prebuilding #{target_label}..."
25
+
26
+ other_options = []
27
+ if bitcode_enabled
28
+ other_options += ['OTHER_CFLAGS="-fembed-bitcode"']
29
+ end
30
+ xcodebuild(sandbox, target_label, device, deployment_target, other_options)
31
+ xcodebuild(sandbox, target_label, simulator, deployment_target, other_options + ["ARCHS=#{simulator_default_arch}",'ONLY_ACTIVE_ARCH=NO'])
32
+
33
+ # paths
34
+ target_name = target.name # equals target.label, like "AFNeworking-iOS" when AFNetworking is used in multiple platforms.
35
+ module_name = target.product_module_name
36
+ device_framwork_path = "#{build_dir}/#{CONFIGURATION}-#{device}/#{target_name}/#{module_name}.framework"
37
+ simulator_framwork_path = "#{build_dir}/#{CONFIGURATION}-#{simulator}/#{target_name}/#{module_name}.framework"
38
+
39
+ device_binary = device_framwork_path + "/#{module_name}"
40
+ simulator_binary = simulator_framwork_path + "/#{module_name}"
41
+ return unless File.file?(device_binary) && File.file?(simulator_binary)
42
+
43
+ # the device_lib path is the final output file path
44
+ # combine the bianries
45
+ tmp_lipoed_binary_path = "#{build_dir}/#{target_name}"
46
+ lipo_log = `lipo -create -output #{tmp_lipoed_binary_path} #{device_binary} #{simulator_binary}`
47
+ puts lipo_log unless File.exist?(tmp_lipoed_binary_path)
48
+ FileUtils.mv tmp_lipoed_binary_path, device_binary, :force => true
49
+
50
+ # collect the swiftmodule file for various archs.
51
+ device_swiftmodule_path = device_framwork_path + "/Modules/#{module_name}.swiftmodule"
52
+ simulator_swiftmodule_path = simulator_framwork_path + "/Modules/#{module_name}.swiftmodule"
53
+ if File.exist?(device_swiftmodule_path)
54
+ FileUtils.cp_r simulator_swiftmodule_path + "/.", device_swiftmodule_path
55
+ end
56
+
57
+ # output
58
+ output_path.mkpath unless output_path.exist?
59
+ FileUtils.mv device_framwork_path, output_path, :force => true
60
+
61
+ end
62
+
63
+ def xcodebuild(sandbox, target, sdk='macosx', deployment_target=nil, other_options=[])
64
+ args = %W(-project #{sandbox.project_path.realdirpath} -scheme #{target} -configuration #{CONFIGURATION} -sdk #{sdk} )
65
+ platform = PLATFORMS[sdk]
66
+ args += Fourflusher::SimControl.new.destination(:oldest, platform, deployment_target) unless platform.nil?
67
+ args += other_options
68
+ Pod::Executable.execute_command 'xcodebuild', args, true
69
+ end
70
+
71
+
72
+
73
+ module Pod
74
+ class Prebuild
75
+
76
+ # Build the frameworks with sandbox and targets
77
+ #
78
+ # @param [String] sandbox_root_path
79
+ # The sandbox root path where the targets project place
80
+ #
81
+ # [PodTarget] target
82
+ # The pod targets to build
83
+ #
84
+ # [Pathname] output_path
85
+ # output path for generated frameworks
86
+ #
87
+ def self.build(sandbox_root_path, target, output_path, bitcode_enabled = false)
88
+
89
+ return unless not target == nil
90
+
91
+ sandbox_root = Pathname(sandbox_root_path)
92
+ sandbox = Pod::Sandbox.new(sandbox_root)
93
+ build_dir = self.build_dir(sandbox_root)
94
+
95
+ # -- build the framework
96
+ case target.platform.name
97
+ when :ios then build_for_iosish_platform(sandbox, build_dir, output_path, target, 'iphoneos', 'iphonesimulator', bitcode_enabled, "x86_64")
98
+ when :osx then xcodebuild(sandbox, target.label)
99
+ # when :tvos then build_for_iosish_platform(sandbox, build_dir, target, 'appletvos', 'appletvsimulator')
100
+ when :watchos then build_for_iosish_platform(sandbox, build_dir, output_path, target, 'watchos', 'watchsimulator', true, "i386")
101
+ else raise "Unsupported platform for '#{target.name}': '#{target.platform.name}'" end
102
+
103
+ raise Pod::Informative, 'The build directory was not found in the expected location.' unless build_dir.directory?
104
+
105
+ # # --- copy the vendored libraries and framework
106
+ # frameworks = build_dir.children.select{ |path| File.extname(path) == ".framework" }
107
+ # Pod::UI.puts "Built #{frameworks.count} #{'frameworks'.pluralize(frameworks.count)}"
108
+
109
+ # pod_target = target
110
+ # consumer = pod_target.root_spec.consumer(pod_target.platform.name)
111
+ # file_accessor = Pod::Sandbox::FileAccessor.new(sandbox.pod_dir(pod_target.pod_name), consumer)
112
+ # frameworks += file_accessor.vendored_libraries
113
+ # frameworks += file_accessor.vendored_frameworks
114
+
115
+ # frameworks.uniq!
116
+
117
+ # frameworks.each do |framework|
118
+ # FileUtils.mkdir_p destination
119
+ # FileUtils.cp_r framework, destination, :remove_destination => true
120
+ # end
121
+ # build_dir.rmtree if build_dir.directory?
122
+ end
123
+
124
+ def self.remove_build_dir(sandbox_root)
125
+ path = build_dir(sandbox_root)
126
+ path.rmtree if path.exist?
127
+ end
128
+
129
+ private
130
+
131
+ def self.build_dir(sandbox_root)
132
+ # don't know why xcode chose this folder
133
+ sandbox_root.parent + 'build'
134
+ end
135
+
136
+ end
137
+ end
138
+
@@ -0,0 +1,12 @@
1
+ # attr_accessor for class variable.
2
+ # usage:
3
+ #
4
+ # ```
5
+ # class Pod
6
+ # class_attr_accessor :is_prebuild_stage
7
+ # end
8
+ # ```
9
+ #
10
+ def class_attr_accessor(symbol)
11
+ self.class.send(:attr_accessor, symbol)
12
+ end
@@ -0,0 +1 @@
1
+ require 'cocoapods-binary/gem_version'
@@ -0,0 +1,2 @@
1
+ require 'cocoapods-binary/Main'
2
+
@@ -0,0 +1,50 @@
1
+ require 'pathname'
2
+ ROOT = Pathname.new(File.expand_path('../../', __FILE__))
3
+ $:.unshift((ROOT + 'lib').to_s)
4
+ $:.unshift((ROOT + 'spec').to_s)
5
+
6
+ require 'bundler/setup'
7
+ require 'bacon'
8
+ require 'mocha-on-bacon'
9
+ require 'pretty_bacon'
10
+ require 'pathname'
11
+ require 'cocoapods'
12
+
13
+ Mocha::Configuration.prevent(:stubbing_non_existent_method)
14
+
15
+ require 'cocoapods_plugin'
16
+
17
+ #-----------------------------------------------------------------------------#
18
+
19
+ module Pod
20
+
21
+ # Disable the wrapping so the output is deterministic in the tests.
22
+ #
23
+ UI.disable_wrap = true
24
+
25
+ # Redirects the messages to an internal store.
26
+ #
27
+ module UI
28
+ @output = ''
29
+ @warnings = ''
30
+
31
+ class << self
32
+ attr_accessor :output
33
+ attr_accessor :warnings
34
+
35
+ def puts(message = '')
36
+ @output << "#{message}\n"
37
+ end
38
+
39
+ def warn(message = '', actions = [])
40
+ @warnings << "#{message}\n"
41
+ end
42
+
43
+ def print(message)
44
+ @output << message
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ #-----------------------------------------------------------------------------#