cocoapods 1.2.1 → 1.3.0.beta.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 +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'
|