cocoapods 1.5.3 → 1.6.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.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +200 -0
  3. data/lib/cocoapods.rb +0 -1
  4. data/lib/cocoapods/command/init.rb +1 -1
  5. data/lib/cocoapods/command/install.rb +7 -0
  6. data/lib/cocoapods/command/lib/lint.rb +8 -1
  7. data/lib/cocoapods/command/outdated.rb +2 -7
  8. data/lib/cocoapods/command/repo/add.rb +1 -1
  9. data/lib/cocoapods/command/repo/list.rb +1 -1
  10. data/lib/cocoapods/command/repo/push.rb +17 -12
  11. data/lib/cocoapods/command/repo/remove.rb +1 -1
  12. data/lib/cocoapods/command/repo/update.rb +1 -1
  13. data/lib/cocoapods/command/setup.rb +1 -1
  14. data/lib/cocoapods/command/spec/create.rb +39 -39
  15. data/lib/cocoapods/command/spec/lint.rb +8 -1
  16. data/lib/cocoapods/config.rb +13 -2
  17. data/lib/cocoapods/downloader/cache.rb +1 -1
  18. data/lib/cocoapods/executable.rb +2 -2
  19. data/lib/cocoapods/external_sources.rb +7 -4
  20. data/lib/cocoapods/external_sources/abstract_external_source.rb +23 -13
  21. data/lib/cocoapods/gem_version.rb +1 -1
  22. data/lib/cocoapods/generator/acknowledgements/markdown.rb +6 -0
  23. data/lib/cocoapods/generator/acknowledgements/plist.rb +11 -0
  24. data/lib/cocoapods/generator/app_target_helper.rb +102 -16
  25. data/lib/cocoapods/generator/copy_resources_script.rb +6 -0
  26. data/lib/cocoapods/generator/dummy_source.rb +14 -5
  27. data/lib/cocoapods/generator/embed_frameworks_script.rb +13 -2
  28. data/lib/cocoapods/generator/header.rb +1 -1
  29. data/lib/cocoapods/generator/info_plist_file.rb +12 -4
  30. data/lib/cocoapods/generator/prefix_header.rb +2 -2
  31. data/lib/cocoapods/hooks_manager.rb +28 -17
  32. data/lib/cocoapods/installer.rb +103 -42
  33. data/lib/cocoapods/installer/analyzer.rb +362 -277
  34. data/lib/cocoapods/installer/analyzer/analysis_result.rb +52 -22
  35. data/lib/cocoapods/installer/analyzer/locking_dependency_analyzer.rb +9 -6
  36. data/lib/cocoapods/installer/analyzer/pod_variant.rb +4 -5
  37. data/lib/cocoapods/installer/analyzer/sandbox_analyzer.rb +3 -14
  38. data/lib/cocoapods/installer/analyzer/specs_state.rb +28 -4
  39. data/lib/cocoapods/installer/analyzer/target_inspection_result.rb +24 -16
  40. data/lib/cocoapods/installer/analyzer/target_inspector.rb +17 -11
  41. data/lib/cocoapods/installer/pod_source_installer.rb +31 -43
  42. data/lib/cocoapods/installer/post_install_hooks_context.rb +71 -46
  43. data/lib/cocoapods/installer/pre_install_hooks_context.rb +22 -13
  44. data/lib/cocoapods/installer/source_provider_hooks_context.rb +3 -1
  45. data/lib/cocoapods/installer/user_project_integrator.rb +0 -2
  46. data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +38 -28
  47. data/lib/cocoapods/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb +44 -11
  48. data/lib/cocoapods/installer/xcode/pods_project_generator.rb +129 -119
  49. data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_installer.rb +25 -16
  50. data/lib/cocoapods/installer/xcode/pods_project_generator/app_host_installer.rb +95 -0
  51. data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +12 -45
  52. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +277 -169
  53. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +31 -24
  54. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installation_result.rb +93 -0
  55. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer.rb +60 -69
  56. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer_helper.rb +72 -0
  57. data/lib/cocoapods/installer/xcode/target_validator.rb +15 -9
  58. data/lib/cocoapods/project.rb +14 -14
  59. data/lib/cocoapods/resolver.rb +38 -50
  60. data/lib/cocoapods/sandbox.rb +22 -38
  61. data/lib/cocoapods/sandbox/file_accessor.rb +11 -6
  62. data/lib/cocoapods/sandbox/headers_store.rb +9 -8
  63. data/lib/cocoapods/sandbox/path_list.rb +5 -8
  64. data/lib/cocoapods/sources_manager.rb +1 -1
  65. data/lib/cocoapods/target.rb +92 -37
  66. data/lib/cocoapods/target/aggregate_target.rb +140 -84
  67. data/lib/cocoapods/target/build_settings.rb +1076 -0
  68. data/lib/cocoapods/target/pod_target.rb +198 -294
  69. data/lib/cocoapods/user_interface.rb +5 -0
  70. data/lib/cocoapods/validator.rb +133 -41
  71. metadata +18 -18
  72. data/lib/cocoapods/generator/xcconfig.rb +0 -13
  73. data/lib/cocoapods/generator/xcconfig/aggregate_xcconfig.rb +0 -260
  74. data/lib/cocoapods/generator/xcconfig/pod_xcconfig.rb +0 -87
  75. data/lib/cocoapods/generator/xcconfig/xcconfig_helper.rb +0 -558
@@ -8,21 +8,21 @@ module Pod
8
8
  class AggregateTargetInstaller < TargetInstaller
9
9
  # Creates the target in the Pods project and the relative support files.
10
10
  #
11
- # @return [void]
11
+ # @return [TargetInstallationResult] the result of the installation of this target.
12
12
  #
13
13
  def install!
14
14
  UI.message "- Installing target `#{target.name}` #{target.platform}" do
15
- add_target
15
+ native_target = add_target
16
16
  create_support_files_dir
17
17
  create_support_files_group
18
- create_xcconfig_file
18
+ create_xcconfig_file(native_target)
19
19
  if target.requires_frameworks?
20
20
  create_info_plist_file(target.info_plist_path, native_target, target.version, target.platform)
21
- create_module_map
22
- create_umbrella_header
21
+ create_module_map(native_target)
22
+ create_umbrella_header(native_target)
23
23
  elsif target.uses_swift?
24
- create_module_map
25
- create_umbrella_header
24
+ create_module_map(native_target)
25
+ create_umbrella_header(native_target)
26
26
  end
27
27
  # Because embedded targets live in their host target, CocoaPods
