cocoapods 1.6.0.beta.1 → 1.6.0.beta.2

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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +94 -4
  3. data/lib/cocoapods/command/cache/clean.rb +1 -1
  4. data/lib/cocoapods/command/init.rb +3 -1
  5. data/lib/cocoapods/command/outdated.rb +2 -2
  6. data/lib/cocoapods/executable.rb +1 -1
  7. data/lib/cocoapods/gem_version.rb +1 -1
  8. data/lib/cocoapods/generator/acknowledgements/plist.rb +3 -3
  9. data/lib/cocoapods/generator/app_target_helper.rb +2 -4
  10. data/lib/cocoapods/generator/copy_resources_script.rb +8 -3
  11. data/lib/cocoapods/generator/embed_frameworks_script.rb +24 -18
  12. data/lib/cocoapods/installer.rb +37 -21
  13. data/lib/cocoapods/installer/analyzer.rb +19 -13
  14. data/lib/cocoapods/installer/analyzer/locking_dependency_analyzer.rb +5 -0
  15. data/lib/cocoapods/installer/analyzer/target_inspection_result.rb +5 -0
  16. data/lib/cocoapods/installer/installation_options.rb +2 -0
  17. data/lib/cocoapods/installer/pod_source_installer.rb +1 -1
  18. data/lib/cocoapods/installer/post_install_hooks_context.rb +1 -1
  19. data/lib/cocoapods/installer/user_project_integrator.rb +6 -2
  20. data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +42 -12
  21. data/lib/cocoapods/installer/xcode/pods_project_generator.rb +2 -4
  22. data/lib/cocoapods/installer/xcode/pods_project_generator/app_host_installer.rb +14 -5
  23. data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +12 -6
  24. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +22 -11
  25. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +29 -18
  26. data/lib/cocoapods/installer/xcode/target_validator.rb +1 -1
  27. data/lib/cocoapods/project.rb +2 -0
  28. data/lib/cocoapods/resolver.rb +42 -49
  29. data/lib/cocoapods/resolver/resolver_specification.rb +41 -0
  30. data/lib/cocoapods/sandbox.rb +21 -17
  31. data/lib/cocoapods/target/aggregate_target.rb +3 -1
  32. data/lib/cocoapods/target/build_settings.rb +35 -12
  33. data/lib/cocoapods/target/framework_paths.rb +36 -0
  34. data/lib/cocoapods/target/pod_target.rb +16 -17
  35. data/lib/cocoapods/validator.rb +18 -5
  36. metadata +18 -10
@@ -96,10 +96,13 @@ module Pod
96
96
  podfile_state = generate_podfile_state
97
97
 
98
98
  store_existing_checkout_options
99
- if allow_fetches
99
+ if allow_fetches == :outdated
100
+ # special-cased -- we're only really resolving for outdated, rather than doing a full analysis
101
+ elsif allow_fetches == true
100
102
  fetch_external_sources(podfile_state)
101
103
  elsif !dependencies_to_fetch(podfile_state).all?(&:local?)
102
- raise Informative, 'Cannot analyze without fetching dependencies since the sandbox is not up-to-date. Run `pod install` to ensure all dependencies have been fetched.'
104
+ raise Informative, 'Cannot analyze without fetching dependencies since the sandbox is not up-to-date. Run `pod install` to ensure all dependencies have been fetched.' \
105
+ "\n The missing dependencies are:\n \t#{dependencies_to_fetch(podfile_state).reject(&:local?).join("\n \t")}"
103
106
  end
104
107
 
105
108
  locked_dependencies = generate_version_locking_dependencies(podfile_state)
@@ -252,7 +255,7 @@ module Pod
252
255
  end
253
256
  end
254
257
 
255
- # Copies the pod_targets of any of the app embedded aggregate targets into
258
+ # Copies the pod targets of any of the app embedded aggregate targets into
256
259
  # their potential host aggregate target, if that potential host aggregate target's
257
260
  # user_target hosts any of the app embedded aggregate targets' user_targets
258
261
  #
