Class: Pod::Installer

Inherits:
Object
  • Object
show all
Defined in:
lib/cocoapods-xlbuild/helper/feature_switches.rb,
lib/cocoapods-xlbuild/Prebuild.rb,
lib/cocoapods-xlbuild/Integration.rb,
lib/cocoapods-xlbuild/Integration.rb,
lib/cocoapods-xlbuild/helper/podfile_options.rb,
lib/cocoapods-xlbuild/helper/feature_switches.rb,
lib/cocoapods-xlbuild/Reference/reference_source_code.rb

Overview

a option to disable install complete message

Defined Under Namespace

Classes: PodSourceInstaller, PostInstallHooksContext

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.disable_install_complete_message(value) ⇒ Object



65
66
67
# File 'lib/cocoapods-xlbuild/helper/feature_switches.rb', line 65

def self.disable_install_complete_message(value)
    @@disable_install_complete_message = value
end

.force_disable_integration(value) ⇒ Object



50
51
52
# File 'lib/cocoapods-xlbuild/helper/feature_switches.rb', line 50

def self.force_disable_integration(value)
    @@force_disable_integration = value
end

Instance Method Details

#have_exact_prebuild_cache?Boolean

check if need to prebuild

Returns:

  • (Boolean)


38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/cocoapods-xlbuild/Prebuild.rb', line 38

def have_exact_prebuild_cache?
    # check if need build frameworks
    return false if local_manifest == nil
    
    changes = prebuild_pods_changes
    added = changes.added
    changed = changes.changed 
    unchanged = changes.unchanged
    deleted = changes.deleted 
    
    exsited_framework_pod_names = sandbox.exsited_framework_pod_names
    missing = unchanged.select do |pod_name|
        not exsited_framework_pod_names.include?(pod_name)
    end

    needed = (added + changed + deleted + missing)
    return needed.empty?
end

#install_when_cache_hit!Object

The install method when have completed cache



59
60
61
62
63
64
# File 'lib/cocoapods-xlbuild/Prebuild.rb', line 59

def install_when_cache_hit!
    # just print log
    self.sandbox.exsited_framework_target_names.each do |name|
        UI.puts "Using #{name}"
    end
end

#prebuild_frameworks!Object

Build the needed framework files



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
# File 'lib/cocoapods-xlbuild/Prebuild.rb', line 67