28
28
  # copies all of the embedded target's pod_targets to its host
@@ -30,11 +30,13 @@ module Pod
30
30
  # cause an App Store rejection because frameworks cannot be
31
31
  # embedded in embedded targets.
32
32
  #
33
- create_embed_frameworks_script unless target.requires_host_target?
34
- create_bridge_support_file
35
- create_copy_resources_script
33
+ create_embed_frameworks_script if target.includes_frameworks? && !target.requires_host_target?
34
+ create_bridge_support_file(native_target)
35
+ create_copy_resources_script if target.includes_resources?
36
36
  create_acknowledgements
37
- create_dummy_source
37
+ create_dummy_source(native_target)
38
+ clean_support_files_temp_dir
39
+ TargetInstallationResult.new(target, native_target)
38
40
  end
39
41
  end
40
42
 
@@ -87,14 +89,18 @@ module Pod
87
89
 
88
90
  # Generates the contents of the xcconfig file and saves it to disk.
89
91
  #
92
+ # @param [PBXNativeTarget] native_target
93
+ # the native target to link the module map file into.
94
+ #
90
95
  # @return [void]
91
96
  #
92
- def create_xcconfig_file
97
+ def create_xcconfig_file(native_target)
93
98
  native_target.build_configurations.each do |configuration|
99
+ next unless target.user_build_configurations.key?(configuration.name)
94
100
  path = target.xcconfig_path(configuration.name)
95
- gen = Generator::XCConfig::AggregateXCConfig.new(target, configuration.name)
96
- update_changed_file(gen, path)
97
- target.xcconfigs[configuration.name] = gen.xcconfig
101
+ build_settings = target.build_settings(configuration.name)
102
+ update_changed_file(build_settings, path)
103
+ target.xcconfigs[configuration.name] = build_settings.xcconfig
98
104
  xcconfig_file_ref = add_file_to_support_group(path)
99
105
  configuration.base_configuration_reference = xcconfig_file_ref
100
106
  end
@@ -106,9 +112,12 @@ module Pod
106
112
  # target because it is needed for environments interpreted at
107
113
  # runtime.
108
114
  #
115
+ # @param [PBXNativeTarget] native_target
116
+ # the native target to add the bridge support file into.
117
+ #
109
118
  # @return [void]
110
119
  #
111
- def create_bridge_support_file
120
+ def create_bridge_support_file(native_target)
112
121
  if target.podfile.generate_bridge_support?
113
122
  path = target.bridge_support_path
114
123
  headers = native_target.headers_build_phase.files.map { |bf| sandbox.root + bf.file_ref.path }
@@ -0,0 +1,95 @@
1
+ module Pod
2
+ class Installer
3
+ class Xcode
4
+ class PodsProjectGenerator
5
+ # Installs an app host target to a given project.
6
+ #
7
+ class AppHostInstaller
8
+ include TargetInstallerHelper
9
+
10
+ # @return [Sandbox]
11
+ # The sandbox used for this installation.
12
+ #
13
+ attr_reader :sandbox
14
+
15
+ # @return [Pod::Project]
16
+ # The `Pods/Pods.xcodeproj` to install the app host into.
17
+ #
18
+ attr_reader :project
19
+
20
+ # @return [Platform] the platform to use for this app host.
21
+ #
22
+ attr_reader :platform
23
+
24
+ # @return [String] the name to use for this app host target.
25
+ #
26
+ attr_reader :name
27
+
28
+ # Initialize a new instance
29
+ #
30
+ # @param [Sandbox] sandbox @see #sandbox
31
+ # @param [Pod::Project] project @see #project
32
+ # @param [Platform] platform @see #platform
33
+ # @param [String] name @see #name
34
+ #
35
+ def initialize(sandbox, project, platform, name)
36
+ @sandbox = sandbox
37
+ @project = project
38
+ @platform = platform
39
+ @name = name
40
+ end
41
+
42
+ # @return [PBXNativeTarget] the app host native target that was installed.
43
+ #
44
+ def install!
45
+ platform_name = platform.name
46
+ app_host_target = Pod::Generator::AppTargetHelper.add_app_target(project, platform_name, deployment_target,
47
+ name)
48
+ app_host_target.build_configurations.each do |configuration|
49
+ configuration.build_settings['PRODUCT_NAME'] = name
50
+ configuration.build_settings['PRODUCT_BUNDLE_IDENTIFIER'] = 'org.cocoapods.${PRODUCT_NAME:rfc1034identifier}'
51
+ configuration.build_settings['CODE_SIGN_IDENTITY'] = '' if platform == :osx
52
+ configuration.build_settings['CURRENT_PROJECT_VERSION'] = '1'
53
+ 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
56
+ additional_entries = platform == :ios ? ADDITIONAL_IOS_INFO_PLIST_ENTRIES : {}
57
+ create_info_plist_file_with_sandbox(sandbox, app_host_info_plist_path, app_host_target, '1.0.0', platform,
58
+ :appl, additional_entries)
59
+ project[name].new_file(app_host_info_plist_path)
60
+ app_host_target
61
+ end
62
+
63
+ private
64
+
65
+ ADDITIONAL_IOS_INFO_PLIST_ENTRIES = {
66
+ 'UILaunchStoryboardName' => 'LaunchScreen',
67
+ 'UISupportedInterfaceOrientations' => %w(
68
+ UIInterfaceOrientationPortrait
69
+ UIInterfaceOrientationLandscapeLeft
70
+ UIInterfaceOrientationLandscapeRight
71
+ ),
72
+ 'UISupportedInterfaceOrientations~ipad' => %w(
73
+ UIInterfaceOrientationPortrait
74
+ UIInterfaceOrientationPortraitUpsideDown
75
+ UIInterfaceOrientationLandscapeLeft
76
+ UIInterfaceOrientationLandscapeRight
77
+ ),
78
+ }.freeze
79
+
80
+ # @return [Pathname] The absolute path of the Info.plist to use for an app host.
81
+ #
82
+ def app_host_info_plist_path
83
+ project.path.dirname.+("#{name}/#{name}-Info.plist")
84
+ end
85
+
86
+ # @return [String] The deployment target.
87
+ #
88
+ def deployment_target
89
+ platform.deployment_target.to_s
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -20,9 +20,9 @@ module Pod
20
20
 
21
21
  # Initialize a new instance
22
22
  #