@@ -271,7 +274,6 @@ module Pod
271
274
  #
272
275
  def embedded_target_pod_targets_by_host(aggregate_target, embedded_aggregate_targets, libraries_only)
273
276
  return {} if aggregate_target.requires_host_target?
274
- pod_target_names = Set.new(aggregate_target.pod_targets.map(&:name))
275
277
  aggregate_user_target_uuids = Set.new(aggregate_target.user_targets.map(&:uuid))
276
278
  embedded_pod_targets_by_build_config = Hash.new([].freeze)
277
279
  embedded_aggregate_targets.each do |embedded_aggregate_target|
@@ -289,8 +291,12 @@ module Pod
289
291
  !aggregate_user_target_uuids.intersection(host_target_uuids).empty?
290
292
  end
291
293
  embedded_aggregate_target.user_build_configurations.keys.each do |configuration_name|
294
+ pod_target_names = Set.new(aggregate_target.pod_targets_for_build_configuration(configuration_name).map(&:name))
292
295
  embedded_pod_targets = embedded_aggregate_target.pod_targets_for_build_configuration(configuration_name).select do |pod_target|
293
- !pod_target_names.include? pod_target.name
296
+ if !pod_target_names.include?(pod_target.name) &&
297
+ aggregate_target.pod_targets.none? { |aggregate_pod_target| (pod_target.specs - aggregate_pod_target.specs).empty? }
298
+ pod_target.name
299
+ end
294
300
  end
295
301
  embedded_pod_targets_by_build_config[configuration_name] = embedded_pod_targets
296
302
  end
@@ -447,7 +453,7 @@ module Pod
447
453
  target_inspection = target_inspections[target_definition]
448
454
  raise "missing inspection: #{target_definition.name}" unless target_inspection
449
455
  user_project = target_inspection.project
450
- client_root = user_project.path.dirname.realpath
456
+ client_root = target_inspection.client_root
451
457
  user_target_uuids = target_inspection.project_target_uuids
452
458
  user_build_configurations = target_inspection.build_configurations
453
459
  archs = target_requires_64_bit ? ['$(ARCHS_STANDARD_64_BIT)'] : target_inspection.archs
@@ -783,11 +789,12 @@ module Pod
783
789
  #
784
790
  def fetch_external_sources(podfile_state)
785
791
  verify_no_pods_with_different_sources!
786
- unless dependencies_to_fetch(podfile_state).empty?
787
- UI.section 'Fetching external sources' do
788
- dependencies_to_fetch(podfile_state).sort.each do |dependency|
789
- fetch_external_source(dependency, !pods_to_fetch(podfile_state).include?(dependency.root_name))
790
- end
792
+ deps = dependencies_to_fetch(podfile_state)
793
+ pods = pods_to_fetch(podfile_state)
794
+ return if deps.empty?
795
+ UI.section 'Fetching external sources' do
796
+ deps.sort.each do |dependency|
797
+ fetch_external_source(dependency, !pods.include?(dependency.root_name))
791
798
  end
792
799
  end
793
800
  end
@@ -803,8 +810,7 @@ module Pod
803
810
  end
804
811
 
805
812
  def fetch_external_source(dependency, use_lockfile_options)
806
- checkout_options = lockfile.checkout_options_for_pod_named(dependency.root_name) if lockfile
807
- source = if checkout_options && use_lockfile_options
813
+ source = if use_lockfile_options && lockfile && checkout_options = lockfile.checkout_options_for_pod_named(dependency.root_name)
808
814
  ExternalSources.from_params(checkout_options, dependency, podfile.defined_in_file, installation_options.clean?)
809
815
  else
810
816
  ExternalSources.from_dependency(dependency, podfile.defined_in_file, installation_options.clean?)
@@ -53,6 +53,11 @@ module Pod
53
53
  pods_to_update.each do |u|
54
54
  dependency_graph.detach_vertex_named(u)
55
55
  end
