cocoapods-tt 0.0.1
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.
- checksums.yaml +7 -0
- data/lib/cocoapods-tt/command/native/install.rb +56 -0
- data/lib/cocoapods-tt/command/native/update.rb +157 -0
- data/lib/cocoapods-tt/command/tt/make.rb +92 -0
- data/lib/cocoapods-tt/command/tt.rb +115 -0
- data/lib/cocoapods-tt/command.rb +1 -0
- data/lib/cocoapods-tt/gem_version.rb +3 -0
- data/lib/cocoapods-tt/native/command.rb +185 -0
- data/lib/cocoapods-tt/native/config.rb +366 -0
- data/lib/cocoapods-tt/native/core_overrides.rb +1 -0
- data/lib/cocoapods-tt/native/downloader/cache.rb +322 -0
- data/lib/cocoapods-tt/native/downloader/request.rb +86 -0
- data/lib/cocoapods-tt/native/downloader/response.rb +16 -0
- data/lib/cocoapods-tt/native/downloader.rb +192 -0
- data/lib/cocoapods-tt/native/executable.rb +247 -0
- data/lib/cocoapods-tt/native/external_sources/abstract_external_source.rb +205 -0
- data/lib/cocoapods-tt/native/external_sources/downloader_source.rb +30 -0
- data/lib/cocoapods-tt/native/external_sources/path_source.rb +55 -0
- data/lib/cocoapods-tt/native/external_sources/podspec_source.rb +54 -0
- data/lib/cocoapods-tt/native/external_sources.rb +57 -0
- data/lib/cocoapods-tt/native/gem_version.rb +5 -0
- data/lib/cocoapods-tt/native/generator/acknowledgements/markdown.rb +44 -0
- data/lib/cocoapods-tt/native/generator/acknowledgements/plist.rb +94 -0
- data/lib/cocoapods-tt/native/generator/acknowledgements.rb +107 -0
- data/lib/cocoapods-tt/native/generator/app_target_helper.rb +363 -0
- data/lib/cocoapods-tt/native/generator/bridge_support.rb +22 -0
- data/lib/cocoapods-tt/native/generator/constant.rb +19 -0
- data/lib/cocoapods-tt/native/generator/copy_dsyms_script.rb +56 -0
- data/lib/cocoapods-tt/native/generator/copy_resources_script.rb +223 -0
- data/lib/cocoapods-tt/native/generator/copy_xcframework_script.rb +227 -0
- data/lib/cocoapods-tt/native/generator/dummy_source.rb +31 -0
- data/lib/cocoapods-tt/native/generator/embed_frameworks_script.rb +196 -0
- data/lib/cocoapods-tt/native/generator/file_list.rb +39 -0
- data/lib/cocoapods-tt/native/generator/header.rb +103 -0
- data/lib/cocoapods-tt/native/generator/info_plist_file.rb +128 -0
- data/lib/cocoapods-tt/native/generator/module_map.rb +99 -0
- data/lib/cocoapods-tt/native/generator/prefix_header.rb +60 -0
- data/lib/cocoapods-tt/native/generator/script_phase_constants.rb +100 -0
- data/lib/cocoapods-tt/native/generator/umbrella_header.rb +46 -0
- data/lib/cocoapods-tt/native/hooks_manager.rb +132 -0
- data/lib/cocoapods-tt/native/installer/analyzer/analysis_result.rb +87 -0
- data/lib/cocoapods-tt/native/installer/analyzer/locking_dependency_analyzer.rb +103 -0
- data/lib/cocoapods-tt/native/installer/analyzer/pod_variant.rb +87 -0
- data/lib/cocoapods-tt/native/installer/analyzer/pod_variant_set.rb +175 -0
- data/lib/cocoapods-tt/native/installer/analyzer/podfile_dependency_cache.rb +55 -0
- data/lib/cocoapods-tt/native/installer/analyzer/sandbox_analyzer.rb +268 -0
- data/lib/cocoapods-tt/native/installer/analyzer/specs_state.rb +108 -0
- data/lib/cocoapods-tt/native/installer/analyzer/target_inspection_result.rb +58 -0
- data/lib/cocoapods-tt/native/installer/analyzer/target_inspector.rb +258 -0
- data/lib/cocoapods-tt/native/installer/analyzer.rb +1204 -0
- data/lib/cocoapods-tt/native/installer/base_install_hooks_context.rb +135 -0
- data/lib/cocoapods-tt/native/installer/installation_options.rb +195 -0
- data/lib/cocoapods-tt/native/installer/pod_source_installer.rb +224 -0
- data/lib/cocoapods-tt/native/installer/pod_source_preparer.rb +77 -0
- data/lib/cocoapods-tt/native/installer/podfile_validator.rb +168 -0
- data/lib/cocoapods-tt/native/installer/post_install_hooks_context.rb +9 -0
- data/lib/cocoapods-tt/native/installer/post_integrate_hooks_context.rb +9 -0
- data/lib/cocoapods-tt/native/installer/pre_install_hooks_context.rb +51 -0
- data/lib/cocoapods-tt/native/installer/pre_integrate_hooks_context.rb +9 -0
- data/lib/cocoapods-tt/native/installer/project_cache/project_cache.rb +11 -0
- data/lib/cocoapods-tt/native/installer/project_cache/project_cache_analysis_result.rb +53 -0
- data/lib/cocoapods-tt/native/installer/project_cache/project_cache_analyzer.rb +200 -0
- data/lib/cocoapods-tt/native/installer/project_cache/project_cache_version.rb +43 -0
- data/lib/cocoapods-tt/native/installer/project_cache/project_installation_cache.rb +103 -0
- data/lib/cocoapods-tt/native/installer/project_cache/project_metadata_cache.rb +73 -0
- data/lib/cocoapods-tt/native/installer/project_cache/target_cache_key.rb +176 -0
- data/lib/cocoapods-tt/native/installer/project_cache/target_metadata.rb +74 -0
- data/lib/cocoapods-tt/native/installer/sandbox_dir_cleaner.rb +105 -0
- data/lib/cocoapods-tt/native/installer/sandbox_header_paths_installer.rb +45 -0
- data/lib/cocoapods-tt/native/installer/source_provider_hooks_context.rb +34 -0
- data/lib/cocoapods-tt/native/installer/target_uuid_generator.rb +34 -0
- data/lib/cocoapods-tt/native/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb +179 -0
- data/lib/cocoapods-tt/native/installer/user_project_integrator/target_integrator.rb +815 -0
- data/lib/cocoapods-tt/native/installer/user_project_integrator.rb +280 -0
- data/lib/cocoapods-tt/native/installer/xcode/multi_pods_project_generator.rb +82 -0
- data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/aggregate_target_dependency_installer.rb +66 -0
- data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/aggregate_target_installer.rb +192 -0
- data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/app_host_installer.rb +154 -0
- data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/file_references_installer.rb +329 -0
- data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/pod_target_dependency_installer.rb +195 -0
- data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/pod_target_installer.rb +1239 -0
- data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/pod_target_integrator.rb +312 -0
- data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/pods_project_writer.rb +90 -0
- data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/project_generator.rb +120 -0
- data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/target_installation_result.rb +140 -0
- data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/target_installer.rb +257 -0
- data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/target_installer_helper.rb +110 -0
- data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator.rb +291 -0
- data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator_result.rb +54 -0
- data/lib/cocoapods-tt/native/installer/xcode/single_pods_project_generator.rb +38 -0
- data/lib/cocoapods-tt/native/installer/xcode/target_validator.rb +170 -0
- data/lib/cocoapods-tt/native/installer/xcode.rb +11 -0
- data/lib/cocoapods-tt/native/installer.rb +1044 -0
- data/lib/cocoapods-tt/native/native_target_extension.rb +60 -0
- data/lib/cocoapods-tt/native/open-uri.rb +33 -0
- data/lib/cocoapods-tt/native/podfile.rb +13 -0
- data/lib/cocoapods-tt/native/project.rb +544 -0
- data/lib/cocoapods-tt/native/resolver/lazy_specification.rb +88 -0
- data/lib/cocoapods-tt/native/resolver/resolver_specification.rb +41 -0
- data/lib/cocoapods-tt/native/resolver.rb +600 -0
- data/lib/cocoapods-tt/native/sandbox/file_accessor.rb +532 -0
- data/lib/cocoapods-tt/native/sandbox/headers_store.rb +163 -0
- data/lib/cocoapods-tt/native/sandbox/path_list.rb +242 -0
- data/lib/cocoapods-tt/native/sandbox/pod_dir_cleaner.rb +71 -0
- data/lib/cocoapods-tt/native/sandbox/podspec_finder.rb +23 -0
- data/lib/cocoapods-tt/native/sandbox.rb +470 -0
- data/lib/cocoapods-tt/native/sources_manager.rb +221 -0
- data/lib/cocoapods-tt/native/target/aggregate_target.rb +558 -0
- data/lib/cocoapods-tt/native/target/build_settings.rb +1385 -0
- data/lib/cocoapods-tt/native/target/pod_target.rb +1168 -0
- data/lib/cocoapods-tt/native/target.rb +378 -0
- data/lib/cocoapods-tt/native/user_interface/error_report.rb +204 -0
- data/lib/cocoapods-tt/native/user_interface/inspector_reporter.rb +102 -0
- data/lib/cocoapods-tt/native/user_interface.rb +463 -0
- data/lib/cocoapods-tt/native/validator.rb +1170 -0
- data/lib/cocoapods-tt/native/version_metadata.rb +26 -0
- data/lib/cocoapods-tt/native/xcode/framework_paths.rb +54 -0
- data/lib/cocoapods-tt/native/xcode/linkage_analyzer.rb +22 -0
- data/lib/cocoapods-tt/native/xcode/xcframework/xcframework_slice.rb +138 -0
- data/lib/cocoapods-tt/native/xcode/xcframework.rb +99 -0
- data/lib/cocoapods-tt/native/xcode.rb +7 -0
- data/lib/cocoapods-tt.rb +1 -0
- data/lib/cocoapods_plugin.rb +17 -0
- metadata +193 -0
@@ -0,0 +1,1168 @@
|
|
1
|
+
require 'cocoapods/xcode/framework_paths'
|
2
|
+
require 'cocoapods/xcode/xcframework'
|
3
|
+
|
4
|
+
module Pod
|
5
|
+
# Stores the information relative to the target used to compile a single Pod.
|
6
|
+
# A pod can have one or more activated spec, subspecs and test specs.
|
7
|
+
#
|
8
|
+
class PodTarget < Target
|
9
|
+
# @return [Array<Specification>] the spec, subspecs and test specs of the target.
|
10
|
+
#
|
11
|
+
attr_reader :specs
|
12
|
+
|
13
|
+
# @return [Array<Specification>] All of the test specs within this target.
|
14
|
+
# Subset of #specs.
|
15
|
+
#
|
16
|
+
attr_reader :test_specs
|
17
|
+
|
18
|
+
# @return [Array<Specification>] All of the specs within this target that are library specs.
|
19
|
+
# Subset of #specs.
|
20
|
+
#
|
21
|
+
attr_reader :library_specs
|
22
|
+
|
23
|
+
# @return [Array<Specification>] All of the specs within this target that are app specs.
|
24
|
+
# Subset of #specs.
|
25
|
+
#
|
26
|
+
attr_reader :app_specs
|
27
|
+
|
28
|
+
# @return [Array<TargetDefinition>] the target definitions of the Podfile
|
29
|
+
# that generated this target.
|
30
|
+
#
|
31
|
+
attr_reader :target_definitions
|
32
|
+
|
33
|
+
# @return [Array<Sandbox::FileAccessor>] the file accessors for the
|
34
|
+
# specifications of this target.
|
35
|
+
#
|
36
|
+
attr_reader :file_accessors
|
37
|
+
|
38
|
+
# @return [String] the suffix used for this target when deduplicated. May be `nil`.
|
39
|
+
#
|
40
|
+
# @note This affects the value returned by #configuration_build_dir
|
41
|
+
# and accessors relying on this as #build_product_path.
|
42
|
+
#
|
43
|
+
attr_reader :scope_suffix
|
44
|
+
|
45
|
+
# @return [HeadersStore] the header directory for the target.
|
46
|
+
#
|
47
|
+
attr_reader :build_headers
|
48
|
+
|
49
|
+
# @return [Array<PodTarget>] the targets that this target has a dependency
|
50
|
+
# upon.
|
51
|
+
#
|
52
|
+
attr_reader :dependent_targets
|
53
|
+
attr_reader :dependent_targets_by_config
|
54
|
+
|
55
|
+
# @deprecated
|
56
|
+
def dependent_targets=(dependent_targets)
|
57
|
+
@dependent_targets = dependent_targets
|
58
|
+
@dependent_targets_by_config = { :debug => dependent_targets, :release => dependent_targets }
|
59
|
+
end
|
60
|
+
|
61
|
+
def dependent_targets_by_config=(dependent_targets_by_config)
|
62
|
+
@dependent_targets_by_config = dependent_targets_by_config
|
63
|
+
@dependent_targets = dependent_targets_by_config.each_value.reduce([], &:|)
|
64
|
+
end
|
65
|
+
|
66
|
+
# @return [Hash{String=>Array<PodTarget>}] all target dependencies by test spec name.
|
67
|
+
#
|
68
|
+
attr_reader :test_dependent_targets_by_spec_name
|
69
|
+
attr_reader :test_dependent_targets_by_spec_name_by_config
|
70
|
+
|
71
|
+
# @deprecated
|
72
|
+
def test_dependent_targets_by_spec_name=(test_dependent_targets_by_spec_name)
|
73
|
+
@test_dependent_targets_by_spec_name = test_dependent_targets_by_spec_name
|
74
|
+
@test_dependent_targets_by_spec_name_by_config = Hash[test_dependent_targets_by_spec_name.map do |k, v|
|
75
|
+
[k, { :debug => v, :release => v }]
|
76
|
+
end]
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_dependent_targets_by_spec_name_by_config=(test_dependent_targets_by_spec_name_by_config)
|
80
|
+
@test_dependent_targets_by_spec_name_by_config = test_dependent_targets_by_spec_name_by_config
|
81
|
+
@test_dependent_targets_by_spec_name = Hash[test_dependent_targets_by_spec_name_by_config.map do |k, v|
|
82
|
+
[k, v.each_value.reduce(Set.new, &:|).to_a]
|
83
|
+
end]
|
84
|
+
end
|
85
|
+
|
86
|
+
# @return [Hash{String=>Array<PodTarget>}] all target dependencies by app spec name.
|
87
|
+
#
|
88
|
+
attr_reader :app_dependent_targets_by_spec_name
|
89
|
+
attr_reader :app_dependent_targets_by_spec_name_by_config
|
90
|
+
|
91
|
+
# @deprecated
|
92
|
+
def app_dependent_targets_by_spec_name=(app_dependent_targets_by_spec_name)
|
93
|
+
@app_dependent_targets_by_spec_name = app_dependent_targets_by_spec_name
|
94
|
+
@app_dependent_targets_by_spec_name_by_config = Hash[app_dependent_targets_by_spec_name.map do |k, v|
|
95
|
+
[k, { :debug => v, :release => v }]
|
96
|
+
end]
|
97
|
+
end
|
98
|
+
|
99
|
+
def app_dependent_targets_by_spec_name_by_config=(app_dependent_targets_by_spec_name_by_config)
|
100
|
+
@app_dependent_targets_by_spec_name_by_config = app_dependent_targets_by_spec_name_by_config
|
101
|
+
@app_dependent_targets_by_spec_name = Hash[app_dependent_targets_by_spec_name_by_config.map do |k, v|
|
102
|
+
[k, v.each_value.reduce(Set.new, &:|).to_a]
|
103
|
+
end]
|
104
|
+
end
|
105
|
+
|
106
|
+
# @return [Hash{Specification => (Specification,PodTarget)}] tuples of app specs and pod targets by test spec.
|
107
|
+
#
|
108
|
+
attr_accessor :test_app_hosts_by_spec
|
109
|
+
|
110
|
+
# @return [Hash{String => BuildSettings}] the test spec build settings for this target.
|
111
|
+
#
|
112
|
+
attr_reader :test_spec_build_settings
|
113
|
+
attr_reader :test_spec_build_settings_by_config
|
114
|
+
|
115
|
+
# @return [Hash{String => BuildSettings}] the app spec build settings for this target.
|
116
|
+
#
|
117
|
+
attr_reader :app_spec_build_settings
|
118
|
+
attr_reader :app_spec_build_settings_by_config
|
119
|
+
|
120
|
+
# @return [String] the Swift version for this target.
|
121
|
+
#
|
122
|
+
attr_reader :swift_version
|
123
|
+
|
124
|
+
# Initialize a new instance
|
125
|
+
#
|
126
|
+
# @param [Sandbox] sandbox @see Target#sandbox
|
127
|
+
# @param [BuildType] build_type @see Target#build_type
|
128
|
+
# @param [Hash{String=>Symbol}] user_build_configurations @see Target#user_build_configurations
|
129
|
+
# @param [Array<String>] archs @see Target#archs
|
130
|
+
# @param [Platform] platform @see Target#platform
|
131
|
+
# @param [Array<Specification>] specs @see #specs
|
132
|
+
# @param [Array<TargetDefinition>] target_definitions @see #target_definitions
|
133
|
+
# @param [Array<Sandbox::FileAccessor>] file_accessors @see #file_accessors
|
134
|
+
# @param [String] scope_suffix @see #scope_suffix
|
135
|
+
# @param [String] swift_version @see #swift_version
|
136
|
+
#
|
137
|
+
def initialize(sandbox, build_type, user_build_configurations, archs, platform, specs, target_definitions,
|
138
|
+
file_accessors = [], scope_suffix = nil, swift_version = nil)
|
139
|
+
super(sandbox, build_type, user_build_configurations, archs, platform)
|
140
|
+
raise "Can't initialize a PodTarget without specs!" if specs.nil? || specs.empty?
|
141
|
+
raise "Can't initialize a PodTarget without TargetDefinition!" if target_definitions.nil? || target_definitions.empty?
|
142
|
+
raise "Can't initialize a PodTarget with an empty string scope suffix!" if scope_suffix == ''
|
143
|
+
@specs = specs.dup.freeze
|
144
|
+
@target_definitions = target_definitions
|
145
|
+
@file_accessors = file_accessors
|
146
|
+
@scope_suffix = scope_suffix
|
147
|
+
@swift_version = swift_version
|
148
|
+
all_specs_by_type = @specs.group_by(&:spec_type)
|
149
|
+
@library_specs = all_specs_by_type[:library] || []
|
150
|
+
@test_specs = all_specs_by_type[:test] || []
|
151
|
+
@app_specs = all_specs_by_type[:app] || []
|
152
|
+
@build_headers = Sandbox::HeadersStore.new(sandbox, 'Private', :private)
|
153
|
+
self.dependent_targets = []
|
154
|
+
self.test_dependent_targets_by_spec_name = Hash[test_specs.map { |ts| [ts.name, []] }]
|
155
|
+
self.app_dependent_targets_by_spec_name = Hash[app_specs.map { |as| [as.name, []] }]
|
156
|
+
@test_app_hosts_by_spec = {}
|
157
|
+
@build_config_cache = {}
|
158
|
+
@test_spec_build_settings_by_config = create_test_build_settings_by_config
|
159
|
+
@app_spec_build_settings_by_config = create_app_build_settings_by_config
|
160
|
+
end
|
161
|
+
|
162
|
+
# Scopes the current target based on the existing pod targets within the cache.
|
163
|
+
#
|
164
|
+
# @param [Hash{Array => PodTarget}] cache
|
165
|
+
# the cached target for a previously scoped target.
|
166
|
+
#
|
167
|
+
# @return [Array<PodTarget>] a scoped copy for each target definition.
|
168
|
+
#
|
169
|
+
def scoped(cache = {})
|
170
|
+
target_definitions.map do |target_definition|
|
171
|
+
cache_key = [specs, target_definition]
|
172
|
+
cache[cache_key] ||= begin
|
173
|
+
target = PodTarget.new(sandbox, build_type, user_build_configurations, archs, platform, specs,
|
174
|
+
[target_definition], file_accessors, target_definition.label, swift_version)
|
175
|
+
scope_dependent_targets = ->(dependent_targets) do
|
176
|
+
dependent_targets.flat_map do |pod_target|
|
177
|
+
pod_target.scoped(cache).select { |pt| pt.target_definitions == [target_definition] }
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
target.dependent_targets_by_config = Hash[dependent_targets_by_config.map { |k, v| [k, scope_dependent_targets[v]] }]
|
182
|
+
target.test_dependent_targets_by_spec_name_by_config = Hash[test_dependent_targets_by_spec_name_by_config.map do |spec_name, test_pod_targets_by_config|
|
183
|
+
[spec_name, Hash[test_pod_targets_by_config.map { |k, v| [k, scope_dependent_targets[v]] }]]
|
184
|
+
end]
|
185
|
+
target.app_dependent_targets_by_spec_name_by_config = Hash[app_dependent_targets_by_spec_name_by_config.map do |spec_name, app_pod_targets_by_config|
|
186
|
+
[spec_name, Hash[app_pod_targets_by_config.map { |k, v| [k, scope_dependent_targets[v]] }]]
|
187
|
+
end]
|
188
|
+
target.test_app_hosts_by_spec = Hash[test_app_hosts_by_spec.map do |spec, (app_host_spec, app_pod_target)|
|
189
|
+
[spec, [app_host_spec, app_pod_target.scoped(cache).find { |pt| pt.target_definitions == [target_definition] }]]
|
190
|
+
end]
|
191
|
+
target
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
# @return [String] the label for the target.
|
197
|
+
#
|
198
|
+
def label
|
199
|
+
if scope_suffix.nil? || scope_suffix[0] == '.'
|
200
|
+
"#{root_spec.name}#{scope_suffix}"
|
201
|
+
else
|
202
|
+
"#{root_spec.name}-#{scope_suffix}"
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
# @return [Array<Pathname>] The list of all files tracked.
|
207
|
+
#
|
208
|
+
def all_files
|
209
|
+
Sandbox::FileAccessor.all_files(file_accessors)
|
210
|
+
end
|
211
|
+
|
212
|
+
# @return [Pathname] the pathname for headers in the sandbox.
|
213
|
+
#
|
214
|
+
def headers_sandbox
|
215
|
+
Pathname.new(pod_name)
|
216
|
+
end
|
217
|
+
|
218
|
+
# @return [Hash{FileAccessor => Hash}] Hash of file accessors by header mappings.
|
219
|
+
#
|
220
|
+
def header_mappings_by_file_accessor
|
221
|
+
valid_accessors = file_accessors.reject { |fa| fa.spec.non_library_specification? }
|
222
|
+
Hash[valid_accessors.map do |file_accessor|
|
223
|
+
# Private headers will always end up in Pods/Headers/Private/PodA/*.h
|
224
|
+
# This will allow for `""` imports to work.
|
225
|
+
[file_accessor, header_mappings(file_accessor, file_accessor.headers)]
|
226
|
+
end]
|
227
|
+
end
|
228
|
+
|
229
|
+
# @return [Hash{FileAccessor => Hash}] Hash of file accessors by public header mappings.
|
230
|
+
#
|
231
|
+
def public_header_mappings_by_file_accessor
|
232
|
+
valid_accessors = file_accessors.reject { |fa| fa.spec.non_library_specification? }
|
233
|
+
Hash[valid_accessors.map do |file_accessor|
|
234
|
+
# Public headers on the other hand will be added in Pods/Headers/Public/PodA/PodA/*.h
|
235
|
+
# The extra folder is intentional in order for `<>` imports to work.
|
236
|
+
[file_accessor, header_mappings(file_accessor, file_accessor.public_headers)]
|
237
|
+
end]
|
238
|
+
end
|
239
|
+
|
240
|
+
# @return [Array<Version>] the Swift versions supported. Might be empty if the author has not
|
241
|
+
# specified any versions, most likely due to legacy reasons.
|
242
|
+
#
|
243
|
+
def spec_swift_versions
|
244
|
+
root_spec.swift_versions
|
245
|
+
end
|
246
|
+
|
247
|
+
# @return [Podfile] The podfile which declares the dependency.
|
248
|
+
#
|
249
|
+
def podfile
|
250
|
+
target_definitions.first.podfile
|
251
|
+
end
|
252
|
+
|
253
|
+
# @return [String] the project name derived from the target definitions that integrate this pod. If none is
|
254
|
+
# specified then the name of the pod is used by default.
|
255
|
+
#
|
256
|
+
# @note The name is guaranteed to be the same across all target definitions and is validated by the target
|
257
|
+
# validator during installation.
|
258
|
+
#
|
259
|
+
def project_name
|
260
|
+
target_definitions.map { |td| td.project_name_for_pod(pod_name) }.compact.first || pod_name
|
261
|
+
end
|
262
|
+
|
263
|
+
# @return [String] The name to use for the source code module constructed
|
264
|
+
# for this target, and which will be used to import the module in
|
265
|
+
# implementation source files.
|
266
|
+
#
|
267
|
+
def product_module_name
|
268
|
+
root_spec.module_name
|
269
|
+
end
|
270
|
+
|
271
|
+
# @param [Specification] spec the specification
|
272
|
+
#
|
273
|
+
# @return [String] the product basename of the specification's target
|
274
|
+
def product_basename_for_spec(spec)
|
275
|
+
user_specified = build_settings_by_config_for_spec(spec).
|
276
|
+
each_value.
|
277
|
+
map { |settings| settings.merged_pod_target_xcconfigs['PRODUCT_NAME'] }.
|
278
|
+
compact.
|
279
|
+
uniq
|
280
|
+
|
281
|
+
if user_specified.size == 1
|
282
|
+
user_specified.first
|
283
|
+
else
|
284
|
+
spec_label(spec)
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
# @return [Bool] Whether or not this target should be built.
|
289
|
+
#
|
290
|
+
# A target should not be built if it has no source files.
|
291
|
+
#
|
292
|
+
def should_build?
|
293
|
+
return @should_build if defined? @should_build
|
294
|
+
accessors = file_accessors.select { |fa| fa.spec.library_specification? }
|
295
|
+
source_files = accessors.flat_map(&:source_files)
|
296
|
+
source_files -= accessors.flat_map(&:headers)
|
297
|
+
@should_build = !source_files.empty?
|
298
|
+
end
|
299
|
+
|
300
|
+
# @return [Array<Specification::Consumer>] the specification consumers for
|
301
|
+
# the target.
|
302
|
+
#
|
303
|
+
def spec_consumers
|
304
|
+
specs.map { |spec| spec.consumer(platform) }
|
305
|
+
end
|
306
|
+
|
307
|
+
# @return [Array<Specification::Consumer>] the test specification consumers for
|
308
|
+
# the target.
|
309
|
+
#
|
310
|
+
def test_spec_consumers
|
311
|
+
test_specs.map { |test_spec| test_spec.consumer(platform) }
|
312
|
+
end
|
313
|
+
|
314
|
+
# @return [Array<Specification::Consumer>] the app specification consumers for
|
315
|
+
# the target.
|
316
|
+
#
|
317
|
+
def app_spec_consumers
|
318
|
+
app_specs.map { |app_spec| app_spec.consumer(platform) }
|
319
|
+
end
|
320
|
+
|
321
|
+
# Checks whether the target itself plus its specs uses Swift code.
|
322
|
+
# This check excludes source files from non library specs.
|
323
|
+
# Note that if a target does not need to be built (no source code),
|
324
|
+
# we fallback to check whether it indicates a swift version.
|
325
|
+
#
|
326
|
+
# @return [Boolean] Whether the target uses Swift code.
|
327
|
+
#
|
328
|
+
def uses_swift?
|
329
|
+
return @uses_swift if defined? @uses_swift
|
330
|
+
@uses_swift = (!should_build? && !spec_swift_versions.empty?) ||
|
331
|
+
file_accessors.select { |a| a.spec.library_specification? }.any? do |file_accessor|
|
332
|
+
uses_swift_for_spec?(file_accessor.spec)
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
# Checks whether a specification uses Swift or not.
|
337
|
+
#
|
338
|
+
# @param [Specification] spec
|
339
|
+
# The spec to query against.
|
340
|
+
#
|
341
|
+
# @return [Boolean] Whether the target uses Swift code within the requested non library spec.
|
342
|
+
#
|
343
|
+
def uses_swift_for_spec?(spec)
|
344
|
+
@uses_swift_for_spec_cache ||= {}
|
345
|
+
return @uses_swift_for_spec_cache[spec.name] if @uses_swift_for_spec_cache.key?(spec.name)
|
346
|
+
@uses_swift_for_spec_cache[spec.name] = begin
|
347
|
+
file_accessor = file_accessors.find { |fa| fa.spec == spec }
|
348
|
+
raise "[Bug] Unable to find file accessor for spec `#{spec.inspect}` in pod target `#{label}`" unless file_accessor
|
349
|
+
file_accessor.source_files.any? { |sf| sf.extname == '.swift' }
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
# @return [Boolean] Whether the target defines a "module"
|
354
|
+
# (and thus will need a module map and umbrella header).
|
355
|
+
#
|
356
|
+
# @note Static library targets can temporarily opt in to this behavior by setting
|
357
|
+
# `DEFINES_MODULE = YES` in their specification's `pod_target_xcconfig`.
|
358
|
+
#
|
359
|
+
def defines_module?
|
360
|
+
return @defines_module if defined?(@defines_module)
|
361
|
+
return @defines_module = true if uses_swift? || build_as_framework?
|
362
|
+
|
363
|
+
explicit_target_definitions = target_definitions.select { |td| td.dependencies.any? { |d| d.root_name == pod_name } }
|
364
|
+
tds_by_answer = explicit_target_definitions.group_by { |td| td.build_pod_as_module?(pod_name) }
|
365
|
+
|
366
|
+
if tds_by_answer.size > 1
|
367
|
+
UI.warn "Unable to determine whether to build `#{label}` as a module due to a conflict " \
|
368
|
+
"between the following target definitions:\n\t- #{tds_by_answer.map do |a, td|
|
369
|
+
"`#{td.to_sentence}` #{a ? "requires `#{label}` as a module" : "does not require `#{label}` as a module"}"
|
370
|
+
end.join("\n\t- ")}\n\n" \
|
371
|
+
"Defaulting to skip building `#{label}` as a module."
|
372
|
+
elsif tds_by_answer.keys.first == true || target_definitions.all? { |td| td.build_pod_as_module?(pod_name) }
|
373
|
+
return @defines_module = true
|
374
|
+
end
|
375
|
+
|
376
|
+
@defines_module = library_specs.any? { |s| s.consumer(platform).pod_target_xcconfig['DEFINES_MODULE'] == 'YES' }
|
377
|
+
end
|
378
|
+
|
379
|
+
# @return [Array<Hash{Symbol=>String}>] An array of hashes where each hash represents a single script phase.
|
380
|
+
#
|
381
|
+
def script_phases
|
382
|
+
spec_consumers.flat_map(&:script_phases)
|
383
|
+
end
|
384
|
+
|
385
|
+
# @return [Boolean] Whether the target contains any script phases.
|
386
|
+
#
|
387
|
+
def contains_script_phases?
|
388
|
+
!script_phases.empty?
|
389
|
+
end
|
390
|
+
|
391
|
+
# @return [Boolean] Whether the target has any tests specifications.
|
392
|
+
#
|
393
|
+
def contains_test_specifications?
|
394
|
+
!test_specs.empty?
|
395
|
+
end
|
396
|
+
|
397
|
+
# @return [Boolean] Whether the target has any app specifications.
|
398
|
+
#
|
399
|
+
def contains_app_specifications?
|
400
|
+
!app_specs.empty?
|
401
|
+
end
|
402
|
+
|
403
|
+
# @return [Hash{String=>Array<Xcode::FrameworkPaths>}] The vendored and non vendored framework paths this target
|
404
|
+
# depends upon keyed by spec name. For the root spec and subspecs the framework path of the target itself
|
405
|
+
# is included.
|
406
|
+
#
|
407
|
+
def framework_paths
|
408
|
+
@framework_paths ||= begin
|
409
|
+
file_accessors.each_with_object({}) do |file_accessor, hash|
|
410
|
+
frameworks = file_accessor.vendored_dynamic_artifacts.map do |framework_path|
|
411
|
+
relative_path_to_sandbox = framework_path.relative_path_from(sandbox.root)
|
412
|
+
framework_source = "${PODS_ROOT}/#{relative_path_to_sandbox}"
|
413
|
+
# Until this can be configured, assume the dSYM file uses the file name as the framework.
|
414
|
+
# See https://github.com/CocoaPods/CocoaPods/issues/1698
|
415
|
+
dsym_name = "#{framework_path.basename}.dSYM"
|
416
|
+
dsym_path = Pathname.new("#{framework_path.dirname}/#{dsym_name}")
|
417
|
+
dsym_source = if dsym_path.exist?
|
418
|
+
"${PODS_ROOT}/#{relative_path_to_sandbox}.dSYM"
|
419
|
+
end
|
420
|
+
dirname = framework_path.dirname
|
421
|
+
bcsymbolmap_paths = if dirname.exist?
|
422
|
+
Dir.chdir(dirname) do
|
423
|
+
Dir.glob('*.bcsymbolmap').map do |bcsymbolmap_file_name|
|
424
|
+
bcsymbolmap_path = dirname + bcsymbolmap_file_name
|
425
|
+
"${PODS_ROOT}/#{bcsymbolmap_path.relative_path_from(sandbox.root)}"
|
426
|
+
end
|
427
|
+
end
|
428
|
+
end
|
429
|
+
Xcode::FrameworkPaths.new(framework_source, dsym_source, bcsymbolmap_paths)
|
430
|
+
end
|
431
|
+
if file_accessor.spec.library_specification? && should_build? && build_as_dynamic_framework?
|
432
|
+
frameworks << Xcode::FrameworkPaths.new(build_product_path('${BUILT_PRODUCTS_DIR}'))
|
433
|
+
end
|
434
|
+
hash[file_accessor.spec.name] = frameworks
|
435
|
+
end
|
436
|
+
end
|
437
|
+
end
|
438
|
+
|
439
|
+
# @return [Hash{String=>Array<Xcode::XCFramework>}] The vendored xcframeworks this target
|
440
|
+
# depends upon keyed by spec name.
|
441
|
+
#
|
442
|
+
def xcframeworks
|
443
|
+
@xcframeworks ||= begin
|
444
|
+
file_accessors.each_with_object({}) do |file_accessor, hash|
|
445
|
+
frameworks = file_accessor.vendored_xcframeworks.map do |framework_path|
|
446
|
+
Xcode::XCFramework.new(file_accessor.spec.name, framework_path)
|
447
|
+
end
|
448
|
+
hash[file_accessor.spec.name] = frameworks
|
449
|
+
end
|
450
|
+
end
|
451
|
+
end
|
452
|
+
|
453
|
+
# @return [Hash{String=>Array<String>}] The resource and resource bundle paths this target depends upon keyed by
|
454
|
+
# spec name. Resource (not resource bundles) paths can vary depending on the type of spec:
|
455
|
+
# - App specs _always_ get their resource paths added to "Copy Bundle Resources" phase from
|
456
|
+
# [PodTargetInstaller] therefore their resource paths are never included here.
|
457
|
+
# - Test specs may have their resource paths added to "Copy Bundle Resources" if the target itself is
|
458
|
+
# built as a framework, which is again checked and handled by PodTargetInstaller. If that is true then
|
459
|
+
# the resource paths are not included, otherwise they are included and handled via the CocoaPods copy
|
460
|
+
# resources script phase.
|
461
|
+
# - Library specs _do not_ have per-configuration CocoaPods copy resources script phase and their resource
|
462
|
+
# paths will be added to "Copy Bundle Resources" phase if the target is built as a framework because
|
463
|
+
# it supports it. We always include the resource paths for library specs because they are also
|
464
|
+
# integrated to the user target.
|
465
|
+
#
|
466
|
+
def resource_paths
|
467
|
+
@resource_paths ||= begin
|
468
|
+
file_accessors.each_with_object({}) do |file_accessor, hash|
|
469
|
+
resource_paths = if file_accessor.spec.app_specification? || (file_accessor.spec.test_specification? && build_as_framework?)
|
470
|
+
[]
|
471
|
+
else
|
472
|
+
file_accessor.resources.map do |res|
|
473
|
+
"${PODS_ROOT}/#{res.relative_path_from(sandbox.project_path.dirname)}"
|
474
|
+
end
|
475
|
+
end
|
476
|
+
prefix = Pod::Target::BuildSettings::CONFIGURATION_BUILD_DIR_VARIABLE
|
477
|
+
prefix = configuration_build_dir unless file_accessor.spec.test_specification?
|
478
|
+
resource_bundle_paths = file_accessor.resource_bundles.keys.map { |name| "#{prefix}/#{name.shellescape}.bundle" }
|
479
|
+
hash[file_accessor.spec.name] = (resource_paths + resource_bundle_paths).map(&:to_s)
|
480
|
+
end
|
481
|
+
end
|
482
|
+
end
|
483
|
+
|
484
|
+
# @param [Specification] spec The non library spec to calculate the deployment target for.
|
485
|
+
#
|
486
|
+
# @return [String] The deployment target to use for the non library spec. If the non library spec explicitly
|
487
|
+
# specifies one then this is the one used otherwise the one that was determined by the analyzer is used.
|
488
|
+
#
|
489
|
+
def deployment_target_for_non_library_spec(spec)
|
490
|
+
raise ArgumentError, 'Must be a non library spec.' unless spec.non_library_specification?
|
491
|
+
spec.deployment_target(platform.name.to_s) || platform.deployment_target.to_s
|
492
|
+
end
|
493
|
+
|
494
|
+
# Returns the corresponding native product type to use given the test type.
|
495
|
+
# This is primarily used when creating the native targets in order to produce the correct test bundle target
|
496
|
+
# based on the type of tests included.
|
497
|
+
#
|
498
|
+
# @param [Symbol] test_type
|
499
|
+
# The test type to map to provided by the test specification DSL.
|
500
|
+
#
|
501
|
+
# @return [Symbol] The native product type to use.
|
502
|
+
#
|
503
|
+
def product_type_for_test_type(test_type)
|
504
|
+
case test_type
|
505
|
+
when :unit
|
506
|
+
:unit_test_bundle
|
507
|
+
when :ui
|
508
|
+
:ui_test_bundle
|
509
|
+
else
|
510
|
+
raise ArgumentError, "Unknown test type `#{test_type}`."
|
511
|
+
end
|
512
|
+
end
|
513
|
+
|
514
|
+
# Returns the label to use for the given test type.
|
515
|
+
# This is used to generate native target names for test specs.
|
516
|
+
#
|
517
|
+
# @param [Symbol] test_type
|
518
|
+
# The test type to map to provided by the test specification DSL.
|
519
|
+
#
|
520
|
+
# @return [String] The native product type to use.
|
521
|
+
#
|
522
|
+
def label_for_test_type(test_type)
|
523
|
+
case test_type
|
524
|
+
when :unit
|
525
|
+
'Unit'
|
526
|
+
when :ui
|
527
|
+
'UI'
|
528
|
+
else
|
529
|
+
raise ArgumentError, "Unknown test type `#{test_type}`."
|
530
|
+
end
|
531
|
+
end
|
532
|
+
|
533
|
+
# @return [Specification] The root specification for the target.
|
534
|
+
#
|
535
|
+
def root_spec
|
536
|
+
@root_spec ||= specs.first.root
|
537
|
+
end
|
538
|
+
|
539
|
+
# @return [String] The name of the Pod that this target refers to.
|
540
|
+
#
|
541
|
+
def pod_name
|
542
|
+
root_spec.name
|
543
|
+
end
|
544
|
+
|
545
|
+
# @return [Pathname] the absolute path of the LLVM module map file that
|
546
|
+
# defines the module structure for the compiler.
|
547
|
+
#
|
548
|
+
def module_map_path
|
549
|
+
basename = "#{label}.modulemap"
|
550
|
+
if build_as_framework?
|
551
|
+
super
|
552
|
+
elsif file_accessors.any?(&:module_map)
|
553
|
+
build_headers.root + product_module_name + basename
|
554
|
+
else
|
555
|
+
sandbox.public_headers.root + product_module_name + basename
|
556
|
+
end
|
557
|
+
end
|
558
|
+
|
559
|
+
# @return [Pathname] the absolute path of the prefix header file.
|
560
|
+
#
|
561
|
+
def prefix_header_path
|
562
|
+
support_files_dir + "#{label}-prefix.pch"
|
563
|
+
end
|
564
|
+
|
565
|
+
# @return [Hash] the additional entries to add to the generated Info.plist
|
566
|
+
#
|
567
|
+
def info_plist_entries
|
568
|
+
root_spec.info_plist
|
569
|
+
end
|
570
|
+
|
571
|
+
# @param [String] bundle_name
|
572
|
+
# The name of the bundle product, which is given by the +spec+.
|
573
|
+
#
|
574
|
+
# @return [String] The derived name of the resource bundle target.
|
575
|
+
#
|
576
|
+
def resources_bundle_target_label(bundle_name)
|
577
|
+
"#{label}-#{bundle_name}"
|
578
|
+
end
|
579
|
+
|
580
|
+
# @param [Specification] subspec
|
581
|
+
# The subspec to use for producing the label.
|
582
|
+
#
|
583
|
+
# @return [String] The derived name of the target.
|
584
|
+
#
|
585
|
+
def subspec_label(subspec)
|
586
|
+
raise ArgumentError, 'Must not be a root spec' if subspec.root?
|
587
|
+
subspec.name.split('/')[1..-1].join('-').to_s
|
588
|
+
end
|
589
|
+
|
590
|
+
# @param [Specification] test_spec
|
591
|
+
# The test spec to use for producing the test label.
|
592
|
+
#
|
593
|
+
# @return [String] The derived name of the test target.
|
594
|
+
#
|
595
|
+
def test_target_label(test_spec)
|
596
|
+
"#{label}-#{label_for_test_type(test_spec.test_type)}-#{subspec_label(test_spec)}"
|
597
|
+
end
|
598
|
+
|
599
|
+
# @param [Specification] app_spec
|
600
|
+
# The app spec to use for producing the app label.
|
601
|
+
#
|
602
|
+
# @return [String] The derived name of the app target.
|
603
|
+
#
|
604
|
+
def app_target_label(app_spec)
|
605
|
+
"#{label}-#{subspec_label(app_spec)}"
|
606
|
+
end
|
607
|
+
|
608
|
+
# @param [Specification] test_spec
|
609
|
+
# the test spec to use for producing the app host target label.
|
610
|
+
#
|
611
|
+
# @return [(String,String)] a tuple, where the first item is the PodTarget#label of the pod target that defines the
|
612
|
+
# app host, and the second item is the target name of the app host
|
613
|
+
#
|
614
|
+
def app_host_target_label(test_spec)
|
615
|
+
app_spec, app_target = test_app_hosts_by_spec[test_spec]
|
616
|
+
|
617
|
+
if app_spec
|
618
|
+
[app_target.name, app_target.app_target_label(app_spec)]
|
619
|
+
elsif test_spec.consumer(platform).requires_app_host?
|
620
|
+
[name, "AppHost-#{label}-#{label_for_test_type(test_spec.test_type)}-Tests"]
|
621
|
+
end
|
622
|
+
end
|
623
|
+
|
624
|
+
# @param [Specification] spec
|
625
|
+
# the spec to return app host dependencies for
|
626
|
+
#
|
627
|
+
# @param [String] configuration
|
628
|
+
# the configuration to retrieve the app host dependent targets for.
|
629
|
+
#
|
630
|
+
# @return [Array<PodTarget>] the app host dependent targets for the given spec.
|
631
|
+
#
|
632
|
+
def app_host_dependent_targets_for_spec(spec, configuration: nil)
|
633
|
+
return [] unless spec.test_specification? && spec.consumer(platform).test_type == :unit
|
634
|
+
app_host_info = test_app_hosts_by_spec[spec]
|
635
|
+
if app_host_info.nil?
|
636
|
+
[]
|
637
|
+
else
|
638
|
+
app_spec, app_target = *app_host_info
|
639
|
+
app_target.dependent_targets_for_app_spec(app_spec, :configuration => configuration)
|
640
|
+
end
|
641
|
+
end
|
642
|
+
|
643
|
+
def spec_label(spec)
|
644
|
+
case spec.spec_type
|
645
|
+
when :library then label
|
646
|
+
when :test then test_target_label(spec)
|
647
|
+
when :app then app_target_label(spec)
|
648
|
+
else raise ArgumentError, "Unhandled spec type #{spec.spec_type.inspect} for #{spec.inspect}"
|
649
|
+
end
|
650
|
+
end
|
651
|
+
# for backwards compatibility
|
652
|
+
alias non_library_spec_label spec_label
|
653
|
+
|
654
|
+
# @param [Specification] spec
|
655
|
+
# The spec to return scheme configuration for.
|
656
|
+
#
|
657
|
+
# @return [Hash] The scheme configuration used or empty if none is specified.
|
658
|
+
#
|
659
|
+
def scheme_for_spec(spec)
|
660
|
+
return {} if (spec.library_specification? && !spec.root?) || spec.available_platforms.none? do |p|
|
661
|
+
p.name == platform.name
|
662
|
+
end
|
663
|
+
spec.consumer(platform).scheme
|
664
|
+
end
|
665
|
+
|
666
|
+
# @param [Specification] spec
|
667
|
+
# The spec this copy resources script path is for.
|
668
|
+
#
|
669
|
+
# @return [Pathname] The absolute path of the copy resources script for the given spec.
|
670
|
+
#
|
671
|
+
def copy_resources_script_path_for_spec(spec)
|
672
|
+
support_files_dir + "#{spec_label(spec)}-resources.sh"
|
673
|
+
end
|
674
|
+
|
675
|
+
# @param [Specification] spec
|
676
|
+
# The spec this copy resources script path is for.
|
677
|
+
#
|
678
|
+
# @return [Pathname] The absolute path of the copy resources script input file list for the given spec.
|
679
|
+
#
|
680
|
+
def copy_resources_script_input_files_path_for_spec(spec)
|
681
|
+
support_files_dir + "#{spec_label(spec)}-resources-input-files.xcfilelist"
|
682
|
+
end
|
683
|
+
|
684
|
+
# @param [Specification] spec
|
685
|
+
# The spec this copy resources script path is for.
|
686
|
+
#
|
687
|
+
# @return [Pathname] The absolute path of the copy resources script output file list for the given spec.
|
688
|
+
#
|
689
|
+
def copy_resources_script_output_files_path_for_spec(spec)
|
690
|
+
support_files_dir + "#{spec_label(spec)}-resources-output-files.xcfilelist"
|
691
|
+
end
|
692
|
+
|
693
|
+
# @param [Specification] spec
|
694
|
+
# The spec this embed frameworks script path is for.
|
695
|
+
#
|
696
|
+
# @return [Pathname] The absolute path of the embed frameworks script for the given spec.
|
697
|
+
#
|
698
|
+
def embed_frameworks_script_path_for_spec(spec)
|
699
|
+
support_files_dir + "#{spec_label(spec)}-frameworks.sh"
|
700
|
+
end
|
701
|
+
|
702
|
+
# @param [Specification] spec
|
703
|
+
# The spec this embed frameworks script path is for.
|
704
|
+
#
|
705
|
+
# @return [Pathname] The absolute path of the embed frameworks script input file list for the given spec.
|
706
|
+
#
|
707
|
+
def embed_frameworks_script_input_files_path_for_spec(spec)
|
708
|
+
support_files_dir + "#{spec_label(spec)}-frameworks-input-files.xcfilelist"
|
709
|
+
end
|
710
|
+
|
711
|
+
# @param [Specification] spec
|
712
|
+
# The spec this embed frameworks script path is for.
|
713
|
+
#
|
714
|
+
# @return [Pathname] The absolute path of the embed frameworks script output file list for the given spec.
|
715
|
+
#
|
716
|
+
def embed_frameworks_script_output_files_path_for_spec(spec)
|
717
|
+
support_files_dir + "#{spec_label(spec)}-frameworks-output-files.xcfilelist"
|
718
|
+
end
|
719
|
+
|
720
|
+
# @return [Pathname] The absolute path of the copy xcframeworks script.
|
721
|
+
#
|
722
|
+
def copy_xcframeworks_script_path
|
723
|
+
support_files_dir + "#{label}-xcframeworks.sh"
|
724
|
+
end
|
725
|
+
|
726
|
+
# @return [String] The path of the copy xcframeworks input files file list
|
727
|
+
#
|
728
|
+
def copy_xcframeworks_script_input_files_path
|
729
|
+
support_files_dir + "#{label}-xcframeworks-input-files.xcfilelist"
|
730
|
+
end
|
731
|
+
|
732
|
+
# @return [String] The path of the copy xcframeworks output files file list
|
733
|
+
#
|
734
|
+
def copy_xcframeworks_script_output_files_path
|
735
|
+
support_files_dir + "#{label}-xcframeworks-output-files.xcfilelist"
|
736
|
+
end
|
737
|
+
|
738
|
+
# @param [Specification] spec
|
739
|
+
# The spec this script path is for.
|
740
|
+
#
|
741
|
+
# @return [Pathname] The absolute path of the prepare artifacts script for the given spec.
|
742
|
+
#
|
743
|
+
# @deprecated
|
744
|
+
#
|
745
|
+
# @todo Remove in 2.0
|
746
|
+
#
|
747
|
+
def prepare_artifacts_script_path_for_spec(spec)
|
748
|
+
support_files_dir + "#{spec_label(spec)}-artifacts.sh"
|
749
|
+
end
|
750
|
+
|
751
|
+
# @param [Specification] spec
|
752
|
+
# The spec this script path is for.
|
753
|
+
#
|
754
|
+
# @return [Pathname] The absolute path of the prepare artifacts script input file list for the given spec.
|
755
|
+
#
|
756
|
+
# @deprecated
|
757
|
+
#
|
758
|
+
# @todo Remove in 2.0
|
759
|
+
#
|
760
|
+
def prepare_artifacts_script_input_files_path_for_spec(spec)
|
761
|
+
support_files_dir + "#{spec_label(spec)}-artifacts-input-files.xcfilelist"
|
762
|
+
end
|
763
|
+
|
764
|
+
# @param [Specification] spec
|
765
|
+
# The spec this script path is for.
|
766
|
+
#
|
767
|
+
# @return [Pathname] The absolute path of the prepare artifacts script output file list for the given spec.
|
768
|
+
#
|
769
|
+
# @deprecated
|
770
|
+
#
|
771
|
+
# @todo Remove in 2.0
|
772
|
+
#
|
773
|
+
def prepare_artifacts_script_output_files_path_for_spec(spec)
|
774
|
+
support_files_dir + "#{spec_label(spec)}-artifacts-output-files.xcfilelist"
|
775
|
+
end
|
776
|
+
|
777
|
+
# @return [Pathname] The absolute path of the copy dSYMs script.
|
778
|
+
#
|
779
|
+
def copy_dsyms_script_path
|
780
|
+
support_files_dir + "#{label}-copy-dsyms.sh"
|
781
|
+
end
|
782
|
+
|
783
|
+
# @return [Pathname] The absolute path of the copy dSYM script phase input file list.
|
784
|
+
#
|
785
|
+
def copy_dsyms_script_input_files_path
|
786
|
+
support_files_dir + "#{label}-copy-dsyms-input-files.xcfilelist"
|
787
|
+
end
|
788
|
+
|
789
|
+
# @return [Pathname] The absolute path of the copy dSYM script phase output file list.
|
790
|
+
#
|
791
|
+
def copy_dsyms_script_output_files_path
|
792
|
+
support_files_dir + "#{label}-copy-dsyms-output-files.xcfilelist"
|
793
|
+
end
|
794
|
+
|
795
|
+
# @param [Specification] spec
|
796
|
+
# The spec this Info.plist path is for.
|
797
|
+
#
|
798
|
+
# @return [Pathname] The absolute path of the Info.plist for the given spec.
|
799
|
+
#
|
800
|
+
def info_plist_path_for_spec(spec)
|
801
|
+
support_files_dir + "#{spec_label(spec)}-Info.plist"
|
802
|
+
end
|
803
|
+
|
804
|
+
# @param [Specification] spec
|
805
|
+
# The spec this prefix header path is for.
|
806
|
+
#
|
807
|
+
# @return [Pathname] the absolute path of the prefix header file for the given spec.
|
808
|
+
#
|
809
|
+
def prefix_header_path_for_spec(spec)
|
810
|
+
support_files_dir + "#{spec_label(spec)}-prefix.pch"
|
811
|
+
end
|
812
|
+
|
813
|
+
# @return [Array<String>] The names of the Pods on which this target
|
814
|
+
# depends.
|
815
|
+
#
|
816
|
+
def dependencies
|
817
|
+
spec_consumers.flat_map do |consumer|
|
818
|
+
consumer.dependencies.map { |dep| Specification.root_name(dep.name) }
|
819
|
+
end.uniq
|
820
|
+
end
|
821
|
+
|
822
|
+
# Returns all dependent targets of this target. If a configuration is passed then the list can be scoped to a given
|
823
|
+
# configuration.
|
824
|
+
#
|
825
|
+
# @param [String] configuration
|
826
|
+
# The configuration to return the dependent targets for or `nil` if all configurations should be included.
|
827
|
+
#
|
828
|
+
# @return [Array<PodTarget>] the recursive targets that this target has a dependency upon.
|
829
|
+
#
|
830
|
+
def recursive_dependent_targets(configuration: nil)
|
831
|
+
@recursive_dependent_targets ||= begin
|
832
|
+
hash = Hash[config_variants.map do |config|
|
833
|
+
[config, _add_recursive_dependent_targets(Set.new, :configuration => config).delete(self).to_a.freeze]
|
834
|
+
end]
|
835
|
+
hash[nil] = hash.each_value.reduce(Set.new, &:|).to_a
|
836
|
+
hash
|
837
|
+
end
|
838
|
+
@recursive_dependent_targets.fetch(configuration) { raise ArgumentError, "No configuration #{configuration} for #{self}, known configurations are #{@recursive_dependent_targets.keys}" }
|
839
|
+
end
|
840
|
+
|
841
|
+
def _add_recursive_dependent_targets(set, configuration: nil)
|
842
|
+
if defined?(@recursive_dependent_targets)
|
843
|
+
return set.merge(@recursive_dependent_targets[configuration])
|
844
|
+
end
|
845
|
+
dependent_targets = configuration ? dependent_targets_by_config[configuration] : self.dependent_targets
|
846
|
+
dependent_targets.each do |target|
|
847
|
+
target._add_recursive_dependent_targets(set, :configuration => configuration) if set.add?(target)
|
848
|
+
end
|
849
|
+
|
850
|
+
set
|
851
|
+
end
|
852
|
+
protected :_add_recursive_dependent_targets
|
853
|
+
|
854
|
+
# @param [Specification] test_spec
|
855
|
+
# the test spec to scope dependencies for
|
856
|
+
#
|
857
|
+
# @param [String] configuration
|
858
|
+
# the configuration to retrieve the test dependent targets for.
|
859
|
+
#
|
860
|
+
# @return [Array<PodTarget>] the recursive targets that this target has a
|
861
|
+
# test dependency upon.
|
862
|
+
#
|
863
|
+
def recursive_test_dependent_targets(test_spec, configuration: nil)
|
864
|
+
@recursive_test_dependent_targets ||= {}
|
865
|
+
@recursive_test_dependent_targets[test_spec] ||= begin
|
866
|
+
hash = Hash[config_variants.map do |config|
|
867
|
+
[config, _add_recursive_test_dependent_targets(test_spec, Set.new, :configuration => config).to_a.freeze]
|
868
|
+
end]
|
869
|
+
hash[nil] = hash.each_value.reduce(Set.new, &:|).to_a.freeze
|
870
|
+
hash
|
871
|
+
end
|
872
|
+
@recursive_test_dependent_targets[test_spec][configuration]
|
873
|
+
end
|
874
|
+
|
875
|
+
def _add_recursive_test_dependent_targets(test_spec, set, configuration: nil)
|
876
|
+
raise ArgumentError, 'Must give a test spec' unless test_spec
|
877
|
+
dependent_targets = configuration ? test_dependent_targets_by_spec_name_by_config[test_spec.name][configuration] : test_dependent_targets_by_spec_name[test_spec.name]
|
878
|
+
raise ArgumentError, "Unable to find deps for #{test_spec} for config #{configuration.inspect} (out of #{test_dependent_targets_by_spec_name_by_config.inspect})" unless dependent_targets
|
879
|
+
|
880
|
+
dependent_targets.each do |target|
|
881
|
+
target._add_recursive_dependent_targets(set, :configuration => configuration) if set.add?(target)
|
882
|
+
end
|
883
|
+
|
884
|
+
set
|
885
|
+
end
|
886
|
+
private :_add_recursive_test_dependent_targets
|
887
|
+
|
888
|
+
# @param [Specification] test_spec
|
889
|
+
# the test spec to scope dependencies for
|
890
|
+
#
|
891
|
+
# @param [String] configuration
|
892
|
+
# the configuration to retrieve the test dependent targets for.
|
893
|
+
#
|
894
|
+
# @return [Array<PodTarget>] the canonical list of dependent targets this target has a dependency upon.
|
895
|
+
# This list includes the target itself as well as its recursive dependent and test dependent targets.
|
896
|
+
#
|
897
|
+
def dependent_targets_for_test_spec(test_spec, configuration: nil)
|
898
|
+
[self, *recursive_dependent_targets(:configuration => configuration), *recursive_test_dependent_targets(test_spec, :configuration => configuration)].uniq
|
899
|
+
end
|
900
|
+
|
901
|
+
# @param [Specification] app_spec
|
902
|
+
# the app spec to scope dependencies for
|
903
|
+
#
|
904
|
+
# @param [String] configuration
|
905
|
+
# the configuration to retrieve the app dependent targets for.
|
906
|
+
#
|
907
|
+
# @return [Array<PodTarget>] the recursive targets that this target has a
|
908
|
+
# app dependency upon.
|
909
|
+
#
|
910
|
+
def recursive_app_dependent_targets(app_spec, configuration: nil)
|
911
|
+
@recursive_app_dependent_targets ||= {}
|
912
|
+
@recursive_app_dependent_targets[app_spec] ||= begin
|
913
|
+
hash = Hash[config_variants.map do |config|
|
914
|
+
[config, _add_recursive_app_dependent_targets(app_spec, Set.new, :configuration => config).to_a.freeze]
|
915
|
+
end]
|
916
|
+
hash[nil] = hash.each_value.reduce(Set.new, &:|).to_a.freeze
|
917
|
+
hash
|
918
|
+
end
|
919
|
+
@recursive_app_dependent_targets[app_spec][configuration]
|
920
|
+
end
|
921
|
+
|
922
|
+
def _add_recursive_app_dependent_targets(app_spec, set, configuration: nil)
|
923
|
+
raise ArgumentError, 'Must give a app spec' unless app_spec
|
924
|
+
dependent_targets = configuration ? app_dependent_targets_by_spec_name_by_config[app_spec.name][configuration] : app_dependent_targets_by_spec_name[app_spec.name]
|
925
|
+
raise ArgumentError, "Unable to find deps for #{app_spec} for config #{configuration.inspect} #{app_dependent_targets_by_spec_name_by_config.inspect}" unless dependent_targets
|
926
|
+
|
927
|
+
dependent_targets.each do |target|
|
928
|
+
target._add_recursive_dependent_targets(set, :configuration => configuration) if set.add?(target)
|
929
|
+
end
|
930
|
+
|
931
|
+
set
|
932
|
+
end
|
933
|
+
private :_add_recursive_app_dependent_targets
|
934
|
+
|
935
|
+
# @param [Specification] app_spec
|
936
|
+
# the app spec to scope dependencies for
|
937
|
+
#
|
938
|
+
# @param [String] configuration
|
939
|
+
# the configuration to retrieve the app dependent targets for.
|
940
|
+
#
|
941
|
+
# @return [Array<PodTarget>] the canonical list of dependent targets this target has a dependency upon.
|
942
|
+
# This list includes the target itself as well as its recursive dependent and app dependent targets.
|
943
|
+
#
|
944
|
+
def dependent_targets_for_app_spec(app_spec, configuration: nil)
|
945
|
+
[self, *recursive_dependent_targets(:configuration => configuration), *recursive_app_dependent_targets(app_spec, :configuration => configuration)].uniq
|
946
|
+
end
|
947
|
+
|
948
|
+
# Checks if warnings should be inhibited for this pod.
|
949
|
+
#
|
950
|
+
# @return [Bool]
|
951
|
+
#
|
952
|
+
def inhibit_warnings?
|
953
|
+
return @inhibit_warnings if defined? @inhibit_warnings
|
954
|
+
whitelists = target_definitions.map do |target_definition|
|
955
|
+
target_definition.inhibits_warnings_for_pod?(root_spec.name)
|
956
|
+
end.uniq
|
957
|
+
|
958
|
+
if whitelists.empty?
|
959
|
+
@inhibit_warnings = false
|
960
|
+
false
|
961
|
+
elsif whitelists.count == 1
|
962
|
+
@inhibit_warnings = whitelists.first
|
963
|
+
whitelists.first
|
964
|
+
else
|
965
|
+
UI.warn "The pod `#{pod_name}` is linked to different targets " \
|
966
|
+
"(#{target_definitions.map { |td| "`#{td.name}`" }.to_sentence}), which contain different " \
|
967
|
+
'settings to inhibit warnings. CocoaPods does not currently ' \
|
968
|
+
'support different settings and will fall back to your preference ' \
|
969
|
+
'set in the root target definition.'
|
970
|
+
@inhibit_warnings = podfile.root_target_definitions.first.inhibits_warnings_for_pod?(root_spec.name)
|
971
|
+
end
|
972
|
+
end
|
973
|
+
|
974
|
+
# @param [String] dir
|
975
|
+
# The directory (which might be a variable) relative to which
|
976
|
+
# the returned path should be. This must be used if the
|
977
|
+
# $CONFIGURATION_BUILD_DIR is modified.
|
978
|
+
#
|
979
|
+
# @return [String] The absolute path to the configuration build dir
|
980
|
+
#
|
981
|
+
def configuration_build_dir(dir = BuildSettings::CONFIGURATION_BUILD_DIR_VARIABLE)
|
982
|
+
"#{dir}/#{label}"
|
983
|
+
end
|
984
|
+
|
985
|
+
# @param [String] dir
|
986
|
+
# @see #configuration_build_dir
|
987
|
+
#
|
988
|
+
# @return [String] The absolute path to the build product
|
989
|
+
#
|
990
|
+
def build_product_path(dir = BuildSettings::CONFIGURATION_BUILD_DIR_VARIABLE)
|
991
|
+
"#{configuration_build_dir(dir)}/#{product_name}"
|
992
|
+
end
|
993
|
+
|
994
|
+
# @return [String] The source path of the root for this target relative to `$(PODS_ROOT)`
|
995
|
+
#
|
996
|
+
def pod_target_srcroot
|
997
|
+
"${PODS_ROOT}/#{sandbox.pod_dir(pod_name).relative_path_from(sandbox.root)}"
|
998
|
+
end
|
999
|
+
|
1000
|
+
# @return [String] The version associated with this target
|
1001
|
+
#
|
1002
|
+
def version
|
1003
|
+
version = root_spec.version
|
1004
|
+
[version.major, version.minor, version.patch].join('.')
|
1005
|
+
end
|
1006
|
+
|
1007
|
+
# @param [Boolean] include_dependent_targets_for_test_spec
|
1008
|
+
# whether to include header search paths for test dependent targets
|
1009
|
+
#
|
1010
|
+
# @param [Boolean] include_dependent_targets_for_app_spec
|
1011
|
+
# whether to include header search paths for app dependent targets
|
1012
|
+
#
|
1013
|
+
# @param [Boolean] include_private_headers
|
1014
|
+
# whether to include header search paths for private headers of this
|
1015
|
+
# target
|
1016
|
+
#
|
1017
|
+
# @param [String] configuration
|
1018
|
+
# the configuration to return header search paths for or `nil` for all configurations.
|
1019
|
+
#
|
1020
|
+
# @return [Array<String>] The set of header search paths this target uses.
|
1021
|
+
#
|
1022
|
+
def header_search_paths(include_dependent_targets_for_test_spec: nil, include_dependent_targets_for_app_spec: nil,
|
1023
|
+
include_private_headers: true, configuration: nil)
|
1024
|
+
header_search_paths = []
|
1025
|
+
header_search_paths.concat(build_headers.search_paths(platform, nil, false)) if include_private_headers
|
1026
|
+
header_search_paths.concat(sandbox.public_headers.search_paths(platform, pod_name, uses_modular_headers?))
|
1027
|
+
dependent_targets = recursive_dependent_targets(:configuration => configuration)
|
1028
|
+
if include_dependent_targets_for_test_spec
|
1029
|
+
dependent_targets += recursive_test_dependent_targets(include_dependent_targets_for_test_spec, :configuration => configuration)
|
1030
|
+
end
|
1031
|
+
if include_dependent_targets_for_app_spec
|
1032
|
+
dependent_targets += recursive_app_dependent_targets(include_dependent_targets_for_app_spec, :configuration => configuration)
|
1033
|
+
end
|
1034
|
+
dependent_targets.uniq.each do |dependent_target|
|
1035
|
+
header_search_paths.concat(sandbox.public_headers.search_paths(platform, dependent_target.pod_name, defines_module? && dependent_target.uses_modular_headers?(false)))
|
1036
|
+
end
|
1037
|
+
header_search_paths.uniq
|
1038
|
+
end
|
1039
|
+
|
1040
|
+
# @param [Specification] spec the specification to return build settings for.
|
1041
|
+
#
|
1042
|
+
# @param [String] configuration the configuration to scope the build settings.
|
1043
|
+
#
|
1044
|
+
# @return [BuildSettings::PodTargetSettings] The build settings for the given spec
|
1045
|
+
#
|
1046
|
+
def build_settings_for_spec(spec, configuration: nil)
|
1047
|
+
raise ArgumentError, 'Must give configuration' unless configuration
|
1048
|
+
configuration = user_build_configurations[configuration] if user_build_configurations.key?(configuration)
|
1049
|
+
build_settings_by_config_for_spec(spec)[configuration] || raise(ArgumentError, "No build settings for #{spec} (configuration #{configuration.inspect}) (known configurations #{config_variants})")
|
1050
|
+
end
|
1051
|
+
|
1052
|
+
def build_settings_by_config_for_spec(spec)
|
1053
|
+
case spec.spec_type
|
1054
|
+
when :test then test_spec_build_settings_by_config[spec.name]
|
1055
|
+
when :app then app_spec_build_settings_by_config[spec.name]
|
1056
|
+
else build_settings
|
1057
|
+
end || raise(ArgumentError, "No build settings for #{spec}")
|
1058
|
+
end
|
1059
|
+
|
1060
|
+
def user_config_names_by_config_type
|
1061
|
+
user_build_configurations.each_with_object({}) do |(user, type), hash|
|
1062
|
+
hash[type] ||= []
|
1063
|
+
hash[type] << user
|
1064
|
+
end.each_value(&:freeze).freeze
|
1065
|
+
end
|
1066
|
+
|
1067
|
+
protected
|
1068
|
+
|
1069
|
+
# Returns whether the pod target should use modular headers.
|
1070
|
+
#
|
1071
|
+
# @param [Boolean] only_if_defines_modules
|
1072
|
+
# whether the use of modular headers should require the target to define a module
|
1073
|
+
#
|
1074
|
+
# @note This must return false when a pod has a `header_mappings_dir` or `header_dir`,
|
1075
|
+
# as that allows the spec to customize the header structure, and
|
1076
|
+
# therefore it might not be expecting the module name to be prepended
|
1077
|
+
# to imports at all.
|
1078
|
+
#
|
1079
|
+
def uses_modular_headers?(only_if_defines_modules = true)
|
1080
|
+
return false if only_if_defines_modules && !defines_module?
|
1081
|
+
return @uses_modular_headers if defined? @uses_modular_headers
|
1082
|
+
@uses_modular_headers = spec_consumers.none?(&:header_mappings_dir) && spec_consumers.none?(&:header_dir)
|
1083
|
+
end
|
1084
|
+
|
1085
|
+
private
|
1086
|
+
|
1087
|
+
def config_variants
|
1088
|
+
if user_build_configurations.empty?
|
1089
|
+
%i(debug release)
|
1090
|
+
else
|
1091
|
+
user_build_configurations.values.uniq
|
1092
|
+
end
|
1093
|
+
end
|
1094
|
+
|
1095
|
+
def create_build_settings
|
1096
|
+
Hash[config_variants.map do |config|
|
1097
|
+
[config, BuildSettings::PodTargetSettings.new(self, nil, :configuration => config)]
|
1098
|
+
end]
|
1099
|
+
end
|
1100
|
+
|
1101
|
+
def create_test_build_settings_by_config
|
1102
|
+
Hash[test_specs.map do |test_spec|
|
1103
|
+
[test_spec.name, Hash[config_variants.map do |config|
|
1104
|
+
[config, BuildSettings::PodTargetSettings.new(self, test_spec, :configuration => config)]
|
1105
|
+
end]]
|
1106
|
+
end]
|
1107
|
+
end
|
1108
|
+
|
1109
|
+
def create_app_build_settings_by_config
|
1110
|
+
Hash[app_specs.map do |app_spec|
|
1111
|
+
[app_spec.name, Hash[config_variants.map do |config|
|
1112
|
+
[config, BuildSettings::PodTargetSettings.new(self, app_spec, :configuration => config)]
|
1113
|
+
end]]
|
1114
|
+
end]
|
1115
|
+
end
|
1116
|
+
|
1117
|
+
# Computes the destination sub-directory in the sandbox
|
1118
|
+
#
|
1119
|
+
# @param [Sandbox::FileAccessor] file_accessor
|
1120
|
+
# The consumer file accessor for which the headers need to be
|
1121
|
+
# linked.
|
1122
|
+
#
|
1123
|
+
# @param [Array<Pathname>] headers
|
1124
|
+
# The absolute paths of the headers which need to be mapped.
|
1125
|
+
#
|
1126
|
+
# @return [Hash{Pathname => Array<Pathname>}] A hash containing the
|
1127
|
+
# headers folders as the keys and the absolute paths of the
|
1128
|
+
# header files as the values.
|
1129
|
+
#
|
1130
|
+
def header_mappings(file_accessor, headers)
|
1131
|
+
consumer = file_accessor.spec_consumer
|
1132
|
+
header_mappings_dir = consumer.header_mappings_dir
|
1133
|
+
dir = headers_sandbox
|
1134
|
+
dir += consumer.header_dir if consumer.header_dir
|
1135
|
+
|
1136
|
+
mappings = {}
|
1137
|
+
headers.each do |header|
|
1138
|
+
next if header.to_s.include?('.framework/')
|
1139
|
+
|
1140
|
+
sub_dir = dir
|
1141
|
+
if header_mappings_dir
|
1142
|
+
relative_path = header.relative_path_from(file_accessor.path_list.root + header_mappings_dir)
|
1143
|
+
sub_dir += relative_path.dirname
|
1144
|
+
end
|
1145
|
+
mappings[sub_dir] ||= []
|
1146
|
+
mappings[sub_dir] << header
|
1147
|
+
end
|
1148
|
+
mappings
|
1149
|
+
end
|
1150
|
+
|
1151
|
+
# @!group Deprecated APIs
|
1152
|
+
# ----------------------------------------------------------------------- #
|
1153
|
+
|
1154
|
+
public
|
1155
|
+
|
1156
|
+
# @deprecated Use `test_app_hosts_by_spec` instead.
|
1157
|
+
#
|
1158
|
+
# @todo Remove in 2.0
|
1159
|
+
#
|
1160
|
+
# @return [Hash{String => (Specification,PodTarget)}] tuples of app specs and pod targets by test spec name.
|
1161
|
+
#
|
1162
|
+
def test_app_hosts_by_spec_name
|
1163
|
+
Hash[test_app_hosts_by_spec.map do |spec, value|
|
1164
|
+
[spec.name, value]
|
1165
|
+
end]
|
1166
|
+
end
|
1167
|
+
end
|
1168
|
+
end
|