cocoapods 1.2.1 → 1.3.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +89 -1
- data/lib/cocoapods/command/lib/lint.rb +3 -0
- data/lib/cocoapods/command/repo/push.rb +1 -1
- data/lib/cocoapods/command/spec/lint.rb +3 -0
- data/lib/cocoapods/gem_version.rb +1 -1
- data/lib/cocoapods/generator/copy_resources_script.rb +11 -11
- data/lib/cocoapods/generator/embed_frameworks_script.rb +18 -6
- data/lib/cocoapods/generator/xcconfig/aggregate_xcconfig.rb +6 -66
- data/lib/cocoapods/generator/xcconfig/pod_xcconfig.rb +16 -3
- data/lib/cocoapods/generator/xcconfig/xcconfig_helper.rb +102 -6
- data/lib/cocoapods/installer.rb +17 -76
- data/lib/cocoapods/installer/analyzer.rb +48 -44
- data/lib/cocoapods/installer/xcode.rb +1 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator.rb +22 -9
- data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_installer.rb +11 -5
- data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +78 -5
- data/lib/cocoapods/installer/xcode/target_validator.rb +126 -0
- data/lib/cocoapods/project.rb +5 -0
- data/lib/cocoapods/resolver.rb +1 -1
- data/lib/cocoapods/resolver/lazy_specification.rb +2 -2
- data/lib/cocoapods/sandbox.rb +23 -0
- data/lib/cocoapods/target/pod_target.rb +72 -5
- data/lib/cocoapods/validator.rb +101 -46
- metadata +9 -8
data/lib/cocoapods/installer.rb
CHANGED
@@ -71,6 +71,7 @@ module Pod
|
|
71
71
|
@lockfile = lockfile
|
72
72
|
|
73
73
|
@use_default_plugins = true
|
74
|
+
@has_dependencies = true
|
74
75
|
end
|
75
76
|
|
76
77
|
# @return [Hash, Boolean, nil] Pods that have been requested to be
|
@@ -80,6 +81,11 @@ module Pod
|
|
80
81
|
#
|
81
82
|
attr_accessor :update
|
82
83
|
|
84
|
+
# @return [Boolean] Whether it has dependencies. Defaults to true.
|
85
|
+
#
|
86
|
+
attr_accessor :has_dependencies
|
87
|
+
alias_method :has_dependencies?, :has_dependencies
|
88
|
+
|
83
89
|
# @return [Boolean] Whether the spec repos should be updated.
|
84
90
|
#
|
85
91
|
attr_accessor :repo_update
|
@@ -109,9 +115,7 @@ module Pod
|
|
109
115
|
prepare
|
110
116
|
resolve_dependencies
|
111
117
|
download_dependencies
|
112
|
-
|
113
|
-
verify_no_static_framework_transitive_dependencies
|
114
|
-
verify_framework_usage
|
118
|
+
validate_targets
|
115
119
|
generate_pods_project
|
116
120
|
if installation_options.integrate_targets?
|
117
121
|
integrate_user_project
|
@@ -214,7 +218,9 @@ module Pod
|
|
214
218
|
# generated as result of the analyzer.
|
215
219
|
#
|
216
220
|
def pod_targets
|
217
|
-
aggregate_targets.map(&:pod_targets).flatten
|
221
|
+
aggregate_target_pod_targets = aggregate_targets.map(&:pod_targets).flatten
|
222
|
+
test_dependent_targets = aggregate_target_pod_targets.map(&:test_dependent_targets).flatten
|
223
|
+
(aggregate_target_pod_targets + test_dependent_targets).uniq
|
218
224
|
end
|
219
225
|
|
220
226
|
# @return [Array<Specification>] The specifications that where installed.
|
@@ -240,6 +246,7 @@ module Pod
|
|
240
246
|
def create_analyzer
|
241
247
|
Analyzer.new(sandbox, podfile, lockfile).tap do |analyzer|
|
242
248
|
analyzer.installation_options = installation_options
|
249
|
+
analyzer.has_dependencies = has_dependencies?
|
243
250
|
end
|
244
251
|
end
|
245
252
|
|
@@ -286,19 +293,11 @@ module Pod
|
|
286
293
|
end
|
287
294
|
end
|
288
295
|
|
289
|
-
#
|
290
|
-
#
|
296
|
+
# @return [void] In this step we create the file accessors for the pod
|
297
|
+
# targets.
|
291
298
|
#
|
292
299
|
def create_file_accessors
|
293
|
-
pod_targets
|
294
|
-
pod_root = sandbox.pod_dir(pod_target.root_spec.name)
|
295
|
-
path_list = Sandbox::PathList.new(pod_root)
|
296
|
-
file_accessors = pod_target.specs.map do |spec|
|
297
|
-
Sandbox::FileAccessor.new(path_list, spec.consumer(pod_target.platform))
|
298
|
-
end
|
299
|
-
pod_target.file_accessors ||= []
|
300
|
-
pod_target.file_accessors.concat(file_accessors)
|
301
|
-
end
|
300
|
+
sandbox.create_file_accessors(pod_targets)
|
302
301
|
end
|
303
302
|
|
304
303
|
# Downloads, installs the documentation and cleans the sources of the Pods
|
@@ -393,67 +392,9 @@ module Pod
|
|
393
392
|
end
|
394
393
|
end
|
395
394
|
|
396
|
-
def
|
397
|
-
aggregate_targets
|
398
|
-
|
399
|
-
pod_targets = aggregate_target.pod_targets_for_build_configuration(config)
|
400
|
-
file_accessors = pod_targets.flat_map(&:file_accessors)
|
401
|
-
|
402
|
-
frameworks = file_accessors.flat_map(&:vendored_frameworks).uniq.map(&:basename)
|
403
|
-
frameworks += pod_targets.select { |pt| pt.should_build? && pt.requires_frameworks? }.map(&:product_module_name)
|
404
|
-
verify_no_duplicate_names(frameworks, aggregate_target.label, 'frameworks')
|
405
|
-
|
406
|
-
libraries = file_accessors.flat_map(&:vendored_libraries).uniq.map(&:basename)
|
407
|
-
libraries += pod_targets.select { |pt| pt.should_build? && !pt.requires_frameworks? }.map(&:product_name)
|
408
|
-
verify_no_duplicate_names(libraries, aggregate_target.label, 'libraries')
|
409
|
-
end
|
410
|
-
end
|
411
|
-
end
|
412
|
-
|
413
|
-
def verify_no_duplicate_names(names, label, type)
|
414
|
-
duplicates = names.map { |n| n.to_s.downcase }.group_by { |f| f }.select { |_, v| v.size > 1 }.keys
|
415
|
-
|
416
|
-
unless duplicates.empty?
|
417
|
-
raise Informative, "The '#{label}' target has " \
|
418
|
-
"#{type} with conflicting names: #{duplicates.to_sentence}."
|
419
|
-
end
|
420
|
-
end
|
421
|
-
|
422
|
-
def verify_no_static_framework_transitive_dependencies
|
423
|
-
aggregate_targets.each do |aggregate_target|
|
424
|
-
next unless aggregate_target.requires_frameworks?
|
425
|
-
|
426
|
-
aggregate_target.user_build_configurations.keys.each do |config|
|
427
|
-
pod_targets = aggregate_target.pod_targets_for_build_configuration(config)
|
428
|
-
|
429
|
-
dependencies = pod_targets.select(&:should_build?).flat_map(&:dependencies)
|
430
|
-
dependended_upon_targets = pod_targets.select { |t| dependencies.include?(t.pod_name) && !t.should_build? }
|
431
|
-
|
432
|
-
static_libs = dependended_upon_targets.flat_map(&:file_accessors).flat_map(&:vendored_static_artifacts)
|
433
|
-
unless static_libs.empty?
|
434
|
-
raise Informative, "The '#{aggregate_target.label}' target has " \
|
435
|
-
"transitive dependencies that include static binaries: (#{static_libs.to_sentence})"
|
436
|
-
end
|
437
|
-
end
|
438
|
-
end
|
439
|
-
end
|
440
|
-
|
441
|
-
def verify_framework_usage
|
442
|
-
aggregate_targets.each do |aggregate_target|
|
443
|
-
next if aggregate_target.requires_frameworks?
|
444
|
-
|
445
|
-
aggregate_target.user_build_configurations.keys.each do |config|
|
446
|
-
pod_targets = aggregate_target.pod_targets_for_build_configuration(config)
|
447
|
-
|
448
|
-
swift_pods = pod_targets.select(&:uses_swift?)
|
449
|
-
unless swift_pods.empty?
|
450
|
-
raise Informative, 'Pods written in Swift can only be integrated as frameworks; ' \
|
451
|
-
'add `use_frameworks!` to your Podfile or target to opt into using it. ' \
|
452
|
-
"The Swift #{swift_pods.size == 1 ? 'Pod being used is' : 'Pods being used are'}: " +
|
453
|
-
swift_pods.map(&:name).to_sentence
|
454
|
-
end
|
455
|
-
end
|
456
|
-
end
|
395
|
+
def validate_targets
|
396
|
+
validator = Xcode::TargetValidator.new(aggregate_targets, pod_targets)
|
397
|
+
validator.validate!
|
457
398
|
end
|
458
399
|
|
459
400
|
# Runs the registered callbacks for the plugins pre install hooks.
|
@@ -45,6 +45,7 @@ module Pod
|
|
45
45
|
|
46
46
|
@update = false
|
47
47
|
@allow_pre_downloads = true
|
48
|
+
@has_dependencies = true
|
48
49
|
end
|
49
50
|
|
50
51
|
# Performs the analysis.
|
@@ -152,6 +153,15 @@ module Pod
|
|
152
153
|
attr_accessor :allow_pre_downloads
|
153
154
|
alias_method :allow_pre_downloads?, :allow_pre_downloads
|
154
155
|
|
156
|
+
# @return [Bool] Whether the analysis has dependencies and thus
|
157
|
+
# sources must be configured.
|
158
|
+
#
|
159
|
+
# @note This is used by the `pod lib lint` command to prevent
|
160
|
+
# update of specs when not needed.
|
161
|
+
#
|
162
|
+
attr_accessor :has_dependencies
|
163
|
+
alias_method :has_dependencies?, :has_dependencies
|
164
|
+
|
155
165
|
#-----------------------------------------------------------------------#
|
156
166
|
|
157
167
|
private
|
@@ -313,12 +323,12 @@ module Pod
|
|
313
323
|
end
|
314
324
|
|
315
325
|
unless embedded_targets_missing_hosts.empty?
|
316
|
-
embedded_targets_missing_hosts_product_types = embedded_targets_missing_hosts.map(&:user_targets).flatten.map(&:symbol_type)
|
326
|
+
embedded_targets_missing_hosts_product_types = Set.new embedded_targets_missing_hosts.map(&:user_targets).flatten.map(&:symbol_type)
|
317
327
|
# If the targets missing hosts are only frameworks, then this is likely
|
318
328
|
# a project for doing framework development. In that case, just warn that
|
319
329
|
# the frameworks that these targets depend on won't be integrated anywhere
|
320
|
-
if embedded_targets_missing_hosts_product_types
|
321
|
-
UI.warn 'The Podfile contains framework targets, for which the Podfile does not contain host targets (targets which embed the framework).' \
|
330
|
+
if embedded_targets_missing_hosts_product_types.subset?(Set.new([:framework, :static_library]))
|
331
|
+
UI.warn 'The Podfile contains framework or static library targets, for which the Podfile does not contain host targets (targets which embed the framework).' \
|
322
332
|
"\n" \
|
323
333
|
'If this project is for doing framework development, you can ignore this message. Otherwise, add a target to the Podfile that embeds these frameworks to make this message go away (e.g. a test target).'
|
324
334
|
else
|
@@ -357,7 +367,6 @@ module Pod
|
|
357
367
|
#
|
358
368
|
def generate_targets
|
359
369
|
specs_by_target = result.specs_by_target.reject { |td, _| td.abstract? }
|
360
|
-
check_pod_target_swift_versions(specs_by_target)
|
361
370
|
pod_targets = generate_pod_targets(specs_by_target)
|
362
371
|
aggregate_targets = specs_by_target.keys.map do |target_definition|
|
363
372
|
generate_target(target_definition, pod_targets)
|
@@ -419,43 +428,30 @@ module Pod
|
|
419
428
|
end
|
420
429
|
|
421
430
|
target.pod_targets = pod_targets.select do |pod_target|
|
422
|
-
pod_target.target_definitions.include?(target_definition)
|
431
|
+
target_definition_included = pod_target.target_definitions.include?(target_definition)
|
432
|
+
explicitly_defined_in_target_definition = target_definition.non_inherited_dependencies.map(&:name).include?(pod_target.name)
|
433
|
+
test_pod_target_only = pod_target_test_only?(pod_target, pod_targets)
|
434
|
+
target_definition_included && (explicitly_defined_in_target_definition || !test_pod_target_only)
|
423
435
|
end
|
424
436
|
|
425
437
|
target
|
426
438
|
end
|
427
439
|
|
428
|
-
#
|
440
|
+
# Returns true if a pod target is only used by other pod targets as a test dependency and therefore should
|
441
|
+
# not be included as part of the aggregate target.
|
429
442
|
#
|
430
|
-
# @param
|
431
|
-
#
|
443
|
+
# @param [PodTarget] pod_target
|
444
|
+
# the pod target being queried
|
432
445
|
#
|
433
|
-
# @
|
434
|
-
#
|
446
|
+
# @param [Array<PodTarget>] pod_targets
|
447
|
+
# the array of pod targets to check against
|
435
448
|
#
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
end
|
443
|
-
|
444
|
-
error_message_for_target = lambda do |target|
|
445
|
-
"#{target.name} (Swift #{target.swift_version})"
|
446
|
-
end
|
447
|
-
|
448
|
-
error_messages = targets_by_spec.map do |spec, targets|
|
449
|
-
swift_targets = targets.reject { |target| target.swift_version.blank? }
|
450
|
-
next if swift_targets.empty? || swift_targets.uniq(&:swift_version).count == 1
|
451
|
-
target_errors = swift_targets.map(&error_message_for_target).join(', ')
|
452
|
-
"- #{spec.name} required by #{target_errors}"
|
453
|
-
end.compact
|
454
|
-
|
455
|
-
unless error_messages.empty?
|
456
|
-
raise Informative, 'The following pods are integrated into targets ' \
|
457
|
-
"that do not have the same Swift version:\n\n#{error_messages.join("\n")}"
|
458
|
-
end
|
449
|
+
# @return [Boolean] if the pod target is only referenced from test dependencies.
|
450
|
+
#
|
451
|
+
def pod_target_test_only?(pod_target, pod_targets)
|
452
|
+
source = pod_targets.any? { |pt| pt.dependent_targets.map(&:name).include?(pod_target.name) }
|
453
|
+
test = pod_targets.any? { |pt| pt.test_dependent_targets.map(&:name).include?(pod_target.name) }
|
454
|
+
!source && test
|
459
455
|
end
|
460
456
|
|
461
457
|
# Setup the pod targets for an aggregate target. Deduplicates resulting
|
@@ -492,15 +488,10 @@ module Pod
|
|
492
488
|
hash[name] = values.sort_by { |pt| pt.specs.count }
|
493
489
|
end
|
494
490
|
pod_targets.each do |target|
|
495
|
-
dependencies = transitive_dependencies_for_specs(target.specs, target.platform, all_specs).group_by(&:root)
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
t.requires_frameworks? != target.requires_frameworks?
|
500
|
-
spec_names = t.specs.map(&:name)
|
501
|
-
deps.all? { |dep| spec_names.include?(dep.name) }
|
502
|
-
end
|
503
|
-
end
|
491
|
+
dependencies = transitive_dependencies_for_specs(target.specs.reject(&:test_specification?), target.platform, all_specs).group_by(&:root)
|
492
|
+
test_dependencies = transitive_dependencies_for_specs(target.specs.select(&:test_specification?), target.platform, all_specs).group_by(&:root)
|
493
|
+
target.dependent_targets = filter_dependencies(dependencies, pod_targets_by_name, target)
|
494
|
+
target.test_dependent_targets = filter_dependencies(test_dependencies, pod_targets_by_name, target)
|
504
495
|
end
|
505
496
|
else
|
506
497
|
dedupe_cache = {}
|
@@ -512,12 +503,25 @@ module Pod
|
|
512
503
|
|
513
504
|
pod_targets.each do |target|
|
514
505
|
dependencies = transitive_dependencies_for_specs(target.specs, target.platform, specs).group_by(&:root)
|
506
|
+
test_dependencies = transitive_dependencies_for_specs(target.specs.select(&:test_specification?), target.platform, all_specs).group_by(&:root)
|
515
507
|
target.dependent_targets = pod_targets.reject { |t| dependencies[t.root_spec].nil? }
|
508
|
+
target.test_dependent_targets = pod_targets.reject { |t| test_dependencies[t.root_spec].nil? }
|
516
509
|
end
|
517
510
|
end
|
518
511
|
end
|
519
512
|
end
|
520
513
|
|
514
|
+
def filter_dependencies(dependencies, pod_targets_by_name, target)
|
515
|
+
dependencies.map do |root_spec, deps|
|
516
|
+
pod_targets_by_name[root_spec.name].find do |t|
|
517
|
+
next false if t.platform.symbolic_name != target.platform.symbolic_name ||
|
518
|
+
t.requires_frameworks? != target.requires_frameworks?
|
519
|
+
spec_names = t.specs.map(&:name)
|
520
|
+
deps.all? { |dep| spec_names.include?(dep.name) }
|
521
|
+
end
|
522
|
+
end
|
523
|
+
end
|
524
|
+
|
521
525
|
# Returns the specs upon which the given specs _transitively_ depend.
|
522
526
|
#
|
523
527
|
# @note: This is implemented in the analyzer, because we don't have to
|
@@ -819,11 +823,11 @@ module Pod
|
|
819
823
|
|
820
824
|
# Add any sources specified using the :source flag on individual dependencies.
|
821
825
|
dependency_sources = podfile.dependencies.map(&:podspec_repo).compact
|
822
|
-
|
823
826
|
all_dependencies_have_sources = dependency_sources.count == podfile.dependencies.count
|
827
|
+
|
824
828
|
if all_dependencies_have_sources
|
825
829
|
sources = dependency_sources
|
826
|
-
elsif sources.empty?
|
830
|
+
elsif has_dependencies? && sources.empty?
|
827
831
|
sources = ['https://github.com/CocoaPods/Specs.git']
|
828
832
|
else
|
829
833
|
sources += dependency_sources
|
@@ -86,6 +86,11 @@ module Pod
|
|
86
86
|
development_pod_targets.select(&:should_build?).each do |pod_target|
|
87
87
|
next unless share_scheme_for_development_pod?(pod_target.pod_name)
|
88
88
|
Xcodeproj::XCScheme.share_scheme(project.path, pod_target.label)
|
89
|
+
if pod_target.contains_test_specifications?
|
90
|
+
pod_target.supported_test_types.each do |test_type|
|
91
|
+
Xcodeproj::XCScheme.share_scheme(project.path, pod_target.test_target_label(test_type))
|
92
|
+
end
|
93
|
+
end
|
89
94
|
end
|
90
95
|
end
|
91
96
|
|
@@ -203,16 +208,10 @@ module Pod
|
|
203
208
|
aggregate_target.native_target.add_dependency(pod_target.native_target)
|
204
209
|
configure_app_extension_api_only_for_target(pod_target) if is_app_extension
|
205
210
|
|
206
|
-
pod_target.dependent_targets.
|
207
|
-
next unless pod_dependency_target.should_build?
|
208
|
-
pod_target.native_target.add_dependency(pod_dependency_target.native_target)
|
209
|
-
configure_app_extension_api_only_for_target(pod_dependency_target) if is_app_extension
|
211
|
+
add_dependent_targets_to_native_target(pod_target.dependent_targets, pod_target.native_target, is_app_extension, pod_target.requires_frameworks?, frameworks_group)
|
210
212
|
|
211
|
-
|
212
|
-
|
213
|
-
frameworks_group.new_product_ref_for_target(pod_dependency_target.product_basename, pod_dependency_target.product_type)
|
214
|
-
pod_target.native_target.frameworks_build_phase.add_file_reference(product_ref, true)
|
215
|
-
end
|
213
|
+
pod_target.test_native_targets.each do |test_native_target|
|
214
|
+
add_dependent_targets_to_native_target([pod_target, *pod_target.test_dependent_targets], test_native_target, false, pod_target.requires_frameworks?, frameworks_group)
|
216
215
|
end
|
217
216
|
end
|
218
217
|
end
|
@@ -251,6 +250,20 @@ module Pod
|
|
251
250
|
|
252
251
|
private
|
253
252
|
|
253
|
+
def add_dependent_targets_to_native_target(dependent_targets, native_target, is_app_extension, requires_frameworks, frameworks_group)
|
254
|
+
dependent_targets.each do |pod_dependency_target|
|
255
|
+
next unless pod_dependency_target.should_build?
|
256
|
+
native_target.add_dependency(pod_dependency_target.native_target)
|
257
|
+
configure_app_extension_api_only_for_target(pod_dependency_target) if is_app_extension
|
258
|
+
|
259
|
+
if requires_frameworks
|
260
|
+
product_ref = frameworks_group.files.find { |f| f.path == pod_dependency_target.product_name } ||
|
261
|
+
frameworks_group.new_product_ref_for_target(pod_dependency_target.product_basename, pod_dependency_target.product_type)
|
262
|
+
native_target.frameworks_build_phase.add_file_reference(product_ref, true)
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
254
267
|
# Sets the APPLICATION_EXTENSION_API_ONLY build setting to YES for all
|
255
268
|
# configurations of the given target
|
256
269
|
#
|
@@ -158,18 +158,24 @@ module Pod
|
|
158
158
|
#
|
159
159
|
def create_embed_frameworks_script
|
160
160
|
path = target.embed_frameworks_script_path
|
161
|
-
|
161
|
+
frameworks_and_dsyms_by_config = {}
|
162
162
|
target.user_build_configurations.keys.each do |config|
|
163
163
|
relevant_pod_targets = target.pod_targets.select do |pod_target|
|
164
164
|
pod_target.include_in_build_config?(target_definition, config)
|
165
165
|
end
|
166
|
-
|
167
|
-
frameworks = pod_target.file_accessors.flat_map(&:vendored_dynamic_artifacts).map
|
168
|
-
|
166
|
+
frameworks_and_dsyms_by_config[config] = relevant_pod_targets.flat_map do |pod_target|
|
167
|
+
frameworks = pod_target.file_accessors.flat_map(&:vendored_dynamic_artifacts).map do |fw|
|
168
|
+
path_to_framework = "${PODS_ROOT}/#{fw.relative_path_from(sandbox.root)}"
|
169
|
+
# Until this can be configured, assume the dSYM file uses the file name as the framework.
|
170
|
+
# See https://github.com/CocoaPods/CocoaPods/issues/1698
|
171
|
+
{ :framework => path_to_framework, :dSYM => "#{path_to_framework}.dSYM" }
|
172
|
+
end
|
173
|
+
# For non vendored frameworks Xcode will generate the dSYM and copy it instead.
|
174
|
+
frameworks << { :framework => pod_target.build_product_path('$BUILT_PRODUCTS_DIR'), :dSYM => nil } if pod_target.should_build? && pod_target.requires_frameworks?
|
169
175
|
frameworks
|
170
176
|
end
|
171
177
|
end
|
172
|
-
generator = Generator::EmbedFrameworksScript.new(
|
178
|
+
generator = Generator::EmbedFrameworksScript.new(frameworks_and_dsyms_by_config)
|
173
179
|
generator.save_as(path)
|
174
180
|
add_file_to_support_group(path)
|
175
181
|
end
|
@@ -18,20 +18,24 @@ module Pod
|
|
18
18
|
|
19
19
|
UI.message "- Installing target `#{target.name}` #{target.platform}" do
|
20
20
|
add_target
|
21
|
+
add_test_targets if target.contains_test_specifications?
|
21
22
|
create_support_files_dir
|
22
23
|
add_resources_bundle_targets
|
23
24
|
add_files_to_build_phases
|
24
25
|
create_xcconfig_file
|
26
|
+
create_test_xcconfig_files if target.contains_test_specifications?
|
25
27
|
if target.requires_frameworks?
|
26
28
|
create_info_plist_file
|
27
29
|
create_module_map
|
28
30
|
create_umbrella_header do |generator|
|
31
|
+
file_accessors = target.file_accessors
|
32
|
+
file_accessors = file_accessors.reject { |f| f.spec.test_specification? } if target.contains_test_specifications?
|
29
33
|
generator.imports += if header_mappings_dir
|
30
|
-
|
34
|
+
file_accessors.flat_map(&:public_headers).map do |pathname|
|
31
35
|
pathname.relative_path_from(header_mappings_dir)
|
32
36
|
end
|
33
37
|
else
|
34
|
-
|
38
|
+
file_accessors.flat_map(&:public_headers).map(&:basename)
|
35
39
|
end
|
36
40
|
end
|
37
41
|
create_build_phase_to_symlink_header_folders
|
@@ -59,6 +63,8 @@ module Pod
|
|
59
63
|
settings['CODE_SIGN_IDENTITY[sdk=iphoneos*]'] = ''
|
60
64
|
settings['CODE_SIGN_IDENTITY[sdk=watchos*]'] = ''
|
61
65
|
|
66
|
+
settings['SWIFT_ACTIVE_COMPILATION_CONDITIONS'] = '$(inherited) '
|
67
|
+
|
62
68
|
if target.swift_version
|
63
69
|
settings['SWIFT_VERSION'] = target.swift_version
|
64
70
|
end
|
@@ -128,6 +134,7 @@ module Pod
|
|
128
134
|
target.file_accessors.each do |file_accessor|
|
129
135
|
consumer = file_accessor.spec_consumer
|
130
136
|
|
137
|
+
native_target = target.native_target_for_spec(consumer.spec)
|
131
138
|
headers = file_accessor.headers
|
132
139
|
public_headers = file_accessor.public_headers
|
133
140
|
private_headers = file_accessor.private_headers
|
@@ -145,7 +152,7 @@ module Pod
|
|
145
152
|
|
146
153
|
header_file_refs = project_file_references_array(headers, 'header')
|
147
154
|
native_target.add_file_references(header_file_refs) do |build_file|
|
148
|
-
add_header(build_file, public_headers, private_headers)
|
155
|
+
add_header(build_file, public_headers, private_headers, native_target)
|
149
156
|
end
|
150
157
|
|
151
158
|
other_file_refs = other_source_files.map { |sf| project.reference_for_path(sf) }
|
@@ -160,6 +167,39 @@ module Pod
|
|
160
167
|
end
|
161
168
|
end
|
162
169
|
|
170
|
+
# Adds the test targets for the library to the Pods project with the
|
171
|
+
# appropriate build configurations.
|
172
|
+
#
|
173
|
+
# @return [void]
|
174
|
+
#
|
175
|
+
def add_test_targets
|
176
|
+
target.supported_test_types.each do |test_type|
|
177
|
+
product_type = target.product_type_for_test_type(test_type)
|
178
|
+
name = target.test_target_label(test_type)
|
179
|
+
platform = target.platform.name
|
180
|
+
language = target.uses_swift? ? :swift : :objc
|
181
|
+
native_test_target = project.new_target(product_type, name, platform, deployment_target, nil, language)
|
182
|
+
native_test_target.product_reference.name = name
|
183
|
+
|
184
|
+
target.user_build_configurations.each do |bc_name, type|
|
185
|
+
native_test_target.add_build_configuration(bc_name, type)
|
186
|
+
end
|
187
|
+
|
188
|
+
native_test_target.build_configurations.each do |configuration|
|
189
|
+
configuration.build_settings.merge!(custom_build_settings)
|
190
|
+
# target_installer will automatically add an empty `OTHER_LDFLAGS`. For test
|
191
|
+
# targets those are set via a test xcconfig file instead.
|
192
|
+
configuration.build_settings.delete('OTHER_LDFLAGS')
|
193
|
+
# target_installer will automatically set the product name to the module name if the target
|
194
|
+
# requires frameworks. For tests we always use the test target name as the product name
|
195
|
+
# irrelevant to whether we use frameworks or not.
|
196
|
+
configuration.build_settings['PRODUCT_NAME'] = name
|
197
|
+
end
|
198
|
+
|
199
|
+
target.test_native_targets << native_test_target
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
163
203
|
# Adds the resources of the Pods to the Pods project.
|
164
204
|
#
|
165
205
|
# @note The source files are grouped by Pod and in turn by subspec
|
@@ -184,6 +224,7 @@ module Pod
|
|
184
224
|
bundle_target.add_resources(resource_phase_refs + compile_phase_refs)
|
185
225
|
end
|
186
226
|
|
227
|
+
native_target = target.native_target_for_spec(file_accessor.spec_consumer.spec)
|
187
228
|
target.user_build_configurations.each do |bc_name, type|
|
188
229
|
bundle_target.add_build_configuration(bc_name, type)
|
189
230
|
end
|
@@ -219,7 +260,7 @@ module Pod
|
|
219
260
|
:watchos => '1,2' # The device family for watchOS is 4, but Xcode creates watchkit-compatible bundles as 1,2
|
220
261
|
}
|
221
262
|
|
222
|
-
if family = device_family_by_platform[target.platform.name]
|
263
|
+
if (family = device_family_by_platform[target.platform.name])
|
223
264
|
c.build_settings['TARGETED_DEVICE_FAMILY'] = family
|
224
265
|
end
|
225
266
|
end
|
@@ -249,6 +290,38 @@ module Pod
|
|
249
290
|
end
|
250
291
|
end
|
251
292
|
|
293
|
+
# Generates the contents of the xcconfig file used for each test target type and saves it to disk.
|
294
|
+
#
|
295
|
+
# @return [void]
|
296
|
+
#
|
297
|
+
def create_test_xcconfig_files
|
298
|
+
target.supported_test_types.each do |test_type|
|
299
|
+
path = target.xcconfig_path(test_type.to_s)
|
300
|
+
xcconfig_gen = Generator::XCConfig::PodXCConfig.new(target, true)
|
301
|
+
xcconfig_gen.save_as(path)
|
302
|
+
xcconfig_file_ref = add_file_to_support_group(path)
|
303
|
+
|
304
|
+
target.test_native_targets.each do |test_target|
|
305
|
+
test_target.build_configurations.each do |test_target_bc|
|
306
|
+
test_target_swift_debug_hack(test_target_bc)
|
307
|
+
test_target_bc.base_configuration_reference = xcconfig_file_ref
|
308
|
+
end
|
309
|
+
end
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
# Manually add `libswiftSwiftOnoneSupport.dylib` as it seems there is an issue with tests that do not include it for Debug configurations.
|
314
|
+
# Possibly related to Swift module optimization.
|
315
|
+
#
|
316
|
+
# @return [void]
|
317
|
+
#
|
318
|
+
def test_target_swift_debug_hack(test_target_bc)
|
319
|
+
return unless test_target_bc.debug?
|
320
|
+
return unless [target, *target.recursive_dependent_targets].any?(&:uses_swift?)
|
321
|
+
ldflags = test_target_bc.build_settings['OTHER_LDFLAGS'] ||= '$(inherited)'
|
322
|
+
ldflags << ' -lswiftSwiftOnoneSupport'
|
323
|
+
end
|
324
|
+
|
252
325
|
# Creates a build phase which links the versioned header folders
|
253
326
|
# of the OS X into the framework bundle's root root directory.
|
254
327
|
# This is only necessary because the way how headers are copied
|
@@ -398,7 +471,7 @@ module Pod
|
|
398
471
|
end
|
399
472
|
end
|
400
473
|
|
401
|
-
def add_header(build_file, public_headers, private_headers)
|
474
|
+
def add_header(build_file, public_headers, private_headers, native_target)
|
402
475
|
file_ref = build_file.file_ref
|
403
476
|
acl = if public_headers.include?(file_ref.real_path)
|
404
477
|
'Public'
|