56
+
57
+ dependency_graph.each do |vertex|
58
+ next unless dep = vertex.payload
59
+ dep.podspec_repo ||= lockfile.spec_repo(dep.root_name)
60
+ end
56
61
  end
57
62
 
58
63
  dependency_graph
@@ -30,6 +30,10 @@ module Pod
30
30
  #
31
31
  attr_reader :archs
32
32
 
33
+ # @return [Pathname] the path to the root of the project containing the user target
34
+ #
35
+ attr_reader :client_root
36
+
33
37
  # Initialize a new instance
34
38
  #
35
39
  # @param [TargetDefinition] target_definition @see #target_definition
@@ -46,6 +50,7 @@ module Pod
46
50
  @build_configurations = build_configurations
47
51
  @platform = platform
48
52
  @archs = archs
53
+ @client_root = project.project_dir.realpath
49
54
  end
50
55
  end
51
56
  end
@@ -108,6 +108,8 @@ module Pod
108
108
  option :lock_pod_sources, true
109
109
  option :warn_for_multiple_pod_sources, true
110
110
  option :share_schemes_for_development_pods, false
111
+ option :disable_input_output_paths, false
112
+ option :preserve_pod_file_structure, false
111
113
 
112
114
  module Mixin
113
115
  module ClassMethods
@@ -123,7 +123,7 @@ module Pod
123
123
  return unless git_source =~ /^#{URI.regexp}$/
124
124
  URI(git_source)
125
125
  end
126
- if UNENCRYPTED_PROTOCOLS.include?(source.scheme)
126
+ if UNENCRYPTED_PROTOCOLS.include?(source.scheme) && source.host != 'localhost'
127
127
  UI.warn "'#{root_spec.name}' uses the unencrypted '#{source.scheme}' protocol to transfer the Pod. " \
128
128
  'Please be sure you\'re in a safe network with only trusted hosts. ' \
129
129
  'Otherwise, please reach out to the library author to notify them of this security issue.'
@@ -61,7 +61,7 @@ module Pod
61
61
  new(sandbox, sandbox.root.to_s, sandbox.project, umbrella_targets_descriptions)
62
62
  end
63
63
 
64
- # Pure data class which describes and umbrella target.
64
+ # Pure data class which describes an umbrella target.
65
65
  #
66
66
  class UmbrellaTargetDescription
67
67
  # @return [Xcodeproj::Project] The user project into which this target
@@ -13,6 +13,10 @@ module Pod
13
13
  class UserProjectIntegrator
14
14
  autoload :TargetIntegrator, 'cocoapods/installer/user_project_integrator/target_integrator'
15
15
 
16
+ include InstallationOptions::Mixin
17
+
18
+ delegate_installation_options { podfile }
19
+
16
20
  # @return [Podfile] the podfile that should be integrated with the user
17
21
  # projects.
18
22
  #
@@ -42,7 +46,7 @@ module Pod
42
46
  # @param [Podfile] podfile @see #podfile
43
47
  # @param [Sandbox] sandbox @see #sandbox
44
48
  # @param [Pathname] installation_root @see #installation_root
45
- # @param [Array<AggregateTarget>] targets @see #targets
49
+ # @param [Array<AggregateTarget>] targets @see #targets
46
50
  #
47
51
  def initialize(podfile, sandbox, installation_root, targets)
48
52
  @podfile = podfile
@@ -111,7 +115,7 @@ module Pod
111
115
  #
112
116
  def integrate_user_targets
113
117
  target_integrators = targets_to_integrate.sort_by(&:name).map do |target|
114
- TargetIntegrator.new(target)
118
+ TargetIntegrator.new(target, installation_options)
115
119
  end
116
120
 
117
121
  Config.instance.with_changes(:silent => true) do
@@ -1,4 +1,5 @@
1
1
  require 'active_support/core_ext/string/inflections'
2
+ require 'cocoapods/target/framework_paths'
2
3
 
3
4
  module Pod
4
5
  class Installer
@@ -48,12 +49,18 @@ module Pod
48
49
  #
49
50
  attr_reader :target
50
51
 