23
- # @param [Sandbox] sandbox @see sandbox
24
- # @param [Array<PodTarget>] pod_targets @see pod_targets
25
- # @param [Project] pods_project @see pod_project
23
+ # @param [Sandbox] sandbox @see #sandbox
24
+ # @param [Array<PodTarget>] pod_targets @see #pod_targets
25
+ # @param [Project] pods_project @see #pods_project
26
26
  #
27
27
  def initialize(sandbox, pod_targets, pods_project)
28
28
  @sandbox = sandbox
@@ -115,8 +115,9 @@ module Pod
115
115
  next unless sandbox.local?(pod_name)
116
116
  root_name = Specification.root_name(pod_name)
117
117
  paths = file_accessor.developer_files
118
+ next if paths.empty?
119
+ group = pods_project.group_for_spec(root_name, :developer)
118
120
  paths.each do |path|
119
- group = pods_project.group_for_spec(root_name, :developer)
120
121
  ref = pods_project.add_file_reference(path, group, false)
121
122
  if path.extname == '.podspec'
122
123
  pods_project.mark_ruby_file_ref(ref)
@@ -143,7 +144,8 @@ module Pod
143
144
  added_build_headers = false
144
145
  added_public_headers = false
145
146
 
146
- pod_target.file_accessors.each do |file_accessor|
147
+ file_accessors = pod_target.file_accessors.reject { |fa| fa.spec.test_specification? }
148
+ file_accessors.each do |file_accessor|
147
149
  # Private headers will always end up in Pods/Headers/Private/PodA/*.h
148
150
  # This will allow for `""` imports to work.
149
151
  header_mappings(headers_sandbox, file_accessor, file_accessor.headers).each do |namespaced_path, files|
@@ -157,13 +159,6 @@ module Pod
157
159
  added_public_headers = true
158
160
  sandbox.public_headers.add_files(namespaced_path, files)
159
161
  end
160
-
161
- unless pod_target.requires_frameworks?
162
- vendored_frameworks_header_mappings(headers_sandbox, file_accessor).each do |namespaced_path, files|
163
- added_public_headers = true
164
- sandbox.public_headers.add_files(namespaced_path, files)
165
- end
166
- end
167
162
  end
168
163
 
169
164
  pod_target.build_headers.add_search_path(headers_sandbox, pod_target.platform) if added_build_headers
@@ -203,13 +198,15 @@ module Pod
203
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
200
  file_accessors.each do |file_accessor|
206
- pod_name = file_accessor.spec.name
207
- local = sandbox.local?(pod_name)
208
201
  paths = file_accessor.send(file_accessor_key)
209
202
  paths = allowable_project_paths(paths)
203
+ next if paths.empty?
204
+
205
+ pod_name = file_accessor.spec.name
206
+ local = sandbox.local?(pod_name)
210
207
  base_path = local ? common_path(paths) : nil
208
+ group = pods_project.group_for_spec(pod_name, group_key)
211
209
  paths.each do |path|
212
- group = pods_project.group_for_spec(pod_name, group_key)
213
210
  pods_project.add_file_reference(path, group, local && reflect_file_system_structure_for_development, base_path)
214
211
  end
215
212
  end
@@ -329,36 +326,6 @@ module Pod
329
326
  mappings
330
327
  end
331
328
 
332
- # Computes the destination sub-directory in the sandbox for headers
333
- # from inside vendored frameworks.
334
- #
335
- # @param [Pathname] headers_sandbox
336
- # The sandbox where the header links should be stored for this
337
- # Pod.
338
- #
339
- # @param [Sandbox::FileAccessor] file_accessor
340
- # The consumer file accessor for which the headers need to be
341
- # linked.
342
- #
343
- def vendored_frameworks_header_mappings(headers_sandbox, file_accessor)
344
- mappings = {}
345
- file_accessor.vendored_frameworks.each do |framework|
346
- headers_dir = Sandbox::FileAccessor.vendored_frameworks_headers_dir(framework)
347
- headers = Sandbox::FileAccessor.vendored_frameworks_headers(framework)
348
- framework_name = framework.basename(framework.extname)
349
- dir = headers_sandbox + framework_name
350
- headers.each do |header|
351
- # the relative path of framework headers should be kept,
352
- # not flattened like is done for most public headers.
353
- relative_path = header.relative_path_from(headers_dir)
354
- sub_dir = dir + relative_path.dirname
355
- mappings[sub_dir] ||= []
356
- mappings[sub_dir] << header
357
- end
358
- end
359
- mappings
360
- end
361
-
362
329
  #-----------------------------------------------------------------------#
363
330
  end
364
331
  end
@@ -6,75 +6,105 @@ module Pod
6
6
  # relative support files.
7
7
  #
8
8
  class PodTargetInstaller < TargetInstaller
9
+ require 'cocoapods/installer/xcode/pods_project_generator/app_host_installer'
10
+
11
+ # @return [Array<Pathname>] Array of umbrella header paths in the headers directory
12
+ #
13
+ attr_reader :umbrella_header_paths
14
+
15
+ # Initialize a new instance
16
+ #
17
+ # @param [Sandbox] sandbox @see TargetInstaller#sandbox
18
+ # @param [Pod::Project] project @see TargetInstaller#project
19
+ # @param [Target] target @see TargetInstaller#target
20
+ # @param [Array<Pathname>] umbrella_header_paths @see #umbrella_header_paths
21
+ #
22
+ def initialize(sandbox, project, target, umbrella_header_paths = nil)
23
+ super(sandbox, project, target)
24
+ @umbrella_header_paths = umbrella_header_paths
25
+ end
26
+
9
27
  # Creates the target in the Pods project and the relative support files.
10
28
  #
11
- # @return [void]
29
+ # @return [TargetInstallationResult] the result of the installation of this target.
12
30
  #
13
31
  def install!
14
- unless target.should_build?
15
- add_resources_bundle_targets
16
- return
17
- end
18
-
19
32
  UI.message "- Installing target `#{target.name}` #{target.platform}" do
20
- add_target
21
33
  create_support_files_dir
22
- if target.contains_test_specifications?
23
- add_test_targets
24
- add_test_app_host_targets
34
+ test_file_accessors, file_accessors = target.file_accessors.partition { |fa| fa.spec.test_specification? }
35
+
36
+ unless target.should_build?
37
+ # For targets that should not be built (e.g. pre-built vendored frameworks etc), we add a placeholder
38
+ # PBXAggregateTarget that will be used to wire up dependencies later.
39
+ native_target = add_placeholder_target
40
+ resource_bundle_targets = add_resources_bundle_targets(file_accessors).values.flatten
41
+ create_xcconfig_file(native_target, resource_bundle_targets)
42
+ return TargetInstallationResult.new(target, native_target, resource_bundle_targets)
25
43
  end