def prebuild_frameworks! 
    # build options
    sandbox_path = sandbox.root
    existed_framework_folder = sandbox.generate_framework_path
    bitcode_enabled = Pod::Podfile::DSL.bitcode_enabled
    use_static_framework = Pod::Podfile::DSL.static_binary
    targets = []
    
    if local_manifest != nil
        changes = prebuild_pods_changes
        added = changes.added
        changed = changes.changed 
        unchanged = changes.unchanged
        deleted = changes.deleted 
    
        existed_framework_folder.mkdir unless existed_framework_folder.exist?
        exsited_framework_pod_names = sandbox.exsited_framework_pod_names
    
        # additions
        missing = unchanged.select do |pod_name|
            not exsited_framework_pod_names.include?(pod_name)
        end
        root_names_to_update = (added + changed + missing).uniq
        # 生成预编译target
        cache = []
        targets = root_names_to_update.map do |pod_name|
            tars = Pod.fast_get_targets_for_pod_name(pod_name, self.pod_targets, cache)
            if tars.nil?
                tars = []
            end
            tars
        end.flatten

        # 添加依赖
        dependency_targets = targets.map {|t| t.recursive_dependent_targets }.flatten.uniq || []
        dependency_targets = dependency_targets.select do |tar|
            sandbox.existed_target_version_for_pod_name(tar.pod_name) != tar.version
        end
        targets = (targets + dependency_targets).uniq
    else
        targets = self.pod_targets
    end

    targets = targets.reject {|pod_target| sandbox.local?(pod_target.pod_name) }

    
    # build!
    Pod::UI.puts "Prebuild frameworks (total #{targets.count})"
    Pod::Prebuild.remove_build_dir(sandbox_path)
    targets.each do |target|
        #linpeng edit  + target.version
        @sandbox_framework_folder_path_for_target_name = sandbox.framework_folder_path_for_target_name(target.name)
        output_path = @sandbox_framework_folder_path_for_target_name
        output_path.rmtree if output_path.exist?
        if !target.should_build?
            UI.puts "Prebuilding #{target.label}"
            next
        end
        output_path.mkpath unless output_path.exist?

        #local cache
        localCachePathRoot = Pod::Podfile::DSL.local_frameworks_cache_path
        is_static_binary = Pod::Podfile::DSL.static_binary
        type_frameworks_dir = is_static_binary ? "static" : "dynamic"
        is_has_local_cache = localCachePathRoot != nil
        if not is_has_local_cache
            #开始使用XcodeBuild进行编译静态库
            Pod::Prebuild.build(sandbox_path, target, output_path, bitcode_enabled,  Podfile::DSL.custom_build_options,  Podfile::DSL.custom_build_options_simulator)
        else
            targetFrameworkPath = localCachePathRoot + "/#{type_frameworks_dir}/#{target.name}/#{target.version}"
            if Dir.exist?(targetFrameworkPath)
                puts "[XL].本地缓存仓库获取:#{target.name}#{target.version}#{type_frameworks_dir}"
                Dir.foreach(targetFrameworkPath) do |file|
                    if file !="." and file !=".."
                        f = targetFrameworkPath+"/"+file
                        FileUtils.cp_r(f, output_path, :remove_destination => false )
                    end
                end
            else
                #开始使用XcodeBuild进行编译静态库
                Pod::Prebuild.build(sandbox_path, target, output_path, bitcode_enabled,  Podfile::DSL.custom_build_options,  Podfile::DSL.custom_build_options_simulator)

                #save for cache
                puts "[XL].本地缓存仓库新增:#{target.name}#{target.version} #{type_frameworks_dir}"
                local_cache_path = targetFrameworkPath
                FileUtils.makedirs(local_cache_path) unless File.exists?local_cache_path
                c_output_path = output_path.to_s
                if Dir.exist?(output_path)
                    Dir.foreach(output_path) do |file|
                        if file !="." and file !=".."
                            f = c_output_path+"/"+file
                            FileUtils.cp_r(f, local_cache_path, :remove_destination => false )
                        end
                    end
                end
            end
        end

        # save the resource paths for later installing,动态库需要将frameworkwork中资源链接到pod上
        if target.static_framework? and !target.resource_paths.empty?
            framework_path = output_path + target.framework_name
            standard_sandbox_path = sandbox.standard_sanbox_path

            resources = begin
                if Pod::VERSION.start_with? "1.5"
                    target.resource_paths
                else
                    # resource_paths is Hash{String=>Array<String>} on 1.6 and above
                    # (use AFNetworking to generate a demo data)
                    # https://github.com/leavez/cocoapods-binary/issues/50
                    target.resource_paths.values.flatten
                end
            end
            raise "Wrong type: #{resources}" unless resources.kind_of? Array
            path_objects = resources.map do |path|
                object = Prebuild::Passer::ResourcePath.new
                object.real_file_path = framework_path + File.basename(path)
                # 静态库资源目录处理
                if use_static_framework
                    object.real_file_path = path.gsub('${PODS_ROOT}', existed_framework_folder.to_s) if path.start_with? '${PODS_ROOT}'
                    object.real_file_path = path.gsub("${PODS_CONFIGURATION_BUILD_DIR}", existed_framework_folder.to_s) if path.start_with? "${PODS_CONFIGURATION_BUILD_DIR}"
                    real_bundle_path = path.gsub('${PODS_ROOT}', sandbox_path.to_s) if path.start_with? '${PODS_ROOT}'
                    real_bundle_path = path.gsub('${PODS_CONFIGURATION_BUILD_DIR}', sandbox_path.to_s) if path.start_with? '${PODS_CONFIGURATION_BUILD_DIR}'
                    real_origin_path = Pathname.new(real_bundle_path)
                    real_file_path_obj = Pathname.new(object.real_file_path)
                    if real_origin_path.exist?
                        real_file_path_obj.parent.mkpath unless real_file_path_obj.parent.exist?
                        FileUtils.cp_r(real_origin_path, real_file_path_obj, :remove_destination => true)
                    end
                end
                object.target_file_path = path.gsub('${PODS_ROOT}', standard_sandbox_path.to_s) if path.start_with? '${PODS_ROOT}'
                object.target_file_path = path.gsub("${PODS_CONFIGURATION_BUILD_DIR}", standard_sandbox_path.to_s) if path.start_with? "${PODS_CONFIGURATION_BUILD_DIR}"
                object
            end
            Prebuild::Passer.resources_to_copy_for_static_framework[target.name] = path_objects
        end
    end
    Pod::Prebuild.remove_build_dir(sandbox_path)

    # copy vendored libraries and frameworks
    targets.each do |target|
        root_path = self.sandbox.pod_dir(target.name)
        target_folder = sandbox.framework_folder_path_for_target_name(target.name)
        
        # If target shouldn't build, we copy all the original files
        # This is for target with only .a and .h files
        if not target.should_build? 
            Prebuild::Passer.target_names_to_skip_integration_framework << target.name
            FileUtils.cp_r(root_path, target_folder, :remove_destination => true)
            next
        end

        target.spec_consumers.each do |consumer|
            file_accessor = Sandbox::FileAccessor.new(root_path, consumer)
            lib_paths = file_accessor.vendored_frameworks || []
            lib_paths += file_accessor.vendored_libraries
            # @TODO dSYM files
            lib_paths.each do |lib_path|
                relative = lib_path.relative_path_from(root_path)
                destination = target_folder + relative
                destination.dirname.mkpath unless destination.dirname.exist?
                FileUtils.cp_r(lib_path, destination, :remove_destination => true)
            end
        end
    end

    # save the pod_name for prebuild framwork in sandbox 
    targets.each do |target|
        sandbox.save_pod_name_for_target target
    end
    
    # Remove useless files
    # remove useless pods
    all_needed_names = self.pod_targets.map(&:name).uniq
    useless_target_names = sandbox.exsited_framework_target_names.reject do |name| 
        all_needed_names.include? name
    end
    useless_target_names.each do |name|
        path = sandbox.framework_folder_path_for_target_name(name)
        path.rmtree if path.exist?
    end

    if Podfile::DSL.dont_remove_source_code 
         # just remove the tmp files
        path = sandbox.root + 'Manifest.lock.tmp'
        path.rmtree if path.exist?
    else 
       # only keep manifest.lock and framework folder in _Prebuild
        to_remain_files = ["Manifest.lock", File.basename(existed_framework_folder)]
        to_delete_files = sandbox_path.children.select do |file|
            filename = File.basename(file)
            not to_remain_files.include?(filename)
        end
        to_delete_files.each do |path|
            path.rmtree if path.exist?
        end
    end