52
+ # @return [InstallationOptions] the installation options from the Podfile.
53
+ #
54
+ attr_reader :installation_options
55
+
51
56
  # Init a new TargetIntegrator
52
57
  #
53
58
  # @param [AggregateTarget] target @see #target
59
+ # @param [InstallationOptions] installation_options @see #installation_options
54
60
  #
55
- def initialize(target)
61
+ def initialize(target, installation_options)
56
62
  @target = target
63
+ @installation_options = installation_options
57
64
  end
58
65
 
59
66
  class << self
@@ -254,6 +261,23 @@ module Pod
254
261
  File.join(base_path, File.basename(basename, extname) + output_extension)
255
262
  end.uniq
256
263
  end
264
+
265
+ # Returns the framework output paths for the given input paths
266
+ #
267
+ # @param [Array<Target::FrameworkPaths>] framework_input_paths
268
+ # The framework input paths to map to output paths.
269
+ #
270
+ # @return [Array<String>] The framework output paths
271
+ #
272
+ def framework_output_paths(framework_input_paths)
273
+ framework_input_paths.flat_map do |framework_path|
274
+ framework_output_path = "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/#{File.basename(framework_path.source_path)}"
275
+ dsym_path = if (dsym_input_path = framework_path.dsym_path)
276
+ "${DWARF_DSYM_FOLDER_PATH}/#{File.basename(dsym_input_path)}"
277
+ end
278
+ [framework_output_path, dsym_path]
279
+ end.compact.uniq
280
+ end
257
281
  end
258
282
 
259
283
  # Integrates the user project targets. Only the targets that do **not**
@@ -327,14 +351,16 @@ module Pod
327
351
  end
328
352
  return
329
353
  end
330
-
331
354
  script_path = target.copy_resources_script_relative_path
332
- resource_paths_by_config = target.resource_paths_by_config
333
- resource_paths_flattened = resource_paths_by_config.values.flatten.uniq
334
- input_paths = [target.copy_resources_script_relative_path, *resource_paths_flattened]
335
- output_paths = TargetIntegrator.resource_output_paths(resource_paths_flattened)
355
+ input_paths = []
356
+ output_paths = []
357
+ unless installation_options.disable_input_output_paths?
358
+ resource_paths_by_config = target.resource_paths_by_config
359
+ resource_paths_flattened = resource_paths_by_config.values.flatten.uniq
360
+ input_paths = [target.copy_resources_script_relative_path, *resource_paths_flattened]
361
+ output_paths = TargetIntegrator.resource_output_paths(resource_paths_flattened)
362
+ end
336
363
  TargetIntegrator.validate_input_output_path_limit(input_paths, output_paths)
337
-
338
364
  native_targets.each do |native_target|
339
365
  # Static library targets cannot include resources. Skip this phase from being added instead.
340
366
  next if native_target.symbol_type == :static_library
@@ -368,12 +394,16 @@ module Pod
368
394
  end
369
395
  return
370
396
  end
371
-
372
397
  script_path = target.embed_frameworks_script_relative_path
373
- framework_paths_by_config = target.framework_paths_by_config.values.flatten.uniq
374
- input_paths = [target.embed_frameworks_script_relative_path, *framework_paths_by_config.map { |fw| [fw[:input_path], fw[:dsym_input_path]] }.flatten.compact]
375
- output_paths = framework_paths_by_config.map { |fw| [fw[:output_path], fw[:dsym_output_path]] }.flatten.compact.uniq
376
- TargetIntegrator.validate_input_output_path_limit(input_paths, output_paths)
398
+ input_paths = []
399
+ output_paths = []
400
+ unless installation_options.disable_input_output_paths?
401
+ framework_paths = target.framework_paths_by_config.values.flatten.uniq
402
+ framework_input_paths = framework_paths.flat_map { |path| [path.source_path, path.dsym_path] }.compact
403
+ input_paths = [target.embed_frameworks_script_relative_path, *framework_input_paths]
404
+ output_paths = TargetIntegrator.framework_output_paths(framework_paths)
405
+ TargetIntegrator.validate_input_output_path_limit(input_paths, output_paths)
406
+ end
377
407
 