26
- add_resources_bundle_targets
27
- add_files_to_build_phases
28
- create_xcconfig_file
29
- create_test_xcconfig_files if target.contains_test_specifications?
44
+
45
+ native_target = add_target
46
+ resource_bundle_targets = add_resources_bundle_targets(file_accessors).values.flatten
47
+
48
+ test_native_targets = add_test_targets
49
+ test_app_host_targets = add_test_app_host_targets(test_native_targets)
50
+ test_resource_bundle_targets = add_resources_bundle_targets(test_file_accessors)
51
+
52
+ add_files_to_build_phases(native_target, test_native_targets)
53
+
54
+ create_xcconfig_file(native_target, resource_bundle_targets)
55
+ create_test_xcconfig_files(test_native_targets, test_resource_bundle_targets)
30
56
 
31
57
  if target.defines_module?
32
- create_module_map do |generator|
58
+ create_module_map(native_target) do |generator|
33
59
  generator.headers.concat module_map_additional_headers
34
60
  end
35
- create_umbrella_header do |generator|
36
- file_accessors = target.file_accessors
37
- file_accessors = file_accessors.reject { |f| f.spec.test_specification? } if target.contains_test_specifications?
38
- generator.imports += if header_mappings_dir
39
- file_accessors.flat_map(&:public_headers).map do |pathname|
40
- pathname.relative_path_from(header_mappings_dir)
41
- end
42
- else
43
- file_accessors.flat_map(&:public_headers).map(&:basename)
61
+ create_umbrella_header(native_target) do |generator|
62
+ generator.imports += file_accessors.flat_map do |file_accessor|
63
+ header_dir = if !target.requires_frameworks? && dir = file_accessor.spec_consumer.header_dir
64
+ Pathname.new(dir)
65
+ end
66
+
67
+ file_accessor.public_headers.map do |public_header|
68
+ public_header = if header_mappings_dir
69
+ public_header.relative_path_from(header_mappings_dir)
70
+ else
71
+ public_header.basename
44
72
  end
73
+ if header_dir
74
+ public_header = header_dir.join(public_header)
75
+ end
76
+ public_header
77
+ end
78
+ end
45
79
  end
46
80
  end
47
81
 
48
82
  if target.requires_frameworks?
49
- unless target.static_framework?
83
+ unless skip_info_plist?(native_target)
50
84
  create_info_plist_file(target.info_plist_path, native_target, target.version, target.platform)
51
85
  end
52
- create_build_phase_to_symlink_header_folders
86
+ create_build_phase_to_symlink_header_folders(native_target)
53
87
  elsif target.uses_swift?
54
- add_swift_static_library_compatibility_header_phase
88
+ add_swift_static_library_compatibility_header_phase(native_target)
55
89
  end
56
90
 
57
91
  unless skip_pch?(target.non_test_specs)
58
92
  path = target.prefix_header_path
59
- file_accessors = target.file_accessors.reject { |f| f.spec.test_specification? }
60
93
  create_prefix_header(path, file_accessors, target.platform, [native_target])
61
94
  end
62
95
  unless skip_pch?(target.test_specs)
63
- target.supported_test_types.each do |test_type|
64
- path = target.prefix_header_path_for_test_type(test_type)
65
- file_accessors = target.file_accessors.select { |f| f.spec.test_specification? }
66
- create_prefix_header(path, file_accessors, target.platform, target.test_native_targets)
96
+ target.test_specs.each do |test_spec|
97
+ path = target.prefix_header_path_for_test_spec(test_spec)
98
+ create_prefix_header(path, test_file_accessors, target.platform, test_native_targets)
67
99
  end
68
100
  end
69
- create_dummy_source
101
+ create_dummy_source(native_target)
102
+ clean_support_files_temp_dir
103
+ TargetInstallationResult.new(target, native_target, resource_bundle_targets, test_native_targets,
104
+ test_resource_bundle_targets, test_app_host_targets)
70
105
  end
71
106
  end
72
107
 
73
- # @return [Hash<Pathname,Pathname>] A hash of all umbrella headers, grouped by the directory
74
- # the are stored in
75
- #
76
- attr_accessor :umbrella_headers_by_dir
77
-
78
108
  private
79
109
 
80
110
  # @param [Array<Specification>] specs
@@ -86,6 +116,18 @@ module Pod
86
116
  specs.any? { |spec| spec.prefix_header_file.is_a?(FalseClass) }
87
117
  end
88
118
 
119
+ # True if info.plist generation should be skipped
120
+ #
121
+ # @param [PXNativeTarget] native_target
122
+ #
123
+ # @return [Boolean] Whether the target should build an Info.plist file
124
+ #
125
+ def skip_info_plist?(native_target)
126
+ return true if target.static_framework?
127
+ existing_setting = native_target.resolved_build_setting('INFOPLIST_FILE', true).values.compact
128
+ !existing_setting.empty?
129
+ end
130
+
89
131
  # Remove the default headers folder path settings for static library pod
90
132
  # targets.
91
133
  #
@@ -158,8 +200,6 @@ module Pod
158
200
 
159
201
  #-----------------------------------------------------------------------#
160
202
 
161
- SOURCE_FILE_EXTENSIONS = Sandbox::FileAccessor::SOURCE_FILE_EXTENSIONS
162
-
163
203
  # Adds the build files of the pods to the target and adds a reference to
164
204
  # the frameworks of the Pods.
165
205
  #
@@ -173,20 +213,26 @@ module Pod
173
213
  #
174
214
  # @return [void]
175
215
  #
176
- def add_files_to_build_phases
216
+ def add_files_to_build_phases(native_target, test_native_targets)
177
217
  target.file_accessors.each do |file_accessor|
178
218
  consumer = file_accessor.spec_consumer
179
219
 
180
- native_target = target.native_target_for_spec(consumer.spec)
220
+ native_target = if !consumer.spec.test_specification?
221
+ native_target
222
+ else
223
+ test_native_target_from_spec_consumer(consumer, test_native_targets)
224
+ end
225
+
181
226
  headers = file_accessor.headers
182
227
  public_headers = file_accessor.public_headers.map(&:realpath)
183
228
  private_headers = file_accessor.private_headers.map(&:realpath)
184
- other_source_files = file_accessor.source_files.reject { |sf| SOURCE_FILE_EXTENSIONS.include?(sf.extname) }
229
+ other_source_files = file_accessor.other_source_files
185
230
 