end

#prebuild_pod_namesObject

the root names who needs prebuild, including dependency pods.



100
101
102
# File 'lib/cocoapods-xlbuild/helper/podfile_options.rb', line 100

def prebuild_pod_names 
   @prebuild_pod_names ||= self.prebuild_pod_targets.map(&:pod_name)
end

#prebuild_pod_targetsObject



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/cocoapods-xlbuild/helper/podfile_options.rb', line 69

def prebuild_pod_targets
    @prebuild_pod_targets ||= (
    all = []

    aggregate_targets = self.aggregate_targets
    aggregate_targets.each do |aggregate_target|
        target_definition = aggregate_target.target_definition
        targets = aggregate_target.pod_targets || []

        # filter prebuild
        prebuild_names = target_definition.prebuild_framework_pod_names
        # if not Podfile::DSL.prebuild_all
        #     targets = targets.select { |pod_target| prebuild_names.include?(pod_target.pod_name) } 
        # end
        targets = targets.select { |pod_target| prebuild_names.include?(pod_target.pod_name) } 
        dependency_targets = targets.map {|t| t.recursive_dependent_targets }.flatten.uniq || []
        targets = (targets + dependency_targets).uniq

        # filter should not prebuild
        explict_should_not_names = target_definition.should_not_prebuild_framework_pod_names
        targets = targets.reject { |pod_target| explict_should_not_names.include?(pod_target.pod_name) } 

        all += targets
    end

    all = all.reject {|pod_target| sandbox.local?(pod_target.pod_name) }
    all.uniq
    )