378
408
  native_targets_to_embed_in.each do |native_target|
379
409
  TargetIntegrator.create_or_update_embed_frameworks_script_phase_to_target(native_target, script_path, input_paths, output_paths)
@@ -165,14 +165,12 @@ module Pod
165
165
  build_configuration.build_settings['TVOS_DEPLOYMENT_TARGET'] = tvos_deployment_target.to_s if tvos_deployment_target
166
166
  build_configuration.build_settings['STRIP_INSTALLED_PRODUCT'] = 'NO'
167
167
  build_configuration.build_settings['CLANG_ENABLE_OBJC_ARC'] = 'YES'
168
- build_configuration.build_settings['CODE_SIGNING_REQUIRED'] = 'NO'
169
- build_configuration.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
170
168
  end
171
169
  end
172
170
  end
173
171
 
174
172
  def install_file_references
175
- installer = FileReferencesInstaller.new(sandbox, pod_targets, project)
173
+ installer = FileReferencesInstaller.new(sandbox, pod_targets, project, installation_options.preserve_pod_file_structure)
176
174
  installer.install!
177
175
  end
178
176
 
@@ -212,7 +210,7 @@ module Pod
212
210
  unless pod_installations_to_integrate.empty?
213
211
  UI.message '- Integrating targets' do
214
212
  pod_installations_to_integrate.each do |pod_target_installation_result|
215
- PodTargetIntegrator.new(pod_target_installation_result).integrate!
213
+ PodTargetIntegrator.new(pod_target_installation_result, installation_options).integrate!
216
214
  end
217
215
  end
218
216
  end
@@ -25,18 +25,26 @@ module Pod
25
25
  #
26
26
  attr_reader :name
27
27
 
28
+ # @return [String] the name of the pod the app host installer will be installing within.
29
+ #
30
+ attr_reader :pod_name
31
+
28
32
  # Initialize a new instance
29
33
  #
30
34
  # @param [Sandbox] sandbox @see #sandbox
31
35
  # @param [Pod::Project] project @see #project
32
36
  # @param [Platform] platform @see #platform
33
37
  # @param [String] name @see #name
38
+ # @param [String] pod_name @see #pod_name
34
39
  #
35
- def initialize(sandbox, project, platform, name)
40
+ def initialize(sandbox, project, platform, name, pod_name)
36
41
  @sandbox = sandbox
37
42
  @project = project
38
43
  @platform = platform
39
44
  @name = name
45
+ @pod_name = pod_name
46
+ target_group = project.pod_group(pod_name)
47
+ @group = target_group[name] || target_group.new_group(name)
40
48
  end
41
49
 
42
50
  # @return [PBXNativeTarget] the app host native target that was installed.
@@ -51,12 +59,13 @@ module Pod
51
59
  configuration.build_settings['CODE_SIGN_IDENTITY'] = '' if platform == :osx
52
60
  configuration.build_settings['CURRENT_PROJECT_VERSION'] = '1'
53
61
  end
54
- Pod::Generator::AppTargetHelper.add_app_host_main_file(project, app_host_target, platform_name, name)
55
- Pod::Generator::AppTargetHelper.add_launchscreen_storyboard(project, app_host_target, name) if platform == :ios
62
+
63
+ Pod::Generator::AppTargetHelper.add_app_host_main_file(project, app_host_target, platform_name, @group, name)
64
+ Pod::Generator::AppTargetHelper.add_launchscreen_storyboard(project, app_host_target, @group, name) if platform == :ios
56
65
  additional_entries = platform == :ios ? ADDITIONAL_IOS_INFO_PLIST_ENTRIES : {}
57
66
  create_info_plist_file_with_sandbox(sandbox, app_host_info_plist_path, app_host_target, '1.0.0', platform,
58
67
  :appl, additional_entries)
59
- project[name].new_file(app_host_info_plist_path)
68
+ @group.new_file(app_host_info_plist_path)
60
69
  app_host_target