186
231
  {
187
232
  true => file_accessor.arc_source_files,
188
233
  false => file_accessor.non_arc_source_files,
189
234
  }.each do |arc, files|
235
+ next if files.empty?
190
236
  files = files - headers - other_source_files
191
237
  flags = compiler_flags_for_consumer(consumer, arc)
192
238
  regular_file_refs = project_file_references_array(files, 'source')
@@ -210,62 +256,27 @@ module Pod
210
256
  end
211
257
  end
212
258
 
213
- # Adds the test app host targets for the library to the Pods project with the
214
- # appropriate build configurations.
215
- #
216
- # @return [void]
217
- #
218
- def add_test_app_host_targets
219
- target.test_specs.each do |test_spec|
220
- next unless test_spec.consumer(target.platform).requires_app_host?
221
- name = target.app_host_label(test_spec.test_type)
222
- platform_name = target.platform.name
223
- app_host_target = project.targets.find { |t| t.name == name }
224
- if app_host_target.nil?
225
- app_host_target = Pod::Generator::AppTargetHelper.add_app_target(project, platform_name, deployment_target, name)
226
- app_host_target.build_configurations.each do |configuration|
227
- configuration.build_settings.merge!(custom_build_settings)
228
- configuration.build_settings['PRODUCT_NAME'] = name
229
- configuration.build_settings['PRODUCT_BUNDLE_IDENTIFIER'] = 'org.cocoapods.${PRODUCT_NAME:rfc1034identifier}'
230
- configuration.build_settings['CODE_SIGN_IDENTITY'] = '' if target.platform == :osx
231
- end
232
- Pod::Generator::AppTargetHelper.add_app_host_main_file(project, app_host_target, platform_name, name)
233
- app_host_info_plist_path = project.path.dirname.+("#{name}/Info.plist")
234
- create_info_plist_file(app_host_info_plist_path, app_host_target, '1.0.0', target.platform, :appl)
235
- end
236
- # Wire all test native targets with the app host.
237
- native_test_target = target.native_target_for_spec(test_spec)
238
- native_test_target.build_configurations.each do |configuration|
239
- test_host = "$(BUILT_PRODUCTS_DIR)/#{name}.app/"
240
- test_host << 'Contents/MacOS/' if target.platform == :osx
241
- test_host << name.to_s
242
- configuration.build_settings['TEST_HOST'] = test_host
243
- end
244
- target_attributes = project.root_object.attributes['TargetAttributes'] || {}
245
- target_attributes[native_test_target.uuid.to_s] = { 'TestTargetID' => app_host_target.uuid.to_s }
246
- project.root_object.attributes['TargetAttributes'] = target_attributes
247
- end
248
- end
249
-
250
259
  # Adds the test targets for the library to the Pods project with the
251
260
  # appropriate build configurations.
252
261
  #
253
- # @return [void]
262
+ # @return [Array<PBXNativeTarget>] the test native targets created.
254
263
  #
255
264
  def add_test_targets
256
- target.supported_test_types.each do |test_type|
265
+ target.test_specs.map do |test_spec|
266
+ spec_consumer = test_spec.consumer(target.platform)
267
+ test_type = spec_consumer.test_type
257
268
  product_type = target.product_type_for_test_type(test_type)
258
- name = target.test_target_label(test_type)
269
+ name = target.test_target_label(test_spec)
259
270
  platform_name = target.platform.name
260
- language = target.all_dependent_targets.any?(&:uses_swift?) ? :swift : :objc
261
- native_test_target = project.new_target(product_type, name, platform_name, deployment_target, nil, language)
262
- native_test_target.product_reference.name = name
271
+ language = target.uses_swift_for_test_spec?(test_spec) ? :swift : :objc
272
+ test_native_target = project.new_target(product_type, name, platform_name, deployment_target, nil, language)
273
+ test_native_target.product_reference.name = name
263
274
 
264
275
  target.user_build_configurations.each do |bc_name, type|
265
- native_test_target.add_build_configuration(bc_name, type)
276
+ test_native_target.add_build_configuration(bc_name, type)
266
277
  end
267
278
 
268
- native_test_target.build_configurations.each do |configuration|
279
+ test_native_target.build_configurations.each do |configuration|
269
280
  configuration.build_settings.merge!(custom_build_settings)
270
281
  # target_installer will automatically add an empty `OTHER_LDFLAGS`. For test
271
282
  # targets those are set via a test xcconfig file instead.
@@ -288,15 +299,46 @@ module Pod
288
299
  end
289
300
 
290
301
  # Test native targets also need frameworks and resources to be copied over to their xctest bundle.
291
- create_test_target_embed_frameworks_script(test_type)
292
- create_test_target_copy_resources_script(test_type)
302
+ create_test_target_embed_frameworks_script(test_spec)
303
+ create_test_target_copy_resources_script(test_spec)
293
304
 
294
- # Generate vanila Info.plist for test target similar to the one xcode gererates for new test target.
305
+ # Generate vanilla Info.plist for test target similar to the one Xcode generates for new test target.
295
306
  # This creates valid test bundle accessible at the runtime, allowing tests to load bundle resources
296
307
  # defined in podspec.
297
- create_info_plist_file(target.info_plist_path_for_test_type(test_type), native_test_target, '1.0', target.platform, :bndl)
308
+ create_info_plist_file(target.info_plist_path_for_test_spec(test_spec), test_native_target, '1.0', target.platform, :bndl)
298
309
 
299
- target.test_native_targets << native_test_target
310
+ test_native_target
311
+ end
312
+ end
313
+
314
+ # Adds the test app host targets for the library to the Pods project with the
315
+ # appropriate build configurations.
316
+ #
317
+ # @param [Array<PBXNativeTarget>] test_native_targets
318
+ # the test native targets that have been created to use as a lookup when linking the app host to.
319
+ #
320
+ # @return [Array<PBXNativeTarget>] the app host targets created.
321
+ #
322
+ def add_test_app_host_targets(test_native_targets)
323
+ target.test_spec_consumers.select(&:requires_app_host?).group_by(&:test_type).map do |test_type, test_spec_consumers|
324
+ platform = target.platform
325
+ name = "AppHost-#{target.label}-#{test_type.capitalize}-Tests"
326
+ app_host_target = AppHostInstaller.new(sandbox, project, platform, name).install!
327
+ # Wire test native targets to the generated app host.
328
+ test_spec_consumers.each do |test_spec_consumer|
329
+ test_native_target = test_native_target_from_spec_consumer(test_spec_consumer, test_native_targets)
330
+ test_native_target.build_configurations.each do |configuration|
331
+ test_host = "$(BUILT_PRODUCTS_DIR)/#{app_host_target.name}.app/"
332
+ test_host << 'Contents/MacOS/' if platform == :osx
333
+ test_host << app_host_target.name.to_s
334
+ configuration.build_settings['TEST_HOST'] = test_host
335
+ end
336
+ target_attributes = project.root_object.attributes['TargetAttributes'] || {}
337
+ target_attributes[test_native_target.uuid.to_s] = { 'TestTargetID' => app_host_target.uuid.to_s }
338
+ project.root_object.attributes['TargetAttributes'] = target_attributes
339
+ test_native_target.add_dependency(app_host_target)
340
+ end
341
+ app_host_target
300
342
  end
