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,280 @@
|
|
1
|
+
require 'xcodeproj/workspace'
|
2
|
+
require 'xcodeproj/project'
|
3
|
+
|
4
|
+
require 'active_support/core_ext/string/inflections'
|
5
|
+
require 'active_support/core_ext/array/conversions'
|
6
|
+
|
7
|
+
module Pod
|
8
|
+
class Installer
|
9
|
+
# The {UserProjectIntegrator} integrates the libraries generated by
|
10
|
+
# TargetDefinitions of the {Podfile} with their correspondent user
|
11
|
+
# projects.
|
12
|
+
#
|
13
|
+
class UserProjectIntegrator
|
14
|
+
autoload :TargetIntegrator, 'cocoapods/installer/user_project_integrator/target_integrator'
|
15
|
+
|
16
|
+
# @return [Podfile] the podfile that should be integrated with the user
|
17
|
+
# projects.
|
18
|
+
#
|
19
|
+
attr_reader :podfile
|
20
|
+
|
21
|
+
# @return [Sandbox] The sandbox used for this installation.
|
22
|
+
#
|
23
|
+
attr_reader :sandbox
|
24
|
+
|
25
|
+
# @return [Pathname] the path of the installation.
|
26
|
+
#
|
27
|
+
# @todo This is only used to compute the workspace path in case that it
|
28
|
+
# should be inferred by the project. If the workspace should be in
|
29
|
+
# the same dir of the project, this could be removed.
|
30
|
+
#
|
31
|
+
attr_reader :installation_root
|
32
|
+
|
33
|
+
# @return [Array<AggregateTarget>] the targets represented in the Podfile.
|
34
|
+
#
|
35
|
+
attr_reader :targets
|
36
|
+
|
37
|
+
# @return [Array<AggregateTarget>] the targets that require integration. This will always be equal or a smaller
|
38
|
+
# subset of #targets.
|
39
|
+
#
|
40
|
+
attr_reader :targets_to_integrate
|
41
|
+
|
42
|
+
# @return [Boolean] whether to use input/output paths for build phase scripts
|
43
|
+
#
|
44
|
+
attr_reader :use_input_output_paths
|
45
|
+
alias use_input_output_paths? use_input_output_paths
|
46
|
+
|
47
|
+
# Initialize a new instance
|
48
|
+
#
|
49
|
+
# @param [Podfile] podfile @see #podfile
|
50
|
+
# @param [Sandbox] sandbox @see #sandbox
|
51
|
+
# @param [Pathname] installation_root @see #installation_root
|
52
|
+
# @param [Array<AggregateTarget>] targets @see #targets
|
53
|
+
# @param [Array<AggregateTarget>] targets_to_integrate @see #targets_to_integrate
|
54
|
+
# @param [Boolean] use_input_output_paths @see #use_input_output_paths
|
55
|
+
#
|
56
|
+
def initialize(podfile, sandbox, installation_root, targets, targets_to_integrate, use_input_output_paths: true)
|
57
|
+
@podfile = podfile
|
58
|
+
@sandbox = sandbox
|
59
|
+
@installation_root = installation_root
|
60
|
+
@targets = targets
|
61
|
+
@targets_to_integrate = targets_to_integrate
|
62
|
+
@use_input_output_paths = use_input_output_paths
|
63
|
+
end
|
64
|
+
|
65
|
+
# Integrates the user projects associated with the {TargetDefinitions}
|
66
|
+
# with the Pods project and its products.
|
67
|
+
#
|
68
|
+
# @return [void]
|
69
|
+
#
|
70
|
+
def integrate!
|
71
|
+
create_workspace
|
72
|
+
deintegrated_projects = deintegrate_removed_targets
|
73
|
+
integrate_user_targets
|
74
|
+
warn_about_xcconfig_overrides
|
75
|
+
projects_to_save = (user_projects_to_integrate + deintegrated_projects).uniq
|
76
|
+
save_projects(projects_to_save)
|
77
|
+
end
|
78
|
+
|
79
|
+
#-----------------------------------------------------------------------#
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
# @!group Integration steps
|
84
|
+
|
85
|
+
# Creates and saved the workspace containing the Pods project and the
|
86
|
+
# user projects, if needed.
|
87
|
+
#
|
88
|
+
# @note If the workspace already contains the projects it is not saved
|
89
|
+
# to avoid Xcode from displaying the revert dialog: `Do you want to
|
90
|
+
# keep the Xcode version or revert to the version on disk?`
|
91
|
+
#
|
92
|
+
# @return [void]
|
93
|
+
#
|
94
|
+
def create_workspace
|
95
|
+
all_projects = user_project_paths.sort.push(sandbox.project_path).uniq
|
96
|
+
file_references = all_projects.map do |path|
|
97
|
+
relative_path = path.relative_path_from(workspace_path.dirname).to_s
|
98
|
+
Xcodeproj::Workspace::FileReference.new(relative_path, 'group')
|
99
|
+
end
|
100
|
+
|
101
|
+
if workspace_path.exist?
|
102
|
+
workspace = Xcodeproj::Workspace.new_from_xcworkspace(workspace_path)
|
103
|
+
new_file_references = file_references - workspace.file_references
|
104
|
+
unless new_file_references.empty?
|
105
|
+
new_file_references.each { |fr| workspace << fr }
|
106
|
+
workspace.save_as(workspace_path)
|
107
|
+
end
|
108
|
+
|
109
|
+
else
|
110
|
+
UI.notice "Please close any current Xcode sessions and use `#{workspace_path.basename}` for this project from now on."
|
111
|
+
workspace = Xcodeproj::Workspace.new(*file_references)
|
112
|
+
workspace.save_as(workspace_path)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# Deintegrates the targets of the user projects that are no longer part of the installation.
|
117
|
+
#
|
118
|
+
# @return [Array<Xcodeproj::PBXProject>] The list of projects that were deintegrated.
|
119
|
+
#
|
120
|
+
def deintegrate_removed_targets
|
121
|
+
Config.instance.with_changes(:silent => true) do
|
122
|
+
deintegrator = Deintegrator.new
|
123
|
+
all_project_targets = user_projects.flat_map(&:native_targets).uniq
|
124
|
+
all_native_targets = targets.flat_map(&:user_targets).uniq
|
125
|
+
targets_to_deintegrate = all_project_targets - all_native_targets
|
126
|
+
targets_to_deintegrate.each do |target|
|
127
|
+
deintegrator.deintegrate_target(target)
|
128
|
+
end
|
129
|
+
return targets_to_deintegrate.map(&:project).select(&:dirty?).uniq
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# Integrates the targets of the user projects with the libraries
|
134
|
+
# generated from the {Podfile}.
|
135
|
+
#
|
136
|
+
# @note {TargetDefinition} without dependencies are skipped prevent
|
137
|
+
# creating empty libraries for targets definitions which are only
|
138
|
+
# wrappers for others.
|
139
|
+
#
|
140
|
+
# @return [void]
|
141
|
+
#
|
142
|
+
def integrate_user_targets
|
143
|
+
target_integrators = targets_to_integrate.sort_by(&:name).map do |target|
|
144
|
+
TargetIntegrator.new(target, :use_input_output_paths => use_input_output_paths?)
|
145
|
+
end
|
146
|
+
target_integrators.each(&:integrate!)
|
147
|
+
end
|
148
|
+
|
149
|
+
# Save all user projects.
|
150
|
+
#
|
151
|
+
# @param [Array<Xcodeproj::PBXProject>] projects The projects to save.
|
152
|
+
#
|
153
|
+
# @return [void]
|
154
|
+
#
|
155
|
+
def save_projects(projects)
|
156
|
+
projects.each do |project|
|
157
|
+
if project.dirty?
|
158
|
+
project.save
|
159
|
+
else
|
160
|
+
# There is a bug in Xcode where the process of deleting and
|
161
|
+
# re-creating the xcconfig files used in the build
|
162
|
+
# configuration cause building the user project to fail until
|
163
|
+
# Xcode is relaunched.
|
164
|
+
#
|
165
|
+
# Touching/saving the project causes Xcode to reload these.
|
166
|
+
#
|
167
|
+
# https://github.com/CocoaPods/CocoaPods/issues/2665
|
168
|
+
FileUtils.touch(project.path + 'project.pbxproj')
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
IGNORED_KEYS = %w(CODE_SIGN_IDENTITY).freeze
|
174
|
+
INHERITED_FLAGS = %w($(inherited) ${inherited}).freeze
|
175
|
+
|
176
|
+
# Checks whether the settings of the CocoaPods generated xcconfig are
|
177
|
+
# overridden by the build configuration of a target and prints a
|
178
|
+
# warning to inform the user if needed.
|
179
|
+
#
|
180
|
+
def warn_about_xcconfig_overrides
|
181
|
+
targets_to_integrate.each do |aggregate_target|
|
182
|
+
aggregate_target.user_targets.each do |user_target|
|
183
|
+
user_target.build_configurations.each do |config|
|
184
|
+
xcconfig = aggregate_target.xcconfigs[config.name]
|
185
|
+
if xcconfig
|
186
|
+
(xcconfig.to_hash.keys - IGNORED_KEYS).each do |key|
|
187
|
+
target_values = config.build_settings[key]
|
188
|
+
if target_values &&
|
189
|
+
!INHERITED_FLAGS.any? { |flag| target_values.include?(flag) }
|
190
|
+
print_override_warning(aggregate_target, user_target, config, key)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
private
|
200
|
+
|
201
|
+
# @!group Private Helpers
|
202
|
+
#-----------------------------------------------------------------------#
|
203
|
+
|
204
|
+
# @return [Pathname] the path where the workspace containing the Pods
|
205
|
+
# project and the user projects should be saved.
|
206
|
+
#
|
207
|
+
def workspace_path
|
208
|
+
if podfile.workspace_path
|
209
|
+
declared_path = podfile.workspace_path
|
210
|
+
path_with_ext = File.extname(declared_path) == '.xcworkspace' ? declared_path : "#{declared_path}.xcworkspace"
|
211
|
+
podfile_dir = File.dirname(podfile.defined_in_file || '')
|
212
|
+
absolute_path = File.expand_path(path_with_ext, podfile_dir)
|
213
|
+
Pathname.new(absolute_path)
|
214
|
+
elsif user_project_paths.count == 1
|
215
|
+
project = user_project_paths.first.basename('.xcodeproj')
|
216
|
+
installation_root + "#{project}.xcworkspace"
|
217
|
+
else
|
218
|
+
raise Informative, 'Could not automatically select an Xcode ' \
|
219
|
+
"workspace. Specify one in your Podfile like so:\n\n" \
|
220
|
+
" workspace 'path/to/Workspace.xcworkspace'\n"
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
# @return [Array<Xcodeproj::Project>] the projects of all the targets that require integration.
|
225
|
+
#
|
226
|
+
# @note Empty target definitions are ignored.
|
227
|
+
#
|
228
|
+
def user_projects_to_integrate
|
229
|
+
targets_to_integrate.map(&:user_project).compact.uniq
|
230
|
+
end
|
231
|
+
|
232
|
+
# @return [Array<Xcodeproj::Project>] the projects of all the targets regardless of whether they are integrated
|
233
|
+
# or not.
|
234
|
+
#
|
235
|
+
# @note Empty target definitions are ignored.
|
236
|
+
#
|
237
|
+
def user_projects
|
238
|
+
targets.map(&:user_project).compact.uniq
|
239
|
+
end
|
240
|
+
|
241
|
+
# @return [Array<Pathname>] the paths of all the user projects from all targets regardless of whether they are
|
242
|
+
# integrated or not.
|
243
|
+
#
|
244
|
+
# @note Empty target definitions are ignored.
|
245
|
+
#
|
246
|
+
def user_project_paths
|
247
|
+
targets.map(&:user_project_path).compact.uniq
|
248
|
+
end
|
249
|
+
|
250
|
+
# Prints a warning informing the user that a build configuration of
|
251
|
+
# the integrated target is overriding the CocoaPods build settings.
|
252
|
+
#
|
253
|
+
# @param [Target::AggregateTarget] aggregate_target
|
254
|
+
# The umbrella target.
|
255
|
+
#
|
256
|
+
# @param [Xcodeproj::PBXNativeTarget] user_target
|
257
|
+
# The native target.
|
258
|
+
#
|
259
|
+
# @param [Xcodeproj::XCBuildConfiguration] config
|
260
|
+
# The build configuration.
|
261
|
+
#
|
262
|
+
# @param [String] key
|
263
|
+
# The key of the overridden build setting.
|
264
|
+
#
|
265
|
+
def print_override_warning(aggregate_target, user_target, config, key)
|
266
|
+
actions = [
|
267
|
+
'Use the `$(inherited)` flag, or',
|
268
|
+
'Remove the build settings from the target.',
|
269
|
+
]
|
270
|
+
message = "The `#{user_target.name} [#{config.name}]` " \
|
271
|
+
"target overrides the `#{key}` build setting defined in " \
|
272
|
+
"`#{aggregate_target.xcconfig_relative_path(config.name)}'. " \
|
273
|
+
'This can lead to problems with the CocoaPods installation'
|
274
|
+
UI.warn(message, actions)
|
275
|
+
end
|
276
|
+
|
277
|
+
#-----------------------------------------------------------------------#
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module Pod
|
2
|
+
class Installer
|
3
|
+
class Xcode
|
4
|
+
# The {MultiPodsProjectGenerator} handles generation of the 'Pods/Pods.xcodeproj' and Xcode projects
|
5
|
+
# for every {PodTarget}. All Pod Target projects are nested under the 'Pods.xcodeproj'.
|
6
|
+
#
|
7
|
+
class MultiPodsProjectGenerator < PodsProjectGenerator
|
8
|
+
# Generates `Pods/Pods.xcodeproj` and all pod target subprojects.
|
9
|
+
#
|
10
|
+
# @return [PodsProjectGeneratorResult]
|
11
|
+
#
|
12
|
+
def generate!
|
13
|
+
# Generate container Pods.xcodeproj.
|
14
|
+
container_project = create_container_project(aggregate_targets, sandbox.project_path)
|
15
|
+
|
16
|
+
project_paths_by_pod_targets = pod_targets.group_by do |pod_target|
|
17
|
+
sandbox.pod_target_project_path(pod_target.project_name)
|
18
|
+
end
|
19
|
+
projects_by_pod_targets = Hash[project_paths_by_pod_targets.map do |project_path, pod_targets|
|
20
|
+
project = create_pods_project(pod_targets, project_path, container_project)
|
21
|
+
[project, pod_targets]
|
22
|
+
end]
|
23
|
+
|
24
|
+
# Note: We must call `install_file_references` on all pod targets before installing them.
|
25
|
+
pod_target_installation_results = install_all_pod_targets(projects_by_pod_targets)
|
26
|
+
aggregate_target_installation_results = install_aggregate_targets_into_project(container_project, aggregate_targets)
|
27
|
+
target_installation_results = InstallationResults.new(pod_target_installation_results, aggregate_target_installation_results)
|
28
|
+
|
29
|
+
integrate_targets(target_installation_results.pod_target_installation_results)
|
30
|
+
wire_target_dependencies(target_installation_results)
|
31
|
+
PodsProjectGeneratorResult.new(container_project, projects_by_pod_targets, target_installation_results)
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def create_container_project(aggregate_targets, path)
|
37
|
+
return unless aggregate_targets
|
38
|
+
platforms = aggregate_targets.map(&:platform)
|
39
|
+
ProjectGenerator.new(sandbox, path, [], build_configurations, platforms,
|
40
|
+
project_object_version, config.podfile_path).generate!
|
41
|
+
end
|
42
|
+
|
43
|
+
def create_pods_project(pod_targets, path, parent_project)
|
44
|
+
platforms = pod_targets.map(&:platform)
|
45
|
+
project = ProjectGenerator.new(sandbox, path, pod_targets, build_configurations, platforms,
|
46
|
+
project_object_version, false, :pod_target_subproject => true).generate!
|
47
|
+
# Instead of saving every subproject to disk, we can optimize this by creating a temporary folder
|
48
|
+
# the file reference can use so that we only have to call `save` once for all projects.
|
49
|
+
project.path.mkpath
|
50
|
+
if parent_project
|
51
|
+
pod_name = pod_name_from_grouping(pod_targets)
|
52
|
+
is_local = sandbox.local?(pod_name)
|
53
|
+
parent_project.add_pod_subproject(project, is_local)
|
54
|
+
end
|
55
|
+
|
56
|
+
install_file_references(project, pod_targets)
|
57
|
+
project
|
58
|
+
end
|
59
|
+
|
60
|
+
def install_all_pod_targets(projects_by_pod_targets)
|
61
|
+
UI.message '- Installing Pod Targets' do
|
62
|
+
projects_by_pod_targets.each_with_object({}) do |(project, pod_targets), target_installation_results|
|
63
|
+
target_installation_results.merge!(install_pod_targets(project, pod_targets))
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def install_aggregate_targets_into_project(project, aggregate_targets)
|
69
|
+
return {} unless project
|
70
|
+
install_aggregate_targets(project, aggregate_targets)
|
71
|
+
end
|
72
|
+
|
73
|
+
def pod_name_from_grouping(pod_targets)
|
74
|
+
# The presumption here for multi pods project is that we group by `pod_name`, thus the grouping of `pod_targets`
|
75
|
+
# should share the same `pod_name`.
|
76
|
+
raise '[BUG] Expected at least 1 pod target' if pod_targets.empty?
|
77
|
+
pod_targets.first.pod_name
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module Pod
|
2
|
+
class Installer
|
3
|
+
class Xcode
|
4
|
+
# Wires up the dependencies for aggregate targets from the target installation results
|
5
|
+
#
|
6
|
+
class AggregateTargetDependencyInstaller
|
7
|
+
require 'cocoapods/native_target_extension.rb'
|
8
|
+
|
9
|
+
# @return [Hash{String => TargetInstallationResult}] The target installation results for pod targets.
|
10
|
+
#
|
11
|
+
attr_reader :pod_target_installation_results
|
12
|
+
|
13
|
+
# @return [Hash{String => TargetInstallationResult}] The target installation results for aggregate targets.
|
14
|
+
#
|
15
|
+
attr_reader :aggregate_target_installation_results
|
16
|
+
|
17
|
+
# @return [ProjectMetadataCache] The project metadata cache.
|
18
|
+
#
|
19
|
+
attr_reader :metadata_cache
|
20
|
+
|
21
|
+
# @return [Sandbox] The sandbox used for this installation.
|
22
|
+
#
|
23
|
+
attr_reader :sandbox
|
24
|
+
|
25
|
+
# Initialize a new instance.
|
26
|
+
#
|
27
|
+
# @param [Sandbox] sandbox @see #sandbox
|
28
|
+
# @param [Hash{String => TargetInstallationResult}] aggregate_target_installation_results @see #aggregate_target_installation_results
|
29
|
+
# @param [Hash{String => TargetInstallationResult}] pod_target_installation_results @see #pod_target_installation_results
|
30
|
+
# @param [ProjectMetadataCache] metadata_cache @see #metadata_cache
|
31
|
+
#
|
32
|
+
def initialize(sandbox, aggregate_target_installation_results, pod_target_installation_results, metadata_cache)
|
33
|
+
@sandbox = sandbox
|
34
|
+
@aggregate_target_installation_results = aggregate_target_installation_results
|
35
|
+
@pod_target_installation_results = pod_target_installation_results
|
36
|
+
@metadata_cache = metadata_cache
|
37
|
+
end
|
38
|
+
|
39
|
+
def install!
|
40
|
+
aggregate_target_installation_results.values.each do |aggregate_target_installation_result|
|
41
|
+
aggregate_target = aggregate_target_installation_result.target
|
42
|
+
aggregate_native_target = aggregate_target_installation_result.native_target
|
43
|
+
project = aggregate_native_target.project
|
44
|
+
# Wire up dependencies that are part of inherit search paths for this aggregate target.
|
45
|
+
aggregate_target.search_paths_aggregate_targets.each do |search_paths_target|
|
46
|
+
aggregate_native_target.add_dependency(aggregate_target_installation_results[search_paths_target.name].native_target)
|
47
|
+
end
|
48
|
+
# Wire up all pod target dependencies to aggregate target.
|
49
|
+
aggregate_target.pod_targets.each do |pod_target|
|
50
|
+
if pod_target_installation_result = pod_target_installation_results[pod_target.name]
|
51
|
+
pod_target_native_target = pod_target_installation_result.native_target
|
52
|
+
aggregate_native_target.add_dependency(pod_target_native_target)
|
53
|
+
else
|
54
|
+
# Hit the cache
|
55
|
+
is_local = sandbox.local?(pod_target.pod_name)
|
56
|
+
cached_dependency = metadata_cache.target_label_by_metadata[pod_target.label]
|
57
|
+
project.add_cached_pod_subproject(sandbox, cached_dependency, is_local)
|
58
|
+
Project.add_cached_dependency(sandbox, aggregate_native_target, cached_dependency)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/aggregate_target_installer.rb
ADDED
@@ -0,0 +1,192 @@
|
|
1
|
+
module Pod
|
2
|
+
class Installer
|
3
|
+
class Xcode
|
4
|
+
class PodsProjectGenerator
|
5
|
+
# Creates the targets which aggregate the Pods libraries in the Pods
|
6
|
+
# project and the relative support files.
|
7
|
+
#
|
8
|
+
class AggregateTargetInstaller < TargetInstaller
|
9
|
+
# @return [AggregateTarget] @see TargetInstaller#target
|
10
|
+
#
|
11
|
+
attr_reader :target
|
12
|
+
|
13
|
+
# Creates the target in the Pods project and the relative support files.
|
14
|
+
#
|
15
|
+
# @return [TargetInstallationResult] the result of the installation of this target.
|
16
|
+
#
|
17
|
+
def install!
|
18
|
+
UI.message "- Installing target `#{target.name}` #{target.platform}" do
|
19
|
+
native_target = add_target
|
20
|
+
create_support_files_dir
|
21
|
+
create_support_files_group
|
22
|
+
create_xcconfig_file(native_target)
|
23
|
+
if target.build_as_framework?
|
24
|
+
create_info_plist_file(target.info_plist_path, native_target, target.version, target.platform)
|
25
|
+
create_module_map(native_target)
|
26
|
+
create_umbrella_header(native_target)
|
27
|
+
elsif target.uses_swift?
|
28
|
+
create_module_map(native_target)
|
29
|
+
create_umbrella_header(native_target)
|
30
|
+
end
|
31
|
+
# Because embedded targets live in their host target, CocoaPods
|
32
|
+
# copies all of the embedded target's pod_targets to its host
|
33
|
+
# targets. Having this script for the embedded target would
|
34
|
+
# cause an App Store rejection because frameworks cannot be
|
35
|
+
# embedded in embedded targets.
|
36
|
+
#
|
37
|
+
create_embed_frameworks_script if embed_frameworks_script_required?
|
38
|
+
create_bridge_support_file(native_target)
|
39
|
+
create_copy_resources_script if target.includes_resources?
|
40
|
+
create_acknowledgements
|
41
|
+
create_dummy_source(native_target)
|
42
|
+
clean_support_files_temp_dir
|
43
|
+
TargetInstallationResult.new(target, native_target)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
#-----------------------------------------------------------------------#
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
# @return [TargetDefinition] the target definition of the library.
|
52
|
+
#
|
53
|
+
def target_definition
|
54
|
+
target.target_definition
|
55
|
+
end
|
56
|
+
|
57
|
+
# Ensure that vendored static frameworks and libraries are not linked
|
58
|
+
# twice to the aggregate target, which shares the xcconfig of the user
|
59
|
+
# target.
|
60
|
+
#
|
61
|
+
def custom_build_settings
|
62
|
+
settings = {
|
63
|
+
'CODE_SIGN_IDENTITY[sdk=appletvos*]' => '',
|
64
|
+
'CODE_SIGN_IDENTITY[sdk=iphoneos*]' => '',
|
65
|
+
'CODE_SIGN_IDENTITY[sdk=watchos*]' => '',
|
66
|
+
'MACH_O_TYPE' => 'staticlib',
|
67
|
+
'OTHER_LDFLAGS' => '',
|
68
|
+
'OTHER_LIBTOOLFLAGS' => '',
|
69
|
+
'PODS_ROOT' => '$(SRCROOT)',
|
70
|
+
'PRODUCT_BUNDLE_IDENTIFIER' => 'org.cocoapods.${PRODUCT_NAME:rfc1034identifier}',
|
71
|
+
'SKIP_INSTALL' => 'YES',
|
72
|
+
|
73
|
+
# Needed to ensure that static libraries won't try to embed the swift stdlib,
|
74
|
+
# since there's no where to embed in for a static library.
|
75
|
+
# Not necessary for dynamic frameworks either, since the aggregate targets are never shipped
|
76
|
+
# on their own, and are always further embedded into an app target.
|
77
|
+
'ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES' => 'NO',
|
78
|
+
}
|
79
|
+
super.merge(settings)
|
80
|
+
end
|
81
|
+
|
82
|
+
# @return [Boolean] whether this target requires an `Embed Frameworks` script phase
|
83
|
+
#
|
84
|
+
def embed_frameworks_script_required?
|
85
|
+
includes_dynamic_xcframeworks = target.xcframeworks_by_config.values.flatten.map(&:build_type).any?(&:dynamic_framework?)
|
86
|
+
(target.includes_frameworks? || includes_dynamic_xcframeworks) && !target.requires_host_target?
|
87
|
+
end
|
88
|
+
|
89
|
+
# Creates the group that holds the references to the support files
|
90
|
+
# generated by this installer.
|
91
|
+
#
|
92
|
+
# @return [void]
|
93
|
+
#
|
94
|
+
def create_support_files_group
|
95
|
+
parent = project.support_files_group
|
96
|
+
name = target.name
|
97
|
+
dir = target.support_files_dir
|
98
|
+
@support_files_group = parent.new_group(name, dir)
|
99
|
+
end
|
100
|
+
|
101
|
+
# Generates the contents of the xcconfig file and saves it to disk.
|
102
|
+
#
|
103
|
+
# @param [PBXNativeTarget] native_target
|
104
|
+
# the native target to link the module map file into.
|
105
|
+
#
|
106
|
+
# @return [void]
|
107
|
+
#
|
108
|
+
def create_xcconfig_file(native_target)
|
109
|
+
native_target.build_configurations.each do |configuration|
|
110
|
+
next unless target.user_build_configurations.key?(configuration.name)
|
111
|
+
path = target.xcconfig_path(configuration.name)
|
112
|
+
build_settings = target.build_settings(configuration.name)
|
113
|
+
update_changed_file(build_settings, path)
|
114
|
+
target.xcconfigs[configuration.name] = build_settings.xcconfig
|
115
|
+
xcconfig_file_ref = add_file_to_support_group(path)
|
116
|
+
configuration.base_configuration_reference = xcconfig_file_ref
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# Generates the bridge support metadata if requested by the {Podfile}.
|
121
|
+
#
|
122
|
+
# @note The bridge support metadata is added to the resources of the
|
123
|
+
# target because it is needed for environments interpreted at
|
124
|
+
# runtime.
|
125
|
+
#
|
126
|
+
# @param [PBXNativeTarget] native_target
|
127
|
+
# the native target to add the bridge support file into.
|
128
|
+
#
|
129
|
+
# @return [void]
|
130
|
+
#
|
131
|
+
def create_bridge_support_file(native_target)
|
132
|
+
if target.podfile.generate_bridge_support?
|
133
|
+
path = target.bridge_support_path
|
134
|
+
headers = native_target.headers_build_phase.files.map { |bf| sandbox.root + bf.file_ref.path }
|
135
|
+
generator = Generator::BridgeSupport.new(headers)
|
136
|
+
update_changed_file(generator, path)
|
137
|
+
add_file_to_support_group(path)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
# Creates a script that copies the resources to the bundle of the client
|
142
|
+
# target.
|
143
|
+
#
|
144
|
+
# @note The bridge support file needs to be created before the prefix
|
145
|
+
# header, otherwise it will not be added to the resources script.
|
146
|
+
#
|
147
|
+
# @return [void]
|
148
|
+
#
|
149
|
+
def create_copy_resources_script
|
150
|
+
path = target.copy_resources_script_path
|
151
|
+
generator = Generator::CopyResourcesScript.new(target.resource_paths_by_config, target.platform)
|
152
|
+
update_changed_file(generator, path)
|
153
|
+
add_file_to_support_group(path)
|
154
|
+
end
|
155
|
+
|
156
|
+
# Creates a script that embeds the frameworks to the bundle of the client
|
157
|
+
# target.
|
158
|
+
#
|
159
|
+
# @note We can't use Xcode default link libraries phase, because
|
160
|
+
# we need to ensure that we only copy the frameworks which are
|
161
|
+
# relevant for the current build configuration.
|
162
|
+
#
|
163
|
+
# @return [void]
|
164
|
+
#
|
165
|
+
def create_embed_frameworks_script
|
166
|
+
path = target.embed_frameworks_script_path
|
167
|
+
generator = Generator::EmbedFrameworksScript.new(target.framework_paths_by_config, target.xcframeworks_by_config)
|
168
|
+
update_changed_file(generator, path)
|
169
|
+
add_file_to_support_group(path)
|
170
|
+
end
|
171
|
+
|
172
|
+
# Generates the acknowledgement files (markdown and plist) for the target.
|
173
|
+
#
|
174
|
+
# @return [void]
|
175
|
+
#
|
176
|
+
def create_acknowledgements
|
177
|
+
basepath = target.acknowledgements_basepath
|
178
|
+
Generator::Acknowledgements.generators.each do |generator_class|
|
179
|
+
path = generator_class.path_from_basepath(basepath)
|
180
|
+
file_accessors = target.pod_targets.map(&:file_accessors).flatten
|
181
|
+
generator = generator_class.new(file_accessors)
|
182
|
+
update_changed_file(generator, path)
|
183
|
+
add_file_to_support_group(path)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
#-----------------------------------------------------------------------#
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|