61
70
  end
62
71
 
@@ -80,7 +89,7 @@ module Pod
80
89
  # @return [Pathname] The absolute path of the Info.plist to use for an app host.
81
90
  #
82
91
  def app_host_info_plist_path
83
- project.path.dirname.+("#{name}/#{name}-Info.plist")
92
+ project.path.dirname.+(name).+("#{name}-Info.plist")
84
93
  end
85
94
 
86
95
  # @return [String] The deployment target.
@@ -18,16 +18,22 @@ module Pod
18
18
  #
19
19
  attr_reader :pods_project
20
20
 
21
+ # @return [Bool] add support for preserving the file structure of externally sourced pods, in addition to local pods.
22
+ #
23
+ attr_reader :preserve_pod_file_structure
24
+
21
25
  # Initialize a new instance
22
26
  #
23
27
  # @param [Sandbox] sandbox @see #sandbox
24
28
  # @param [Array<PodTarget>] pod_targets @see #pod_targets
25
29
  # @param [Project] pods_project @see #pods_project
30
+ # @param [Bool] preserve_pod_file_structure @see #preserve_pod_file_structure
26
31
  #
27
- def initialize(sandbox, pod_targets, pods_project)
32
+ def initialize(sandbox, pod_targets, pods_project, preserve_pod_file_structure = false)
28
33
  @sandbox = sandbox
29
34
  @pod_targets = pod_targets
30
35
  @pods_project = pods_project
36
+ @preserve_pod_file_structure = preserve_pod_file_structure
31
37
  end
32
38
 
33
39
  # Installs the file references.
@@ -190,24 +196,24 @@ module Pod
190
196
  # @param [Symbol] group_key
191
197
  # The key of the group of the Pods project.
192
198
  #
193
- # @param [Bool] reflect_file_system_structure_for_development
199
+ # @param [Bool] reflect_file_system_structure
194
200
  # Whether organizing a local pod's files in subgroups inside
195
201
  # the pod's group is allowed.
196
202
  #
197
203
  # @return [void]
198
204
  #
199
- def add_file_accessors_paths_to_pods_group(file_accessor_key, group_key = nil, reflect_file_system_structure_for_development = false)
205
+ def add_file_accessors_paths_to_pods_group(file_accessor_key, group_key = nil, reflect_file_system_structure = false)
200
206
  file_accessors.each do |file_accessor|
201
207
  paths = file_accessor.send(file_accessor_key)
202
208
  paths = allowable_project_paths(paths)
203
209
  next if paths.empty?
204
210
 
205
211
  pod_name = file_accessor.spec.name
206
- local = sandbox.local?(pod_name)
207
- base_path = local ? common_path(paths) : nil
212
+ preserve_pod_file_structure_flag = (sandbox.local?(pod_name) || preserve_pod_file_structure)
213
+ base_path = preserve_pod_file_structure_flag ? common_path(paths) : nil
208
214
  group = pods_project.group_for_spec(pod_name, group_key)
209
215
  paths.each do |path|
210
- pods_project.add_file_reference(path, group, local && reflect_file_system_structure_for_development, base_path)
216
+ pods_project.add_file_reference(path, group, preserve_pod_file_structure_flag && reflect_file_system_structure, base_path)
211
217
  end
212
218
  end
213
219
  end
@@ -50,6 +50,7 @@ module Pod
50
50
  test_resource_bundle_targets = add_resources_bundle_targets(test_file_accessors)
51
51
 
52
52
  add_files_to_build_phases(native_target, test_native_targets)
53
+ validate_targets_contain_sources(test_native_targets + [native_target])
53
54
 
54
55
  create_xcconfig_file(native_target, resource_bundle_targets)
55
56
  create_test_xcconfig_files(test_native_targets, test_resource_bundle_targets)
@@ -90,12 +91,14 @@ module Pod
90
91
 
91
92
  unless skip_pch?(target.non_test_specs)
92
93
  path = target.prefix_header_path