301
343
  end
302
344
 
@@ -305,58 +347,53 @@ module Pod
305
347
  # @note The source files are grouped by Pod and in turn by subspec
306
348
  # (recursively) in the resources group.
307
349
  #
308
- # @return [void]
350
+ # @param [Array<Sandbox::FileAccessor>] file_accessors
351
+ # the file accessors list to generate resource bundles for.
309
352
  #
310
- def add_resources_bundle_targets
311
- target.file_accessors.each do |file_accessor|
312
- file_accessor.resource_bundles.each do |bundle_name, paths|
353
+ # @return [Array<PBXNativeTarget] the resource bundle native targets created.
354
+ #
355
+ def add_resources_bundle_targets(file_accessors)
356
+ file_accessors.each_with_object({}) do |file_accessor, hash|
357
+ hash[file_accessor.spec.name] = file_accessor.resource_bundles.map do |bundle_name, paths|
313
358
  label = target.resources_bundle_target_label(bundle_name)
314
- bundle_target = project.new_resources_bundle(label, file_accessor.spec_consumer.platform_name)
315
- bundle_target.product_reference.tap do |bundle_product|
359
+ resource_bundle_target = project.new_resources_bundle(label, file_accessor.spec_consumer.platform_name)
360
+ resource_bundle_target.product_reference.tap do |bundle_product|
316
361
  bundle_file_name = "#{bundle_name}.bundle"
317
362
  bundle_product.name = bundle_file_name
318
363
  end
319
364
 
365
+ contains_compile_phase_refs = false
320
366
  filter_resource_file_references(paths) do |resource_phase_refs, compile_phase_refs|
321
367
  # Resource bundles are only meant to have resources, so install everything
322
368
  # into the resources phase. See note in filter_resource_file_references.
323
- bundle_target.add_resources(resource_phase_refs + compile_phase_refs)
369
+ resource_bundle_target.add_resources(resource_phase_refs + compile_phase_refs)
370
+ contains_compile_phase_refs = !compile_phase_refs.empty?
324
371
  end
325
372
 
326
- native_target = target.native_target_for_spec(file_accessor.spec_consumer.spec)
327
373
  target.user_build_configurations.each do |bc_name, type|
328
- bundle_target.add_build_configuration(bc_name, type)
329
- end
330
- bundle_target.deployment_target = deployment_target
331
-
332
- test_specification = file_accessor.spec.test_specification?
333
-
334
- if test_specification
335
- target.test_resource_bundle_targets << bundle_target
336
- else
337
- target.resource_bundle_targets << bundle_target
338
- end
339
-
340
- if target.should_build?
341
- native_target.add_dependency(bundle_target)
342
- if target.requires_frameworks?
343
- native_target.add_resources([bundle_target.product_reference])
344
- end
374
+ resource_bundle_target.add_build_configuration(bc_name, type)
345
375
  end
376
+ resource_bundle_target.deployment_target = deployment_target
346
377
 
347
378
  # Create Info.plist file for bundle
348
379
  path = target.info_plist_path
349
380
  path.dirname.mkdir unless path.dirname.exist?
350
381
  info_plist_path = path.dirname + "ResourceBundle-#{bundle_name}-#{path.basename}"
351
- create_info_plist_file(info_plist_path, bundle_target, target.version, target.platform, :bndl)
382
+ create_info_plist_file(info_plist_path, resource_bundle_target, target.version, target.platform, :bndl)
352
383
 
353
- bundle_target.build_configurations.each do |c|
354
- c.build_settings['PRODUCT_NAME'] = bundle_name
384
+ resource_bundle_target.build_configurations.each do |configuration|
385
+ configuration.build_settings['PRODUCT_NAME'] = bundle_name
355
386
  # Do not set the CONFIGURATION_BUILD_DIR for resource bundles that are only meant for test targets.
356
387
  # This is because the test target itself also does not set this configuration build dir and it expects
357
388
  # all bundles to be copied from the default path.
358
- unless test_specification
359
- c.build_settings['CONFIGURATION_BUILD_DIR'] = target.configuration_build_dir('$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)')
389
+ unless file_accessor.spec.test_specification?
390
+ configuration.build_settings['CONFIGURATION_BUILD_DIR'] = target.configuration_build_dir('$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)')
391
+ end
392
+
393
+ # Set the `SWIFT_VERSION` build setting for resource bundles that could have resources that get
394
+ # compiled such as an `xcdatamodeld` file which has 'Swift' as its code generation language.
395
+ if contains_compile_phase_refs && target.uses_swift?
396
+ configuration.build_settings['SWIFT_VERSION'] = target.swift_version
360
397
  end
361
398
 
362
399
  # Set the correct device family for this bundle, based on the platform
@@ -367,21 +404,28 @@ module Pod
367
404
  }
368
405
 
369
406
  if (family = device_family_by_platform[target.platform.name])
370
- c.build_settings['TARGETED_DEVICE_FAMILY'] = family
407
+ configuration.build_settings['TARGETED_DEVICE_FAMILY'] = family
371
408
  end
372
409
  end
410
+
411
+ resource_bundle_target
373
412
  end
374
413
  end
375
414
  end
376
415
 
377
416
  # Generates the contents of the xcconfig file and saves it to disk.
378
417
  #
418
+ # @param [PBXNativeTarget] native_target
419
+ # the native target to link the xcconfig file into.
420
+ #
421
+ # @param [Array<PBXNativeTarget>] resource_bundle_targets
422
+ # the additional resource bundle targets to link the xcconfig file into.
423
+ #
379
424
  # @return [void]
380
425
  #
381
- def create_xcconfig_file
426
+ def create_xcconfig_file(native_target, resource_bundle_targets)
382
427
  path = target.xcconfig_path
