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

Sign up to get free protection for your applications and to get access to all the features.
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