93
- create_prefix_header(path, file_accessors, target.platform, [native_target])
94
+ create_prefix_header(path, file_accessors, target.platform, native_target)
94
95
  end
95
96
  unless skip_pch?(target.test_specs)
96
97
  target.test_specs.each do |test_spec|
97
98
  path = target.prefix_header_path_for_test_spec(test_spec)
98
- create_prefix_header(path, test_file_accessors, target.platform, test_native_targets)
99
+ test_spec_consumer = test_spec.consumer(target.platform)
100
+ test_native_target = test_native_target_from_spec_consumer(test_spec_consumer, test_native_targets)
101
+ create_prefix_header(path, test_file_accessors, target.platform, test_native_target)
99
102
  end
100
103
  end
101
104
  create_dummy_source(native_target)
@@ -285,6 +288,9 @@ module Pod
285
288
  # requires frameworks. For tests we always use the test target name as the product name
286
289
  # irrelevant to whether we use frameworks or not.
287
290
  configuration.build_settings['PRODUCT_NAME'] = name
291
+ # target_installer sets 'MACH_O_TYPE' for static frameworks ensure this does not propagate
292
+ # to test target.
293
+ configuration.build_settings.delete('MACH_O_TYPE')
288
294
  # Use xcode default product module name, which is $(PRODUCT_NAME:c99extidentifier)
289
295
  # this gives us always valid name that is distinct from the parent spec module name
290
296
  # which allow tests to use either import or @testable import to access the parent framework
@@ -323,7 +329,7 @@ module Pod
323
329
  target.test_spec_consumers.select(&:requires_app_host?).group_by(&:test_type).map do |test_type, test_spec_consumers|
324
330
  platform = target.platform
325
331
  name = "AppHost-#{target.label}-#{test_type.capitalize}-Tests"
326
- app_host_target = AppHostInstaller.new(sandbox, project, platform, name).install!
332
+ app_host_target = AppHostInstaller.new(sandbox, project, platform, name, target.pod_name).install!
327
333
  # Wire test native targets to the generated app host.
328
334
  test_spec_consumers.each do |test_spec_consumer|
329
335
  test_native_target = test_native_target_from_spec_consumer(test_spec_consumer, test_native_targets)
@@ -560,21 +566,19 @@ module Pod
560
566
  # @param [Platform] platform
561
567
  # the platform to use for this prefix header.
562
568
  #
563
- # @param [Array<PBXNativeTarget>] native_targets
564
- # the native targets on which the prefix header should be configured for.
569
+ # @param [PBXNativeTarget] native_target
570
+ # the native target on which the prefix header should be configured for.
565
571
  #
566
572
  # @return [void]
567
573
  #
568
- def create_prefix_header(path, file_accessors, platform, native_targets)
574
+ def create_prefix_header(path, file_accessors, platform, native_target)
569
575
  generator = Generator::PrefixHeader.new(file_accessors, platform)
570
576
  update_changed_file(generator, path)
571
577
  add_file_to_support_group(path)
572
578
 
573
- native_targets.each do |native_target|
574
- native_target.build_configurations.each do |c|
575
- relative_path = path.relative_path_from(project.path.dirname)
576
- c.build_settings['GCC_PREFIX_HEADER'] = relative_path.to_s
577
- end
579
+ relative_path = path.relative_path_from(project.path.dirname)
580
+ native_target.build_configurations.each do |c|
581
+ c.build_settings['GCC_PREFIX_HEADER'] = relative_path.to_s
578
582
  end
579
583
  end
580
584
 
@@ -818,6 +822,13 @@ module Pod
818
822
  )
819
823
  end
820
824
 
825
+ def validate_targets_contain_sources(native_targets)
826
+ native_targets.each do |native_target|
827
+ next unless native_target.source_build_phase.files.empty?
828
+ raise Informative, "Unable to install the `#{target.label}` pod, because the `#{native_target}` target in Xcode would have no sources to compile."
829
+ end
830
+ end
831
+
821
832
  #-----------------------------------------------------------------------#
822
833
  end
823
834
  end