383
- xcconfig_gen = Generator::XCConfig::PodXCConfig.new(target)
384
- update_changed_file(xcconfig_gen, path)
428
+ update_changed_file(target.build_settings, path)
385
429
  xcconfig_file_ref = add_file_to_support_group(path)
386
430
 
387
431
  native_target.build_configurations.each do |c|
@@ -389,46 +433,56 @@ module Pod
389
433
  end
390
434
 
391
435
  # also apply the private config to resource bundle targets.
392
- apply_xcconfig_file_ref_to_resource_bundle_targets(target.resource_bundle_targets, xcconfig_file_ref)
436
+ apply_xcconfig_file_ref_to_resource_bundle_targets(resource_bundle_targets, xcconfig_file_ref)
393
437
  end
394
438
 
395
439
  # Generates the contents of the xcconfig file used for each test target type and saves it to disk.
396
440
  #
441
+ # @param [Array<PBXNativeTarget>] test_native_targets
442
+ # the test native target to link the xcconfig file into.
443
+ #
444
+ # @param [Hash{String=>Array<PBXNativeTarget>}] test_resource_bundle_targets
445
+ # the additional test resource bundle targets to link the xcconfig file into.
446
+ #
397
447
  # @return [void]
398
448
  #
399
- def create_test_xcconfig_files
400
- target.supported_test_types.each do |test_type|
401
- path = target.xcconfig_path(test_type.to_s)
402
- xcconfig_gen = Generator::XCConfig::PodXCConfig.new(target, true)
403
- update_changed_file(xcconfig_gen, path)
404
- xcconfig_file_ref = add_file_to_support_group(path)
405
-
406
- target.test_native_targets.each do |test_target|
407
- test_target.build_configurations.each do |test_target_bc|
408
- test_target_swift_debug_hack(test_target_bc)
409
- test_target_bc.base_configuration_reference = xcconfig_file_ref
410
- end
449
+ def create_test_xcconfig_files(test_native_targets, test_resource_bundle_targets)
450
+ target.test_specs.each do |test_spec|
451
+ spec_consumer = test_spec.consumer(target.platform)
452
+ test_type = spec_consumer.test_type
453
+ path = target.xcconfig_path("#{test_type.capitalize}-#{test_spec.name.split('/')[1..-1].join('-')}")
454
+ update_changed_file(Target::BuildSettings::PodTargetSettings.new(target, test_spec), path)
455
+ test_xcconfig_file_ref = add_file_to_support_group(path)
456
+
457
+ test_native_target = test_native_target_from_spec_consumer(spec_consumer, test_native_targets)
458
+ test_native_target.build_configurations.each do |test_native_target_bc|
459
+ test_target_swift_debug_hack(test_spec, test_native_target_bc)
460
+ test_native_target_bc.base_configuration_reference = test_xcconfig_file_ref
411
461
  end
412
462
 
413
- # also apply the private config to resource bundle test targets.
414
- apply_xcconfig_file_ref_to_resource_bundle_targets(target.test_resource_bundle_targets, xcconfig_file_ref)
463
+ # also apply the private config to resource bundle test targets related to this test spec.
464
+ scoped_test_resource_bundle_targets = test_resource_bundle_targets[test_spec.name]
465
+ unless scoped_test_resource_bundle_targets.empty?
466
+ apply_xcconfig_file_ref_to_resource_bundle_targets(scoped_test_resource_bundle_targets, test_xcconfig_file_ref)
467
+ end
415
468
  end
416
469
  end
417
470
 
418
471
  # Creates a script that copies the resources to the bundle of the test target.
419
472
  #
420
- # @param [Symbol] test_type
421
- # The test type to create the script for.
473
+ # @param [Specification] test_spec
474
+ # The test spec to create the copy resources script for.
422
475
  #
423
476
  # @return [void]
424
477
  #
425
- def create_test_target_copy_resources_script(test_type)
426
- path = target.copy_resources_script_path_for_test_type(test_type)
427
- pod_targets = target.all_dependent_targets
478
+ def create_test_target_copy_resources_script(test_spec)
479
+ path = target.copy_resources_script_path_for_test_spec(test_spec)
480
+ pod_targets = target.dependent_targets_for_test_spec(test_spec)
428
481
  resource_paths_by_config = target.user_build_configurations.keys.each_with_object({}) do |config, resources_by_config|
429
482
  resources_by_config[config] = pod_targets.flat_map do |pod_target|
430
- include_test_spec_paths = pod_target == target
431
- pod_target.resource_paths(include_test_spec_paths)
483
+ spec_paths_to_include = pod_target.non_test_specs.map(&:name)
484
+ spec_paths_to_include << test_spec.name if pod_target == target
485
+ pod_target.resource_paths.values_at(*spec_paths_to_include).flatten.compact
432
486
  end
433
487
  end
434
488
  generator = Generator::CopyResourcesScript.new(resource_paths_by_config, target.platform)
@@ -438,18 +492,19 @@ module Pod
438
492
 
439
493
  # Creates a script that embeds the frameworks to the bundle of the test target.
440
494
  #
441
- # @param [Symbol] test_type
442
- # The test type to create the script for.
495
+ # @param [Specification] test_spec
496
+ # The test spec to create the embed frameworks script for.
443
497
  #
444
498
  # @return [void]
445
499
  #
446
- def create_test_target_embed_frameworks_script(test_type)
447
- path = target.embed_frameworks_script_path_for_test_type(test_type)
448
- pod_targets = target.all_dependent_targets
500
+ def create_test_target_embed_frameworks_script(test_spec)
501
+ path = target.embed_frameworks_script_path_for_test_spec(test_spec)
502
+ pod_targets = target.dependent_targets_for_test_spec(test_spec)
449
503
  framework_paths_by_config = target.user_build_configurations.keys.each_with_object({}) do |config, paths_by_config|
450
504
  paths_by_config[config] = pod_targets.flat_map do |pod_target|
451
- include_test_spec_paths = pod_target == target
452
- pod_target.framework_paths(include_test_spec_paths)
505
+ spec_paths_to_include = pod_target.non_test_specs.map(&:name)
506
+ spec_paths_to_include << test_spec.name if pod_target == target
507
+ pod_target.framework_paths.values_at(*spec_paths_to_include).flatten.compact.uniq
453
508
  end
454
509
  end
455
510
  generator = Generator::EmbedFrameworksScript.new(framework_paths_by_config)
@@ -462,9 +517,9 @@ module Pod
462
517
  #
463
518
  # @return [void]
464
519
  #