end

#remove_target_files_if_neededObject

Remove the old target files if prebuild frameworks changed



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/cocoapods-xlbuild/Integration.rb', line 137

def remove_target_files_if_needed

    changes = Pod::Prebuild::Passer.prebuild_pod_targets_changes
    updated_names = []
    if changes == nil
        updated_names = PrebuildSandbox.from_standard_sandbox(self.sandbox).exsited_framework_pod_names
    else
        t_changes = Pod::Prebuild::Passer.prebuild_pods_changes
        added = t_changes.added
        changed = t_changes.changed 
        deleted = t_changes.deleted 
        updated_names = (added + changed + deleted).to_a

        updated_names = (changes + updated_names).uniq
    end

    updated_names.each do |name|
        root_name = Specification.root_name(name)
        next if self.sandbox.local?(root_name)

        # delete the cached files
        target_path = self.sandbox.pod_dir(root_name)
        target_path.rmtree if target_path.exist?

        support_path = sandbox.target_support_files_dir(root_name)
        support_path.rmtree if support_path.exist?
    end

end

#save_change_targets!Object



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/cocoapods-xlbuild/Integration.rb', line 167

def save_change_targets!
    sandbox_path = sandbox.root
    existed_framework_folder = sandbox.generate_framework_path
    if local_manifest != nil
        changes = prebuild_pods_changes
        added = changes.added
        changed = changes.changed 
        unchanged = changes.unchanged
        deleted = changes.deleted.to_a
    
        existed_framework_folder.mkdir unless existed_framework_folder.exist?
        exsited_framework_pod_names = sandbox.exsited_framework_pod_names
    
        # additions
        missing = unchanged.select do |pod_name|
            not exsited_framework_pod_names.include?(pod_name)
        end

        # 保存有改变的target列表
        root_names_to_update = (added + changed + missing).uniq
        updates_target_names = (root_names_to_update + deleted).uniq
        cache = []
        updates_targets = []
        updates_target_names.each do |pod_name|
            tars = Pod.fast_get_targets_for_pod_name(pod_name, self.pod_targets, cache)
            if tars.nil?
                tars = []
            end
            updates_targets = (updates_targets + tars).uniq 
        end
        updates_dependency_targets = updates_targets.map {|t| 
            t.recursive_dependent_targets 
        }.flatten.uniq || []
        dependency_names = updates_dependency_targets.map { |e| e.pod_name }
        if Pod::Prebuild::Passer.prebuild_pod_targets_changes.nil?
            Pod::Prebuild::Passer.prebuild_pod_targets_changes = (updates_target_names + dependency_names).uniq
        else
            Pod::Prebuild::Passer.prebuild_pod_targets_changes = (Pod::Prebuild::Passer.prebuild_pod_targets_changes + updates_target_names + dependency_names).uniq
        end
    end
end

#validate_every_pod_only_have_one_formObject

Raises:

  • (Informative)


105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/cocoapods-xlbuild/helper/podfile_options.rb', line 105

def validate_every_pod_only_have_one_form

    multi_targets_pods = self.pod_targets.group_by do |t|
        t.pod_name
    end.select do |k, v|
        v.map{|t| t.platform.name }.count > 1
    end

    multi_targets_pods = multi_targets_pods.reject do |name, targets|
        contained = targets.map{|t| self.prebuild_pod_targets.include? t }
        contained.uniq.count == 1 # all equal
    end

    return if multi_targets_pods.empty?

    warnings = "One pod can only be prebuilt or not prebuilt. These pod have different forms in multiple targets:\n"
    warnings += multi_targets_pods.map{|name, targets| "         #{name}: #{targets.map{|t|t.platform.name}}"}.join("\n")
    raise Informative, warnings
end