465
- def test_target_swift_debug_hack(test_target_bc)
520
+ def test_target_swift_debug_hack(test_spec, test_target_bc)
466
521
  return unless test_target_bc.debug?
467
- return unless target.all_dependent_targets.any?(&:uses_swift?)
522
+ return unless target.dependent_targets_for_test_spec(test_spec).any?(&:uses_swift?)
468
523
  ldflags = test_target_bc.build_settings['OTHER_LDFLAGS'] ||= '$(inherited)'
469
524
  ldflags << ' -lswiftSwiftOnoneSupport'
470
525
  end
@@ -476,9 +531,12 @@ module Pod
476
531
  # header_mappings_dir interferes with xcodebuild's expectations
477
532
  # about the existence of private or public headers.
478
533
  #
534
+ # @param [PBXNativeTarget] native_target
535
+ # the native target to add the script phase into.
536
+ #
479
537
  # @return [void]
480
538
  #
481
- def create_build_phase_to_symlink_header_folders
539
+ def create_build_phase_to_symlink_header_folders(native_target)
482
540
  return unless target.platform.name == :osx && header_mappings_dir
483
541
 
484
542
  build_phase = native_target.new_shell_script_build_phase('Create Symlinks to Header Folders')
@@ -502,7 +560,7 @@ module Pod
502
560
  # @param [Platform] platform
503
561
  # the platform to use for this prefix header.
504
562
  #
505
- # @param [Array<PBXNativetarget>] native_targets
563
+ # @param [Array<PBXNativeTarget>] native_targets
506
564
  # the native targets on which the prefix header should be configured for.
507
565
  #
508
566
  # @return [void]
@@ -587,10 +645,10 @@ module Pod
587
645
  end
588
646
  end
589
647
 
590
- def create_module_map
591
- return super unless custom_module_map
648
+ def create_module_map(native_target)
649
+ return super(native_target) unless custom_module_map
592
650
 
593
- path = target.module_map_path
651
+ path = target.module_map_path_to_write
594
652
  UI.message "- Copying module map file to #{UI.path(path)}" do
595
653
  contents = custom_module_map.read
596
654
  unless target.requires_frameworks?
@@ -600,17 +658,23 @@ module Pod
600
658
  update_changed_file(generator, path)
601
659
  add_file_to_support_group(path)
602
660
 
661
+ linked_path = target.module_map_path
662
+ if path != linked_path
663
+ linked_path.dirname.mkpath
664
+ FileUtils.ln_sf(path, linked_path)
665
+ end
666
+
667
+ relative_path = target.module_map_path.relative_path_from(sandbox.root).to_s
603
668
  native_target.build_configurations.each do |c|
604
- relative_path = path.relative_path_from(sandbox.root)
605
669
  c.build_settings['MODULEMAP_FILE'] = relative_path.to_s
606
670
  end
607
671
  end
608
672
  end
609
673
 
610
674
  def module_map_additional_headers
611
- return [] unless umbrella_headers_by_dir
675
+ return [] unless umbrella_header_paths
612
676
 
613
- other_paths = umbrella_headers_by_dir[target.module_map_path.dirname] - [target.umbrella_header_path]
677
+ other_paths = umbrella_header_paths - [target.umbrella_header_path]
614
678
  other_paths.map do |module_map_path|
615
679
  # exclude other targets umbrella headers, to avoid
616
680
  # incomplete umbrella warnings
@@ -618,8 +682,8 @@ module Pod
618
682
  end
619
683
  end
620
684
 
621
- def create_umbrella_header
622
- return super unless custom_module_map
685
+ def create_umbrella_header(native_target)
686
+ return super(native_target) unless custom_module_map
623
687
  end
624
688
 
625
689
  def custom_module_map
@@ -675,15 +739,59 @@ module Pod
675
739
  project.pod_support_files_group(pod_name, dir)
676
740
  end
677
741
 
742
+ # @param [String] name
743
+ # The name of the app host.
744
+
745
+ # @param [Symbol] test_type
746
+ # The test type this Info.plist path is for.
747
+ #
748
+ # @return [Pathname] The absolute path of the Info.plist to use for an app host.
749
+ #
750
+ def app_host_info_plist_path_for_test_type(name, test_type)
751
+ project.path.dirname.+("#{name}/#{target.app_host_label(test_type)}-Info.plist")
752
+ end
753
+
754
+ def test_native_target_from_spec_consumer(spec_consumer, test_native_targets)
755
+ test_native_targets.find do |test_native_target|
756
+ test_native_target.name == target.test_target_label(spec_consumer.spec)
757
+ end
758
+ end
759
+
760
+ # Adds a placeholder native target for the library to the Pods project with the
761
+ # appropriate build configurations.
762
+ #
763
+ # @return [PBXAggregateTarget] the native target that was added.
764
+ #
765
+ def add_placeholder_target
766
+ native_target = project.new_aggregate_target(target.label, [], target.platform.name, deployment_target)
767
+ target.user_build_configurations.each do |bc_name, type|
768
+ native_target.add_build_configuration(bc_name, type)
769
+ end
770
+ unless target.archs.empty?
771
+ native_target.build_configurations.each do |configuration|
772
+ configuration.build_settings['ARCHS'] = target.archs
773
+ end
774
+ end
775
+ native_target
776
+ end
777
+
678
778
  # Adds a shell script phase, intended only for static library targets that contain swift,
679
779
  # to copy the ObjC compatibility header (the -Swift.h file that the swift compiler generates)
680
780
  # to the built products directory. Additionally, the script phase copies the module map, appending a `.Swift`
681
781
  # submodule that references the (moved) compatibility header. Since the module map has been moved, the umbrella header
682
782
  # is _also_ copied, so that it is sitting next to the module map. This is necessary for a successful archive build.
683
783
  #
784
+ # @param [PBXNativeTarget] native_target
785
+ # the native target to add the Swift static library script phase into.
786
+ #
684
787
  # @return [Void]
685
788
  #
686
- def add_swift_static_library_compatibility_header_phase
789
+ def add_swift_static_library_compatibility_header_phase(native_target)
790
+ if custom_module_map
791
+ raise Informative, 'Using Swift static libraries with custom module maps is currently not supported. ' \
792
+ "Please build `#{target.label}` as a framework or remove the custom module map."
793
+ end
794
+
687
795
  build_phase = native_target.new_shell_script_build_phase('Copy generated compatibility header')
688
796
 
689
797
  relative_module_map_path = target.module_map_path.relative_path_from(target.sandbox.root)